aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkSpecialImage.cpp4
-rw-r--r--src/effects/SkTableColorFilter.cpp11
-rw-r--r--src/gpu/SkGr.cpp38
-rw-r--r--src/gpu/SkGr.h5
-rw-r--r--src/gpu/effects/GrTextureStripAtlas.cpp9
-rw-r--r--src/shaders/gradients/SkGradientShader.cpp16
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;