Allow numerical color spaces with legacy rendering
Bug: 720083
Change-Id: Ibd4dbf6ee95ac14857e8280a441f81976710e5e8
Reviewed-on: https://skia-review.googlesource.com/16700
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
diff --git a/src/core/SkImageInfoPriv.h b/src/core/SkImageInfoPriv.h
index 42e80ca..c9b4b6c 100644
--- a/src/core/SkImageInfoPriv.h
+++ b/src/core/SkImageInfoPriv.h
@@ -76,6 +76,19 @@
}
/**
+ * Returns true if |info| contains a valid combination of width, height, colorType, alphaType,
+ * colorSpace. Uses |colorMode| to decide how to treat color spaces.
+ */
+static inline bool SkImageInfoIsValid(const SkImageInfo& info,
+ SkDestinationSurfaceColorMode colorMode) {
+ if (SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware == colorMode) {
+ return SkImageInfoIsValidRenderingCS(info);
+ }
+
+ return SkImageInfoIsValidAllowNumericalCS(info);
+}
+
+/**
* Returns true if Skia has defined a pixel conversion from the |src| to the |dst|.
* Returns false otherwise. Some discussion of false cases:
* We will not convert to kIndex8 unless it exactly matches the src, since color tables
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp
index 6c77167..bde8276 100644
--- a/src/gpu/GrBitmapTextureMaker.cpp
+++ b/src/gpu/GrBitmapTextureMaker.cpp
@@ -41,7 +41,8 @@
proxy = GrGenerateMipMapsAndUploadToTextureProxy(this->context(), fBitmap, dstColorSpace);
}
if (!proxy) {
- proxy = GrUploadBitmapToTextureProxy(this->context()->resourceProvider(), fBitmap);
+ proxy = GrUploadBitmapToTextureProxy(this->context()->resourceProvider(), fBitmap,
+ dstColorSpace);
}
if (proxy && fOriginalKey.isValid()) {
this->context()->resourceProvider()->assignUniqueKeyToProxy(fOriginalKey, proxy.get());
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index d331278..81fde35 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -62,7 +62,8 @@
//////////////////////////////////////////////////////////////////////////////
sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrResourceProvider* resourceProvider,
- const SkBitmap& bitmap) {
+ const SkBitmap& bitmap,
+ SkColorSpace* dstColorSpace) {
if (!bitmap.readyToDraw()) {
return nullptr;
}
@@ -70,7 +71,7 @@
if (!bitmap.peekPixels(&pixmap)) {
return nullptr;
}
- return GrUploadPixmapToTextureProxy(resourceProvider, pixmap, SkBudgeted::kYes);
+ return GrUploadPixmapToTextureProxy(resourceProvider, pixmap, SkBudgeted::kYes, dstColorSpace);
}
static const SkPixmap* compute_desc(const GrCaps& caps, const SkPixmap& pixmap,
@@ -127,9 +128,18 @@
return pmap;
}
-sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxyNoCheck(GrResourceProvider* resourceProvider,
- const SkPixmap& pixmap,
- SkBudgeted budgeted) {
+sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider* resourceProvider,
+ const SkPixmap& pixmap,
+ SkBudgeted budgeted,
+ SkColorSpace* dstColorSpace) {
+ SkDestinationSurfaceColorMode colorMode = dstColorSpace
+ ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
+ : SkDestinationSurfaceColorMode::kLegacy;
+
+ if (!SkImageInfoIsValid(pixmap.info(), colorMode)) {
+ return nullptr;
+ }
+
SkBitmap tmpBitmap;
SkPixmap tmpPixmap;
GrSurfaceDesc desc;
@@ -143,16 +153,6 @@
return nullptr;
}
-sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider* resourceProvider,
- const SkPixmap& pixmap,
- SkBudgeted budgeted) {
- if (!SkImageInfoIsValidRenderingCS(pixmap.info())) {
- return nullptr;
- }
-
- return GrUploadPixmapToTextureProxyNoCheck(resourceProvider, pixmap, budgeted);
-}
-
////////////////////////////////////////////////////////////////////////////////
void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
@@ -175,7 +175,7 @@
? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
: SkDestinationSurfaceColorMode::kLegacy;
- if (!SkImageInfoIsValidRenderingCS(bitmap.info())) {
+ if (!SkImageInfoIsValid(bitmap.info(), colorMode)) {
return nullptr;
}
@@ -222,7 +222,7 @@
const GrMipLevel* texels,
int mipLevelCount,
SkDestinationSurfaceColorMode colorMode) {
- if (!SkImageInfoIsValidRenderingCS(info)) {
+ if (!SkImageInfoIsValid(info, colorMode)) {
return nullptr;
}
@@ -257,7 +257,10 @@
proxy = resourceProvider->findProxyByUniqueKey(originalKey);
}
if (!proxy) {
- proxy = GrUploadBitmapToTextureProxy(resourceProvider, bitmap);
+ // Pass nullptr for |dstColorSpace|. This is lenient - we allow a wider range of
+ // color spaces in legacy mode. Unfortunately, we have to be lenient here, since
+ // we can't necessarily know the |dstColorSpace| at this time.
+ proxy = GrUploadBitmapToTextureProxy(resourceProvider, bitmap, nullptr);
if (proxy && originalKey.isValid()) {
resourceProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
// MDB TODO (caching): this has to play nice with the GrSurfaceProxy's caching
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index cefcc48..7784c53 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -211,7 +211,8 @@
* The bitmap must have CPU-accessible pixels. Attempts to take advantage of faster paths for
* compressed textures and yuv planes.
*/
-sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrResourceProvider*, const SkBitmap&);
+sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrResourceProvider*, const SkBitmap&,
+ SkColorSpace* dstColorSpace);
sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext*, const SkBitmap&,
SkColorSpace* dstColorSpace);
@@ -220,9 +221,7 @@
* Creates a new texture for the pixmap.
*/
sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider*,
- const SkPixmap&, SkBudgeted);
-sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxyNoCheck(GrResourceProvider*,
- const SkPixmap&, SkBudgeted);
+ const SkPixmap&, SkBudgeted, SkColorSpace*);
/**
* Creates a new texture populated with the mipmap levels.
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 4740543..501d95b 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -847,13 +847,11 @@
SkPixmap pixmap;
pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData, dti->fMipMapLevelData[0].fRowBytes);
- // Use the NoCheck version because we have already validated the SkImage. The |data|
- // used to be an SkImage before calling getDeferredTextureImageData(). In legacy mode,
- // getDeferredTextureImageData() will allow parametric transfer functions for images
- // generated from codecs - which is slightly more lenient than typical SkImage
- // constructors.
- sk_sp<GrTextureProxy> proxy(GrUploadPixmapToTextureProxyNoCheck(
- context->resourceProvider(), pixmap, budgeted));
+ // Pass nullptr for the |dstColorSpace|. This opts in to more lenient color space
+ // verification. This is ok because we've already verified the color space in
+ // getDeferredTextureImageData().
+ sk_sp<GrTextureProxy> proxy(GrUploadPixmapToTextureProxy(
+ context->resourceProvider(), pixmap, budgeted, nullptr));
if (!proxy) {
return nullptr;
}
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index e94041b..7108a1a 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -743,7 +743,7 @@
proxy = GrGenerateMipMapsAndUploadToTextureProxy(ctx, bitmap, dstColorSpace);
}
if (!proxy) {
- proxy = GrUploadBitmapToTextureProxy(ctx->resourceProvider(), bitmap);
+ proxy = GrUploadBitmapToTextureProxy(ctx->resourceProvider(), bitmap, dstColorSpace);
}
if (proxy) {
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kRGBA_LockTexturePath,