Use dstColorSpace in SkPictureShader cache key
authorMatt Sarett <msarett@google.com>
Fri, 21 Apr 2017 19:06:51 +0000 (15:06 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 21 Apr 2017 19:34:43 +0000 (19:34 +0000)
Starting with the bug fix + test.

Broken off of:
https://skia-review.googlesource.com/c/13976

Bug: skia:
Change-Id: If6c28e2dfb0c5340c48e943d0313a9ea9515a6c3
Reviewed-on: https://skia-review.googlesource.com/14061
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Matt Sarett <msarett@google.com>

gm/pictureshadercache.cpp [new file with mode: 0644]
gn/gm.gni
src/core/SkPictureShader.cpp

diff --git a/gm/pictureshadercache.cpp b/gm/pictureshadercache.cpp
new file mode 100644 (file)
index 0000000..0784222
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm.h"
+
+#include "SkPaint.h"
+#include "SkPicture.h"
+#include "SkPictureRecorder.h"
+#include "SkShader.h"
+#include "SkSurface.h"
+
+class PictureShaderCacheGM : public skiagm::GM {
+public:
+    PictureShaderCacheGM(SkScalar tileSize)
+        : fTileSize(tileSize) {
+    }
+
+ protected:
+    void drawTile(SkCanvas* canvas) {
+        SkPaint paint;
+        paint.setColor(SK_ColorGREEN);
+        paint.setStyle(SkPaint::kFill_Style);
+        paint.setAntiAlias(true);
+
+        canvas->drawCircle(fTileSize / 4, fTileSize / 4, fTileSize / 4, paint);
+        canvas->drawRect(SkRect::MakeXYWH(fTileSize / 2, fTileSize / 2,
+                                          fTileSize / 2, fTileSize / 2), paint);
+
+        paint.setColor(SK_ColorRED);
+        canvas->drawLine(fTileSize / 2, fTileSize * 1 / 3,
+                         fTileSize / 2, fTileSize * 2 / 3, paint);
+        canvas->drawLine(fTileSize * 1 / 3, fTileSize / 2,
+                         fTileSize * 2 / 3, fTileSize / 2, paint);
+    }
+
+    void onOnceBeforeDraw() override {
+        SkPictureRecorder recorder;
+        SkCanvas* pictureCanvas = recorder.beginRecording(fTileSize, fTileSize, nullptr, 0);
+        this->drawTile(pictureCanvas);
+        fPicture = recorder.finishRecordingAsPicture();
+    }
+
+    SkString onShortName() override {
+        return SkString("pictureshadercache");
+    }
+
+    SkISize onISize() override {
+        return SkISize::Make(100, 100);
+    }
+
+    void onDraw(SkCanvas* canvas) override {
+        SkPaint paint;
+        paint.setShader(SkShader::MakePictureShader(fPicture, SkShader::kRepeat_TileMode,
+                                                    SkShader::kRepeat_TileMode, nullptr,
+                                                    nullptr));
+
+        {
+            // Render in a funny color space that converts green to yellow.
+            SkMatrix44 greenToYellow(SkMatrix44::kIdentity_Constructor);
+            greenToYellow.setFloat(0, 1, 1.0f);
+            sk_sp<SkColorSpace> gty = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
+                                                            greenToYellow);
+            SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100, std::move(gty));
+            sk_sp<SkSurface> surface(SkSurface::MakeRaster(info));
+            surface->getCanvas()->drawRect(SkRect::MakeWH(fTileSize, fTileSize), paint);
+        }
+
+        // When we draw to the canvas, we should see green because we should *not* reuse the
+        // cached picture shader.
+        canvas->drawRect(SkRect::MakeWH(fTileSize, fTileSize), paint);
+    }
+
+private:
+    SkScalar         fTileSize;
+    sk_sp<SkPicture> fPicture;
+    SkBitmap         fBitmap;
+
+    typedef GM INHERITED;
+};
+
+DEF_GM(return new PictureShaderCacheGM(100);)
index 67d2ced..252de69 100644 (file)
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -224,6 +224,7 @@ gm_sources = [
   "$_gm/pictureimagefilter.cpp",
   "$_gm/pictureimagegenerator.cpp",
   "$_gm/pictureshader.cpp",
+  "$_gm/pictureshadercache.cpp",
   "$_gm/pictureshadertile.cpp",
   "$_gm/pixelsnap.cpp",
   "$_gm/plus.cpp",
index 50c33a8..3e36ffb 100644 (file)
@@ -30,13 +30,15 @@ static unsigned gBitmapSkaderKeyNamespaceLabel;
 
 struct BitmapShaderKey : public SkResourceCache::Key {
 public:
-    BitmapShaderKey(uint32_t pictureID,
+    BitmapShaderKey(sk_sp<SkColorSpace> colorSpace,
+                    uint32_t pictureID,
                     const SkRect& tile,
                     SkShader::TileMode tmx,
                     SkShader::TileMode tmy,
                     const SkSize& scale,
                     const SkMatrix& localMatrix)
-        : fPictureID(pictureID)
+        : fColorSpace(std::move(colorSpace))
+        , fPictureID(pictureID)
         , fTile(tile)
         , fTmx(tmx)
         , fTmy(tmy)
@@ -46,22 +48,24 @@ public:
             fLocalMatrixStorage[i] = localMatrix[i];
         }
 
-        static const size_t keySize = sizeof(fPictureID) +
+        static const size_t keySize = sizeof(fColorSpace) +
+                                      sizeof(fPictureID) +
                                       sizeof(fTile) +
                                       sizeof(fTmx) + sizeof(fTmy) +
                                       sizeof(fScale) +
                                       sizeof(fLocalMatrixStorage);
         // This better be packed.
-        SkASSERT(sizeof(uint32_t) * (&fEndOfStruct - &fPictureID) == keySize);
+        SkASSERT(sizeof(uint32_t) * (&fEndOfStruct - (uint32_t*)&fColorSpace) == keySize);
         this->init(&gBitmapSkaderKeyNamespaceLabel, 0, keySize);
     }
 
 private:
-    uint32_t           fPictureID;
-    SkRect             fTile;
-    SkShader::TileMode fTmx, fTmy;
-    SkSize             fScale;
-    SkScalar           fLocalMatrixStorage[9];
+    sk_sp<SkColorSpace> fColorSpace;
+    uint32_t            fPictureID;
+    SkRect              fTile;
+    SkShader::TileMode  fTmx, fTmy;
+    SkSize              fScale;
+    SkScalar            fLocalMatrixStorage[9];
 
     SkDEBUGCODE(uint32_t fEndOfStruct;)
 };
@@ -216,7 +220,8 @@ sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix, con
                                           SkIntToScalar(tileSize.height()) / fTile.height());
 
     sk_sp<SkShader> tileShader;
-    BitmapShaderKey key(fPicture->uniqueID(),
+    BitmapShaderKey key(sk_ref_sp(dstColorSpace),
+                        fPicture->uniqueID(),
                         fTile,
                         fTmx,
                         fTmy,