Chromium Code Reviews| 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* |