Index: src/gpu/SkGr.cpp |
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp |
index e0892d8ab974e88db4034b429cba09727ab8cb93..8ac8496b0a8a133c30a29b0e74542aa9a8c8eb32 100644 |
--- a/src/gpu/SkGr.cpp |
+++ b/src/gpu/SkGr.cpp |
@@ -503,31 +503,6 @@ static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const Stretch& stretch) { |
return stretched; |
} |
-static GrTexture* create_bitmap_texture(GrContext* ctx, |
- const SkBitmap& bmp, |
- const Stretch& stretch, |
- const GrUniqueKey& unstretchedKey, |
- const GrUniqueKey& stretchedKey) { |
- if (Stretch::kNone_Type != stretch.fType) { |
- SkAutoTUnref<GrTexture> unstretched; |
- // Check if we have the unstretched version in the cache, if not create it. |
- if (unstretchedKey.isValid()) { |
- unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueKey(unstretchedKey)); |
- } |
- if (!unstretched) { |
- unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey)); |
- if (!unstretched) { |
- // We might not have been able to create a unstrecthed texture because it is smaller |
- // than the min texture size. In that case do cpu stretching. |
- SkBitmap stretchedBmp = stretch_on_cpu(bmp, stretch); |
- return create_unstretched_bitmap_texture(ctx, stretchedBmp, stretchedKey); |
- } |
- } |
- return stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKey); |
- } |
- return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); |
-} |
- |
bool GrIsImageInCache(const GrContext* ctx, uint32_t imageID, const SkIRect& subset, |
GrTexture* nativeTexture, const GrTextureParams* params) { |
Stretch stretch; |
@@ -562,21 +537,50 @@ bool GrIsBitmapInCache(const GrContext* ctx, const SkBitmap& bitmap, |
params); |
} |
-GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
- const SkBitmap& bitmap, |
- const GrTextureParams* params) { |
+class GrTextureMaker { |
bsalomon
2015/09/29 13:23:24
Is this going to be exposed outside of this cpp? J
reed1
2015/09/29 17:41:17
Not sure, but likely (for generators, etc.) so I w
|
+public: |
+ GrTextureMaker(int width, int height) : fWidth(width), fHeight(height) {} |
+ |
+ int width() const { return fWidth; } |
+ int height() const { return fHeight; } |
+ |
+ GrTexture* refCachedTexture(GrContext*, const GrTextureParams*); |
+ |
+protected: |
+ virtual GrTexture* peekTexture() = 0; |
bsalomon
2015/09/29 13:23:24
wonder about all these virtuals... this guy can ge
reed1
2015/09/29 17:41:17
Agree to all concerns. Will start with trying to r
|
+ virtual void notifyStretchCached(const GrUniqueKey& stretchedKey) = 0; |
+ virtual bool isVolatile() = 0; |
+ virtual uint32_t imageID() = 0; |
+ virtual SkIRect subset() = 0; |
+ virtual GrTexture* onRefCachedTexture(GrContext*, const GrUniqueKey& unstretchedKey) = 0; |
+ virtual bool getROBitmap(SkBitmap*) = 0; |
+ |
+private: |
+ const int fWidth; |
+ const int fHeight; |
+ |
+ GrTexture* stretchTexture(GrTexture* tex, const Stretch& stretch, |
+ const GrUniqueKey& stretchedKey) { |
+ GrTexture* result = stretch_texture(tex, stretch, nullptr, stretchedKey); |
+ if (result && stretchedKey.isValid()) { |
+ this->notifyStretchCached(stretchedKey); |
+ } |
+ return result; |
+ } |
+}; |
+GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParams* params) { |
Stretch stretch; |
- get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); |
+ get_stretch(ctx, this->width(), this->height(), params, &stretch); |
- GrTexture* result = bitmap.getTexture(); |
+ GrTexture* result = this->peekTexture(); |
if (result) { |
if (Stretch::kNone_Type == stretch.fType) { |
return SkRef(result); |
} |
GrUniqueKey stretchedKey; |
// Don't create a key for the resized version if the bmp is volatile. |
- if (!bitmap.isVolatile()) { |
+ if (!this->isVolatile()) { |
const GrUniqueKey& key = result->getUniqueKey(); |
if (key.isValid()) { |
make_stretched_key(key, stretch, &stretchedKey); |
@@ -587,32 +591,83 @@ GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, |
} |
} |
} |
- return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey); |
+ return this->stretchTexture(result, stretch, stretchedKey); |
} |
- GrUniqueKey key, resizedKey; |
+ GrUniqueKey key, stretchedKey; |
- if (!bitmap.isVolatile()) { |
+ if (!this->isVolatile()) { |
// If the bitmap isn't changing try to find a cached copy first. |
- make_image_keys(bitmap.getGenerationID(), bitmap.getSubset(), stretch, &key, &resizedKey); |
+ make_image_keys(this->imageID(), this->subset(), stretch, &key, &stretchedKey); |
result = ctx->textureProvider()->findAndRefTextureByUniqueKey( |
- resizedKey.isValid() ? resizedKey : key); |
+ stretchedKey.isValid() ? stretchedKey : key); |
if (result) { |
return result; |
} |
} |
- result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); |
- if (result) { |
- return result; |
+ if (Stretch::kNone_Type != stretch.fType) { |
+ SkAutoTUnref<GrTexture> unstretched; |
+ // Check if we have the unstretched version in the cache, if not create it. |
+ if (key.isValid()) { |
+ unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueKey(key)); |
+ } |
+ if (!unstretched) { |
+ if (this->width() < ctx->caps()->minTextureSize() || |
+ this->height() < ctx->caps()->minTextureSize()) { |
+ SkBitmap bitmap; |
+ if (!this->getROBitmap(&bitmap)) { |
+ return nullptr; |
+ } |
+ SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch); |
+ return create_unstretched_bitmap_texture(ctx, stretchedBmp, stretchedKey); |
+ } else { |
+ unstretched.reset(this->onRefCachedTexture(ctx, key)); |
+ if (!unstretched) { |
+ return nullptr; |
+ } |
+ } |
+ } |
+ return this->stretchTexture(unstretched, stretch, stretchedKey); |
+ } else { |
+ return this->onRefCachedTexture(ctx, key); |
} |
+} |
- SkErrorInternals::SetError( kInternalError_SkError, |
- "---- failed to create texture for cache [%d %d]\n", |
- bitmap.width(), bitmap.height()); |
+class Bitmap_GrTextureMaker : public GrTextureMaker { |
+public: |
+ Bitmap_GrTextureMaker(const SkBitmap& bitmap) |
+ : INHERITED(bitmap.width(), bitmap.height()) |
+ , fBitmap(bitmap) |
+ {} |
+ |
+protected: |
+ bool isVolatile() override { return fBitmap.isVolatile(); } |
+ uint32_t imageID() override { return fBitmap.getGenerationID(); } |
+ SkIRect subset() override { return fBitmap.getSubset(); } |
+ GrTexture* peekTexture() override { |
+ return fBitmap.getTexture(); |
+ } |
+ void notifyStretchCached(const GrUniqueKey& stretchedKey) override { |
+ fBitmap.pixelRef()->addGenIDChangeListener(new BitmapInvalidator(stretchedKey)); |
+ } |
+ GrTexture* onRefCachedTexture(GrContext* ctx, const GrUniqueKey& unstretchedKey) override { |
+ return create_unstretched_bitmap_texture(ctx, fBitmap, unstretchedKey); |
+ } |
+ bool getROBitmap(SkBitmap* bitmap) override { |
+ *bitmap = fBitmap; |
+ return true; |
+ } |
+private: |
+ const SkBitmap fBitmap; |
- return nullptr; |
+ typedef GrTextureMaker INHERITED; |
+}; |
+ |
+GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, |
+ const GrTextureParams* params) { |
+ return Bitmap_GrTextureMaker(bitmap).refCachedTexture(ctx, params); |
} |
// TODO: make this be the canonical signature, and turn the version that takes GrTextureParams* |