makeColorSpace() for SkColorFilterShader and SkLightingShader
authorMatt Sarett <msarett@google.com>
Thu, 20 Apr 2017 14:09:23 +0000 (10:09 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 21 Apr 2017 19:55:23 +0000 (19:55 +0000)
Fixes 4 gms in gbr-8888 config.

Bug: skia:6516
Change-Id: I9da839eb0211910989be35db0e13c0e1bbfa185d
Reviewed-on: https://skia-review.googlesource.com/13964
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Matt Sarett <msarett@google.com>

include/core/SkLights.h
include/core/SkShader.h
src/core/SkColorFilterShader.cpp
src/core/SkColorFilterShader.h
src/core/SkLightingShader.cpp
src/core/SkLights.cpp

index d91d919..5c66487 100644 (file)
@@ -113,6 +113,8 @@ public:
         bool operator!= (const Light& b) { return !(this->operator==(b)); }
 
     private:
+        friend class SkLights;
+
         LightType   fType;
         SkColor3f   fColor;           // linear (unpremul) color. Range is 0..1 in each channel.
 
@@ -191,6 +193,10 @@ private:
     SkLights() {
         fAmbientLightColor.set(0.0f, 0.0f, 0.0f);
     }
+
+    friend class SkLightingShaderImpl;
+    sk_sp<SkLights> makeColorSpace(SkColorSpaceXformer* xformer) const;
+
     SkTArray<Light> fLights;
     SkColor3f fAmbientLightColor;
     typedef SkRefCnt INHERITED;
index b3b5faa..ba61314 100644 (file)
@@ -517,7 +517,9 @@ private:
     friend class SkLocalMatrixShader;
     friend class SkBitmapProcLegacyShader;    // for computeTotalInverse()
     friend class SkComposeShader;
+    friend class SkColorFilterShader;
     friend class SkColorSpaceXformer;
+    friend class SkLightingShaderImpl;
 
     typedef SkFlattenable INHERITED;
 };
index 5e96b24..bfe7461 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "SkArenaAlloc.h"
 #include "SkColorFilterShader.h"
+#include "SkColorSpaceXformer.h"
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
 #include "SkShader.h"
@@ -62,6 +63,9 @@ SkShader::Context* SkColorFilterShader::onMakeContext(const ContextRec& rec,
     return alloc->make<FilterShaderContext>(*this, shaderContext, rec);
 }
 
+sk_sp<SkShader> SkColorFilterShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
+    return fShader->makeColorSpace(xformer)->makeWithColorFilter(xformer->apply(fFilter.get()));
+}
 
 SkColorFilterShader::FilterShaderContext::FilterShaderContext(
                                                          const SkColorFilterShader& filterShader,
index e697736..18f65ba 100644 (file)
@@ -48,6 +48,7 @@ public:
 protected:
     void flatten(SkWriteBuffer&) const override;
     Context* onMakeContext(const ContextRec&, SkArenaAlloc* alloc) const override;
+    sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
 
 private:
     sk_sp<SkShader>      fShader;
index 1c8b1b4..600134d 100644 (file)
@@ -83,6 +83,7 @@ public:
 protected:
     void flatten(SkWriteBuffer&) const override;
     Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
+    sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
 
 private:
     sk_sp<SkShader> fDiffuseShader;
@@ -455,6 +456,13 @@ SkShader::Context* SkLightingShaderImpl::onMakeContext(
     return alloc->make<LightingShaderContext>(*this, rec, diffuseContext, normalProvider, nullptr);
 }
 
+sk_sp<SkShader> SkLightingShaderImpl::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
+    sk_sp<SkShader> xformedDiffuseShader =
+            fDiffuseShader ? fDiffuseShader->makeColorSpace(xformer) : nullptr;
+    return SkLightingShader::Make(std::move(xformedDiffuseShader), fNormalSource,
+                                  fLights->makeColorSpace(xformer));
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 sk_sp<SkShader> SkLightingShader::Make(sk_sp<SkShader> diffuseShader,
index 56c9299..1073ba0 100644 (file)
@@ -6,6 +6,7 @@
  * found in the LICENSE file.
  */
 
+#include "SkColorSpaceXformer.h"
 #include "SkLights.h"
 #include "SkReadBuffer.h"
 
@@ -59,6 +60,28 @@ sk_sp<SkLights> SkLights::MakeFromBuffer(SkReadBuffer& buf) {
     return builder.finish();
 }
 
+static SkColor3f xform_color(const SkColor3f& color, SkColorSpaceXformer* xformer) {
+    SkColor origColor = SkColorSetARGBInline(0xFF,
+                                             SkScalarRoundToInt(color.fX),
+                                             SkScalarRoundToInt(color.fY),
+                                             SkScalarRoundToInt(color.fZ));
+    SkColor xformedColor = xformer->apply(origColor);
+    return SkColor3f::Make(SkIntToScalar(SkGetPackedR32(xformedColor)),
+                           SkIntToScalar(SkGetPackedG32(xformedColor)),
+                           SkIntToScalar(SkGetPackedB32(xformedColor)));
+}
+
+sk_sp<SkLights> SkLights::makeColorSpace(SkColorSpaceXformer* xformer) const {
+    SkLights::Builder builder;
+    for (int i = 0; i < this->numLights(); i++) {
+        Light light(fLights[i].type(), xform_color(fLights[i].color(), xformer),
+                    fLights[i].fDirOrPos, fLights[i].fIntensity, fLights[i].isRadial());
+        builder.add(light);
+    }
+    builder.setAmbientLightColor(xform_color(fAmbientLightColor, xformer));
+    return builder.finish();
+}
+
 void SkLights::flatten(SkWriteBuffer& buf) const {
     buf.writeScalarArray(&this->ambientLightColor().fX, 3);