gfx/skia/trunk/src/utils/SkPictureUtils.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/utils/SkPictureUtils.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,237 @@
     1.4 +/*
     1.5 + * Copyright 2012 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#include "SkBitmapDevice.h"
    1.12 +#include "SkCanvas.h"
    1.13 +#include "SkData.h"
    1.14 +#include "SkNoSaveLayerCanvas.h"
    1.15 +#include "SkPictureUtils.h"
    1.16 +#include "SkPixelRef.h"
    1.17 +#include "SkRRect.h"
    1.18 +#include "SkShader.h"
    1.19 +
    1.20 +class PixelRefSet {
    1.21 +public:
    1.22 +    PixelRefSet(SkTDArray<SkPixelRef*>* array) : fArray(array) {}
    1.23 +
    1.24 +    // This does a linear search on existing pixelrefs, so if this list gets big
    1.25 +    // we should use a more complex sorted/hashy thing.
    1.26 +    //
    1.27 +    void add(SkPixelRef* pr) {
    1.28 +        uint32_t genID = pr->getGenerationID();
    1.29 +        if (fGenID.find(genID) < 0) {
    1.30 +            *fArray->append() = pr;
    1.31 +            *fGenID.append() = genID;
    1.32 +//            SkDebugf("--- adding [%d] %x %d\n", fArray->count() - 1, pr, genID);
    1.33 +        } else {
    1.34 +//            SkDebugf("--- already have %x %d\n", pr, genID);
    1.35 +        }
    1.36 +    }
    1.37 +
    1.38 +private:
    1.39 +    SkTDArray<SkPixelRef*>* fArray;
    1.40 +    SkTDArray<uint32_t>     fGenID;
    1.41 +};
    1.42 +
    1.43 +static void not_supported() {
    1.44 +    SkDEBUGFAIL("this method should never be called");
    1.45 +}
    1.46 +
    1.47 +static void nothing_to_do() {}
    1.48 +
    1.49 +/**
    1.50 + *  This device will route all bitmaps (primitives and in shaders) to its PRSet.
    1.51 + *  It should never actually draw anything, so there need not be any pixels
    1.52 + *  behind its device.
    1.53 + */
    1.54 +class GatherPixelRefDevice : public SkBaseDevice {
    1.55 +public:
    1.56 +    SK_DECLARE_INST_COUNT(GatherPixelRefDevice)
    1.57 +
    1.58 +    GatherPixelRefDevice(int width, int height, PixelRefSet* prset) {
    1.59 +        fSize.set(width, height);
    1.60 +        fEmptyBitmap.setConfig(SkImageInfo::MakeUnknown(width, height));
    1.61 +        fPRSet = prset;
    1.62 +    }
    1.63 +
    1.64 +    virtual int width() const SK_OVERRIDE { return fSize.width(); }
    1.65 +    virtual int height() const SK_OVERRIDE { return fSize.height(); }
    1.66 +    virtual bool isOpaque() const SK_OVERRIDE { return false; }
    1.67 +    virtual SkBitmap::Config config() const SK_OVERRIDE {
    1.68 +        return SkBitmap::kNo_Config;
    1.69 +    }
    1.70 +    virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; }
    1.71 +    virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE {
    1.72 +        return false;
    1.73 +    }
    1.74 +    // TODO: allow this call to return failure, or move to SkBitmapDevice only.
    1.75 +    virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE {
    1.76 +        return fEmptyBitmap;
    1.77 +    }
    1.78 +    virtual void lockPixels() SK_OVERRIDE { nothing_to_do(); }
    1.79 +    virtual void unlockPixels() SK_OVERRIDE { nothing_to_do(); }
    1.80 +    virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; }
    1.81 +    virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; }
    1.82 +    virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&,
    1.83 +                             SkBitmap* result, SkIPoint* offset) SK_OVERRIDE {
    1.84 +        return false;
    1.85 +    }
    1.86 +
    1.87 +    virtual void clear(SkColor color) SK_OVERRIDE {
    1.88 +        nothing_to_do();
    1.89 +    }
    1.90 +
    1.91 +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
    1.92 +    virtual void writePixels(const SkBitmap& bitmap, int x, int y,
    1.93 +                             SkCanvas::Config8888 config8888) SK_OVERRIDE {
    1.94 +        not_supported();
    1.95 +    }
    1.96 +#endif
    1.97 +
    1.98 +    virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE {
    1.99 +        this->addBitmapFromPaint(paint);
   1.100 +    }
   1.101 +    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
   1.102 +                            const SkPoint[], const SkPaint& paint) SK_OVERRIDE {
   1.103 +        this->addBitmapFromPaint(paint);
   1.104 +    }
   1.105 +    virtual void drawRect(const SkDraw&, const SkRect&,
   1.106 +                          const SkPaint& paint) SK_OVERRIDE {
   1.107 +        this->addBitmapFromPaint(paint);
   1.108 +    }
   1.109 +    virtual void drawRRect(const SkDraw&, const SkRRect&,
   1.110 +                           const SkPaint& paint) SK_OVERRIDE {
   1.111 +        this->addBitmapFromPaint(paint);
   1.112 +    }
   1.113 +    virtual void drawOval(const SkDraw&, const SkRect&,
   1.114 +                          const SkPaint& paint) SK_OVERRIDE {
   1.115 +        this->addBitmapFromPaint(paint);
   1.116 +    }
   1.117 +    virtual void drawPath(const SkDraw&, const SkPath& path,
   1.118 +                          const SkPaint& paint, const SkMatrix* prePathMatrix,
   1.119 +                          bool pathIsMutable) SK_OVERRIDE {
   1.120 +        this->addBitmapFromPaint(paint);
   1.121 +    }
   1.122 +    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
   1.123 +                            const SkMatrix&, const SkPaint& paint) SK_OVERRIDE {
   1.124 +        this->addBitmap(bitmap);
   1.125 +        if (SkBitmap::kA8_Config == bitmap.config()) {
   1.126 +            this->addBitmapFromPaint(paint);
   1.127 +        }
   1.128 +    }
   1.129 +    virtual void drawBitmapRect(const SkDraw&, const SkBitmap& bitmap,
   1.130 +                                const SkRect* srcOrNull, const SkRect& dst,
   1.131 +                                const SkPaint& paint,
   1.132 +                                SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE {
   1.133 +        this->addBitmap(bitmap);
   1.134 +        if (SkBitmap::kA8_Config == bitmap.config()) {
   1.135 +            this->addBitmapFromPaint(paint);
   1.136 +        }
   1.137 +    }
   1.138 +    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
   1.139 +                            int x, int y, const SkPaint& paint) SK_OVERRIDE {
   1.140 +        this->addBitmap(bitmap);
   1.141 +    }
   1.142 +    virtual void drawText(const SkDraw&, const void* text, size_t len,
   1.143 +                          SkScalar x, SkScalar y,
   1.144 +                          const SkPaint& paint) SK_OVERRIDE {
   1.145 +        this->addBitmapFromPaint(paint);
   1.146 +    }
   1.147 +    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
   1.148 +                             const SkScalar pos[], SkScalar constY,
   1.149 +                             int, const SkPaint& paint) SK_OVERRIDE {
   1.150 +        this->addBitmapFromPaint(paint);
   1.151 +    }
   1.152 +    virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
   1.153 +                                const SkPath& path, const SkMatrix* matrix,
   1.154 +                                const SkPaint& paint) SK_OVERRIDE {
   1.155 +        this->addBitmapFromPaint(paint);
   1.156 +    }
   1.157 +    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
   1.158 +                              const SkPoint verts[], const SkPoint texs[],
   1.159 +                              const SkColor colors[], SkXfermode* xmode,
   1.160 +                              const uint16_t indices[], int indexCount,
   1.161 +                              const SkPaint& paint) SK_OVERRIDE {
   1.162 +        this->addBitmapFromPaint(paint);
   1.163 +    }
   1.164 +    virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
   1.165 +                            const SkPaint&) SK_OVERRIDE {
   1.166 +        nothing_to_do();
   1.167 +    }
   1.168 +
   1.169 +protected:
   1.170 +    virtual bool onReadPixels(const SkBitmap& bitmap,
   1.171 +                              int x, int y,
   1.172 +                              SkCanvas::Config8888 config8888) SK_OVERRIDE {
   1.173 +        not_supported();
   1.174 +        return false;
   1.175 +    }
   1.176 +
   1.177 +    virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE {
   1.178 +        not_supported();
   1.179 +    }
   1.180 +    virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) SK_OVERRIDE {
   1.181 +        // we expect to only get called via savelayer, in which case it is fine.
   1.182 +        SkASSERT(kSaveLayer_Usage == usage);
   1.183 +        return SkNEW_ARGS(GatherPixelRefDevice, (info.width(), info.height(), fPRSet));
   1.184 +    }
   1.185 +    virtual void flush() SK_OVERRIDE {}
   1.186 +
   1.187 +private:
   1.188 +    PixelRefSet*  fPRSet;
   1.189 +    SkBitmap fEmptyBitmap;  // legacy -- need to remove the need for this guy
   1.190 +    SkISize fSize;
   1.191 +
   1.192 +    void addBitmap(const SkBitmap& bm) {
   1.193 +      fPRSet->add(bm.pixelRef());
   1.194 +    }
   1.195 +
   1.196 +    void addBitmapFromPaint(const SkPaint& paint) {
   1.197 +      SkShader* shader = paint.getShader();
   1.198 +      if (shader) {
   1.199 +          SkBitmap bm;
   1.200 +          // Check whether the shader is a gradient in order to short-circuit
   1.201 +          // call to asABitmap to prevent generation of bitmaps from
   1.202 +          // gradient shaders, which implement asABitmap.
   1.203 +          if (SkShader::kNone_GradientType == shader->asAGradient(NULL) &&
   1.204 +              shader->asABitmap(&bm, NULL, NULL)) {
   1.205 +              fPRSet->add(bm.pixelRef());
   1.206 +          }
   1.207 +      }
   1.208 +    }
   1.209 +
   1.210 +    typedef SkBaseDevice INHERITED;
   1.211 +};
   1.212 +
   1.213 +SkData* SkPictureUtils::GatherPixelRefs(SkPicture* pict, const SkRect& area) {
   1.214 +    if (NULL == pict) {
   1.215 +        return NULL;
   1.216 +    }
   1.217 +
   1.218 +    // this test also handles if either area or pict's width/height are empty
   1.219 +    if (!SkRect::Intersects(area,
   1.220 +                            SkRect::MakeWH(SkIntToScalar(pict->width()),
   1.221 +                                           SkIntToScalar(pict->height())))) {
   1.222 +        return NULL;
   1.223 +    }
   1.224 +
   1.225 +    SkTDArray<SkPixelRef*> array;
   1.226 +    PixelRefSet prset(&array);
   1.227 +
   1.228 +    GatherPixelRefDevice device(pict->width(), pict->height(), &prset);
   1.229 +    SkNoSaveLayerCanvas canvas(&device);
   1.230 +
   1.231 +    canvas.clipRect(area, SkRegion::kIntersect_Op, false);
   1.232 +    canvas.drawPicture(*pict);
   1.233 +
   1.234 +    SkData* data = NULL;
   1.235 +    int count = array.count();
   1.236 +    if (count > 0) {
   1.237 +        data = SkData::NewFromMalloc(array.detach(), count * sizeof(SkPixelRef*));
   1.238 +    }
   1.239 +    return data;
   1.240 +}

mercurial