getDeferredTextureImageData(): preserve color space in legacy mode
authorMatt Sarett <msarett@google.com>
Mon, 10 Apr 2017 15:03:27 +0000 (11:03 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Mon, 10 Apr 2017 20:10:33 +0000 (20:10 +0000)
Bug: skia:
Change-Id: Ib205f6104827b734635df6932d6dcfdc2248d091
Reviewed-on: https://skia-review.googlesource.com/12103
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>

src/gpu/SkGr.cpp
src/gpu/SkGr.h
src/image/SkImage_Gpu.cpp

index 5f21e1d..84be09e 100644 (file)
@@ -158,13 +158,9 @@ static const SkPixmap* compute_desc(const GrCaps& caps, const SkPixmap& pixmap,
     return pmap;
 }
 
-sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider* resourceProvider,
-                                                   const SkPixmap& pixmap,
-                                                   SkBudgeted budgeted) {
-    if (!SkImageInfoIsValid(pixmap.info())) {
-        return nullptr;
-    }
-
+sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxyNoCheck(GrResourceProvider* resourceProvider,
+                                                          const SkPixmap& pixmap,
+                                                          SkBudgeted budgeted) {
     SkBitmap tmpBitmap;
     SkPixmap tmpPixmap;
     GrSurfaceDesc desc;
@@ -178,6 +174,16 @@ sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider* resourceP
     return nullptr;
 }
 
+sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider* resourceProvider,
+                                                   const SkPixmap& pixmap,
+                                                   SkBudgeted budgeted) {
+    if (!SkImageInfoIsValid(pixmap.info())) {
+        return nullptr;
+    }
+
+    return GrUploadPixmapToTextureProxyNoCheck(resourceProvider, pixmap, budgeted);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
index 866dcce..144a477 100644 (file)
@@ -224,6 +224,8 @@ sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext*, const
  */
 sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider*,
                                                    const SkPixmap&, SkBudgeted);
+sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxyNoCheck(GrResourceProvider*,
+                                                          const SkPixmap&, SkBudgeted);
 
 /**
  * Creates a new texture populated with the mipmap levels.
index 08c2e0d..119eb91 100644 (file)
@@ -682,10 +682,18 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
     size += pixelSize;
     size_t colorSpaceOffset = 0;
     size_t colorSpaceSize = 0;
+    SkColorSpaceTransferFn fn;
     if (info.colorSpace()) {
         colorSpaceOffset = size;
         colorSpaceSize = info.colorSpace()->writeToMemory(nullptr);
         size += colorSpaceSize;
+    } else if (this->colorSpace() && this->colorSpace()->isNumericalTransferFn(&fn)) {
+        // In legacy mode, preserve the color space tag on the SkImage.  This is only
+        // supported if the color space has a parametric transfer function.
+        SkASSERT(!dstColorSpace);
+        colorSpaceOffset = size;
+        colorSpaceSize = this->colorSpace()->writeToMemory(nullptr);
+        size += colorSpaceSize;
     }
     if (!fillMode) {
         return size;
@@ -730,7 +738,13 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
         void* colorSpace = bufferAsCharPtr + colorSpaceOffset;
         FILL_MEMBER(dtiBufferFiller, fColorSpace, &colorSpace);
         FILL_MEMBER(dtiBufferFiller, fColorSpaceSize, &colorSpaceSize);
-        info.colorSpace()->writeToMemory(bufferAsCharPtr + colorSpaceOffset);
+        if (info.colorSpace()) {
+            info.colorSpace()->writeToMemory(bufferAsCharPtr + colorSpaceOffset);
+        } else {
+            SkASSERT(this->colorSpace() && this->colorSpace()->isNumericalTransferFn(&fn));
+            SkASSERT(!dstColorSpace);
+            this->colorSpace()->writeToMemory(bufferAsCharPtr + colorSpaceOffset);
+        }
     } else {
         memset(bufferAsCharPtr + offsetof(DeferredTextureImage, fColorSpace),
                0, sizeof(DeferredTextureImage::fColorSpace));
@@ -803,8 +817,14 @@ sk_sp<SkImage> SkImage::MakeFromDeferredTextureImageData(GrContext* context, con
     if (mipLevelCount == 1) {
         SkPixmap pixmap;
         pixmap.reset(info, dti->fMipMapLevelData[0].fPixelData, dti->fMipMapLevelData[0].fRowBytes);
-        sk_sp<GrTextureProxy> proxy(GrUploadPixmapToTextureProxy(context->resourceProvider(),
-                                                                 pixmap, budgeted));
+
+        // 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));
         if (!proxy) {
             return nullptr;
         }