Add color space xform to GrMagnifierEffect
authorBrian Osman <brianosman@google.com>
Tue, 20 Dec 2016 20:54:11 +0000 (15:54 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Tue, 20 Dec 2016 21:34:12 +0000 (21:34 +0000)
Tag helper image as sRGB in magnifier image filter GM, so we can see
this working.

BUG=skia:

Change-Id: I8057dc332d09e1d508ad8462aaf0749b307f480f
Reviewed-on: https://skia-review.googlesource.com/6347
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>

gm/imagemagnifier.cpp
src/effects/SkMagnifierImageFilter.cpp

index 88a6d10..888bb5d 100644 (file)
@@ -8,6 +8,7 @@
 #include "gm.h"
 #include "SkImageSource.h"
 #include "SkMagnifierImageFilter.h"
+#include "SkPixelRef.h"
 #include "SkRandom.h"
 #include "SkSurface.h"
 
@@ -43,23 +44,25 @@ DEF_SIMPLE_GM_BG(imagemagnifier, canvas, WIDTH, HEIGHT, SK_ColorBLACK) {
 #define WIDTH_HEIGHT 256
 
 static sk_sp<SkImage> make_img() {
-    const SkImageInfo info = SkImageInfo::MakeN32Premul(WIDTH_HEIGHT, WIDTH_HEIGHT);
+    SkBitmap bitmap;
+    bitmap.allocN32Pixels(WIDTH_HEIGHT, WIDTH_HEIGHT);
+    SkCanvas canvas(bitmap);
 
-    sk_sp<SkSurface> surf(SkSurface::MakeRaster(info));
-
-    SkCanvas* canvas = surf->getCanvas();
-
-    canvas->clear(0x0);
+    canvas.clear(0x0);
 
     SkPaint paint;
     paint.setColor(SK_ColorBLUE);
 
     for (float pos = 0; pos < WIDTH_HEIGHT; pos += 16) {
-        canvas->drawLine(0, pos, SkIntToScalar(WIDTH_HEIGHT), pos, paint);
-        canvas->drawLine(pos, 0, pos, SkIntToScalar(WIDTH_HEIGHT), paint);
+        canvas.drawLine(0, pos, SkIntToScalar(WIDTH_HEIGHT), pos, paint);
+        canvas.drawLine(pos, 0, pos, SkIntToScalar(WIDTH_HEIGHT), paint);
     }
 
-    return surf->makeImageSnapshot();
+    SkBitmap result;
+    result.setInfo(SkImageInfo::MakeS32(WIDTH_HEIGHT, WIDTH_HEIGHT, kPremul_SkAlphaType));
+    result.setPixelRef(sk_ref_sp(bitmap.pixelRef()), 0, 0);
+
+    return SkImage::MakeFromBitmap(result);
 }
 
 DEF_SIMPLE_GM_BG(imagemagnifier_cropped, canvas, WIDTH_HEIGHT, WIDTH_HEIGHT, SK_ColorBLACK) {
index 916bd95..2b04532 100644 (file)
@@ -19,6 +19,7 @@
 #include "GrContext.h"
 #include "GrInvariantOutput.h"
 #include "effects/GrSingleTextureEffect.h"
+#include "glsl/GrGLSLColorSpaceXformHelper.h"
 #include "glsl/GrGLSLFragmentProcessor.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
 #include "glsl/GrGLSLProgramDataManager.h"
@@ -29,6 +30,7 @@ class GrMagnifierEffect : public GrSingleTextureEffect {
 
 public:
     static sk_sp<GrFragmentProcessor> Make(GrTexture* texture,
+                                           sk_sp<GrColorSpaceXform> colorSpaceXform,
                                            const SkRect& bounds,
                                            float xOffset,
                                            float yOffset,
@@ -36,8 +38,8 @@ public:
                                            float yInvZoom,
                                            float xInvInset,
                                            float yInvInset) {
-        return sk_sp<GrFragmentProcessor>(new GrMagnifierEffect(texture, bounds,
-                                                                xOffset, yOffset,
+        return sk_sp<GrFragmentProcessor>(new GrMagnifierEffect(texture, std::move(colorSpaceXform),
+                                                                bounds, xOffset, yOffset,
                                                                 xInvZoom, yInvZoom,
                                                                 xInvInset, yInvInset));
     }
@@ -61,6 +63,7 @@ public:
 
 private:
     GrMagnifierEffect(GrTexture* texture,
+                      sk_sp<GrColorSpaceXform> colorSpaceXform,
                       const SkRect& bounds,
                       float xOffset,
                       float yOffset,
@@ -68,7 +71,8 @@ private:
                       float yInvZoom,
                       float xInvInset,
                       float yInvInset)
-        : INHERITED(texture, nullptr, GrCoordTransform::MakeDivByTextureWHMatrix(texture))
+        : INHERITED(texture, std::move(colorSpaceXform),
+                    GrCoordTransform::MakeDivByTextureWHMatrix(texture))
         , fBounds(bounds)
         , fXOffset(xOffset)
         , fYOffset(yOffset)
@@ -107,6 +111,12 @@ class GrGLMagnifierEffect : public GrGLSLFragmentProcessor {
 public:
     void emitCode(EmitArgs&) override;
 
+    static inline void GenKey(const GrProcessor& effect, const GrShaderCaps&,
+                              GrProcessorKeyBuilder* b) {
+        const GrMagnifierEffect& zoom = effect.cast<GrMagnifierEffect>();
+        b->add32(GrColorSpaceXform::XformKey(zoom.colorSpaceXform()));
+    }
+
 protected:
     void onSetData(const GrGLSLProgramDataManager&, const GrProcessor&) override;
 
@@ -115,6 +125,7 @@ private:
     UniformHandle       fInvZoomVar;
     UniformHandle       fInvInsetVar;
     UniformHandle       fBoundsVar;
+    UniformHandle       fColorSpaceXformVar;
 
     typedef GrGLSLFragmentProcessor INHERITED;
 };
@@ -134,6 +145,10 @@ void GrGLMagnifierEffect::emitCode(EmitArgs& args) {
                                             kVec4f_GrSLType, kDefault_GrSLPrecision,
                                             "Bounds");
 
+    const GrMagnifierEffect& zoom = args.fFp.cast<GrMagnifierEffect>();
+    GrGLSLColorSpaceXformHelper colorSpaceHelper(uniformHandler, zoom.colorSpaceXform(),
+                                                 &fColorSpaceXformVar);
+
     GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
     SkString coords2D = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
     fragBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str());
@@ -160,7 +175,8 @@ void GrGLMagnifierEffect::emitCode(EmitArgs& args) {
 
     fragBuilder->codeAppend("\t\tvec2 mix_coord = mix(coord, zoom_coord, weight);\n");
     fragBuilder->codeAppend("\t\tvec4 output_color = ");
-    fragBuilder->appendTextureLookup(args.fTexSamplers[0], "mix_coord");
+    fragBuilder->appendTextureLookup(args.fTexSamplers[0], "mix_coord", kVec2f_GrSLType,
+                                     &colorSpaceHelper);
     fragBuilder->codeAppend(";\n");
 
     fragBuilder->codeAppendf("\t\t%s = output_color;", args.fOutputColor);
@@ -177,6 +193,9 @@ void GrGLMagnifierEffect::onSetData(const GrGLSLProgramDataManager& pdman,
     pdman.set2f(fInvInsetVar, zoom.xInvInset(), zoom.yInvInset());
     pdman.set4f(fBoundsVar, zoom.bounds().x(), zoom.bounds().y(),
                             zoom.bounds().width(), zoom.bounds().height());
+    if (SkToBool(zoom.colorSpaceXform())) {
+        pdman.setSkMatrix44(fColorSpaceXformVar, zoom.colorSpaceXform()->srcToDst());
+    }
 }
 
 /////////////////////////////////////////////////////////////////////
@@ -202,9 +221,11 @@ sk_sp<GrFragmentProcessor> GrMagnifierEffect::TestCreate(GrProcessorTestData* d)
     uint32_t x = d->fRandom->nextULessThan(kMaxWidth - width);
     uint32_t y = d->fRandom->nextULessThan(kMaxHeight - height);
     uint32_t inset = d->fRandom->nextULessThan(kMaxInset);
+    auto colorSpaceXform = GrTest::TestColorXform(d->fRandom);
 
     sk_sp<GrFragmentProcessor> effect(GrMagnifierEffect::Make(
         texture,
+        std::move(colorSpaceXform),
         SkRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)),
         (float) width / texture->width(),
         (float) height / texture->height(),
@@ -323,9 +344,13 @@ sk_sp<SkSpecialImage> SkMagnifierImageFilter::onFilterImage(SkSpecialImage* sour
             SkIntToScalar(boundsY) / inputTexture->height(),
             SkIntToScalar(inputTexture->width()) / bounds.width(),
             SkIntToScalar(inputTexture->height()) / bounds.height());
-        // SRGBTODO: Handle sRGB here
+
+        SkColorSpace* dstColorSpace = ctx.outputProperties().colorSpace();
+        sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(input->getColorSpace(),
+                                                                           dstColorSpace);
         sk_sp<GrFragmentProcessor> fp(GrMagnifierEffect::Make(
                                                         inputTexture.get(),
+                                                        std::move(colorSpaceXform),
                                                         effectBounds,
                                                         fSrcRect.x() / inputTexture->width(),
                                                         yOffset / inputTexture->height(),