Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(287)

Unified Diff: src/gpu/SkGr.cpp

Issue 1376603002: try texture-maker to generalize stretching for npot and min-tex-size (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/SkGr.cpp
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index e0892d8ab974e88db4034b429cba09727ab8cb93..a26cdb8b8aa9e48c13d1abbf6fdcfc9cad2689f8 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,57 +537,159 @@ bool GrIsBitmapInCache(const GrContext* ctx, const SkBitmap& bitmap,
params);
}
-GrTexture* GrRefCachedBitmapTexture(GrContext* ctx,
- const SkBitmap& bitmap,
- const GrTextureParams* params) {
+class GrTextureMaker {
+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:
+ /**
+ * Return the maker's "original" unstretched texture. It is the responsibility of the maker
+ * to make this efficient ... if the texture is being generated, the maker must handle
+ * caching it.
+ */
+ virtual GrTexture* onRefUnstretchedTexture(GrContext*) = 0;
+
+ /**
+ * If we need to stretch the maker's original texture, the maker is asked to return a key
+ * that identifies its origianl + the stretch parameter. If the maker does not want to cache
+ * the stretched version (e.g. the maker is volatile), this should ignore the key parameter
+ * and return false.
+ */
+ virtual bool onMakeStretchedKey(const Stretch&, GrUniqueKey* stretchedKey) = 0;
+
+ /**
+ * Return a new (uncached) texture that is the stretch of the maker's original.
+ *
+ * The base-class handles general logic for this, and only needs access to the following
+ * methods:
+ * - onRefUnstretchedTexture()
+ * - onGetROBitmkap()
bsalomon 2015/09/29 19:23:29 ROBitmap
reed1 2015/09/29 19:38:13 Done.
+ *
+ * Subclass may override this if they can handle stretching more efficiently.
+ */
+ virtual GrTexture* onGenerateStretchedTexture(GrContext*, const Stretch&);
+
+ /**
+ * If a stretched version of the texture is generated, it may be cached (assuming that
+ * onMakeStretchedKey() returns true). In that case, the maker is notified in case it
+ * wants to note that for when the maker is destroyed.
+ */
+ virtual void onNotifyStretchCached(const GrUniqueKey& stretchedKey) = 0;
+
+ /**
+ * Some GPUs are unreliable w/ very small texture sizes. If we run into that case, this
+ * method will be called (in service of onGenerateStretchedTexture) to return a raster version
+ * of the original texture.
+ */
+ virtual bool onGetROBitmap(SkBitmap*) = 0;
- Stretch stretch;
- get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch);
+private:
+ const int fWidth;
+ const int fHeight;
+};
- GrTexture* result = bitmap.getTexture();
- if (result) {
- if (Stretch::kNone_Type == stretch.fType) {
- return SkRef(result);
+GrTexture* GrTextureMaker::onGenerateStretchedTexture(GrContext* ctx, const Stretch& stretch) {
+ if (this->width() < ctx->caps()->minTextureSize() ||
+ this->height() < ctx->caps()->minTextureSize())
+ {
+ // we can't trust our ability to use HW to perform the stretch, so we request
+ // a raster instead, and perform the stretch on the CPU.
+ SkBitmap bitmap;
+ if (!this->onGetROBitmap(&bitmap)) {
+ return nullptr;
}
- GrUniqueKey stretchedKey;
- // Don't create a key for the resized version if the bmp is volatile.
- if (!bitmap.isVolatile()) {
- const GrUniqueKey& key = result->getUniqueKey();
- if (key.isValid()) {
- make_stretched_key(key, stretch, &stretchedKey);
- GrTexture* stretched =
- ctx->textureProvider()->findAndRefTextureByUniqueKey(stretchedKey);
- if (stretched) {
- return stretched;
- }
- }
+ SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch);
+ return create_unstretched_bitmap_texture(ctx, stretchedBmp, GrUniqueKey());
+ } else {
+ SkAutoTUnref<GrTexture> unstretched(this->onRefUnstretchedTexture(ctx));
+ if (!unstretched) {
+ return nullptr;
}
- return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey);
+ return stretch_texture(unstretched, stretch, nullptr, GrUniqueKey());
}
+}
bsalomon 2015/09/29 19:23:29 extra \n
reed1 2015/09/29 19:38:13 Done.
- GrUniqueKey key, resizedKey;
- if (!bitmap.isVolatile()) {
- // If the bitmap isn't changing try to find a cached copy first.
- make_image_keys(bitmap.getGenerationID(), bitmap.getSubset(), stretch, &key, &resizedKey);
+GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParams* params) {
+ Stretch stretch;
+ get_stretch(ctx, this->width(), this->height(), params, &stretch);
- result = ctx->textureProvider()->findAndRefTextureByUniqueKey(
- resizedKey.isValid() ? resizedKey : key);
+ if (Stretch::kNone_Type == stretch.fType) {
+ return this->onRefUnstretchedTexture(ctx);
+ }
+
+ GrUniqueKey stretchedKey;
+ if (this->onMakeStretchedKey(stretch, &stretchedKey)) {
+ GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey(stretchedKey);
if (result) {
return result;
}
}
- result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey);
- if (result) {
- return result;
+ GrTexture* result = this->onGenerateStretchedTexture(ctx, stretch);
+ if (!result) {
+ return nullptr;
}
- SkErrorInternals::SetError( kInternalError_SkError,
- "---- failed to create texture for cache [%d %d]\n",
- bitmap.width(), bitmap.height());
+ if (stretchedKey.isValid()) {
+ ctx->textureProvider()->assignUniqueKeyToTexture(stretchedKey, result);
+ this->onNotifyStretchCached(stretchedKey);
+ }
+ return result;
+}
+
+class Bitmap_GrTextureMaker : public GrTextureMaker {
+public:
+ Bitmap_GrTextureMaker(const SkBitmap& bitmap)
+ : INHERITED(bitmap.width(), bitmap.height())
+ , fBitmap(bitmap)
+ {}
+
+protected:
+ GrTexture* onRefUnstretchedTexture(GrContext* ctx) override {
+ GrTexture* tex = fBitmap.getTexture();
+ if (tex) {
+ return SkRef(tex);
+ }
+
+ GrUniqueKey unstretchedKey;
+ make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap.getSubset());
+ return create_unstretched_bitmap_texture(ctx, fBitmap, unstretchedKey);
+ }
+
+ bool onMakeStretchedKey(const Stretch& stretch, GrUniqueKey* stretchedKey) override {
+ if (fBitmap.isVolatile()) {
+ return false;
+ }
- return nullptr;
+ GrUniqueKey unstretchedKey;
+ make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap.getSubset());
+ return make_stretched_key(unstretchedKey, stretch, stretchedKey);
+ }
+
+ void onNotifyStretchCached(const GrUniqueKey& stretchedKey) override {
+ fBitmap.pixelRef()->addGenIDChangeListener(new BitmapInvalidator(stretchedKey));
+ }
+
+ bool onGetROBitmap(SkBitmap* bitmap) override {
+ *bitmap = fBitmap;
+ return true;
+ }
+
+private:
+ const SkBitmap fBitmap;
+
+ 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*
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698