diff options
-rw-r--r-- | src/core/SkSpecialImage.cpp | 4 | ||||
-rw-r--r-- | src/effects/SkTableColorFilter.cpp | 11 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 38 | ||||
-rw-r--r-- | src/gpu/SkGr.h | 5 | ||||
-rw-r--r-- | src/gpu/effects/GrTextureStripAtlas.cpp | 9 | ||||
-rw-r--r-- | src/shaders/gradients/SkGradientShader.cpp | 16 |
6 files changed, 75 insertions, 8 deletions
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp index 56ec66a191..f6e4224452 100644 --- a/src/core/SkSpecialImage.cpp +++ b/src/core/SkSpecialImage.cpp @@ -87,6 +87,7 @@ sk_sp<SkSpecialImage> SkSpecialImage::makeTextureImage(GrContext* context) { return curContext == context ? sk_sp<SkSpecialImage>(SkRef(this)) : nullptr; } + auto proxyProvider = context->contextPriv().proxyProvider(); SkBitmap bmp; // At this point, we are definitely not texture-backed, so we must be raster or generator // backed. If we remove the special-wrapping-an-image subclass, we may be able to assert that @@ -102,8 +103,7 @@ sk_sp<SkSpecialImage> SkSpecialImage::makeTextureImage(GrContext* context) { // TODO: this is a tight copy of 'bmp' but it doesn't have to be (given SkSpecialImage's // semantics). Since this is cached though we would have to bake the fit into the cache key. - sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(context->contextPriv().proxyProvider(), - bmp); + sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(proxyProvider, bmp); if (!proxy) { return nullptr; } diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp index d808c6fb12..45c70d6215 100644 --- a/src/effects/SkTableColorFilter.cpp +++ b/src/effects/SkTableColorFilter.cpp @@ -444,17 +444,24 @@ std::unique_ptr<GrFragmentProcessor> ColorTableEffect::Make(GrContext* context, desc.fWidth = bitmap.width(); desc.fHeight = 128; desc.fRowHeight = bitmap.height(); - // TODO: this seems a bit heavy handed (passing a GrContext as part of the desc) desc.fContext = context; desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *context->caps()); + GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(desc); int row = atlas->lockRow(bitmap); sk_sp<GrTextureProxy> proxy; if (-1 == row) { atlas = nullptr; - proxy = GrMakeCachedBitmapProxy(context->contextPriv().proxyProvider(), bitmap); + SkASSERT(bitmap.isImmutable()); + + sk_sp<SkImage> srcImage = SkImage::MakeFromBitmap(bitmap); + if (!srcImage) { + return nullptr; + } + + proxy = GrMakeCachedImageProxy(context->contextPriv().proxyProvider(), std::move(srcImage)); } else { proxy = atlas->asTextureProxyRef(); } diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index 90fe4f62d6..ad996f82b6 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -23,6 +23,7 @@ #include "SkColorFilter.h" #include "SkConvertPixels.h" #include "SkData.h" +#include "SkImage_Base.h" #include "SkImageInfoPriv.h" #include "SkMaskFilterBase.h" #include "SkMessageBus.h" @@ -239,6 +240,43 @@ sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider* proxyProvider, return proxy; } +static void create_unique_key_for_image(const SkImage* image, GrUniqueKey* result) { + if (!image) { + result->reset(); // will be invalid + return; + } + + if (const SkBitmap* bm = as_IB(image)->onPeekBitmap()) { + SkIPoint origin = bm->pixelRefOrigin(); + SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bm->width(), bm->height()); + GrMakeKeyFromImageID(result, bm->getGenerationID(), subset); + return; + } + + GrMakeKeyFromImageID(result, image->uniqueID(), image->bounds()); +} + +sk_sp<GrTextureProxy> GrMakeCachedImageProxy(GrProxyProvider* proxyProvider, + sk_sp<SkImage> srcImage) { + sk_sp<GrTextureProxy> proxy; + GrUniqueKey originalKey; + + create_unique_key_for_image(srcImage.get(), &originalKey); + + if (originalKey.isValid()) { + proxy = proxyProvider->findOrCreateProxyByUniqueKey(originalKey, kTopLeft_GrSurfaceOrigin); + } + if (!proxy) { + proxy = proxyProvider->createTextureProxy(std::move(srcImage), kNone_GrSurfaceFlags, + kTopLeft_GrSurfaceOrigin, 0, SkBudgeted::kYes); + if (proxy && originalKey.isValid()) { + proxyProvider->assignUniqueKeyToProxy(originalKey, proxy.get()); + } + } + + return proxy; +} + /////////////////////////////////////////////////////////////////////////////// GrColor4f SkColorToPremulGrColor4f(SkColor c, const GrColorSpaceInfo& colorSpaceInfo) { diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h index 3bf3ba9c5d..8cd6e61bcc 100644 --- a/src/gpu/SkGr.h +++ b/src/gpu/SkGr.h @@ -244,6 +244,11 @@ sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrProxyProvider*, const SkIma // } sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider*, const SkBitmap& bitmap); +/* + * Create a texture proxy from the provided 'srcImage' and add it to the texture cache + * using the key also extracted from 'srcImage'. + */ +sk_sp<GrTextureProxy> GrMakeCachedImageProxy(GrProxyProvider*, sk_sp<SkImage> srcImage); /** * Our key includes the offset, width, and height so that bitmaps created by extractSubset() diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp index f5697c9442..a3d4fc0a0e 100644 --- a/src/gpu/effects/GrTextureStripAtlas.cpp +++ b/src/gpu/effects/GrTextureStripAtlas.cpp @@ -95,6 +95,15 @@ void GrTextureStripAtlas::lockRow(int row) { int GrTextureStripAtlas::lockRow(const SkBitmap& bitmap) { VALIDATE; + + if (!this->getContext()->contextPriv().resourceProvider()) { + // DDL TODO: For DDL we need to schedule inline & ASAP uploads. However these systems + // currently use the flushState which we can't use for the opList-based DDL phase. + // For the opList-based solution every texture strip will get its own texture proxy. + // We will revisit this for the flushState-based solution. + return -1; + } + if (0 == fLockedRows) { this->lockTexture(); if (!fTexContext) { diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp index 3367d9e33b..871c7ba55e 100644 --- a/src/shaders/gradients/SkGradientShader.cpp +++ b/src/shaders/gradients/SkGradientShader.cpp @@ -591,6 +591,7 @@ void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap, bitmap->allocPixels(info); this->initLinearBitmap(bitmap, bitmapType); + bitmap->setImmutable(); gCache->add(storage.get(), size, *bitmap); } } @@ -1275,7 +1276,7 @@ GrGradientEffect::GrGradientEffect(ClassID classID, const CreateArgs& args, bool GrTextureStripAtlas::Desc desc; desc.fWidth = bitmap.width(); desc.fHeight = 32; - desc.fRowHeight = bitmap.height(); + desc.fRowHeight = bitmap.height(); // always 1 here desc.fContext = args.fContext; desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *args.fContext->caps()); fAtlas = GrTextureStripAtlas::GetAtlas(desc); @@ -1297,11 +1298,18 @@ GrGradientEffect::GrGradientEffect(ClassID classID, const CreateArgs& args, bool // and the proxy is: // exact fit, power of two in both dimensions // Only the x-tileMode is unknown. However, given all the other knowns we know - // that GrMakeCachedBitmapProxy is sufficient (i.e., it won't need to be + // that GrMakeCachedImageProxy is sufficient (i.e., it won't need to be // extracted to a subset or mipmapped). - sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy( + + SkASSERT(bitmap.isImmutable()); + sk_sp<SkImage> srcImage = SkImage::MakeFromBitmap(bitmap); + if (!srcImage) { + return; + } + + sk_sp<GrTextureProxy> proxy = GrMakeCachedImageProxy( args.fContext->contextPriv().proxyProvider(), - bitmap); + std::move(srcImage)); if (!proxy) { SkDebugf("Gradient won't draw. Could not create texture."); return; |