moved files generated from .fp files into generated/ directories
Bug: skia:
Change-Id: I8605cdfcc0b1c56c23a6075c7fe188ab7384681c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/207221
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/gpu/effects/generated/GrAARectEffect.cpp b/src/gpu/effects/generated/GrAARectEffect.cpp
new file mode 100644
index 0000000..62d9f52
--- /dev/null
+++ b/src/gpu/effects/generated/GrAARectEffect.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrAARectEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrAARectEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLAARectEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLAARectEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrAARectEffect& _outer = args.fFp.cast<GrAARectEffect>();
+ (void)_outer;
+ auto edgeType = _outer.edgeType;
+ (void)edgeType;
+ auto rect = _outer.rect;
+ (void)rect;
+ prevRect = float4(-1.0);
+ rectUniformVar = args.fUniformHandler->addUniform(
+ kFragment_GrShaderFlag, kFloat4_GrSLType, "rectUniform");
+ fragBuilder->codeAppendf(
+ "float4 prevRect = float4(%f, %f, %f, %f);\nhalf alpha;\n@switch (%d) {\n case "
+ "0:\n case 2:\n alpha = half(all(greaterThan(float4(sk_FragCoord.xy, "
+ "%s.zw), float4(%s.xy, sk_FragCoord.xy))) ? 1 : 0);\n break;\n "
+ "default:\n half xSub, ySub;\n xSub = min(half(sk_FragCoord.x - "
+ "%s.x), 0.0);\n xSub += min(half(%s.z - sk_FragCoord.x), 0.0);\n "
+ "ySub = min(half(sk_FragCoord.y - %s.y), 0.0);\n ySub += min(half(%s.w - "
+ "sk_FragCoord.y), 0.0);\n alpha = (1.0 + ",
+ prevRect.left(),
+ prevRect.top(),
+ prevRect.right(),
+ prevRect.bottom(),
+ (int)_outer.edgeType,
+ args.fUniformHandler->getUniformCStr(rectUniformVar),
+ args.fUniformHandler->getUniformCStr(rectUniformVar),
+ args.fUniformHandler->getUniformCStr(rectUniformVar),
+ args.fUniformHandler->getUniformCStr(rectUniformVar),
+ args.fUniformHandler->getUniformCStr(rectUniformVar),
+ args.fUniformHandler->getUniformCStr(rectUniformVar));
+ fragBuilder->codeAppendf(
+ "max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n}\n@if (%d == 2 || %d == 3) {\n "
+ "alpha = 1.0 - alpha;\n}\n%s = %s * alpha;\n",
+ (int)_outer.edgeType,
+ (int)_outer.edgeType,
+ args.fOutputColor,
+ args.fInputColor);
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrAARectEffect& _outer = _proc.cast<GrAARectEffect>();
+ auto edgeType = _outer.edgeType;
+ (void)edgeType;
+ auto rect = _outer.rect;
+ (void)rect;
+ UniformHandle& rectUniform = rectUniformVar;
+ (void)rectUniform;
+
+ const SkRect& newRect = GrProcessorEdgeTypeIsAA(edgeType) ? rect.makeInset(.5f, .5f) : rect;
+ if (newRect != prevRect) {
+ pdman.set4f(rectUniform, newRect.fLeft, newRect.fTop, newRect.fRight, newRect.fBottom);
+ prevRect = newRect;
+ }
+ }
+ SkRect prevRect = float4(0);
+ UniformHandle rectUniformVar;
+};
+GrGLSLFragmentProcessor* GrAARectEffect::onCreateGLSLInstance() const {
+ return new GrGLSLAARectEffect();
+}
+void GrAARectEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {
+ b->add32((int32_t)edgeType);
+}
+bool GrAARectEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrAARectEffect& that = other.cast<GrAARectEffect>();
+ (void)that;
+ if (edgeType != that.edgeType) return false;
+ if (rect != that.rect) return false;
+ return true;
+}
+GrAARectEffect::GrAARectEffect(const GrAARectEffect& src)
+ : INHERITED(kGrAARectEffect_ClassID, src.optimizationFlags())
+ , edgeType(src.edgeType)
+ , rect(src.rect) {}
+std::unique_ptr<GrFragmentProcessor> GrAARectEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrAARectEffect(*this));
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAARectEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrAARectEffect::TestCreate(GrProcessorTestData* d) {
+ SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(),
+ d->fRandom->nextSScalar1(),
+ d->fRandom->nextSScalar1(),
+ d->fRandom->nextSScalar1());
+ std::unique_ptr<GrFragmentProcessor> fp;
+ do {
+ GrClipEdgeType edgeType =
+ static_cast<GrClipEdgeType>(d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
+
+ fp = GrAARectEffect::Make(edgeType, rect);
+ } while (nullptr == fp);
+ return fp;
+}
+#endif
diff --git a/src/gpu/effects/generated/GrAARectEffect.h b/src/gpu/effects/generated/GrAARectEffect.h
new file mode 100644
index 0000000..0c302c5
--- /dev/null
+++ b/src/gpu/effects/generated/GrAARectEffect.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrAARectEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrAARectEffect_DEFINED
+#define GrAARectEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrAARectEffect : public GrFragmentProcessor {
+public:
+ static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, SkRect rect) {
+ return std::unique_ptr<GrFragmentProcessor>(new GrAARectEffect(edgeType, rect));
+ }
+ GrAARectEffect(const GrAARectEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "AARectEffect"; }
+ GrClipEdgeType edgeType;
+ SkRect rect;
+
+private:
+ GrAARectEffect(GrClipEdgeType edgeType, SkRect rect)
+ : INHERITED(kGrAARectEffect_ClassID,
+ (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+ , edgeType(edgeType)
+ , rect(rect) {}
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.cpp b/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.cpp
new file mode 100644
index 0000000..70fe78a
--- /dev/null
+++ b/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrAlphaThresholdFragmentProcessor.fp; do not modify.
+ **************************************************************************************************/
+#include "GrAlphaThresholdFragmentProcessor.h"
+
+inline GrFragmentProcessor::OptimizationFlags GrAlphaThresholdFragmentProcessor::optFlags(
+ float outerThreshold) {
+ if (outerThreshold >= 1.0) {
+ return kPreservesOpaqueInput_OptimizationFlag |
+ kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+ } else {
+ return kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+ }
+}
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLAlphaThresholdFragmentProcessor : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLAlphaThresholdFragmentProcessor() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrAlphaThresholdFragmentProcessor& _outer =
+ args.fFp.cast<GrAlphaThresholdFragmentProcessor>();
+ (void)_outer;
+ auto innerThreshold = _outer.innerThreshold;
+ (void)innerThreshold;
+ auto outerThreshold = _outer.outerThreshold;
+ (void)outerThreshold;
+ innerThresholdVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
+ "innerThreshold");
+ outerThresholdVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
+ "outerThreshold");
+ SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ fragBuilder->codeAppendf(
+ "half4 color = %s;\nhalf4 mask_color = texture(%s, %s).%s;\nif (mask_color.w < "
+ "0.5) {\n if (color.w > %s) {\n half scale = %s / color.w;\n "
+ "color.xyz *= scale;\n color.w = %s;\n }\n} else if (color.w < %s) {\n "
+ " half scale = %s / max(0.001, color.w);\n color.xyz *= scale;\n color.w = "
+ "%s;\n}\n%s = color;\n",
+ args.fInputColor,
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ sk_TransformedCoords2D_0.c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ args.fUniformHandler->getUniformCStr(outerThresholdVar),
+ args.fUniformHandler->getUniformCStr(outerThresholdVar),
+ args.fUniformHandler->getUniformCStr(outerThresholdVar),
+ args.fUniformHandler->getUniformCStr(innerThresholdVar),
+ args.fUniformHandler->getUniformCStr(innerThresholdVar),
+ args.fUniformHandler->getUniformCStr(innerThresholdVar), args.fOutputColor);
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrAlphaThresholdFragmentProcessor& _outer =
+ _proc.cast<GrAlphaThresholdFragmentProcessor>();
+ {
+ pdman.set1f(innerThresholdVar, (_outer.innerThreshold));
+ pdman.set1f(outerThresholdVar, (_outer.outerThreshold));
+ }
+ }
+ UniformHandle innerThresholdVar;
+ UniformHandle outerThresholdVar;
+};
+GrGLSLFragmentProcessor* GrAlphaThresholdFragmentProcessor::onCreateGLSLInstance() const {
+ return new GrGLSLAlphaThresholdFragmentProcessor();
+}
+void GrAlphaThresholdFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrAlphaThresholdFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrAlphaThresholdFragmentProcessor& that = other.cast<GrAlphaThresholdFragmentProcessor>();
+ (void)that;
+ if (mask != that.mask) return false;
+ if (innerThreshold != that.innerThreshold) return false;
+ if (outerThreshold != that.outerThreshold) return false;
+ return true;
+}
+GrAlphaThresholdFragmentProcessor::GrAlphaThresholdFragmentProcessor(
+ const GrAlphaThresholdFragmentProcessor& src)
+ : INHERITED(kGrAlphaThresholdFragmentProcessor_ClassID, src.optimizationFlags())
+ , maskCoordTransform(src.maskCoordTransform)
+ , mask(src.mask)
+ , innerThreshold(src.innerThreshold)
+ , outerThreshold(src.outerThreshold) {
+ this->setTextureSamplerCnt(1);
+ this->addCoordTransform(&maskCoordTransform);
+}
+std::unique_ptr<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(*this));
+}
+const GrFragmentProcessor::TextureSampler& GrAlphaThresholdFragmentProcessor::onTextureSampler(
+ int index) const {
+ return IthTextureSampler(index, mask);
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAlphaThresholdFragmentProcessor);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCreate(
+ GrProcessorTestData* testData) {
+ sk_sp<GrTextureProxy> maskProxy = testData->textureProxy(GrProcessorUnitTest::kAlphaTextureIdx);
+ // Make the inner and outer thresholds be in (0, 1) exclusive and be sorted correctly.
+ float innerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
+ float outerThresh = testData->fRandom->nextUScalar1() * .99f + 0.005f;
+ const int kMaxWidth = 1000;
+ const int kMaxHeight = 1000;
+ uint32_t width = testData->fRandom->nextULessThan(kMaxWidth);
+ uint32_t height = testData->fRandom->nextULessThan(kMaxHeight);
+ uint32_t x = testData->fRandom->nextULessThan(kMaxWidth - width);
+ uint32_t y = testData->fRandom->nextULessThan(kMaxHeight - height);
+ SkIRect bounds = SkIRect::MakeXYWH(x, y, width, height);
+ return GrAlphaThresholdFragmentProcessor::Make(std::move(maskProxy), innerThresh, outerThresh,
+ bounds);
+}
+#endif
diff --git a/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.h b/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.h
new file mode 100644
index 0000000..8067db5
--- /dev/null
+++ b/src/gpu/effects/generated/GrAlphaThresholdFragmentProcessor.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrAlphaThresholdFragmentProcessor.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrAlphaThresholdFragmentProcessor_DEFINED
+#define GrAlphaThresholdFragmentProcessor_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrAlphaThresholdFragmentProcessor : public GrFragmentProcessor {
+public:
+ inline OptimizationFlags optFlags(float outerThreshold);
+
+ static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> mask,
+ float innerThreshold,
+ float outerThreshold,
+ const SkIRect& bounds) {
+ return std::unique_ptr<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(
+ mask, innerThreshold, outerThreshold, bounds));
+ }
+ GrAlphaThresholdFragmentProcessor(const GrAlphaThresholdFragmentProcessor& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "AlphaThresholdFragmentProcessor"; }
+ GrCoordTransform maskCoordTransform;
+ TextureSampler mask;
+ float innerThreshold;
+ float outerThreshold;
+
+private:
+ GrAlphaThresholdFragmentProcessor(sk_sp<GrTextureProxy> mask, float innerThreshold,
+ float outerThreshold, const SkIRect& bounds)
+ : INHERITED(kGrAlphaThresholdFragmentProcessor_ClassID, kNone_OptimizationFlags)
+ , maskCoordTransform(
+ SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
+ mask.get())
+ , mask(std::move(mask))
+ , innerThreshold(innerThreshold)
+ , outerThreshold(outerThreshold) {
+ this->setTextureSamplerCnt(1);
+ this->addCoordTransform(&maskCoordTransform);
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ const TextureSampler& onTextureSampler(int) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.cpp b/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.cpp
new file mode 100644
index 0000000..b91e148
--- /dev/null
+++ b/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrBlurredEdgeFragmentProcessor.fp; do not modify.
+ **************************************************************************************************/
+#include "GrBlurredEdgeFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLBlurredEdgeFragmentProcessor : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLBlurredEdgeFragmentProcessor() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrBlurredEdgeFragmentProcessor& _outer =
+ args.fFp.cast<GrBlurredEdgeFragmentProcessor>();
+ (void)_outer;
+ auto mode = _outer.mode;
+ (void)mode;
+ fragBuilder->codeAppendf(
+ "half factor = 1.0 - %s.w;\n@switch (%d) {\n case 0:\n factor = "
+ "exp((-factor * factor) * 4.0) - 0.017999999999999999;\n break;\n case "
+ "1:\n factor = smoothstep(1.0, 0.0, factor);\n break;\n}\n%s = "
+ "half4(factor);\n",
+ args.fInputColor, (int)_outer.mode, args.fOutputColor);
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {}
+};
+GrGLSLFragmentProcessor* GrBlurredEdgeFragmentProcessor::onCreateGLSLInstance() const {
+ return new GrGLSLBlurredEdgeFragmentProcessor();
+}
+void GrBlurredEdgeFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {
+ b->add32((int32_t)mode);
+}
+bool GrBlurredEdgeFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrBlurredEdgeFragmentProcessor& that = other.cast<GrBlurredEdgeFragmentProcessor>();
+ (void)that;
+ if (mode != that.mode) return false;
+ return true;
+}
+GrBlurredEdgeFragmentProcessor::GrBlurredEdgeFragmentProcessor(
+ const GrBlurredEdgeFragmentProcessor& src)
+ : INHERITED(kGrBlurredEdgeFragmentProcessor_ClassID, src.optimizationFlags())
+ , mode(src.mode) {}
+std::unique_ptr<GrFragmentProcessor> GrBlurredEdgeFragmentProcessor::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrBlurredEdgeFragmentProcessor(*this));
+}
diff --git a/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.h b/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.h
new file mode 100644
index 0000000..c149bcc
--- /dev/null
+++ b/src/gpu/effects/generated/GrBlurredEdgeFragmentProcessor.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrBlurredEdgeFragmentProcessor.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrBlurredEdgeFragmentProcessor_DEFINED
+#define GrBlurredEdgeFragmentProcessor_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrBlurredEdgeFragmentProcessor : public GrFragmentProcessor {
+public:
+ enum class Mode { kGaussian = 0, kSmoothStep = 1 };
+ static std::unique_ptr<GrFragmentProcessor> Make(Mode mode) {
+ return std::unique_ptr<GrFragmentProcessor>(new GrBlurredEdgeFragmentProcessor(mode));
+ }
+ GrBlurredEdgeFragmentProcessor(const GrBlurredEdgeFragmentProcessor& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "BlurredEdgeFragmentProcessor"; }
+ Mode mode;
+
+private:
+ GrBlurredEdgeFragmentProcessor(Mode mode)
+ : INHERITED(kGrBlurredEdgeFragmentProcessor_ClassID, kNone_OptimizationFlags)
+ , mode(mode) {}
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.cpp b/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.cpp
new file mode 100644
index 0000000..28cdbd5
--- /dev/null
+++ b/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.cpp
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrCircleBlurFragmentProcessor.fp; do not modify.
+ **************************************************************************************************/
+#include "GrCircleBlurFragmentProcessor.h"
+
+#include "GrProxyProvider.h"
+
+// Computes an unnormalized half kernel (right side). Returns the summation of all the half
+// kernel values.
+static float make_unnormalized_half_kernel(float* halfKernel, int halfKernelSize, float sigma) {
+ const float invSigma = 1.f / sigma;
+ const float b = -0.5f * invSigma * invSigma;
+ float tot = 0.0f;
+ // Compute half kernel values at half pixel steps out from the center.
+ float t = 0.5f;
+ for (int i = 0; i < halfKernelSize; ++i) {
+ float value = expf(t * t * b);
+ tot += value;
+ halfKernel[i] = value;
+ t += 1.f;
+ }
+ return tot;
+}
+
+// Create a Gaussian half-kernel (right side) and a summed area table given a sigma and number
+// of discrete steps. The half kernel is normalized to sum to 0.5.
+static void make_half_kernel_and_summed_table(float* halfKernel, float* summedHalfKernel,
+ int halfKernelSize, float sigma) {
+ // The half kernel should sum to 0.5 not 1.0.
+ const float tot = 2.f * make_unnormalized_half_kernel(halfKernel, halfKernelSize, sigma);
+ float sum = 0.f;
+ for (int i = 0; i < halfKernelSize; ++i) {
+ halfKernel[i] /= tot;
+ sum += halfKernel[i];
+ summedHalfKernel[i] = sum;
+ }
+}
+
+// Applies the 1D half kernel vertically at points along the x axis to a circle centered at the
+// origin with radius circleR.
+void apply_kernel_in_y(float* results, int numSteps, float firstX, float circleR,
+ int halfKernelSize, const float* summedHalfKernelTable) {
+ float x = firstX;
+ for (int i = 0; i < numSteps; ++i, x += 1.f) {
+ if (x < -circleR || x > circleR) {
+ results[i] = 0;
+ continue;
+ }
+ float y = sqrtf(circleR * circleR - x * x);
+ // In the column at x we exit the circle at +y and -y
+ // The summed table entry j is actually reflects an offset of j + 0.5.
+ y -= 0.5f;
+ int yInt = SkScalarFloorToInt(y);
+ SkASSERT(yInt >= -1);
+ if (y < 0) {
+ results[i] = (y + 0.5f) * summedHalfKernelTable[0];
+ } else if (yInt >= halfKernelSize - 1) {
+ results[i] = 0.5f;
+ } else {
+ float yFrac = y - yInt;
+ results[i] = (1.f - yFrac) * summedHalfKernelTable[yInt] +
+ yFrac * summedHalfKernelTable[yInt + 1];
+ }
+ }
+}
+
+// Apply a Gaussian at point (evalX, 0) to a circle centered at the origin with radius circleR.
+// This relies on having a half kernel computed for the Gaussian and a table of applications of
+// the half kernel in y to columns at (evalX - halfKernel, evalX - halfKernel + 1, ..., evalX +
+// halfKernel) passed in as yKernelEvaluations.
+static uint8_t eval_at(float evalX, float circleR, const float* halfKernel, int halfKernelSize,
+ const float* yKernelEvaluations) {
+ float acc = 0;
+
+ float x = evalX - halfKernelSize;
+ for (int i = 0; i < halfKernelSize; ++i, x += 1.f) {
+ if (x < -circleR || x > circleR) {
+ continue;
+ }
+ float verticalEval = yKernelEvaluations[i];
+ acc += verticalEval * halfKernel[halfKernelSize - i - 1];
+ }
+ for (int i = 0; i < halfKernelSize; ++i, x += 1.f) {
+ if (x < -circleR || x > circleR) {
+ continue;
+ }
+ float verticalEval = yKernelEvaluations[i + halfKernelSize];
+ acc += verticalEval * halfKernel[i];
+ }
+ // Since we applied a half kernel in y we multiply acc by 2 (the circle is symmetric about
+ // the x axis).
+ return SkUnitScalarClampToByte(2.f * acc);
+}
+
+// This function creates a profile of a blurred circle. It does this by computing a kernel for
+// half the Gaussian and a matching summed area table. The summed area table is used to compute
+// an array of vertical applications of the half kernel to the circle along the x axis. The
+// table of y evaluations has 2 * k + n entries where k is the size of the half kernel and n is
+// the size of the profile being computed. Then for each of the n profile entries we walk out k
+// steps in each horizontal direction multiplying the corresponding y evaluation by the half
+// kernel entry and sum these values to compute the profile entry.
+static void create_circle_profile(uint8_t* weights, float sigma, float circleR,
+ int profileTextureWidth) {
+ const int numSteps = profileTextureWidth;
+
+ // The full kernel is 6 sigmas wide.
+ int halfKernelSize = SkScalarCeilToInt(6.0f * sigma);
+ // round up to next multiple of 2 and then divide by 2
+ halfKernelSize = ((halfKernelSize + 1) & ~1) >> 1;
+
+ // Number of x steps at which to apply kernel in y to cover all the profile samples in x.
+ int numYSteps = numSteps + 2 * halfKernelSize;
+
+ SkAutoTArray<float> bulkAlloc(halfKernelSize + halfKernelSize + numYSteps);
+ float* halfKernel = bulkAlloc.get();
+ float* summedKernel = bulkAlloc.get() + halfKernelSize;
+ float* yEvals = bulkAlloc.get() + 2 * halfKernelSize;
+ make_half_kernel_and_summed_table(halfKernel, summedKernel, halfKernelSize, sigma);
+
+ float firstX = -halfKernelSize + 0.5f;
+ apply_kernel_in_y(yEvals, numYSteps, firstX, circleR, halfKernelSize, summedKernel);
+
+ for (int i = 0; i < numSteps - 1; ++i) {
+ float evalX = i + 0.5f;
+ weights[i] = eval_at(evalX, circleR, halfKernel, halfKernelSize, yEvals + i);
+ }
+ // Ensure the tail of the Gaussian goes to zero.
+ weights[numSteps - 1] = 0;
+}
+
+static void create_half_plane_profile(uint8_t* profile, int profileWidth) {
+ SkASSERT(!(profileWidth & 0x1));
+ // The full kernel is 6 sigmas wide.
+ float sigma = profileWidth / 6.f;
+ int halfKernelSize = profileWidth / 2;
+
+ SkAutoTArray<float> halfKernel(halfKernelSize);
+
+ // The half kernel should sum to 0.5.
+ const float tot = 2.f * make_unnormalized_half_kernel(halfKernel.get(), halfKernelSize, sigma);
+ float sum = 0.f;
+ // Populate the profile from the right edge to the middle.
+ for (int i = 0; i < halfKernelSize; ++i) {
+ halfKernel[halfKernelSize - i - 1] /= tot;
+ sum += halfKernel[halfKernelSize - i - 1];
+ profile[profileWidth - i - 1] = SkUnitScalarClampToByte(sum);
+ }
+ // Populate the profile from the middle to the left edge (by flipping the half kernel and
+ // continuing the summation).
+ for (int i = 0; i < halfKernelSize; ++i) {
+ sum += halfKernel[i];
+ profile[halfKernelSize - i - 1] = SkUnitScalarClampToByte(sum);
+ }
+ // Ensure tail goes to 0.
+ profile[profileWidth - 1] = 0;
+}
+
+static sk_sp<GrTextureProxy> create_profile_texture(GrProxyProvider* proxyProvider,
+ const SkRect& circle, float sigma,
+ float* solidRadius, float* textureRadius) {
+ float circleR = circle.width() / 2.0f;
+ if (circleR < SK_ScalarNearlyZero) {
+ return nullptr;
+ }
+ // Profile textures are cached by the ratio of sigma to circle radius and by the size of the
+ // profile texture (binned by powers of 2).
+ SkScalar sigmaToCircleRRatio = sigma / circleR;
+ // When sigma is really small this becomes a equivalent to convolving a Gaussian with a
+ // half-plane. Similarly, in the extreme high ratio cases circle becomes a point WRT to the
+ // Guassian and the profile texture is a just a Gaussian evaluation. However, we haven't yet
+ // implemented this latter optimization.
+ sigmaToCircleRRatio = SkTMin(sigmaToCircleRRatio, 8.f);
+ SkFixed sigmaToCircleRRatioFixed;
+ static const SkScalar kHalfPlaneThreshold = 0.1f;
+ bool useHalfPlaneApprox = false;
+ if (sigmaToCircleRRatio <= kHalfPlaneThreshold) {
+ useHalfPlaneApprox = true;
+ sigmaToCircleRRatioFixed = 0;
+ *solidRadius = circleR - 3 * sigma;
+ *textureRadius = 6 * sigma;
+ } else {
+ // Convert to fixed point for the key.
+ sigmaToCircleRRatioFixed = SkScalarToFixed(sigmaToCircleRRatio);
+ // We shave off some bits to reduce the number of unique entries. We could probably
+ // shave off more than we do.
+ sigmaToCircleRRatioFixed &= ~0xff;
+ sigmaToCircleRRatio = SkFixedToScalar(sigmaToCircleRRatioFixed);
+ sigma = circleR * sigmaToCircleRRatio;
+ *solidRadius = 0;
+ *textureRadius = circleR + 3 * sigma;
+ }
+
+ static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
+ GrUniqueKey key;
+ GrUniqueKey::Builder builder(&key, kDomain, 1, "1-D Circular Blur");
+ builder[0] = sigmaToCircleRRatioFixed;
+ builder.finish();
+
+ sk_sp<GrTextureProxy> blurProfile =
+ proxyProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin);
+ if (!blurProfile) {
+ static constexpr int kProfileTextureWidth = 512;
+
+ SkBitmap bm;
+ if (!bm.tryAllocPixels(SkImageInfo::MakeA8(kProfileTextureWidth, 1))) {
+ return nullptr;
+ }
+
+ if (useHalfPlaneApprox) {
+ create_half_plane_profile(bm.getAddr8(0, 0), kProfileTextureWidth);
+ } else {
+ // Rescale params to the size of the texture we're creating.
+ SkScalar scale = kProfileTextureWidth / *textureRadius;
+ create_circle_profile(bm.getAddr8(0, 0), sigma * scale, circleR * scale,
+ kProfileTextureWidth);
+ }
+
+ bm.setImmutable();
+ sk_sp<SkImage> image = SkImage::MakeFromBitmap(bm);
+
+ blurProfile = proxyProvider->createTextureProxy(std::move(image), kNone_GrSurfaceFlags, 1,
+ SkBudgeted::kYes, SkBackingFit::kExact);
+ if (!blurProfile) {
+ return nullptr;
+ }
+
+ SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
+ proxyProvider->assignUniqueKeyToProxy(key, blurProfile.get());
+ }
+
+ return blurProfile;
+}
+
+std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
+ GrProxyProvider* proxyProvider, const SkRect& circle, float sigma) {
+ float solidRadius;
+ float textureRadius;
+ sk_sp<GrTextureProxy> profile(
+ create_profile_texture(proxyProvider, circle, sigma, &solidRadius, &textureRadius));
+ if (!profile) {
+ return nullptr;
+ }
+ return std::unique_ptr<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(
+ circle, textureRadius, solidRadius, std::move(profile)));
+}
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLCircleBlurFragmentProcessor : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLCircleBlurFragmentProcessor() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrCircleBlurFragmentProcessor& _outer =
+ args.fFp.cast<GrCircleBlurFragmentProcessor>();
+ (void)_outer;
+ auto circleRect = _outer.circleRect;
+ (void)circleRect;
+ auto textureRadius = _outer.textureRadius;
+ (void)textureRadius;
+ auto solidRadius = _outer.solidRadius;
+ (void)solidRadius;
+ circleDataVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
+ "circleData");
+ fragBuilder->codeAppendf(
+ "half2 vec = half2(half((sk_FragCoord.x - float(%s.x)) * float(%s.w)), "
+ "half((sk_FragCoord.y - float(%s.y)) * float(%s.w)));\nhalf dist = length(vec) + "
+ "(0.5 - %s.z) * %s.w;\n%s = %s * texture(%s, float2(half2(dist, 0.5))).%s.w;\n",
+ args.fUniformHandler->getUniformCStr(circleDataVar),
+ args.fUniformHandler->getUniformCStr(circleDataVar),
+ args.fUniformHandler->getUniformCStr(circleDataVar),
+ args.fUniformHandler->getUniformCStr(circleDataVar),
+ args.fUniformHandler->getUniformCStr(circleDataVar),
+ args.fUniformHandler->getUniformCStr(circleDataVar), args.fOutputColor,
+ args.fInputColor,
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& data,
+ const GrFragmentProcessor& _proc) override {
+ const GrCircleBlurFragmentProcessor& _outer = _proc.cast<GrCircleBlurFragmentProcessor>();
+ auto circleRect = _outer.circleRect;
+ (void)circleRect;
+ auto textureRadius = _outer.textureRadius;
+ (void)textureRadius;
+ auto solidRadius = _outer.solidRadius;
+ (void)solidRadius;
+ GrSurfaceProxy& blurProfileSamplerProxy = *_outer.textureSampler(0).proxy();
+ GrTexture& blurProfileSampler = *blurProfileSamplerProxy.peekTexture();
+ (void)blurProfileSampler;
+ UniformHandle& circleData = circleDataVar;
+ (void)circleData;
+
+ data.set4f(circleData, circleRect.centerX(), circleRect.centerY(), solidRadius,
+ 1.f / textureRadius);
+ }
+ UniformHandle circleDataVar;
+};
+GrGLSLFragmentProcessor* GrCircleBlurFragmentProcessor::onCreateGLSLInstance() const {
+ return new GrGLSLCircleBlurFragmentProcessor();
+}
+void GrCircleBlurFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrCircleBlurFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrCircleBlurFragmentProcessor& that = other.cast<GrCircleBlurFragmentProcessor>();
+ (void)that;
+ if (circleRect != that.circleRect) return false;
+ if (textureRadius != that.textureRadius) return false;
+ if (solidRadius != that.solidRadius) return false;
+ if (blurProfileSampler != that.blurProfileSampler) return false;
+ return true;
+}
+GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(
+ const GrCircleBlurFragmentProcessor& src)
+ : INHERITED(kGrCircleBlurFragmentProcessor_ClassID, src.optimizationFlags())
+ , circleRect(src.circleRect)
+ , textureRadius(src.textureRadius)
+ , solidRadius(src.solidRadius)
+ , blurProfileSampler(src.blurProfileSampler) {
+ this->setTextureSamplerCnt(1);
+}
+std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(*this));
+}
+const GrFragmentProcessor::TextureSampler& GrCircleBlurFragmentProcessor::onTextureSampler(
+ int index) const {
+ return IthTextureSampler(index, blurProfileSampler);
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCircleBlurFragmentProcessor);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::TestCreate(
+ GrProcessorTestData* testData) {
+ SkScalar wh = testData->fRandom->nextRangeScalar(100.f, 1000.f);
+ SkScalar sigma = testData->fRandom->nextRangeF(1.f, 10.f);
+ SkRect circle = SkRect::MakeWH(wh, wh);
+ return GrCircleBlurFragmentProcessor::Make(testData->proxyProvider(), circle, sigma);
+}
+#endif
diff --git a/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.h b/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.h
new file mode 100644
index 0000000..1969fc3
--- /dev/null
+++ b/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrCircleBlurFragmentProcessor.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrCircleBlurFragmentProcessor_DEFINED
+#define GrCircleBlurFragmentProcessor_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrCircleBlurFragmentProcessor : public GrFragmentProcessor {
+public:
+ static std::unique_ptr<GrFragmentProcessor> Make(GrProxyProvider*, const SkRect& circle,
+ float sigma);
+ GrCircleBlurFragmentProcessor(const GrCircleBlurFragmentProcessor& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "CircleBlurFragmentProcessor"; }
+ SkRect circleRect;
+ float textureRadius;
+ float solidRadius;
+ TextureSampler blurProfileSampler;
+
+private:
+ GrCircleBlurFragmentProcessor(SkRect circleRect, float textureRadius, float solidRadius,
+ sk_sp<GrTextureProxy> blurProfileSampler)
+ : INHERITED(kGrCircleBlurFragmentProcessor_ClassID,
+ (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+ , circleRect(circleRect)
+ , textureRadius(textureRadius)
+ , solidRadius(solidRadius)
+ , blurProfileSampler(std::move(blurProfileSampler)) {
+ this->setTextureSamplerCnt(1);
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ const TextureSampler& onTextureSampler(int) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrCircleEffect.cpp b/src/gpu/effects/generated/GrCircleEffect.cpp
new file mode 100644
index 0000000..f24f2d7
--- /dev/null
+++ b/src/gpu/effects/generated/GrCircleEffect.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrCircleEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrCircleEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLCircleEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLCircleEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrCircleEffect& _outer = args.fFp.cast<GrCircleEffect>();
+ (void)_outer;
+ auto edgeType = _outer.edgeType;
+ (void)edgeType;
+ auto center = _outer.center;
+ (void)center;
+ auto radius = _outer.radius;
+ (void)radius;
+ prevRadius = -1.0;
+ circleVar =
+ args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, "circle");
+ fragBuilder->codeAppendf(
+ "half2 prevCenter;\nhalf prevRadius = %f;\nhalf d;\n@if (%d == 2 || %d == 3) {\n "
+ " d = half((length((float2(%s.xy) - sk_FragCoord.xy) * float(%s.w)) - 1.0) * "
+ "float(%s.z));\n} else {\n d = half((1.0 - length((float2(%s.xy) - "
+ "sk_FragCoord.xy) * float(%s.w))) * float(%s.z));\n}\n@if ((%d == 1 || %d == 3) || "
+ "%d == 4) {\n d = clamp(d, 0.0, 1.0);\n} else {\n d = d > 0.5 ? 1.0 : "
+ "0.0;\n}\n%s = %s * d;\n",
+ prevRadius, (int)_outer.edgeType, (int)_outer.edgeType,
+ args.fUniformHandler->getUniformCStr(circleVar),
+ args.fUniformHandler->getUniformCStr(circleVar),
+ args.fUniformHandler->getUniformCStr(circleVar),
+ args.fUniformHandler->getUniformCStr(circleVar),
+ args.fUniformHandler->getUniformCStr(circleVar),
+ args.fUniformHandler->getUniformCStr(circleVar), (int)_outer.edgeType,
+ (int)_outer.edgeType, (int)_outer.edgeType, args.fOutputColor, args.fInputColor);
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrCircleEffect& _outer = _proc.cast<GrCircleEffect>();
+ auto edgeType = _outer.edgeType;
+ (void)edgeType;
+ auto center = _outer.center;
+ (void)center;
+ auto radius = _outer.radius;
+ (void)radius;
+ UniformHandle& circle = circleVar;
+ (void)circle;
+
+ if (radius != prevRadius || center != prevCenter) {
+ SkScalar effectiveRadius = radius;
+ if (GrProcessorEdgeTypeIsInverseFill((GrClipEdgeType)edgeType)) {
+ effectiveRadius -= 0.5f;
+ // When the radius is 0.5 effectiveRadius is 0 which causes an inf * 0 in the
+ // shader.
+ effectiveRadius = SkTMax(0.001f, effectiveRadius);
+ } else {
+ effectiveRadius += 0.5f;
+ }
+ pdman.set4f(circle, center.fX, center.fY, effectiveRadius,
+ SkScalarInvert(effectiveRadius));
+ prevCenter = center;
+ prevRadius = radius;
+ }
+ }
+ SkPoint prevCenter = half2(0);
+ float prevRadius = 0;
+ UniformHandle circleVar;
+};
+GrGLSLFragmentProcessor* GrCircleEffect::onCreateGLSLInstance() const {
+ return new GrGLSLCircleEffect();
+}
+void GrCircleEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {
+ b->add32((int32_t)edgeType);
+}
+bool GrCircleEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrCircleEffect& that = other.cast<GrCircleEffect>();
+ (void)that;
+ if (edgeType != that.edgeType) return false;
+ if (center != that.center) return false;
+ if (radius != that.radius) return false;
+ return true;
+}
+GrCircleEffect::GrCircleEffect(const GrCircleEffect& src)
+ : INHERITED(kGrCircleEffect_ClassID, src.optimizationFlags())
+ , edgeType(src.edgeType)
+ , center(src.center)
+ , radius(src.radius) {}
+std::unique_ptr<GrFragmentProcessor> GrCircleEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrCircleEffect(*this));
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCircleEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrCircleEffect::TestCreate(GrProcessorTestData* testData) {
+ SkPoint center;
+ center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f);
+ center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
+ SkScalar radius = testData->fRandom->nextRangeF(1.f, 1000.f);
+ GrClipEdgeType et;
+ do {
+ et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
+ } while (GrClipEdgeType::kHairlineAA == et);
+ return GrCircleEffect::Make(et, center, radius);
+}
+#endif
diff --git a/src/gpu/effects/generated/GrCircleEffect.h b/src/gpu/effects/generated/GrCircleEffect.h
new file mode 100644
index 0000000..81ab40e
--- /dev/null
+++ b/src/gpu/effects/generated/GrCircleEffect.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrCircleEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrCircleEffect_DEFINED
+#define GrCircleEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrCircleEffect : public GrFragmentProcessor {
+public:
+ static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, SkPoint center,
+ float radius) {
+ // A radius below half causes the implicit insetting done by this processor to become
+ // inverted. We could handle this case by making the processor code more complicated.
+ if (radius < .5f && GrProcessorEdgeTypeIsInverseFill(edgeType)) {
+ return nullptr;
+ }
+ return std::unique_ptr<GrFragmentProcessor>(new GrCircleEffect(edgeType, center, radius));
+ }
+ GrCircleEffect(const GrCircleEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "CircleEffect"; }
+ GrClipEdgeType edgeType;
+ SkPoint center;
+ float radius;
+
+private:
+ GrCircleEffect(GrClipEdgeType edgeType, SkPoint center, float radius)
+ : INHERITED(kGrCircleEffect_ClassID,
+ (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+ , edgeType(edgeType)
+ , center(center)
+ , radius(radius) {}
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrComposeLerpEffect.cpp b/src/gpu/effects/generated/GrComposeLerpEffect.cpp
new file mode 100644
index 0000000..a768b5c
--- /dev/null
+++ b/src/gpu/effects/generated/GrComposeLerpEffect.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2019 Google LLC.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrComposeLerpEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrComposeLerpEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLComposeLerpEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLComposeLerpEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrComposeLerpEffect& _outer = args.fFp.cast<GrComposeLerpEffect>();
+ (void)_outer;
+ auto weight = _outer.weight;
+ (void)weight;
+ weightVar =
+ args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, "weight");
+ SkString _child0("_child0");
+ if (_outer.child1_index >= 0) {
+ this->emitChild(_outer.child1_index, &_child0, args);
+ } else {
+ fragBuilder->codeAppendf("half4 %s;", _child0.c_str());
+ }
+ SkString _child1("_child1");
+ if (_outer.child2_index >= 0) {
+ this->emitChild(_outer.child2_index, &_child1, args);
+ } else {
+ fragBuilder->codeAppendf("half4 %s;", _child1.c_str());
+ }
+ fragBuilder->codeAppendf("%s = mix(%s ? %s : %s, %s ? %s : %s, half(%s));\n",
+ args.fOutputColor, _outer.child1_index >= 0 ? "true" : "false",
+ _child0.c_str(), args.fInputColor,
+ _outer.child2_index >= 0 ? "true" : "false", _child1.c_str(),
+ args.fInputColor, args.fUniformHandler->getUniformCStr(weightVar));
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrComposeLerpEffect& _outer = _proc.cast<GrComposeLerpEffect>();
+ { pdman.set1f(weightVar, (_outer.weight)); }
+ }
+ UniformHandle weightVar;
+};
+GrGLSLFragmentProcessor* GrComposeLerpEffect::onCreateGLSLInstance() const {
+ return new GrGLSLComposeLerpEffect();
+}
+void GrComposeLerpEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrComposeLerpEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrComposeLerpEffect& that = other.cast<GrComposeLerpEffect>();
+ (void)that;
+ if (weight != that.weight) return false;
+ return true;
+}
+GrComposeLerpEffect::GrComposeLerpEffect(const GrComposeLerpEffect& src)
+ : INHERITED(kGrComposeLerpEffect_ClassID, src.optimizationFlags())
+ , child1_index(src.child1_index)
+ , child2_index(src.child2_index)
+ , weight(src.weight) {
+ if (child1_index >= 0) {
+ this->registerChildProcessor(src.childProcessor(child1_index).clone());
+ }
+ if (child2_index >= 0) {
+ this->registerChildProcessor(src.childProcessor(child2_index).clone());
+ }
+}
+std::unique_ptr<GrFragmentProcessor> GrComposeLerpEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrComposeLerpEffect(*this));
+}
diff --git a/src/gpu/effects/generated/GrComposeLerpEffect.h b/src/gpu/effects/generated/GrComposeLerpEffect.h
new file mode 100644
index 0000000..823d44d
--- /dev/null
+++ b/src/gpu/effects/generated/GrComposeLerpEffect.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 Google LLC.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrComposeLerpEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrComposeLerpEffect_DEFINED
+#define GrComposeLerpEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrComposeLerpEffect : public GrFragmentProcessor {
+public:
+ static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child1,
+ std::unique_ptr<GrFragmentProcessor> child2,
+ float weight) {
+ return std::unique_ptr<GrFragmentProcessor>(
+ new GrComposeLerpEffect(std::move(child1), std::move(child2), weight));
+ }
+ GrComposeLerpEffect(const GrComposeLerpEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "ComposeLerpEffect"; }
+ int child1_index = -1;
+ int child2_index = -1;
+ float weight;
+
+private:
+ GrComposeLerpEffect(std::unique_ptr<GrFragmentProcessor> child1,
+ std::unique_ptr<GrFragmentProcessor> child2, float weight)
+ : INHERITED(kGrComposeLerpEffect_ClassID, kNone_OptimizationFlags), weight(weight) {
+ if (child1) {
+ child1_index = this->numChildProcessors();
+ this->registerChildProcessor(std::move(child1));
+ }
+ if (child2) {
+ child2_index = this->numChildProcessors();
+ this->registerChildProcessor(std::move(child2));
+ }
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrComposeLerpRedEffect.cpp b/src/gpu/effects/generated/GrComposeLerpRedEffect.cpp
new file mode 100644
index 0000000..2f3a5e4
--- /dev/null
+++ b/src/gpu/effects/generated/GrComposeLerpRedEffect.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2019 Google LLC.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrComposeLerpRedEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrComposeLerpRedEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLComposeLerpRedEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLComposeLerpRedEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrComposeLerpRedEffect& _outer = args.fFp.cast<GrComposeLerpRedEffect>();
+ (void)_outer;
+ SkString _child0("_child0");
+ if (_outer.child1_index >= 0) {
+ this->emitChild(_outer.child1_index, &_child0, args);
+ } else {
+ fragBuilder->codeAppendf("half4 %s;", _child0.c_str());
+ }
+ SkString _child1("_child1");
+ if (_outer.child2_index >= 0) {
+ this->emitChild(_outer.child2_index, &_child1, args);
+ } else {
+ fragBuilder->codeAppendf("half4 %s;", _child1.c_str());
+ }
+ SkString _child2("_child2");
+ this->emitChild(_outer.lerp_index, &_child2, args);
+ fragBuilder->codeAppendf("%s = mix(%s ? %s : %s, %s ? %s : %s, %s.x);\n", args.fOutputColor,
+ _outer.child1_index >= 0 ? "true" : "false", _child0.c_str(),
+ args.fInputColor, _outer.child2_index >= 0 ? "true" : "false",
+ _child1.c_str(), args.fInputColor, _child2.c_str());
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {}
+};
+GrGLSLFragmentProcessor* GrComposeLerpRedEffect::onCreateGLSLInstance() const {
+ return new GrGLSLComposeLerpRedEffect();
+}
+void GrComposeLerpRedEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrComposeLerpRedEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrComposeLerpRedEffect& that = other.cast<GrComposeLerpRedEffect>();
+ (void)that;
+ return true;
+}
+GrComposeLerpRedEffect::GrComposeLerpRedEffect(const GrComposeLerpRedEffect& src)
+ : INHERITED(kGrComposeLerpRedEffect_ClassID, src.optimizationFlags())
+ , child1_index(src.child1_index)
+ , child2_index(src.child2_index)
+ , lerp_index(src.lerp_index) {
+ if (child1_index >= 0) {
+ this->registerChildProcessor(src.childProcessor(child1_index).clone());
+ }
+ if (child2_index >= 0) {
+ this->registerChildProcessor(src.childProcessor(child2_index).clone());
+ }
+ this->registerChildProcessor(src.childProcessor(lerp_index).clone());
+}
+std::unique_ptr<GrFragmentProcessor> GrComposeLerpRedEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrComposeLerpRedEffect(*this));
+}
diff --git a/src/gpu/effects/generated/GrComposeLerpRedEffect.h b/src/gpu/effects/generated/GrComposeLerpRedEffect.h
new file mode 100644
index 0000000..f109c8c
--- /dev/null
+++ b/src/gpu/effects/generated/GrComposeLerpRedEffect.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019 Google LLC.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrComposeLerpRedEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrComposeLerpRedEffect_DEFINED
+#define GrComposeLerpRedEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrComposeLerpRedEffect : public GrFragmentProcessor {
+public:
+ static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child1,
+ std::unique_ptr<GrFragmentProcessor> child2,
+ std::unique_ptr<GrFragmentProcessor> lerp) {
+ return std::unique_ptr<GrFragmentProcessor>(
+ new GrComposeLerpRedEffect(std::move(child1), std::move(child2), std::move(lerp)));
+ }
+ GrComposeLerpRedEffect(const GrComposeLerpRedEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "ComposeLerpRedEffect"; }
+ int child1_index = -1;
+ int child2_index = -1;
+ int lerp_index = -1;
+
+private:
+ GrComposeLerpRedEffect(std::unique_ptr<GrFragmentProcessor> child1,
+ std::unique_ptr<GrFragmentProcessor> child2,
+ std::unique_ptr<GrFragmentProcessor> lerp)
+ : INHERITED(kGrComposeLerpRedEffect_ClassID, kNone_OptimizationFlags) {
+ if (child1) {
+ child1_index = this->numChildProcessors();
+ this->registerChildProcessor(std::move(child1));
+ }
+ if (child2) {
+ child2_index = this->numChildProcessors();
+ this->registerChildProcessor(std::move(child2));
+ }
+ SkASSERT(lerp);
+ lerp_index = this->numChildProcessors();
+ this->registerChildProcessor(std::move(lerp));
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrConfigConversionEffect.cpp b/src/gpu/effects/generated/GrConfigConversionEffect.cpp
new file mode 100644
index 0000000..5acd214
--- /dev/null
+++ b/src/gpu/effects/generated/GrConfigConversionEffect.cpp
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrConfigConversionEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrConfigConversionEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLConfigConversionEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLConfigConversionEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrConfigConversionEffect& _outer = args.fFp.cast<GrConfigConversionEffect>();
+ (void)_outer;
+ auto pmConversion = _outer.pmConversion;
+ (void)pmConversion;
+
+ fragBuilder->forceHighPrecision();
+ fragBuilder->codeAppendf(
+ "%s = floor(%s * 255.0 + 0.5) / 255.0;\n@switch (%d) {\n case 0:\n "
+ "%s.xyz = floor((%s.xyz * %s.w) * 255.0 + 0.5) / 255.0;\n break;\n case "
+ "1:\n %s.xyz = %s.w <= 0.0 ? half3(0.0) : floor((%s.xyz / %s.w) * 255.0 + "
+ "0.5) / 255.0;\n break;\n}\n",
+ args.fOutputColor, args.fInputColor, (int)_outer.pmConversion, args.fOutputColor,
+ args.fOutputColor, args.fOutputColor, args.fOutputColor, args.fOutputColor,
+ args.fOutputColor, args.fOutputColor);
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {}
+};
+GrGLSLFragmentProcessor* GrConfigConversionEffect::onCreateGLSLInstance() const {
+ return new GrGLSLConfigConversionEffect();
+}
+void GrConfigConversionEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {
+ b->add32((int32_t)pmConversion);
+}
+bool GrConfigConversionEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrConfigConversionEffect& that = other.cast<GrConfigConversionEffect>();
+ (void)that;
+ if (pmConversion != that.pmConversion) return false;
+ return true;
+}
+GrConfigConversionEffect::GrConfigConversionEffect(const GrConfigConversionEffect& src)
+ : INHERITED(kGrConfigConversionEffect_ClassID, src.optimizationFlags())
+ , pmConversion(src.pmConversion) {}
+std::unique_ptr<GrFragmentProcessor> GrConfigConversionEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrConfigConversionEffect(*this));
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConfigConversionEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrConfigConversionEffect::TestCreate(
+ GrProcessorTestData* data) {
+ PMConversion pmConv = static_cast<PMConversion>(
+ data->fRandom->nextULessThan((int)PMConversion::kPMConversionCnt));
+ return std::unique_ptr<GrFragmentProcessor>(new GrConfigConversionEffect(pmConv));
+}
+#endif
diff --git a/src/gpu/effects/generated/GrConfigConversionEffect.h b/src/gpu/effects/generated/GrConfigConversionEffect.h
new file mode 100644
index 0000000..1b8dac2
--- /dev/null
+++ b/src/gpu/effects/generated/GrConfigConversionEffect.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrConfigConversionEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrConfigConversionEffect_DEFINED
+#define GrConfigConversionEffect_DEFINED
+#include "SkTypes.h"
+
+#include "GrClip.h"
+#include "GrContext.h"
+#include "GrContextPriv.h"
+#include "GrProxyProvider.h"
+#include "GrRenderTargetContext.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrConfigConversionEffect : public GrFragmentProcessor {
+public:
+ static bool TestForPreservingPMConversions(GrContext* context) {
+ static constexpr int kSize = 256;
+ static constexpr GrPixelConfig kConfig = kRGBA_8888_GrPixelConfig;
+ static constexpr SkColorType kColorType = kRGBA_8888_SkColorType;
+ const GrBackendFormat format =
+ context->priv().caps()->getBackendFormatFromColorType(kColorType);
+ SkAutoTMalloc<uint32_t> data(kSize * kSize * 3);
+ uint32_t* srcData = data.get();
+ uint32_t* firstRead = data.get() + kSize * kSize;
+ uint32_t* secondRead = data.get() + 2 * kSize * kSize;
+
+ // Fill with every possible premultiplied A, color channel value. There will be 256-y
+ // duplicate values in row y. We set r, g, and b to the same value since they are handled
+ // identically.
+ for (int y = 0; y < kSize; ++y) {
+ for (int x = 0; x < kSize; ++x) {
+ uint8_t* color = reinterpret_cast<uint8_t*>(&srcData[kSize * y + x]);
+ color[3] = y;
+ color[2] = SkTMin(x, y);
+ color[1] = SkTMin(x, y);
+ color[0] = SkTMin(x, y);
+ }
+ }
+ memset(firstRead, 0, kSize * kSize * sizeof(uint32_t));
+ memset(secondRead, 0, kSize * kSize * sizeof(uint32_t));
+
+ const SkImageInfo ii =
+ SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+
+ sk_sp<GrRenderTargetContext> readRTC(context->priv().makeDeferredRenderTargetContext(
+ format, SkBackingFit::kExact, kSize, kSize, kConfig, nullptr));
+ sk_sp<GrRenderTargetContext> tempRTC(context->priv().makeDeferredRenderTargetContext(
+ format, SkBackingFit::kExact, kSize, kSize, kConfig, nullptr));
+ if (!readRTC || !readRTC->asTextureProxy() || !tempRTC) {
+ return false;
+ }
+ // Adding discard to appease vulkan validation warning about loading uninitialized data on
+ // draw
+ readRTC->discard();
+
+ GrProxyProvider* proxyProvider = context->priv().proxyProvider();
+
+ SkPixmap pixmap(ii, srcData, 4 * kSize);
+
+ // This function is only ever called if we are in a GrContext that has a GrGpu since we are
+ // calling read pixels here. Thus the pixel data will be uploaded immediately and we don't
+ // need to keep the pixel data alive in the proxy. Therefore the ReleaseProc is nullptr.
+ sk_sp<SkImage> image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
+
+ sk_sp<GrTextureProxy> dataProxy = proxyProvider->createTextureProxy(
+ std::move(image), kNone_GrSurfaceFlags, 1, SkBudgeted::kYes, SkBackingFit::kExact);
+ if (!dataProxy) {
+ return false;
+ }
+
+ static const SkRect kRect = SkRect::MakeIWH(kSize, kSize);
+
+ // We do a PM->UPM draw from dataTex to readTex and read the data. Then we do a UPM->PM draw
+ // from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data.
+ // We then verify that two reads produced the same values.
+
+ GrPaint paint1;
+ GrPaint paint2;
+ GrPaint paint3;
+ std::unique_ptr<GrFragmentProcessor> pmToUPM(
+ new GrConfigConversionEffect(PMConversion::kToUnpremul));
+ std::unique_ptr<GrFragmentProcessor> upmToPM(
+ new GrConfigConversionEffect(PMConversion::kToPremul));
+
+ paint1.addColorTextureProcessor(dataProxy, SkMatrix::I());
+ paint1.addColorFragmentProcessor(pmToUPM->clone());
+ paint1.setPorterDuffXPFactory(SkBlendMode::kSrc);
+
+ readRTC->fillRectToRect(GrNoClip(), std::move(paint1), GrAA::kNo, SkMatrix::I(), kRect,
+ kRect);
+ if (!readRTC->readPixels(ii, firstRead, 0, 0, 0)) {
+ return false;
+ }
+
+ // Adding discard to appease vulkan validation warning about loading uninitialized data on
+ // draw
+ tempRTC->discard();
+
+ paint2.addColorTextureProcessor(readRTC->asTextureProxyRef(), SkMatrix::I());
+ paint2.addColorFragmentProcessor(std::move(upmToPM));
+ paint2.setPorterDuffXPFactory(SkBlendMode::kSrc);
+
+ tempRTC->fillRectToRect(GrNoClip(), std::move(paint2), GrAA::kNo, SkMatrix::I(), kRect,
+ kRect);
+
+ paint3.addColorTextureProcessor(tempRTC->asTextureProxyRef(), SkMatrix::I());
+ paint3.addColorFragmentProcessor(std::move(pmToUPM));
+ paint3.setPorterDuffXPFactory(SkBlendMode::kSrc);
+
+ readRTC->fillRectToRect(GrNoClip(), std::move(paint3), GrAA::kNo, SkMatrix::I(), kRect,
+ kRect);
+
+ if (!readRTC->readPixels(ii, secondRead, 0, 0, 0)) {
+ return false;
+ }
+
+ for (int y = 0; y < kSize; ++y) {
+ for (int x = 0; x <= y; ++x) {
+ if (firstRead[kSize * y + x] != secondRead[kSize * y + x]) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp,
+ PMConversion pmConversion) {
+ if (!fp) {
+ return nullptr;
+ }
+ std::unique_ptr<GrFragmentProcessor> ccFP(new GrConfigConversionEffect(pmConversion));
+ std::unique_ptr<GrFragmentProcessor> fpPipeline[] = {std::move(fp), std::move(ccFP)};
+ return GrFragmentProcessor::RunInSeries(fpPipeline, 2);
+ }
+ GrConfigConversionEffect(const GrConfigConversionEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "ConfigConversionEffect"; }
+ PMConversion pmConversion;
+
+private:
+ GrConfigConversionEffect(PMConversion pmConversion)
+ : INHERITED(kGrConfigConversionEffect_ClassID, kNone_OptimizationFlags)
+ , pmConversion(pmConversion) {}
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrConstColorProcessor.cpp b/src/gpu/effects/generated/GrConstColorProcessor.cpp
new file mode 100644
index 0000000..ca23d07
--- /dev/null
+++ b/src/gpu/effects/generated/GrConstColorProcessor.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrConstColorProcessor.fp; do not modify.
+ **************************************************************************************************/
+#include "GrConstColorProcessor.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLConstColorProcessor : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLConstColorProcessor() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrConstColorProcessor& _outer = args.fFp.cast<GrConstColorProcessor>();
+ (void)_outer;
+ auto color = _outer.color;
+ (void)color;
+ auto mode = _outer.mode;
+ (void)mode;
+ colorVar =
+ args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, "color");
+ fragBuilder->codeAppendf(
+ "@switch (%d) {\n case 0:\n %s = %s;\n break;\n case 1:\n "
+ " %s = %s * %s;\n break;\n case 2:\n %s = %s.w * %s;\n "
+ "break;\n}\n",
+ (int)_outer.mode, args.fOutputColor, args.fUniformHandler->getUniformCStr(colorVar),
+ args.fOutputColor, args.fInputColor, args.fUniformHandler->getUniformCStr(colorVar),
+ args.fOutputColor, args.fInputColor,
+ args.fUniformHandler->getUniformCStr(colorVar));
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrConstColorProcessor& _outer = _proc.cast<GrConstColorProcessor>();
+ {
+ const SkPMColor4f& colorValue = _outer.color;
+ if (colorPrev != colorValue) {
+ colorPrev = colorValue;
+ pdman.set4fv(colorVar, 1, colorValue.vec());
+ }
+ }
+ }
+ SkPMColor4f colorPrev = {SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN};
+ UniformHandle colorVar;
+};
+GrGLSLFragmentProcessor* GrConstColorProcessor::onCreateGLSLInstance() const {
+ return new GrGLSLConstColorProcessor();
+}
+void GrConstColorProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {
+ b->add32((int32_t)mode);
+}
+bool GrConstColorProcessor::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrConstColorProcessor& that = other.cast<GrConstColorProcessor>();
+ (void)that;
+ if (color != that.color) return false;
+ if (mode != that.mode) return false;
+ return true;
+}
+GrConstColorProcessor::GrConstColorProcessor(const GrConstColorProcessor& src)
+ : INHERITED(kGrConstColorProcessor_ClassID, src.optimizationFlags())
+ , color(src.color)
+ , mode(src.mode) {}
+std::unique_ptr<GrFragmentProcessor> GrConstColorProcessor::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrConstColorProcessor(*this));
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConstColorProcessor);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrConstColorProcessor::TestCreate(GrProcessorTestData* d) {
+ SkPMColor4f color;
+ int colorPicker = d->fRandom->nextULessThan(3);
+ switch (colorPicker) {
+ case 0: {
+ uint32_t a = d->fRandom->nextULessThan(0x100);
+ uint32_t r = d->fRandom->nextULessThan(a + 1);
+ uint32_t g = d->fRandom->nextULessThan(a + 1);
+ uint32_t b = d->fRandom->nextULessThan(a + 1);
+ color = SkPMColor4f::FromBytes_RGBA(GrColorPackRGBA(r, g, b, a));
+ break;
+ }
+ case 1:
+ color = SK_PMColor4fTRANSPARENT;
+ break;
+ case 2:
+ uint32_t c = d->fRandom->nextULessThan(0x100);
+ color = SkPMColor4f::FromBytes_RGBA(c | (c << 8) | (c << 16) | (c << 24));
+ break;
+ }
+ InputMode mode = static_cast<InputMode>(d->fRandom->nextULessThan(kInputModeCnt));
+ return GrConstColorProcessor::Make(color, mode);
+}
+#endif
diff --git a/src/gpu/effects/generated/GrConstColorProcessor.h b/src/gpu/effects/generated/GrConstColorProcessor.h
new file mode 100644
index 0000000..9959cf5
--- /dev/null
+++ b/src/gpu/effects/generated/GrConstColorProcessor.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrConstColorProcessor.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrConstColorProcessor_DEFINED
+#define GrConstColorProcessor_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrConstColorProcessor : public GrFragmentProcessor {
+public:
+ enum class InputMode { kIgnore = 0, kLast = 2, kModulateA = 2, kModulateRGBA = 1 };
+
+ static const int kInputModeCnt = (int)InputMode::kLast + 1;
+
+ static OptimizationFlags OptFlags(const SkPMColor4f& color, InputMode mode) {
+ OptimizationFlags flags = kConstantOutputForConstantInput_OptimizationFlag;
+ if (mode != InputMode::kIgnore) {
+ flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+ }
+ if (color.isOpaque()) {
+ flags |= kPreservesOpaqueInput_OptimizationFlag;
+ }
+ return flags;
+ }
+
+ SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
+ switch (mode) {
+ case InputMode::kIgnore:
+ return color;
+ case InputMode::kModulateA:
+ return color * input.fA;
+ case InputMode::kModulateRGBA:
+ return color * input;
+ }
+ SK_ABORT("Unexpected mode");
+ return SK_PMColor4fTRANSPARENT;
+ }
+ static std::unique_ptr<GrFragmentProcessor> Make(SkPMColor4f color, InputMode mode) {
+ return std::unique_ptr<GrFragmentProcessor>(new GrConstColorProcessor(color, mode));
+ }
+ GrConstColorProcessor(const GrConstColorProcessor& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "ConstColorProcessor"; }
+ SkPMColor4f color;
+ InputMode mode;
+
+private:
+ GrConstColorProcessor(SkPMColor4f color, InputMode mode)
+ : INHERITED(kGrConstColorProcessor_ClassID, (OptimizationFlags)OptFlags(color, mode))
+ , color(color)
+ , mode(mode) {}
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrEllipseEffect.cpp b/src/gpu/effects/generated/GrEllipseEffect.cpp
new file mode 100644
index 0000000..42998d0
--- /dev/null
+++ b/src/gpu/effects/generated/GrEllipseEffect.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrEllipseEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrEllipseEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLEllipseEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLEllipseEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrEllipseEffect& _outer = args.fFp.cast<GrEllipseEffect>();
+ (void)_outer;
+ auto edgeType = _outer.edgeType;
+ (void)edgeType;
+ auto center = _outer.center;
+ (void)center;
+ auto radii = _outer.radii;
+ (void)radii;
+ prevRadii = float2(-1.0);
+ medPrecision = !sk_Caps.floatIs32Bits;
+ ellipseVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
+ "ellipse");
+ if (medPrecision) {
+ scaleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat2_GrSLType,
+ "scale");
+ }
+ fragBuilder->codeAppendf(
+ "float2 prevCenter;\nfloat2 prevRadii = float2(%f, %f);\nbool medPrecision = "
+ "%s;\nfloat2 d = sk_FragCoord.xy - %s.xy;\n@if (medPrecision) {\n d *= "
+ "%s.y;\n}\nfloat2 Z = d * %s.zw;\nfloat implicit = dot(Z, d) - 1.0;\nfloat "
+ "grad_dot = 4.0 * dot(Z, Z);\n@if (medPrecision) {\n grad_dot = max(grad_dot, "
+ "6.1036000000000003e-05);\n} else {\n grad_dot = max(grad_dot, "
+ "1.1755e-38);\n}\nfloat approx_dist = implicit * inversesqrt(grad_dot);\n@if "
+ "(medPrecision) {\n approx_dist *= %s.x;\n}\nhalf alpha;\n@switch ",
+ prevRadii.fX, prevRadii.fY, (medPrecision ? "true" : "false"),
+ args.fUniformHandler->getUniformCStr(ellipseVar),
+ scaleVar.isValid() ? args.fUniformHandler->getUniformCStr(scaleVar) : "float2(0)",
+ args.fUniformHandler->getUniformCStr(ellipseVar),
+ scaleVar.isValid() ? args.fUniformHandler->getUniformCStr(scaleVar) : "float2(0)");
+ fragBuilder->codeAppendf(
+ "(%d) {\n case 0:\n alpha = approx_dist > 0.0 ? 0.0 : 1.0;\n "
+ "break;\n case 1:\n alpha = clamp(0.5 - half(approx_dist), 0.0, 1.0);\n "
+ " break;\n case 2:\n alpha = approx_dist > 0.0 ? 1.0 : 0.0;\n "
+ " break;\n case 3:\n alpha = clamp(0.5 + half(approx_dist), 0.0, 1.0);\n "
+ " break;\n default:\n discard;\n}\n%s = %s * alpha;\n",
+ (int)_outer.edgeType, args.fOutputColor, args.fInputColor);
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrEllipseEffect& _outer = _proc.cast<GrEllipseEffect>();
+ auto edgeType = _outer.edgeType;
+ (void)edgeType;
+ auto center = _outer.center;
+ (void)center;
+ auto radii = _outer.radii;
+ (void)radii;
+ UniformHandle& ellipse = ellipseVar;
+ (void)ellipse;
+ UniformHandle& scale = scaleVar;
+ (void)scale;
+
+ if (radii != prevRadii || center != prevCenter) {
+ float invRXSqd;
+ float invRYSqd;
+ // If we're using a scale factor to work around precision issues, choose the larger
+ // radius as the scale factor. The inv radii need to be pre-adjusted by the scale
+ // factor.
+ if (scale.isValid()) {
+ if (radii.fX > radii.fY) {
+ invRXSqd = 1.f;
+ invRYSqd = (radii.fX * radii.fX) / (radii.fY * radii.fY);
+ pdman.set2f(scale, radii.fX, 1.f / radii.fX);
+ } else {
+ invRXSqd = (radii.fY * radii.fY) / (radii.fX * radii.fX);
+ invRYSqd = 1.f;
+ pdman.set2f(scale, radii.fY, 1.f / radii.fY);
+ }
+ } else {
+ invRXSqd = 1.f / (radii.fX * radii.fX);
+ invRYSqd = 1.f / (radii.fY * radii.fY);
+ }
+ pdman.set4f(ellipse, center.fX, center.fY, invRXSqd, invRYSqd);
+ prevCenter = center;
+ prevRadii = radii;
+ }
+ }
+ SkPoint prevCenter = float2(0);
+ SkPoint prevRadii = float2(0);
+ bool medPrecision = false;
+ UniformHandle ellipseVar;
+ UniformHandle scaleVar;
+};
+GrGLSLFragmentProcessor* GrEllipseEffect::onCreateGLSLInstance() const {
+ return new GrGLSLEllipseEffect();
+}
+void GrEllipseEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {
+ b->add32((int32_t)edgeType);
+}
+bool GrEllipseEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrEllipseEffect& that = other.cast<GrEllipseEffect>();
+ (void)that;
+ if (edgeType != that.edgeType) return false;
+ if (center != that.center) return false;
+ if (radii != that.radii) return false;
+ return true;
+}
+GrEllipseEffect::GrEllipseEffect(const GrEllipseEffect& src)
+ : INHERITED(kGrEllipseEffect_ClassID, src.optimizationFlags())
+ , edgeType(src.edgeType)
+ , center(src.center)
+ , radii(src.radii) {}
+std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrEllipseEffect(*this));
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrEllipseEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::TestCreate(GrProcessorTestData* testData) {
+ SkPoint center;
+ center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f);
+ center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
+ SkScalar rx = testData->fRandom->nextRangeF(0.f, 1000.f);
+ SkScalar ry = testData->fRandom->nextRangeF(0.f, 1000.f);
+ GrClipEdgeType et;
+ do {
+ et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
+ } while (GrClipEdgeType::kHairlineAA == et);
+ return GrEllipseEffect::Make(et, center, SkPoint::Make(rx, ry),
+ *testData->caps()->shaderCaps());
+}
+#endif
diff --git a/src/gpu/effects/generated/GrEllipseEffect.h b/src/gpu/effects/generated/GrEllipseEffect.h
new file mode 100644
index 0000000..c2a76d8
--- /dev/null
+++ b/src/gpu/effects/generated/GrEllipseEffect.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrEllipseEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrEllipseEffect_DEFINED
+#define GrEllipseEffect_DEFINED
+#include "SkTypes.h"
+
+#include "GrShaderCaps.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrEllipseEffect : public GrFragmentProcessor {
+public:
+ static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, SkPoint center,
+ SkPoint radii, const GrShaderCaps& caps) {
+ // Small radii produce bad results on devices without full float.
+ if (!caps.floatIs32Bits() && (radii.fX < 0.5f || radii.fY < 0.5f)) {
+ return nullptr;
+ }
+ // Very narrow ellipses produce bad results on devices without full float
+ if (!caps.floatIs32Bits() && (radii.fX > 255 * radii.fY || radii.fY > 255 * radii.fX)) {
+ return nullptr;
+ }
+ // Very large ellipses produce bad results on devices without full float
+ if (!caps.floatIs32Bits() && (radii.fX > 16384 || radii.fY > 16384)) {
+ return nullptr;
+ }
+ return std::unique_ptr<GrFragmentProcessor>(new GrEllipseEffect(edgeType, center, radii));
+ }
+ GrEllipseEffect(const GrEllipseEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "EllipseEffect"; }
+ GrClipEdgeType edgeType;
+ SkPoint center;
+ SkPoint radii;
+
+private:
+ GrEllipseEffect(GrClipEdgeType edgeType, SkPoint center, SkPoint radii)
+ : INHERITED(kGrEllipseEffect_ClassID,
+ (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+ , edgeType(edgeType)
+ , center(center)
+ , radii(radii) {}
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrLumaColorFilterEffect.cpp b/src/gpu/effects/generated/GrLumaColorFilterEffect.cpp
new file mode 100644
index 0000000..d0b1e1c
--- /dev/null
+++ b/src/gpu/effects/generated/GrLumaColorFilterEffect.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrLumaColorFilterEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrLumaColorFilterEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLLumaColorFilterEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLLumaColorFilterEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrLumaColorFilterEffect& _outer = args.fFp.cast<GrLumaColorFilterEffect>();
+ (void)_outer;
+ fragBuilder->codeAppendf(
+ "\nhalf luma = clamp(dot(half3(0.21260000000000001, 0.71519999999999995, 0.0722), "
+ "%s.xyz), 0.0, 1.0);\n%s = half4(0.0, 0.0, 0.0, luma);\n",
+ args.fInputColor, args.fOutputColor);
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {}
+};
+GrGLSLFragmentProcessor* GrLumaColorFilterEffect::onCreateGLSLInstance() const {
+ return new GrGLSLLumaColorFilterEffect();
+}
+void GrLumaColorFilterEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrLumaColorFilterEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrLumaColorFilterEffect& that = other.cast<GrLumaColorFilterEffect>();
+ (void)that;
+ return true;
+}
+GrLumaColorFilterEffect::GrLumaColorFilterEffect(const GrLumaColorFilterEffect& src)
+ : INHERITED(kGrLumaColorFilterEffect_ClassID, src.optimizationFlags()) {}
+std::unique_ptr<GrFragmentProcessor> GrLumaColorFilterEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrLumaColorFilterEffect(*this));
+}
diff --git a/src/gpu/effects/generated/GrLumaColorFilterEffect.h b/src/gpu/effects/generated/GrLumaColorFilterEffect.h
new file mode 100644
index 0000000..c93f6a3
--- /dev/null
+++ b/src/gpu/effects/generated/GrLumaColorFilterEffect.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrLumaColorFilterEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrLumaColorFilterEffect_DEFINED
+#define GrLumaColorFilterEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrLumaColorFilterEffect : public GrFragmentProcessor {
+public:
+#include "SkColorData.h"
+
+ SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
+ float luma = SK_ITU_BT709_LUM_COEFF_R * input.fR + SK_ITU_BT709_LUM_COEFF_G * input.fG +
+ SK_ITU_BT709_LUM_COEFF_B * input.fB;
+ return {0, 0, 0, SkTPin(luma, 0.0f, 1.0f)};
+ }
+ static std::unique_ptr<GrFragmentProcessor> Make() {
+ return std::unique_ptr<GrFragmentProcessor>(new GrLumaColorFilterEffect());
+ }
+ GrLumaColorFilterEffect(const GrLumaColorFilterEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "LumaColorFilterEffect"; }
+
+private:
+ GrLumaColorFilterEffect()
+ : INHERITED(kGrLumaColorFilterEffect_ClassID, kNone_OptimizationFlags) {}
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrMagnifierEffect.cpp b/src/gpu/effects/generated/GrMagnifierEffect.cpp
new file mode 100644
index 0000000..3e34da7
--- /dev/null
+++ b/src/gpu/effects/generated/GrMagnifierEffect.cpp
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrMagnifierEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrMagnifierEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLMagnifierEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLMagnifierEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrMagnifierEffect& _outer = args.fFp.cast<GrMagnifierEffect>();
+ (void)_outer;
+ auto bounds = _outer.bounds;
+ (void)bounds;
+ auto srcRect = _outer.srcRect;
+ (void)srcRect;
+ auto xInvZoom = _outer.xInvZoom;
+ (void)xInvZoom;
+ auto yInvZoom = _outer.yInvZoom;
+ (void)yInvZoom;
+ auto xInvInset = _outer.xInvInset;
+ (void)xInvInset;
+ auto yInvInset = _outer.yInvInset;
+ (void)yInvInset;
+ boundsUniformVar = args.fUniformHandler->addUniform(
+ kFragment_GrShaderFlag, kFloat4_GrSLType, "boundsUniform");
+ xInvZoomVar = args.fUniformHandler->addUniform(
+ kFragment_GrShaderFlag, kFloat_GrSLType, "xInvZoom");
+ yInvZoomVar = args.fUniformHandler->addUniform(
+ kFragment_GrShaderFlag, kFloat_GrSLType, "yInvZoom");
+ xInvInsetVar = args.fUniformHandler->addUniform(
+ kFragment_GrShaderFlag, kFloat_GrSLType, "xInvInset");
+ yInvInsetVar = args.fUniformHandler->addUniform(
+ kFragment_GrShaderFlag, kFloat_GrSLType, "yInvInset");
+ offsetVar =
+ args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, "offset");
+ SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ fragBuilder->codeAppendf(
+ "float2 coord = %s;\nfloat2 zoom_coord = float2(%s) + coord * float2(%s, "
+ "%s);\nfloat2 delta = (coord - %s.xy) * %s.zw;\ndelta = min(delta, "
+ "float2(half2(1.0, 1.0)) - delta);\ndelta *= float2(%s, %s);\nfloat weight = "
+ "0.0;\nif (delta.x < 2.0 && delta.y < 2.0) {\n delta = float2(half2(2.0, 2.0)) "
+ "- delta;\n float dist = length(delta);\n dist = max(2.0 - dist, 0.0);\n "
+ "weight = min(dist * dist, 1.0);\n} else {\n float2 delta_squared = delta * "
+ "delta;\n weight = min(min(delta_squared.x, delta_square",
+ sk_TransformedCoords2D_0.c_str(),
+ args.fUniformHandler->getUniformCStr(offsetVar),
+ args.fUniformHandler->getUniformCStr(xInvZoomVar),
+ args.fUniformHandler->getUniformCStr(yInvZoomVar),
+ args.fUniformHandler->getUniformCStr(boundsUniformVar),
+ args.fUniformHandler->getUniformCStr(boundsUniformVar),
+ args.fUniformHandler->getUniformCStr(xInvInsetVar),
+ args.fUniformHandler->getUniformCStr(yInvInsetVar));
+ fragBuilder->codeAppendf(
+ "d.y), 1.0);\n}\n%s = texture(%s, mix(coord, zoom_coord, weight)).%s;\n",
+ args.fOutputColor,
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrMagnifierEffect& _outer = _proc.cast<GrMagnifierEffect>();
+ {
+ pdman.set1f(xInvZoomVar, (_outer.xInvZoom));
+ pdman.set1f(yInvZoomVar, (_outer.yInvZoom));
+ pdman.set1f(xInvInsetVar, (_outer.xInvInset));
+ pdman.set1f(yInvInsetVar, (_outer.yInvInset));
+ }
+ GrSurfaceProxy& srcProxy = *_outer.textureSampler(0).proxy();
+ GrTexture& src = *srcProxy.peekTexture();
+ (void)src;
+ auto bounds = _outer.bounds;
+ (void)bounds;
+ UniformHandle& boundsUniform = boundsUniformVar;
+ (void)boundsUniform;
+ auto srcRect = _outer.srcRect;
+ (void)srcRect;
+ UniformHandle& xInvZoom = xInvZoomVar;
+ (void)xInvZoom;
+ UniformHandle& yInvZoom = yInvZoomVar;
+ (void)yInvZoom;
+ UniformHandle& xInvInset = xInvInsetVar;
+ (void)xInvInset;
+ UniformHandle& yInvInset = yInvInsetVar;
+ (void)yInvInset;
+ UniformHandle& offset = offsetVar;
+ (void)offset;
+
+ SkScalar invW = 1.0f / src.width();
+ SkScalar invH = 1.0f / src.height();
+
+ {
+ SkScalar y = srcRect.y() * invH;
+ if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) {
+ y = 1.0f - (srcRect.height() / bounds.height()) - y;
+ }
+
+ pdman.set2f(offset, srcRect.x() * invW, y);
+ }
+
+ {
+ SkScalar y = bounds.y() * invH;
+ if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) {
+ y = 1.0f - bounds.height() * invH;
+ }
+
+ pdman.set4f(boundsUniform,
+ bounds.x() * invW,
+ y,
+ SkIntToScalar(src.width()) / bounds.width(),
+ SkIntToScalar(src.height()) / bounds.height());
+ }
+ }
+ UniformHandle boundsUniformVar;
+ UniformHandle offsetVar;
+ UniformHandle xInvZoomVar;
+ UniformHandle yInvZoomVar;
+ UniformHandle xInvInsetVar;
+ UniformHandle yInvInsetVar;
+};
+GrGLSLFragmentProcessor* GrMagnifierEffect::onCreateGLSLInstance() const {
+ return new GrGLSLMagnifierEffect();
+}
+void GrMagnifierEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrMagnifierEffect& that = other.cast<GrMagnifierEffect>();
+ (void)that;
+ if (src != that.src) return false;
+ if (bounds != that.bounds) return false;
+ if (srcRect != that.srcRect) return false;
+ if (xInvZoom != that.xInvZoom) return false;
+ if (yInvZoom != that.yInvZoom) return false;
+ if (xInvInset != that.xInvInset) return false;
+ if (yInvInset != that.yInvInset) return false;
+ return true;
+}
+GrMagnifierEffect::GrMagnifierEffect(const GrMagnifierEffect& src)
+ : INHERITED(kGrMagnifierEffect_ClassID, src.optimizationFlags())
+ , srcCoordTransform(src.srcCoordTransform)
+ , src(src.src)
+ , bounds(src.bounds)
+ , srcRect(src.srcRect)
+ , xInvZoom(src.xInvZoom)
+ , yInvZoom(src.yInvZoom)
+ , xInvInset(src.xInvInset)
+ , yInvInset(src.yInvInset) {
+ this->setTextureSamplerCnt(1);
+ this->addCoordTransform(&srcCoordTransform);
+}
+std::unique_ptr<GrFragmentProcessor> GrMagnifierEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrMagnifierEffect(*this));
+}
+const GrFragmentProcessor::TextureSampler& GrMagnifierEffect::onTextureSampler(int index) const {
+ return IthTextureSampler(index, src);
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMagnifierEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrMagnifierEffect::TestCreate(GrProcessorTestData* d) {
+ sk_sp<GrTextureProxy> proxy = d->textureProxy(0);
+ const int kMaxWidth = 200;
+ const int kMaxHeight = 200;
+ const SkScalar kMaxInset = 20.0f;
+ uint32_t width = d->fRandom->nextULessThan(kMaxWidth);
+ uint32_t height = d->fRandom->nextULessThan(kMaxHeight);
+ SkScalar inset = d->fRandom->nextRangeScalar(1.0f, kMaxInset);
+
+ SkIRect bounds = SkIRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight));
+ SkRect srcRect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
+
+ auto effect = GrMagnifierEffect::Make(std::move(proxy),
+ bounds,
+ srcRect,
+ srcRect.width() / bounds.width(),
+ srcRect.height() / bounds.height(),
+ bounds.width() / inset,
+ bounds.height() / inset);
+ SkASSERT(effect);
+ return effect;
+}
+#endif
diff --git a/src/gpu/effects/generated/GrMagnifierEffect.h b/src/gpu/effects/generated/GrMagnifierEffect.h
new file mode 100644
index 0000000..c1bf22b
--- /dev/null
+++ b/src/gpu/effects/generated/GrMagnifierEffect.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrMagnifierEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrMagnifierEffect_DEFINED
+#define GrMagnifierEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrMagnifierEffect : public GrFragmentProcessor {
+public:
+ static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> src, SkIRect bounds,
+ SkRect srcRect, float xInvZoom, float yInvZoom,
+ float xInvInset, float yInvInset) {
+ return std::unique_ptr<GrFragmentProcessor>(new GrMagnifierEffect(
+ src, bounds, srcRect, xInvZoom, yInvZoom, xInvInset, yInvInset));
+ }
+ GrMagnifierEffect(const GrMagnifierEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "MagnifierEffect"; }
+ GrCoordTransform srcCoordTransform;
+ TextureSampler src;
+ SkIRect bounds;
+ SkRect srcRect;
+ float xInvZoom;
+ float yInvZoom;
+ float xInvInset;
+ float yInvInset;
+
+private:
+ GrMagnifierEffect(sk_sp<GrTextureProxy> src, SkIRect bounds, SkRect srcRect, float xInvZoom,
+ float yInvZoom, float xInvInset, float yInvInset)
+ : INHERITED(kGrMagnifierEffect_ClassID, kNone_OptimizationFlags)
+ , srcCoordTransform(SkMatrix::I(), src.get())
+ , src(std::move(src))
+ , bounds(bounds)
+ , srcRect(srcRect)
+ , xInvZoom(xInvZoom)
+ , yInvZoom(yInvZoom)
+ , xInvInset(xInvInset)
+ , yInvInset(yInvInset) {
+ this->setTextureSamplerCnt(1);
+ this->addCoordTransform(&srcCoordTransform);
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ const TextureSampler& onTextureSampler(int) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrMixerEffect.cpp b/src/gpu/effects/generated/GrMixerEffect.cpp
new file mode 100644
index 0000000..98e9a47
--- /dev/null
+++ b/src/gpu/effects/generated/GrMixerEffect.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2019 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrMixerEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrMixerEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLMixerEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLMixerEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrMixerEffect& _outer = args.fFp.cast<GrMixerEffect>();
+ (void)_outer;
+ auto weight = _outer.weight;
+ (void)weight;
+ weightVar =
+ args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, "weight");
+ SkString _input0 = SkStringPrintf("%s", args.fInputColor);
+ SkString _child0("_child0");
+ this->emitChild(_outer.fp0_index, _input0.c_str(), &_child0, args);
+ fragBuilder->codeAppendf("half4 in0 = %s;", _child0.c_str());
+ SkString _input1 = SkStringPrintf("%s", args.fInputColor);
+ SkString _child1("_child1");
+ if (_outer.fp1_index >= 0) {
+ this->emitChild(_outer.fp1_index, _input1.c_str(), &_child1, args);
+ } else {
+ fragBuilder->codeAppendf("half4 %s;", _child1.c_str());
+ }
+ fragBuilder->codeAppendf("\nhalf4 in1 = %s ? %s : %s;\n%s = mix(in0, in1, %s);\n",
+ _outer.fp1_index >= 0 ? "true" : "false", _child1.c_str(),
+ args.fInputColor, args.fOutputColor,
+ args.fUniformHandler->getUniformCStr(weightVar));
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrMixerEffect& _outer = _proc.cast<GrMixerEffect>();
+ { pdman.set1f(weightVar, (_outer.weight)); }
+ }
+ UniformHandle weightVar;
+};
+GrGLSLFragmentProcessor* GrMixerEffect::onCreateGLSLInstance() const {
+ return new GrGLSLMixerEffect();
+}
+void GrMixerEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrMixerEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrMixerEffect& that = other.cast<GrMixerEffect>();
+ (void)that;
+ if (weight != that.weight) return false;
+ return true;
+}
+GrMixerEffect::GrMixerEffect(const GrMixerEffect& src)
+ : INHERITED(kGrMixerEffect_ClassID, src.optimizationFlags())
+ , fp0_index(src.fp0_index)
+ , fp1_index(src.fp1_index)
+ , weight(src.weight) {
+ this->registerChildProcessor(src.childProcessor(fp0_index).clone());
+ if (fp1_index >= 0) {
+ this->registerChildProcessor(src.childProcessor(fp1_index).clone());
+ }
+}
+std::unique_ptr<GrFragmentProcessor> GrMixerEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrMixerEffect(*this));
+}
diff --git a/src/gpu/effects/generated/GrMixerEffect.h b/src/gpu/effects/generated/GrMixerEffect.h
new file mode 100644
index 0000000..d318285
--- /dev/null
+++ b/src/gpu/effects/generated/GrMixerEffect.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2019 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrMixerEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrMixerEffect_DEFINED
+#define GrMixerEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrMixerEffect : public GrFragmentProcessor {
+public:
+ static OptimizationFlags OptFlags(const std::unique_ptr<GrFragmentProcessor>& fp0,
+ const std::unique_ptr<GrFragmentProcessor>& fp1) {
+ auto get_flags = [](const std::unique_ptr<GrFragmentProcessor>& fp) {
+ auto flags = kNone_OptimizationFlags;
+
+ if (fp->compatibleWithCoverageAsAlpha()) {
+ flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
+ }
+
+ if (fp->preservesOpaqueInput()) {
+ flags |= kPreservesOpaqueInput_OptimizationFlag;
+ }
+
+ if (fp->hasConstantOutputForConstantInput()) {
+ flags |= kConstantOutputForConstantInput_OptimizationFlag;
+ }
+
+ return flags;
+ };
+
+ const auto fp0_flags = get_flags(fp0);
+
+ return fp1 ? (fp0_flags & get_flags(fp1)) : fp0_flags;
+ }
+
+ SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
+ const auto c0 = ConstantOutputForConstantInput(this->childProcessor(0), input),
+ c1 = (this->numChildProcessors() > 1)
+ ? ConstantOutputForConstantInput(this->childProcessor(1), input)
+ : input;
+ return {c0.fR + (c1.fR - c0.fR) * weight, c0.fG + (c1.fG - c0.fG) * weight,
+ c0.fB + (c1.fB - c0.fB) * weight, c0.fA + (c1.fA - c0.fA) * weight};
+ }
+ static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp0,
+ std::unique_ptr<GrFragmentProcessor>
+ fp1,
+ float weight) {
+ return std::unique_ptr<GrFragmentProcessor>(
+ new GrMixerEffect(std::move(fp0), std::move(fp1), weight));
+ }
+ GrMixerEffect(const GrMixerEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "MixerEffect"; }
+ int fp0_index = -1;
+ int fp1_index = -1;
+ float weight;
+
+private:
+ GrMixerEffect(std::unique_ptr<GrFragmentProcessor> fp0,
+ std::unique_ptr<GrFragmentProcessor>
+ fp1,
+ float weight)
+ : INHERITED(kGrMixerEffect_ClassID, (OptimizationFlags)OptFlags(fp0, fp1))
+ , weight(weight) {
+ SkASSERT(fp0);
+ fp0_index = this->numChildProcessors();
+ this->registerChildProcessor(std::move(fp0));
+ if (fp1) {
+ fp1_index = this->numChildProcessors();
+ this->registerChildProcessor(std::move(fp1));
+ }
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrPremulInputFragmentProcessor.cpp b/src/gpu/effects/generated/GrPremulInputFragmentProcessor.cpp
new file mode 100644
index 0000000..846a4f8
--- /dev/null
+++ b/src/gpu/effects/generated/GrPremulInputFragmentProcessor.cpp
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrPremulInputFragmentProcessor.fp; do not modify.
+ **************************************************************************************************/
+#include "GrPremulInputFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLPremulInputFragmentProcessor : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLPremulInputFragmentProcessor() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrPremulInputFragmentProcessor& _outer =
+ args.fFp.cast<GrPremulInputFragmentProcessor>();
+ (void)_outer;
+ fragBuilder->codeAppendf("%s = %s;\n%s.xyz *= %s.w;\n", args.fOutputColor, args.fInputColor,
+ args.fOutputColor, args.fInputColor);
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {}
+};
+GrGLSLFragmentProcessor* GrPremulInputFragmentProcessor::onCreateGLSLInstance() const {
+ return new GrGLSLPremulInputFragmentProcessor();
+}
+void GrPremulInputFragmentProcessor::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrPremulInputFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrPremulInputFragmentProcessor& that = other.cast<GrPremulInputFragmentProcessor>();
+ (void)that;
+ return true;
+}
+GrPremulInputFragmentProcessor::GrPremulInputFragmentProcessor(
+ const GrPremulInputFragmentProcessor& src)
+ : INHERITED(kGrPremulInputFragmentProcessor_ClassID, src.optimizationFlags()) {}
+std::unique_ptr<GrFragmentProcessor> GrPremulInputFragmentProcessor::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrPremulInputFragmentProcessor(*this));
+}
diff --git a/src/gpu/effects/generated/GrPremulInputFragmentProcessor.h b/src/gpu/effects/generated/GrPremulInputFragmentProcessor.h
new file mode 100644
index 0000000..bfcfdb8
--- /dev/null
+++ b/src/gpu/effects/generated/GrPremulInputFragmentProcessor.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrPremulInputFragmentProcessor.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrPremulInputFragmentProcessor_DEFINED
+#define GrPremulInputFragmentProcessor_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrPremulInputFragmentProcessor : public GrFragmentProcessor {
+public:
+ SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
+ return SkColor4f{input.fR, input.fG, input.fB, input.fA}.premul();
+ }
+ static std::unique_ptr<GrFragmentProcessor> Make() {
+ return std::unique_ptr<GrFragmentProcessor>(new GrPremulInputFragmentProcessor());
+ }
+ GrPremulInputFragmentProcessor(const GrPremulInputFragmentProcessor& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "PremulInputFragmentProcessor"; }
+
+private:
+ GrPremulInputFragmentProcessor()
+ : INHERITED(kGrPremulInputFragmentProcessor_ClassID,
+ (OptimizationFlags)kPreservesOpaqueInput_OptimizationFlag |
+ kConstantOutputForConstantInput_OptimizationFlag) {}
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrRRectBlurEffect.cpp b/src/gpu/effects/generated/GrRRectBlurEffect.cpp
new file mode 100644
index 0000000..878678c
--- /dev/null
+++ b/src/gpu/effects/generated/GrRRectBlurEffect.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrRRectBlurEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrRRectBlurEffect.h"
+
+std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::Make(GrRecordingContext* context,
+ float sigma,
+ float xformedSigma,
+ const SkRRect& srcRRect,
+ const SkRRect& devRRect) {
+ SkASSERT(!SkRRectPriv::IsCircle(devRRect) &&
+ !devRRect.isRect()); // Should've been caught up-stream
+
+ // TODO: loosen this up
+ if (!SkRRectPriv::IsSimpleCircular(devRRect)) {
+ return nullptr;
+ }
+
+ // Make sure we can successfully ninepatch this rrect -- the blur sigma has to be
+ // sufficiently small relative to both the size of the corner radius and the
+ // width (and height) of the rrect.
+ SkRRect rrectToDraw;
+ SkISize size;
+ SkScalar ignored[kSkBlurRRectMaxDivisions];
+ int ignoredSize;
+ uint32_t ignored32;
+
+ bool ninePatchable = SkComputeBlurredRRectParams(
+ srcRRect, devRRect, SkRect::MakeEmpty(), sigma, xformedSigma, &rrectToDraw, &size,
+ ignored, ignored, ignored, ignored, &ignoredSize, &ignoredSize, &ignored32);
+ if (!ninePatchable) {
+ return nullptr;
+ }
+
+ sk_sp<GrTextureProxy> mask(
+ find_or_create_rrect_blur_mask(context, rrectToDraw, size, xformedSigma));
+ if (!mask) {
+ return nullptr;
+ }
+
+ return std::unique_ptr<GrFragmentProcessor>(
+ new GrRRectBlurEffect(xformedSigma, devRRect.getBounds(),
+ SkRRectPriv::GetSimpleRadii(devRRect).fX, std::move(mask)));
+}
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLRRectBlurEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLRRectBlurEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrRRectBlurEffect& _outer = args.fFp.cast<GrRRectBlurEffect>();
+ (void)_outer;
+ auto sigma = _outer.sigma;
+ (void)sigma;
+ auto rect = _outer.rect;
+ (void)rect;
+ auto cornerRadius = _outer.cornerRadius;
+ (void)cornerRadius;
+ cornerRadiusVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
+ "cornerRadius");
+ proxyRectVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
+ "proxyRect");
+ blurRadiusVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
+ "blurRadius");
+ fragBuilder->codeAppendf(
+ "\nhalf2 translatedFragPos = half2(sk_FragCoord.xy - %s.xy);\nhalf threshold = %s "
+ "+ 2.0 * %s;\nhalf2 middle = half2((%s.zw - %s.xy) - float(2.0 * threshold));\nif "
+ "(translatedFragPos.x >= threshold && translatedFragPos.x < middle.x + threshold) "
+ "{\n translatedFragPos.x = threshold;\n} else if (translatedFragPos.x >= "
+ "middle.x + threshold) {\n translatedFragPos.x -= middle.x - 1.0;\n}\nif "
+ "(translatedFragPos.y > threshold && translatedFragPos.y < middle.y + threshold) "
+ "{\n translatedFragPos.y = threshold;",
+ args.fUniformHandler->getUniformCStr(proxyRectVar),
+ args.fUniformHandler->getUniformCStr(cornerRadiusVar),
+ args.fUniformHandler->getUniformCStr(blurRadiusVar),
+ args.fUniformHandler->getUniformCStr(proxyRectVar),
+ args.fUniformHandler->getUniformCStr(proxyRectVar));
+ fragBuilder->codeAppendf(
+ "\n} else if (translatedFragPos.y >= middle.y + threshold) {\n "
+ "translatedFragPos.y -= middle.y - 1.0;\n}\nhalf2 proxyDims = half2(2.0 * "
+ "threshold + 1.0);\nhalf2 texCoord = translatedFragPos / proxyDims;\n%s = %s * "
+ "texture(%s, float2(texCoord)).%s;\n",
+ args.fOutputColor, args.fInputColor,
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrRRectBlurEffect& _outer = _proc.cast<GrRRectBlurEffect>();
+ { pdman.set1f(cornerRadiusVar, (_outer.cornerRadius)); }
+ auto sigma = _outer.sigma;
+ (void)sigma;
+ auto rect = _outer.rect;
+ (void)rect;
+ UniformHandle& cornerRadius = cornerRadiusVar;
+ (void)cornerRadius;
+ GrSurfaceProxy& ninePatchSamplerProxy = *_outer.textureSampler(0).proxy();
+ GrTexture& ninePatchSampler = *ninePatchSamplerProxy.peekTexture();
+ (void)ninePatchSampler;
+ UniformHandle& proxyRect = proxyRectVar;
+ (void)proxyRect;
+ UniformHandle& blurRadius = blurRadiusVar;
+ (void)blurRadius;
+
+ float blurRadiusValue = 3.f * SkScalarCeilToScalar(sigma - 1 / 6.0f);
+ pdman.set1f(blurRadius, blurRadiusValue);
+
+ SkRect outset = rect;
+ outset.outset(blurRadiusValue, blurRadiusValue);
+ pdman.set4f(proxyRect, outset.fLeft, outset.fTop, outset.fRight, outset.fBottom);
+ }
+ UniformHandle proxyRectVar;
+ UniformHandle blurRadiusVar;
+ UniformHandle cornerRadiusVar;
+};
+GrGLSLFragmentProcessor* GrRRectBlurEffect::onCreateGLSLInstance() const {
+ return new GrGLSLRRectBlurEffect();
+}
+void GrRRectBlurEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrRRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrRRectBlurEffect& that = other.cast<GrRRectBlurEffect>();
+ (void)that;
+ if (sigma != that.sigma) return false;
+ if (rect != that.rect) return false;
+ if (cornerRadius != that.cornerRadius) return false;
+ if (ninePatchSampler != that.ninePatchSampler) return false;
+ return true;
+}
+GrRRectBlurEffect::GrRRectBlurEffect(const GrRRectBlurEffect& src)
+ : INHERITED(kGrRRectBlurEffect_ClassID, src.optimizationFlags())
+ , sigma(src.sigma)
+ , rect(src.rect)
+ , cornerRadius(src.cornerRadius)
+ , ninePatchSampler(src.ninePatchSampler) {
+ this->setTextureSamplerCnt(1);
+}
+std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrRRectBlurEffect(*this));
+}
+const GrFragmentProcessor::TextureSampler& GrRRectBlurEffect::onTextureSampler(int index) const {
+ return IthTextureSampler(index, ninePatchSampler);
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::TestCreate(GrProcessorTestData* d) {
+ SkScalar w = d->fRandom->nextRangeScalar(100.f, 1000.f);
+ SkScalar h = d->fRandom->nextRangeScalar(100.f, 1000.f);
+ SkScalar r = d->fRandom->nextRangeF(1.f, 9.f);
+ SkScalar sigma = d->fRandom->nextRangeF(1.f, 10.f);
+ SkRRect rrect;
+ rrect.setRectXY(SkRect::MakeWH(w, h), r, r);
+ return GrRRectBlurEffect::Make(d->context(), sigma, sigma, rrect, rrect);
+}
+#endif
diff --git a/src/gpu/effects/generated/GrRRectBlurEffect.h b/src/gpu/effects/generated/GrRRectBlurEffect.h
new file mode 100644
index 0000000..7c7da9a
--- /dev/null
+++ b/src/gpu/effects/generated/GrRRectBlurEffect.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrRRectBlurEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrRRectBlurEffect_DEFINED
+#define GrRRectBlurEffect_DEFINED
+#include "SkTypes.h"
+
+#include "GrCaps.h"
+#include "GrClip.h"
+#include "GrContext.h"
+#include "GrPaint.h"
+#include "GrProxyProvider.h"
+#include "GrRecordingContext.h"
+#include "GrRecordingContextPriv.h"
+#include "GrRenderTargetContext.h"
+#include "GrStyle.h"
+#include "SkBlurMaskFilter.h"
+#include "SkBlurPriv.h"
+#include "SkGpuBlurUtils.h"
+#include "SkRRectPriv.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrRRectBlurEffect : public GrFragmentProcessor {
+public:
+ static sk_sp<GrTextureProxy> find_or_create_rrect_blur_mask(GrRecordingContext* context,
+ const SkRRect& rrectToDraw,
+ const SkISize& size,
+ float xformedSigma) {
+ static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
+ GrUniqueKey key;
+ GrUniqueKey::Builder builder(&key, kDomain, 9, "RoundRect Blur Mask");
+ builder[0] = SkScalarCeilToInt(xformedSigma - 1 / 6.0f);
+
+ int index = 1;
+ for (auto c : {SkRRect::kUpperLeft_Corner, SkRRect::kUpperRight_Corner,
+ SkRRect::kLowerRight_Corner, SkRRect::kLowerLeft_Corner}) {
+ SkASSERT(SkScalarIsInt(rrectToDraw.radii(c).fX) &&
+ SkScalarIsInt(rrectToDraw.radii(c).fY));
+ builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fX);
+ builder[index++] = SkScalarCeilToInt(rrectToDraw.radii(c).fY);
+ }
+ builder.finish();
+
+ GrProxyProvider* proxyProvider = context->priv().proxyProvider();
+
+ sk_sp<GrTextureProxy> mask(
+ proxyProvider->findOrCreateProxyByUniqueKey(key, kBottomLeft_GrSurfaceOrigin));
+ if (!mask) {
+ GrBackendFormat format =
+ context->priv().caps()->getBackendFormatFromColorType(kAlpha_8_SkColorType);
+ // TODO: this could be approx but the texture coords will need to be updated
+ sk_sp<GrRenderTargetContext> rtc(
+ context->priv().makeDeferredRenderTargetContextWithFallback(
+ format, SkBackingFit::kExact, size.fWidth, size.fHeight,
+ kAlpha_8_GrPixelConfig, nullptr));
+ if (!rtc) {
+ return nullptr;
+ }
+
+ GrPaint paint;
+
+ rtc->clear(nullptr, SK_PMColor4fTRANSPARENT,
+ GrRenderTargetContext::CanClearFullscreen::kYes);
+ rtc->drawRRect(GrNoClip(), std::move(paint), GrAA::kYes, SkMatrix::I(), rrectToDraw,
+ GrStyle::SimpleFill());
+
+ sk_sp<GrTextureProxy> srcProxy(rtc->asTextureProxyRef());
+ if (!srcProxy) {
+ return nullptr;
+ }
+ sk_sp<GrRenderTargetContext> rtc2(
+ SkGpuBlurUtils::GaussianBlur(context,
+ std::move(srcProxy),
+ nullptr,
+ SkIRect::MakeWH(size.fWidth, size.fHeight),
+ SkIRect::EmptyIRect(),
+ xformedSigma,
+ xformedSigma,
+ GrTextureDomain::kIgnore_Mode,
+ kPremul_SkAlphaType,
+ SkBackingFit::kExact));
+ if (!rtc2) {
+ return nullptr;
+ }
+
+ mask = rtc2->asTextureProxyRef();
+ if (!mask) {
+ return nullptr;
+ }
+ SkASSERT(mask->origin() == kBottomLeft_GrSurfaceOrigin);
+ proxyProvider->assignUniqueKeyToProxy(key, mask.get());
+ }
+
+ return mask;
+ }
+
+ static std::unique_ptr<GrFragmentProcessor> Make(GrRecordingContext* context,
+ float sigma,
+ float xformedSigma,
+ const SkRRect& srcRRect,
+ const SkRRect& devRRect);
+ GrRRectBlurEffect(const GrRRectBlurEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "RRectBlurEffect"; }
+ float sigma;
+ SkRect rect;
+ float cornerRadius;
+ TextureSampler ninePatchSampler;
+
+private:
+ GrRRectBlurEffect(float sigma, SkRect rect, float cornerRadius,
+ sk_sp<GrTextureProxy> ninePatchSampler)
+ : INHERITED(kGrRRectBlurEffect_ClassID,
+ (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+ , sigma(sigma)
+ , rect(rect)
+ , cornerRadius(cornerRadius)
+ , ninePatchSampler(std::move(ninePatchSampler)) {
+ this->setTextureSamplerCnt(1);
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ const TextureSampler& onTextureSampler(int) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrRectBlurEffect.cpp b/src/gpu/effects/generated/GrRectBlurEffect.cpp
new file mode 100644
index 0000000..b03c8f9
--- /dev/null
+++ b/src/gpu/effects/generated/GrRectBlurEffect.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrRectBlurEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrRectBlurEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLRectBlurEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLRectBlurEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrRectBlurEffect& _outer = args.fFp.cast<GrRectBlurEffect>();
+ (void)_outer;
+ auto rect = _outer.rect;
+ (void)rect;
+ auto sigma = _outer.sigma;
+ (void)sigma;
+ highPrecision = ((((abs(rect.left()) > 16000.0 || abs(rect.top()) > 16000.0) ||
+ abs(rect.right()) > 16000.0) ||
+ abs(rect.bottom()) > 16000.0) ||
+ abs(rect.right() - rect.left()) > 16000.0) ||
+ abs(rect.bottom() - rect.top()) > 16000.0;
+ rectVar =
+ args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType, "rect");
+ if (!highPrecision) {
+ proxyRectHalfVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
+ kHalf4_GrSLType, "proxyRectHalf");
+ }
+ if (highPrecision) {
+ proxyRectFloatVar = args.fUniformHandler->addUniform(
+ kFragment_GrShaderFlag, kFloat4_GrSLType, "proxyRectFloat");
+ }
+ profileSizeVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
+ "profileSize");
+ fragBuilder->codeAppendf(
+ "/* key */ bool highPrecision = %s;\n@if (highPrecision) {\n float2 "
+ "translatedPos = sk_FragCoord.xy - %s.xy;\n float width = %s.z - %s.x;\n "
+ "float height = %s.w - %s.y;\n float2 smallDims = float2(width - float(%s), "
+ "height - float(%s));\n float center = float(2.0 * floor(%s / 2.0 + 0.25) - "
+ "1.0);\n float2 wh = smallDims - float2(center, center);\n half hcoord = "
+ "half((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / float(%s));\n half "
+ "hlookup = texture(%s, float2(float(hcoord), 0.5)).",
+ (highPrecision ? "true" : "false"), args.fUniformHandler->getUniformCStr(rectVar),
+ args.fUniformHandler->getUniformCStr(rectVar),
+ args.fUniformHandler->getUniformCStr(rectVar),
+ args.fUniformHandler->getUniformCStr(rectVar),
+ args.fUniformHandler->getUniformCStr(rectVar),
+ args.fUniformHandler->getUniformCStr(profileSizeVar),
+ args.fUniformHandler->getUniformCStr(profileSizeVar),
+ args.fUniformHandler->getUniformCStr(profileSizeVar),
+ args.fUniformHandler->getUniformCStr(profileSizeVar),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str());
+ fragBuilder->codeAppendf(
+ "%s.w;\n half vcoord = half((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y) "
+ "/ float(%s));\n half vlookup = texture(%s, float2(float(vcoord), 0.5)).%s.w;\n "
+ " %s = (%s * hlookup) * vlookup;\n} else {\n half2 translatedPos = "
+ "half2(sk_FragCoord.xy - %s.xy);\n half width = half(%s.z - %s.x);\n half "
+ "height = half(%s.w - %s.y);\n half2 smallDims = half2(width - %s, height - "
+ "%s);\n half center = 2.0 * floor(%s / 2.0 + 0.25) - 1.0;\n half2 wh = "
+ "smallDims - half2(center, center);\n half ",
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ args.fUniformHandler->getUniformCStr(profileSizeVar),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ args.fOutputColor, args.fInputColor, args.fUniformHandler->getUniformCStr(rectVar),
+ args.fUniformHandler->getUniformCStr(rectVar),
+ args.fUniformHandler->getUniformCStr(rectVar),
+ args.fUniformHandler->getUniformCStr(rectVar),
+ args.fUniformHandler->getUniformCStr(rectVar),
+ args.fUniformHandler->getUniformCStr(profileSizeVar),
+ args.fUniformHandler->getUniformCStr(profileSizeVar),
+ args.fUniformHandler->getUniformCStr(profileSizeVar));
+ fragBuilder->codeAppendf(
+ "hcoord = (abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / %s;\n half "
+ "hlookup = texture(%s, float2(float(hcoord), 0.5)).%s.w;\n half vcoord = "
+ "(abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y) / %s;\n half vlookup = "
+ "texture(%s, float2(float(vcoord), 0.5)).%s.w;\n %s = (%s * hlookup) * "
+ "vlookup;\n}\n",
+ args.fUniformHandler->getUniformCStr(profileSizeVar),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ args.fUniformHandler->getUniformCStr(profileSizeVar),
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ args.fOutputColor, args.fInputColor);
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {
+ const GrRectBlurEffect& _outer = _proc.cast<GrRectBlurEffect>();
+ { pdman.set4fv(rectVar, 1, reinterpret_cast<const float*>(&(_outer.rect))); }
+ UniformHandle& rect = rectVar;
+ (void)rect;
+ auto sigma = _outer.sigma;
+ (void)sigma;
+ GrSurfaceProxy& blurProfileProxy = *_outer.textureSampler(0).proxy();
+ GrTexture& blurProfile = *blurProfileProxy.peekTexture();
+ (void)blurProfile;
+ UniformHandle& proxyRectHalf = proxyRectHalfVar;
+ (void)proxyRectHalf;
+ UniformHandle& proxyRectFloat = proxyRectFloatVar;
+ (void)proxyRectFloat;
+ UniformHandle& profileSize = profileSizeVar;
+ (void)profileSize;
+
+ pdman.set1f(profileSize, SkScalarCeilToScalar(6 * sigma));
+ }
+ bool highPrecision = false;
+ UniformHandle proxyRectHalfVar;
+ UniformHandle proxyRectFloatVar;
+ UniformHandle profileSizeVar;
+ UniformHandle rectVar;
+};
+GrGLSLFragmentProcessor* GrRectBlurEffect::onCreateGLSLInstance() const {
+ return new GrGLSLRectBlurEffect();
+}
+void GrRectBlurEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrRectBlurEffect& that = other.cast<GrRectBlurEffect>();
+ (void)that;
+ if (rect != that.rect) return false;
+ if (sigma != that.sigma) return false;
+ if (blurProfile != that.blurProfile) return false;
+ return true;
+}
+GrRectBlurEffect::GrRectBlurEffect(const GrRectBlurEffect& src)
+ : INHERITED(kGrRectBlurEffect_ClassID, src.optimizationFlags())
+ , rect(src.rect)
+ , sigma(src.sigma)
+ , blurProfile(src.blurProfile) {
+ this->setTextureSamplerCnt(1);
+}
+std::unique_ptr<GrFragmentProcessor> GrRectBlurEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(*this));
+}
+const GrFragmentProcessor::TextureSampler& GrRectBlurEffect::onTextureSampler(int index) const {
+ return IthTextureSampler(index, blurProfile);
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrRectBlurEffect::TestCreate(GrProcessorTestData* data) {
+ float sigma = data->fRandom->nextRangeF(3, 8);
+ float width = data->fRandom->nextRangeF(200, 300);
+ float height = data->fRandom->nextRangeF(200, 300);
+ return GrRectBlurEffect::Make(data->proxyProvider(), *data->caps()->shaderCaps(),
+ SkRect::MakeWH(width, height), sigma);
+}
+#endif
diff --git a/src/gpu/effects/generated/GrRectBlurEffect.h b/src/gpu/effects/generated/GrRectBlurEffect.h
new file mode 100644
index 0000000..6e09aae
--- /dev/null
+++ b/src/gpu/effects/generated/GrRectBlurEffect.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrRectBlurEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrRectBlurEffect_DEFINED
+#define GrRectBlurEffect_DEFINED
+#include "SkTypes.h"
+
+#include "GrProxyProvider.h"
+#include "GrShaderCaps.h"
+#include "SkBlurMask.h"
+#include "SkScalar.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrRectBlurEffect : public GrFragmentProcessor {
+public:
+ static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrProxyProvider* proxyProvider,
+ float sigma) {
+ unsigned int profileSize = SkScalarCeilToInt(6 * sigma);
+
+ static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
+ GrUniqueKey key;
+ GrUniqueKey::Builder builder(&key, kDomain, 1, "Rect Blur Mask");
+ builder[0] = profileSize;
+ builder.finish();
+
+ sk_sp<GrTextureProxy> blurProfile(
+ proxyProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin));
+ if (!blurProfile) {
+ SkImageInfo ii = SkImageInfo::MakeA8(profileSize, 1);
+
+ SkBitmap bitmap;
+ if (!bitmap.tryAllocPixels(ii)) {
+ return nullptr;
+ }
+
+ SkBlurMask::ComputeBlurProfile(bitmap.getAddr8(0, 0), profileSize, sigma);
+ bitmap.setImmutable();
+
+ sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
+ if (!image) {
+ return nullptr;
+ }
+
+ blurProfile =
+ proxyProvider->createTextureProxy(std::move(image), kNone_GrSurfaceFlags, 1,
+ SkBudgeted::kYes, SkBackingFit::kExact);
+ if (!blurProfile) {
+ return nullptr;
+ }
+
+ SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
+ proxyProvider->assignUniqueKeyToProxy(key, blurProfile.get());
+ }
+
+ return blurProfile;
+ }
+
+ static std::unique_ptr<GrFragmentProcessor> Make(GrProxyProvider* proxyProvider,
+ const GrShaderCaps& caps, const SkRect& rect,
+ float sigma) {
+ if (!caps.floatIs32Bits()) {
+ // We promote the rect uniform from half to float when it has large values for
+ // precision. If we don't have full float then fail.
+ if (SkScalarAbs(rect.fLeft) > 16000.f || SkScalarAbs(rect.fTop) > 16000.f ||
+ SkScalarAbs(rect.fRight) > 16000.f || SkScalarAbs(rect.fBottom) > 16000.f ||
+ SkScalarAbs(rect.width()) > 16000.f || SkScalarAbs(rect.height()) > 16000.f) {
+ return nullptr;
+ }
+ }
+ int doubleProfileSize = SkScalarCeilToInt(12 * sigma);
+
+ if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) {
+ // if the blur sigma is too large so the gaussian overlaps the whole
+ // rect in either direction, fall back to CPU path for now.
+ return nullptr;
+ }
+
+ sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(proxyProvider, sigma));
+ if (!blurProfile) {
+ return nullptr;
+ }
+
+ return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(
+ rect, sigma, std::move(blurProfile),
+ GrSamplerState(GrSamplerState::WrapMode::kClamp, GrSamplerState::Filter::kBilerp)));
+ }
+ GrRectBlurEffect(const GrRectBlurEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "RectBlurEffect"; }
+ SkRect rect;
+ float sigma;
+ TextureSampler blurProfile;
+
+private:
+ GrRectBlurEffect(SkRect rect, float sigma, sk_sp<GrTextureProxy> blurProfile,
+ GrSamplerState samplerParams)
+ : INHERITED(kGrRectBlurEffect_ClassID,
+ (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+ , rect(rect)
+ , sigma(sigma)
+ , blurProfile(std::move(blurProfile), samplerParams) {
+ this->setTextureSamplerCnt(1);
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ const TextureSampler& onTextureSampler(int) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/generated/GrSimpleTextureEffect.cpp b/src/gpu/effects/generated/GrSimpleTextureEffect.cpp
new file mode 100644
index 0000000..8236ebc
--- /dev/null
+++ b/src/gpu/effects/generated/GrSimpleTextureEffect.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrSimpleTextureEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrSimpleTextureEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLSimpleTextureEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLSimpleTextureEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrSimpleTextureEffect& _outer = args.fFp.cast<GrSimpleTextureEffect>();
+ (void)_outer;
+ auto matrix = _outer.matrix;
+ (void)matrix;
+ SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
+ fragBuilder->codeAppendf(
+ "%s = %s * texture(%s, %s).%s;\n", args.fOutputColor, args.fInputColor,
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ sk_TransformedCoords2D_0.c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {}
+};
+GrGLSLFragmentProcessor* GrSimpleTextureEffect::onCreateGLSLInstance() const {
+ return new GrGLSLSimpleTextureEffect();
+}
+void GrSimpleTextureEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {}
+bool GrSimpleTextureEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrSimpleTextureEffect& that = other.cast<GrSimpleTextureEffect>();
+ (void)that;
+ if (image != that.image) return false;
+ if (matrix != that.matrix) return false;
+ return true;
+}
+GrSimpleTextureEffect::GrSimpleTextureEffect(const GrSimpleTextureEffect& src)
+ : INHERITED(kGrSimpleTextureEffect_ClassID, src.optimizationFlags())
+ , imageCoordTransform(src.imageCoordTransform)
+ , image(src.image)
+ , matrix(src.matrix) {
+ this->setTextureSamplerCnt(1);
+ this->addCoordTransform(&imageCoordTransform);
+}
+std::unique_ptr<GrFragmentProcessor> GrSimpleTextureEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrSimpleTextureEffect(*this));
+}
+const GrFragmentProcessor::TextureSampler& GrSimpleTextureEffect::onTextureSampler(
+ int index) const {
+ return IthTextureSampler(index, image);
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSimpleTextureEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrSimpleTextureEffect::TestCreate(
+ GrProcessorTestData* testData) {
+ int texIdx = testData->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
+ : GrProcessorUnitTest::kAlphaTextureIdx;
+ GrSamplerState::WrapMode wrapModes[2];
+ GrTest::TestWrapModes(testData->fRandom, wrapModes);
+ if (!testData->caps()->npotTextureTileSupport()) {
+ // Performing repeat sampling on npot textures will cause asserts on HW
+ // that lacks support.
+ wrapModes[0] = GrSamplerState::WrapMode::kClamp;
+ wrapModes[1] = GrSamplerState::WrapMode::kClamp;
+ }
+
+ GrSamplerState params(wrapModes, testData->fRandom->nextBool()
+ ? GrSamplerState::Filter::kBilerp
+ : GrSamplerState::Filter::kNearest);
+
+ const SkMatrix& matrix = GrTest::TestMatrix(testData->fRandom);
+ return GrSimpleTextureEffect::Make(testData->textureProxy(texIdx), matrix, params);
+}
+#endif
diff --git a/src/gpu/effects/generated/GrSimpleTextureEffect.h b/src/gpu/effects/generated/GrSimpleTextureEffect.h
new file mode 100644
index 0000000..ac54e6a
--- /dev/null
+++ b/src/gpu/effects/generated/GrSimpleTextureEffect.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrSimpleTextureEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrSimpleTextureEffect_DEFINED
+#define GrSimpleTextureEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrSimpleTextureEffect : public GrFragmentProcessor {
+public:
+ static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
+ const SkMatrix& matrix) {
+ return std::unique_ptr<GrFragmentProcessor>(
+ new GrSimpleTextureEffect(std::move(proxy), matrix,
+ GrSamplerState(GrSamplerState::WrapMode::kClamp,
+ GrSamplerState::Filter::kNearest)));
+ }
+
+ /* clamp mode */
+ static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
+ const SkMatrix& matrix,
+ GrSamplerState::Filter filter) {
+ return std::unique_ptr<GrFragmentProcessor>(new GrSimpleTextureEffect(
+ std::move(proxy), matrix,
+ GrSamplerState(GrSamplerState::WrapMode::kClamp, filter)));
+ }
+
+ static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
+ const SkMatrix& matrix,
+ const GrSamplerState& p) {
+ return std::unique_ptr<GrFragmentProcessor>(
+ new GrSimpleTextureEffect(std::move(proxy), matrix, p));
+ }
+ GrSimpleTextureEffect(const GrSimpleTextureEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "SimpleTextureEffect"; }
+ GrCoordTransform imageCoordTransform;
+ TextureSampler image;
+ SkMatrix44 matrix;
+
+private:
+ GrSimpleTextureEffect(sk_sp<GrTextureProxy> image, SkMatrix44 matrix,
+ GrSamplerState samplerParams)
+ : INHERITED(kGrSimpleTextureEffect_ClassID,
+ (OptimizationFlags)ModulateForSamplerOptFlags(
+ image->config(),
+ samplerParams.wrapModeX() ==
+ GrSamplerState::WrapMode::kClampToBorder ||
+ samplerParams.wrapModeY() ==
+ GrSamplerState::WrapMode::kClampToBorder))
+ , imageCoordTransform(matrix, image.get())
+ , image(std::move(image), samplerParams)
+ , matrix(matrix) {
+ this->setTextureSamplerCnt(1);
+ this->addCoordTransform(&imageCoordTransform);
+ }
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ const TextureSampler& onTextureSampler(int) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif