Finish overriding onMakeColorSpace() for SkImageFilters
authorMatt Sarett <msarett@google.com>
Mon, 17 Apr 2017 15:57:29 +0000 (11:57 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Mon, 17 Apr 2017 17:17:32 +0000 (17:17 +0000)
Fixes 3 gms in gbr-8888.  Breaks 0 gms in gbr-8888.

Bug: skia:
Change-Id: I3365390b16353821ef6057a7bb68020887e36f72
Reviewed-on: https://skia-review.googlesource.com/13323
Commit-Queue: Matt Sarett <msarett@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
gm/imagefiltersbase.cpp
include/core/SkImageFilter.h
src/core/SkLocalMatrixImageFilter.cpp
src/core/SkLocalMatrixImageFilter.h
src/core/SkMatrixImageFilter.cpp
src/core/SkMatrixImageFilter.h
src/effects/SkLightingImageFilter.cpp
tests/ImageFilterTest.cpp
tests/PDFPrimitivesTest.cpp

index 8c702b2..f088f67 100644 (file)
@@ -41,6 +41,9 @@ protected:
                                         SkIPoint* offset) const override {
         return nullptr;
     }
+    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override {
+        return nullptr;
+    }
 
 private:
     typedef SkImageFilter INHERITED;
@@ -83,6 +86,9 @@ protected:
         offset->set(0, 0);
         return sk_ref_sp<SkSpecialImage>(source);
     }
+    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override {
+        return sk_ref_sp(const_cast<IdentityImageFilter*>(this));
+    }
 
 private:
     IdentityImageFilter(sk_sp<SkImageFilter> input) : INHERITED(&input, 1, nullptr) {}
index ee24d96..a6ade97 100644 (file)
@@ -406,9 +406,7 @@ protected:
     sk_sp<SkImageFilter> makeColorSpace(SkColorSpaceXformer* xformer) const {
         return this->onMakeColorSpace(xformer);
     }
-    virtual sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const {
-        return sk_ref_sp(const_cast<SkImageFilter*>(this));
-    }
+    virtual sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const = 0;
 
 private:
     // For makeColorSpace().
@@ -418,14 +416,18 @@ private:
     friend class SkColorFilterImageFilter;
     friend class SkColorSpaceXformer;
     friend class SkComposeImageFilter;
+    friend class SkDiffuseLightingImageFilter;
     friend class SkDisplacementMapEffect;
     friend class SkDropShadowImageFilter;
     friend class SkImageSource;
     friend class SkMagnifierImageFilter;
     friend class SkMatrixConvolutionImageFilter;
+    friend class SkMatrixImageFilter;
+    friend class SkLocalMatrixImageFilter;
     friend class SkMergeImageFilter;
     friend class SkMorphologyImageFilter;
     friend class SkOffsetImageFilter;
+    friend class SkSpecularLightingImageFilter;
     friend class SkTileImageFilter;
     friend class SkXfermodeImageFilter_Base;
 
index 864b24b..1e50101 100644 (file)
@@ -55,6 +55,14 @@ SkIRect SkLocalMatrixImageFilter::onFilterBounds(const SkIRect& src, const SkMat
     return this->getInput(0)->filterBounds(src, SkMatrix::Concat(matrix, fLocalM), direction);
 }
 
+sk_sp<SkImageFilter> SkLocalMatrixImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer)
+const {
+    SkASSERT(1 == this->countInputs() && this->getInput(0));
+
+    sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
+    return SkLocalMatrixImageFilter::Make(fLocalM, std::move(input));
+}
+
 #ifndef SK_IGNORE_TO_STRING
 void SkLocalMatrixImageFilter::toString(SkString* str) const {
     str->append("SkLocalMatrixImageFilter: (");
index 5d69a20..b19c065 100644 (file)
@@ -25,6 +25,7 @@ protected:
     void flatten(SkWriteBuffer&) const override;
     sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
                                         SkIPoint* offset) const override;
+    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
     SkIRect onFilterBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
 
 private:
index 0a33280..4d9ea21 100644 (file)
@@ -95,6 +95,16 @@ sk_sp<SkSpecialImage> SkMatrixImageFilter::onFilterImage(SkSpecialImage* source,
     return surf->makeImageSnapshot();
 }
 
+sk_sp<SkImageFilter> SkMatrixImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
+    SkASSERT(1 == this->countInputs());
+    if (!this->getInput(0)) {
+        return sk_ref_sp(const_cast<SkMatrixImageFilter*>(this));
+    }
+
+    sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
+    return SkMatrixImageFilter::Make(fTransform, fFilterQuality, std::move(input));
+}
+
 SkRect SkMatrixImageFilter::computeFastBounds(const SkRect& src) const {
     SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
     SkRect dst;
index f688087..3b451a4 100644 (file)
@@ -42,6 +42,7 @@ protected:
 
     sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
                                         SkIPoint* offset) const override;
+    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
     SkIRect onFilterNodeBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
 
 private:
index 5933cff..cd2a36e 100644 (file)
@@ -8,6 +8,7 @@
 #include "SkLightingImageFilter.h"
 #include "SkBitmap.h"
 #include "SkColorPriv.h"
+#include "SkColorSpaceXformer.h"
 #include "SkPoint3.h"
 #include "SkReadBuffer.h"
 #include "SkSpecialImage.h"
@@ -38,28 +39,26 @@ class GrGLSpecularLightingEffect;
 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
 #endif
 
-namespace {
-
 const SkScalar gOneThird = SkIntToScalar(1) / 3;
 const SkScalar gTwoThirds = SkIntToScalar(2) / 3;
 const SkScalar gOneHalf = 0.5f;
 const SkScalar gOneQuarter = 0.25f;
 
 #if SK_SUPPORT_GPU
-void setUniformPoint3(const GrGLSLProgramDataManager& pdman, UniformHandle uni,
-                      const SkPoint3& point) {
+static void setUniformPoint3(const GrGLSLProgramDataManager& pdman, UniformHandle uni,
+                             const SkPoint3& point) {
     GR_STATIC_ASSERT(sizeof(SkPoint3) == 3 * sizeof(float));
     pdman.set3fv(uni, 1, &point.fX);
 }
 
-void setUniformNormal3(const GrGLSLProgramDataManager& pdman, UniformHandle uni,
-                       const SkPoint3& point) {
+static void setUniformNormal3(const GrGLSLProgramDataManager& pdman, UniformHandle uni,
+                              const SkPoint3& point) {
     setUniformPoint3(pdman, uni, point);
 }
 #endif
 
 // Shift matrix components to the left, as we advance pixels to the right.
-inline void shiftMatrixLeft(int m[9]) {
+static inline void shiftMatrixLeft(int m[9]) {
     m[0] = m[1];
     m[3] = m[4];
     m[6] = m[7];
@@ -121,66 +120,66 @@ private:
     SkScalar fShininess;
 };
 
-inline SkScalar sobel(int a, int b, int c, int d, int e, int f, SkScalar scale) {
+static inline SkScalar sobel(int a, int b, int c, int d, int e, int f, SkScalar scale) {
     return (-a + b - 2 * c + 2 * d -e + f) * scale;
 }
 
-inline SkPoint3 pointToNormal(SkScalar x, SkScalar y, SkScalar surfaceScale) {
+static inline SkPoint3 pointToNormal(SkScalar x, SkScalar y, SkScalar surfaceScale) {
     SkPoint3 vector = SkPoint3::Make(-x * surfaceScale, -y * surfaceScale, 1);
     fast_normalize(&vector);
     return vector;
 }
 
-inline SkPoint3 topLeftNormal(int m[9], SkScalar surfaceScale) {
+static inline SkPoint3 topLeftNormal(int m[9], SkScalar surfaceScale) {
     return pointToNormal(sobel(0, 0, m[4], m[5], m[7], m[8], gTwoThirds),
                          sobel(0, 0, m[4], m[7], m[5], m[8], gTwoThirds),
                          surfaceScale);
 }
 
-inline SkPoint3 topNormal(int m[9], SkScalar surfaceScale) {
+static inline SkPoint3 topNormal(int m[9], SkScalar surfaceScale) {
     return pointToNormal(sobel(   0,    0, m[3], m[5], m[6], m[8], gOneThird),
                          sobel(m[3], m[6], m[4], m[7], m[5], m[8], gOneHalf),
                          surfaceScale);
 }
 
-inline SkPoint3 topRightNormal(int m[9], SkScalar surfaceScale) {
+static inline SkPoint3 topRightNormal(int m[9], SkScalar surfaceScale) {
     return pointToNormal(sobel(   0,    0, m[3], m[4], m[6], m[7], gTwoThirds),
                          sobel(m[3], m[6], m[4], m[7],    0,    0, gTwoThirds),
                          surfaceScale);
 }
 
-inline SkPoint3 leftNormal(int m[9], SkScalar surfaceScale) {
+static inline SkPoint3 leftNormal(int m[9], SkScalar surfaceScale) {
     return pointToNormal(sobel(m[1], m[2], m[4], m[5], m[7], m[8], gOneHalf),
                          sobel(   0,    0, m[1], m[7], m[2], m[8], gOneThird),
                          surfaceScale);
 }
 
 
-inline SkPoint3 interiorNormal(int m[9], SkScalar surfaceScale) {
+static inline SkPoint3 interiorNormal(int m[9], SkScalar surfaceScale) {
     return pointToNormal(sobel(m[0], m[2], m[3], m[5], m[6], m[8], gOneQuarter),
                          sobel(m[0], m[6], m[1], m[7], m[2], m[8], gOneQuarter),
                          surfaceScale);
 }
 
-inline SkPoint3 rightNormal(int m[9], SkScalar surfaceScale) {
+static inline SkPoint3 rightNormal(int m[9], SkScalar surfaceScale) {
     return pointToNormal(sobel(m[0], m[1], m[3], m[4], m[6], m[7], gOneHalf),
                          sobel(m[0], m[6], m[1], m[7],    0,    0, gOneThird),
                          surfaceScale);
 }
 
-inline SkPoint3 bottomLeftNormal(int m[9], SkScalar surfaceScale) {
+static inline SkPoint3 bottomLeftNormal(int m[9], SkScalar surfaceScale) {
     return pointToNormal(sobel(m[1], m[2], m[4], m[5],    0,    0, gTwoThirds),
                          sobel(   0,    0, m[1], m[4], m[2], m[5], gTwoThirds),
                          surfaceScale);
 }
 
-inline SkPoint3 bottomNormal(int m[9], SkScalar surfaceScale) {
+static inline SkPoint3 bottomNormal(int m[9], SkScalar surfaceScale) {
     return pointToNormal(sobel(m[0], m[2], m[3], m[5],    0,    0, gOneThird),
                          sobel(m[0], m[3], m[1], m[4], m[2], m[5], gOneHalf),
                          surfaceScale);
 }
 
-inline SkPoint3 bottomRightNormal(int m[9], SkScalar surfaceScale) {
+static inline SkPoint3 bottomRightNormal(int m[9], SkScalar surfaceScale) {
     return pointToNormal(sobel(m[0], m[1], m[3], m[4], 0,  0, gTwoThirds),
                          sobel(m[0], m[3], m[1], m[4], 0,  0, gTwoThirds),
                          surfaceScale);
@@ -207,7 +206,7 @@ public:
 };
 
 template <class LightingType, class LightType, class PixelFetcher>
-void lightBitmap(const LightingType& lightingType,
+static void lightBitmap(const LightingType& lightingType,
                  const SkImageFilterLight* light,
                  const SkBitmap& src,
                  SkBitmap* dst,
@@ -299,7 +298,7 @@ void lightBitmap(const LightingType& lightingType,
 }
 
 template <class LightingType, class LightType>
-void lightBitmap(const LightingType& lightingType,
+static void lightBitmap(const LightingType& lightingType,
                  const SkImageFilterLight* light,
                  const SkBitmap& src,
                  SkBitmap* dst,
@@ -314,7 +313,7 @@ void lightBitmap(const LightingType& lightingType,
     }
 }
 
-SkPoint3 readPoint3(SkReadBuffer& buffer) {
+static SkPoint3 readPoint3(SkReadBuffer& buffer) {
     SkPoint3 point;
     point.fX = buffer.readScalar();
     point.fY = buffer.readScalar();
@@ -325,7 +324,7 @@ SkPoint3 readPoint3(SkReadBuffer& buffer) {
     return point;
 };
 
-void writePoint3(const SkPoint3& point, SkWriteBuffer& buffer) {
+static void writePoint3(const SkPoint3& point, SkWriteBuffer& buffer) {
     buffer.writeScalar(point.fX);
     buffer.writeScalar(point.fY);
     buffer.writeScalar(point.fZ);
@@ -490,6 +489,7 @@ protected:
 
     sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
                                         SkIPoint* offset) const override;
+    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
 
 #if SK_SUPPORT_GPU
     sk_sp<GrFragmentProcessor> makeFragmentProcessor(GrResourceProvider*, sk_sp<GrTextureProxy>,
@@ -526,6 +526,7 @@ protected:
 
     sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
                                         SkIPoint* offset) const override;
+    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
 
 #if SK_SUPPORT_GPU
     sk_sp<GrFragmentProcessor> makeFragmentProcessor(GrResourceProvider*, sk_sp<GrTextureProxy>,
@@ -752,8 +753,6 @@ class GrGLLight;
 
 #endif
 
-};
-
 ///////////////////////////////////////////////////////////////////////////////
 
 class SkImageFilterLight : public SkRefCnt {
@@ -771,6 +770,8 @@ public:
     }
     virtual SkImageFilterLight* transform(const SkMatrix& matrix) const = 0;
 
+    virtual sk_sp<SkImageFilterLight> makeColorSpace(SkColorSpaceXformer*) const = 0;
+
     // Defined below SkLight's subclasses.
     void flattenLight(SkWriteBuffer& buffer) const;
     static SkImageFilterLight* UnflattenLight(SkReadBuffer& buffer);
@@ -797,6 +798,14 @@ private:
 
 ///////////////////////////////////////////////////////////////////////////////
 
+static SkColor xform_color(const SkPoint3& color, SkColorSpaceXformer* xformer) {
+    SkColor origColor = SkColorSetARGBInline(0xFF,
+                                             SkScalarRoundToInt(color.fX),
+                                             SkScalarRoundToInt(color.fY),
+                                             SkScalarRoundToInt(color.fZ));
+    return xformer->apply(origColor);
+}
+
 class SkDistantLight : public SkImageFilterLight {
 public:
     SkDistantLight(const SkPoint3& direction, SkColor color)
@@ -818,6 +827,10 @@ public:
 #endif
     }
 
+    sk_sp<SkImageFilterLight> makeColorSpace(SkColorSpaceXformer* xformer) const override {
+        return sk_make_sp<SkDistantLight>(fDirection, xform_color(this->color(), xformer));
+    }
+
     bool isEqual(const SkImageFilterLight& other) const override {
         if (other.type() != kDistant_LightType) {
             return false;
@@ -874,6 +887,11 @@ public:
         return nullptr;
 #endif
     }
+
+    sk_sp<SkImageFilterLight> makeColorSpace(SkColorSpaceXformer* xformer) const override {
+        return sk_make_sp<SkPointLight>(fLocation, xform_color(this->color(), xformer));
+    }
+
     bool isEqual(const SkImageFilterLight& other) const override {
         if (other.type() != kPoint_LightType) {
             return false;
@@ -923,7 +941,8 @@ public:
      : INHERITED(color),
        fLocation(location),
        fTarget(target),
-       fSpecularExponent(SkScalarPin(specularExponent, kSpecularExponentMin, kSpecularExponentMax))
+       fSpecularExponent(SkScalarPin(specularExponent, kSpecularExponentMin, kSpecularExponentMax)),
+       fCutoffAngle(cutoffAngle)
     {
        fS = target - location;
        fast_normalize(&fS);
@@ -933,6 +952,11 @@ public:
        fConeScale = SkScalarInvert(antiAliasThreshold);
     }
 
+    sk_sp<SkImageFilterLight> makeColorSpace(SkColorSpaceXformer* xformer) const override {
+        return sk_make_sp<SkSpotLight>(fLocation, fTarget, fSpecularExponent, fCutoffAngle,
+                                       xform_color(this->color(), xformer));
+    }
+
     SkImageFilterLight* transform(const SkMatrix& matrix) const override {
         SkPoint location2 = SkPoint::Make(fLocation.fX, fLocation.fY);
         matrix.mapPoints(&location2, 1);
@@ -1056,6 +1080,7 @@ private:
     SkPoint3 fLocation;
     SkPoint3 fTarget;
     SkScalar fSpecularExponent;
+    SkScalar fCutoffAngle;
     SkScalar fCosOuterConeAngle;
     SkScalar fCosInnerConeAngle;
     SkScalar fConeScale;
@@ -1326,6 +1351,16 @@ sk_sp<SkSpecialImage> SkDiffuseLightingImageFilter::onFilterImage(SkSpecialImage
                                           dst);
 }
 
+sk_sp<SkImageFilter> SkDiffuseLightingImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer)
+const {
+    SkASSERT(1 == this->countInputs());
+    sk_sp<SkImageFilter> input =
+            this->getInput(0) ? this->getInput(0)->onMakeColorSpace(xformer) : nullptr;
+    return SkDiffuseLightingImageFilter::Make(this->light()->makeColorSpace(xformer),
+                                              255.0f * this->surfaceScale(), fKD, std::move(input),
+                                              this->getCropRectIfSet());
+}
+
 #ifndef SK_IGNORE_TO_STRING
 void SkDiffuseLightingImageFilter::toString(SkString* str) const {
     str->appendf("SkDiffuseLightingImageFilter: (");
@@ -1490,6 +1525,17 @@ sk_sp<SkSpecialImage> SkSpecularLightingImageFilter::onFilterImage(SkSpecialImag
     return SkSpecialImage::MakeFromRaster(SkIRect::MakeWH(bounds.width(), bounds.height()), dst);
 }
 
+sk_sp<SkImageFilter> SkSpecularLightingImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer)
+const {
+    SkASSERT(1 == this->countInputs());
+
+    sk_sp<SkImageFilter> input =
+            this->getInput(0) ? this->getInput(0)->onMakeColorSpace(xformer) : nullptr;
+    return SkSpecularLightingImageFilter::Make(this->light()->makeColorSpace(xformer),
+                                               255.0f * this->surfaceScale(), fKS, fShininess,
+                                               std::move(input), this->getCropRectIfSet());
+}
+
 #ifndef SK_IGNORE_TO_STRING
 void SkSpecularLightingImageFilter::toString(SkString* str) const {
     str->appendf("SkSpecularLightingImageFilter: (");
@@ -1516,14 +1562,13 @@ sk_sp<GrFragmentProcessor> SkSpecularLightingImageFilter::makeFragmentProcessor(
 
 #if SK_SUPPORT_GPU
 
-namespace {
-SkPoint3 random_point3(SkRandom* random) {
+static SkPoint3 random_point3(SkRandom* random) {
     return SkPoint3::Make(SkScalarToFloat(random->nextSScalar1()),
                           SkScalarToFloat(random->nextSScalar1()),
                           SkScalarToFloat(random->nextSScalar1()));
 }
 
-SkImageFilterLight* create_random_light(SkRandom* random) {
+static SkImageFilterLight* create_random_light(SkRandom* random) {
     int type = random->nextULessThan(3);
     switch (type) {
         case 0: {
@@ -1542,9 +1587,9 @@ SkImageFilterLight* create_random_light(SkRandom* random) {
     }
 }
 
-SkString emitNormalFunc(BoundaryMode mode,
-                        const char* pointToNormalName,
-                        const char* sobelFuncName) {
+static SkString emitNormalFunc(BoundaryMode mode,
+                               const char* pointToNormalName,
+                               const char* sobelFuncName) {
     SkString result;
     switch (mode) {
     case kTopLeft_BoundaryMode:
@@ -1617,8 +1662,6 @@ SkString emitNormalFunc(BoundaryMode mode,
     return result;
 }
 
-}
-
 class GrGLLightingEffect : public GrGLSLFragmentProcessor {
 public:
     GrGLLightingEffect() : fLight(nullptr) { }
index 5d959d1..56cd5d5 100644 (file)
@@ -63,6 +63,9 @@ protected:
         offset->fX = offset->fY = 0;
         return sk_ref_sp<SkSpecialImage>(source);
     }
+    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override {
+        return sk_ref_sp(const_cast<MatrixTestImageFilter*>(this));
+    }
 
     void flatten(SkWriteBuffer& buffer) const override {
         SkDEBUGFAIL("Should never get here");
@@ -90,6 +93,9 @@ public:
                                         SkIPoint* offset) const override {
         return nullptr;
     }
+    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override {
+        return nullptr;
+    }
 
     SK_TO_STRING_OVERRIDE()
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(FailImageFilter)
index de9af07..766bbef 100644 (file)
@@ -366,6 +366,9 @@ protected:
         offset->fX = offset->fY = 0;
         return sk_ref_sp<SkSpecialImage>(source);
     }
+    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override {
+        return sk_ref_sp(const_cast<DummyImageFilter*>(this));
+    }
 
 private:
     DummyImageFilter(bool visited) : INHERITED(nullptr, 0, nullptr), fVisited(visited) {}