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]); |