| Index: src/core/SkPictureShader.cpp
|
| diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp
|
| index 1453aee0a8658fb34a2d4351da2f7fb1f3d974b0..cf0157c2a59fd880b4f9f3fe65bfd25a0b8e25cc 100644
|
| --- a/src/core/SkPictureShader.cpp
|
| +++ b/src/core/SkPictureShader.cpp
|
| @@ -10,7 +10,6 @@
|
| #include "SkBitmap.h"
|
| #include "SkBitmapProcShader.h"
|
| #include "SkCanvas.h"
|
| -#include "SkImageGenerator.h"
|
| #include "SkMatrixUtils.h"
|
| #include "SkPicture.h"
|
| #include "SkReadBuffer.h"
|
| @@ -22,50 +21,6 @@
|
|
|
| namespace {
|
| static unsigned gBitmapSkaderKeyNamespaceLabel;
|
| -
|
| -class PictureImageGenerator : public SkImageGenerator {
|
| -public:
|
| - PictureImageGenerator(const SkPicture* picture,
|
| - const SkRect& pictureTile,
|
| - const SkISize& tileSize)
|
| - : fPicture(SkRef(picture))
|
| - , fPictureTile(pictureTile)
|
| - , fRasterTileInfo(SkImageInfo::MakeN32Premul(tileSize)) {}
|
| -
|
| -protected:
|
| - virtual bool onGetInfo(SkImageInfo *info) SK_OVERRIDE {
|
| - *info = fRasterTileInfo;
|
| - return true;
|
| - }
|
| -
|
| - virtual Result onGetPixels(const SkImageInfo& info, void *pixels, size_t rowBytes,
|
| - SkPMColor ctable[], int *ctableCount) SK_OVERRIDE {
|
| - if (info != fRasterTileInfo || SkToBool(ctable) || SkToBool(ctableCount)) {
|
| - return kInvalidConversion;
|
| - }
|
| -
|
| - SkSize tileScale = SkSize::Make(SkIntToScalar(info.width()) / fPictureTile.width(),
|
| - SkIntToScalar(info.height()) / fPictureTile.height());
|
| - SkBitmap tileBitmap;
|
| - if (!tileBitmap.installPixels(info, pixels, rowBytes)) {
|
| - return kInvalidParameters;
|
| - }
|
| - tileBitmap.eraseColor(SK_ColorTRANSPARENT);
|
| -
|
| - // Always disable LCD text, since we can't assume our image will be opaque.
|
| - SkCanvas tileCanvas(tileBitmap, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
|
| - tileCanvas.scale(tileScale.width(), tileScale.height());
|
| - tileCanvas.translate(-fPictureTile.x(), -fPictureTile.y());
|
| - tileCanvas.drawPicture(fPicture);
|
| -
|
| - return kSuccess;
|
| - }
|
| -
|
| -private:
|
| - SkAutoTUnref<const SkPicture> fPicture;
|
| - const SkRect fPictureTile;
|
| - const SkImageInfo fRasterTileInfo;
|
| -};
|
|
|
| struct BitmapShaderKey : public SkResourceCache::Key {
|
| public:
|
| @@ -126,11 +81,23 @@
|
|
|
| result->reset(SkRef(rec.fShader.get()));
|
|
|
| - // The bitmap shader is backed by an image generator, thus it can always re-generate its
|
| - // pixels if discarded.
|
| - return true;
|
| + SkBitmap tile;
|
| + rec.fShader.get()->asABitmap(&tile, NULL, NULL);
|
| + // FIXME: this doesn't protect the pixels from being discarded as soon as we unlock.
|
| + // Should be handled via a pixel ref generator instead
|
| + // (https://code.google.com/p/skia/issues/detail?id=3220).
|
| + SkAutoLockPixels alp(tile, true);
|
| + return tile.getPixels() != NULL;
|
| }
|
| };
|
| +
|
| +static bool cache_try_alloc_pixels(SkBitmap* bitmap) {
|
| + SkBitmap::Allocator* allocator = SkResourceCache::GetAllocator();
|
| +
|
| + return NULL != allocator
|
| + ? allocator->allocPixelRef(bitmap, NULL)
|
| + : bitmap->tryAllocPixels();
|
| +}
|
|
|
| } // namespace
|
|
|
| @@ -141,6 +108,10 @@
|
| , fTile(tile ? *tile : picture->cullRect())
|
| , fTmx(tmx)
|
| , fTmy(tmy) {
|
| +}
|
| +
|
| +SkPictureShader::~SkPictureShader() {
|
| + fPicture->unref();
|
| }
|
|
|
| SkPictureShader* SkPictureShader::Create(const SkPicture* picture, TileMode tmx, TileMode tmy,
|
| @@ -217,10 +188,18 @@
|
|
|
| if (!SkResourceCache::Find(key, BitmapShaderRec::Visitor, &tileShader)) {
|
| SkBitmap bm;
|
| - if (!SkInstallDiscardablePixelRef(SkNEW_ARGS(PictureImageGenerator,
|
| - (fPicture, fTile, tileSize)), &bm)) {
|
| + bm.setInfo(SkImageInfo::MakeN32Premul(tileSize));
|
| + if (!cache_try_alloc_pixels(&bm)) {
|
| return NULL;
|
| }
|
| + bm.eraseColor(SK_ColorTRANSPARENT);
|
| +
|
| + // Always disable LCD text, since we can't assume our image will be opaque.
|
| + SkCanvas canvas(bm, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
|
| +
|
| + canvas.scale(tileScale.width(), tileScale.height());
|
| + canvas.translate(-fTile.x(), -fTile.y());
|
| + canvas.drawPicture(fPicture);
|
|
|
| SkMatrix shaderMatrix = this->getLocalMatrix();
|
| shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
|
| @@ -301,10 +280,10 @@
|
| };
|
|
|
| str->appendf("PictureShader: [%f:%f:%f:%f] ",
|
| - fPicture->cullRect().fLeft,
|
| - fPicture->cullRect().fTop,
|
| - fPicture->cullRect().fRight,
|
| - fPicture->cullRect().fBottom);
|
| + fPicture ? fPicture->cullRect().fLeft : 0,
|
| + fPicture ? fPicture->cullRect().fTop : 0,
|
| + fPicture ? fPicture->cullRect().fRight : 0,
|
| + fPicture ? fPicture->cullRect().fBottom : 0);
|
|
|
| str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]);
|
|
|
|
|