aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/effects
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/effects')
-rw-r--r--src/gpu/effects/GrDitherEffect.cpp75
-rw-r--r--src/gpu/effects/GrDitherEffect.fp85
-rw-r--r--src/gpu/effects/GrDitherEffect.h67
-rw-r--r--src/gpu/effects/GrRectBlurEffect.cpp34
-rw-r--r--src/gpu/effects/GrSkSLFP.cpp268
-rw-r--r--src/gpu/effects/GrSkSLFP.h147
6 files changed, 244 insertions, 432 deletions
diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp
new file mode 100644
index 0000000000..17c8776524
--- /dev/null
+++ b/src/gpu/effects/GrDitherEffect.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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 GrDitherEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrDitherEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLDitherEffect : public GrGLSLFragmentProcessor {
+public:
+ GrGLSLDitherEffect() {}
+ void emitCode(EmitArgs& args) override {
+ GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+ const GrDitherEffect& _outer = args.fFp.cast<GrDitherEffect>();
+ (void)_outer;
+ auto rangeType = _outer.rangeType();
+ (void)rangeType;
+ fragBuilder->codeAppendf(
+ "half value;\nhalf range;\n@switch (%d) {\n case 0:\n range = "
+ "0.0039215686274509803;\n break;\n case 1:\n range = "
+ "0.015873015873015872;\n break;\n default:\n range = "
+ "0.066666666666666666;\n break;\n}\n@if (sk_Caps.integerSupport) {\n "
+ "uint x = uint(sk_FragCoord.x);\n uint y = uint(sk_FragCoord.y);\n uint m = "
+ "(((((y & 1) << 5 | (x & 1) << 4) | (y & 2) << 2) | (x & 2) << 1) | (y & 4) >> 1) "
+ "| (x & 4) >> 2;\n value = float(float(half(m)) / 64.0) - 0.4",
+ _outer.rangeType());
+ fragBuilder->codeAppendf(
+ "921875;\n} else {\n half4 modValues = half4(mod(sk_FragCoord.xyxy, "
+ "float4(half4(2.0, 2.0, 4.0, 4.0))));\n half4 stepValues = "
+ "half4(step(float4(modValues), float4(half4(1.0, 1.0, 2.0, 2.0))));\n value = "
+ "float(dot(stepValues, half4(0.5, 0.25, 0.125, 0.0625))) - 0.46875;\n}\n%s = "
+ "half4(clamp(float3(%s.xyz + value * range), 0.0, float(%s.w)), %s.w);\n",
+ args.fOutputColor, args.fInputColor ? args.fInputColor : "half4(1)",
+ args.fInputColor ? args.fInputColor : "half4(1)",
+ args.fInputColor ? args.fInputColor : "half4(1)");
+ }
+
+private:
+ void onSetData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& _proc) override {}
+};
+GrGLSLFragmentProcessor* GrDitherEffect::onCreateGLSLInstance() const {
+ return new GrGLSLDitherEffect();
+}
+void GrDitherEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+ GrProcessorKeyBuilder* b) const {
+ b->add32((int32_t)fRangeType);
+}
+bool GrDitherEffect::onIsEqual(const GrFragmentProcessor& other) const {
+ const GrDitherEffect& that = other.cast<GrDitherEffect>();
+ (void)that;
+ if (fRangeType != that.fRangeType) return false;
+ return true;
+}
+GrDitherEffect::GrDitherEffect(const GrDitherEffect& src)
+ : INHERITED(kGrDitherEffect_ClassID, src.optimizationFlags()), fRangeType(src.fRangeType) {}
+std::unique_ptr<GrFragmentProcessor> GrDitherEffect::clone() const {
+ return std::unique_ptr<GrFragmentProcessor>(new GrDitherEffect(*this));
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDitherEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrDitherEffect::TestCreate(GrProcessorTestData* testData) {
+ float range = testData->fRandom->nextRangeF(0.001f, 0.05f);
+ return std::unique_ptr<GrFragmentProcessor>(new GrDitherEffect(range));
+}
+#endif
diff --git a/src/gpu/effects/GrDitherEffect.fp b/src/gpu/effects/GrDitherEffect.fp
new file mode 100644
index 0000000000..ed6c0e6b70
--- /dev/null
+++ b/src/gpu/effects/GrDitherEffect.fp
@@ -0,0 +1,85 @@
+/*
+ * 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 controls the range of values added to color channels
+layout(key) in int rangeType;
+
+@make {
+ static std::unique_ptr<GrFragmentProcessor> Make(GrPixelConfig dstConfig) {
+ int rangeType;
+ switch (dstConfig) {
+ case kGray_8_GrPixelConfig:
+ case kGray_8_as_Lum_GrPixelConfig:
+ case kGray_8_as_Red_GrPixelConfig:
+ case kRGBA_8888_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
+ case kBGRA_8888_GrPixelConfig:
+ rangeType = 0;
+ break;
+ case kRGB_565_GrPixelConfig:
+ rangeType = 1;
+ break;
+ case kRGBA_4444_GrPixelConfig:
+ rangeType = 2;
+ break;
+ case kUnknown_GrPixelConfig:
+ case kSRGBA_8888_GrPixelConfig:
+ case kSBGRA_8888_GrPixelConfig:
+ case kRGBA_1010102_GrPixelConfig:
+ case kAlpha_half_GrPixelConfig:
+ case kAlpha_half_as_Red_GrPixelConfig:
+ case kRGBA_float_GrPixelConfig:
+ case kRG_float_GrPixelConfig:
+ case kRGBA_half_GrPixelConfig:
+ case kAlpha_8_GrPixelConfig:
+ case kAlpha_8_as_Alpha_GrPixelConfig:
+ case kAlpha_8_as_Red_GrPixelConfig:
+ return nullptr;
+ }
+ return std::unique_ptr<GrFragmentProcessor>(new GrDitherEffect(rangeType));
+ }
+}
+
+void main() {
+ half value;
+ half range;
+ @switch (rangeType) {
+ case 0:
+ range = 1.0 / 255.0;
+ break;
+ case 1:
+ range = 1.0 / 63.0;
+ break;
+ default:
+ // Experimentally this looks better than the expected value of 1/15.
+ range = 1.0 / 15.0;
+ break;
+ }
+ @if (sk_Caps.integerSupport) {
+ // This ordered-dither code is lifted from the cpu backend.
+ uint x = uint(sk_FragCoord.x);
+ uint y = uint(sk_FragCoord.y);
+ uint m = (y & 1) << 5 | (x & 1) << 4 |
+ (y & 2) << 2 | (x & 2) << 1 |
+ (y & 4) >> 1 | (x & 4) >> 2;
+ value = half(m) * 1.0 / 64.0 - 63.0 / 128.0;
+ } else {
+ // Simulate the integer effect used above using step/mod. For speed, simulates a 4x4
+ // dither pattern rather than an 8x8 one.
+ half4 modValues = mod(sk_FragCoord.xyxy, half4(2.0, 2.0, 4.0, 4.0));
+ half4 stepValues = step(modValues, half4(1.0, 1.0, 2.0, 2.0));
+ value = dot(stepValues, half4(8.0 / 16.0, 4.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0)) - 15.0 / 32.0;
+ }
+ // For each color channel, add the random offset to the channel value and then clamp
+ // between 0 and alpha to keep the color premultiplied.
+ sk_OutColor = half4(clamp(sk_InColor.rgb + value * range, 0, sk_InColor.a), sk_InColor.a);
+}
+
+@test(testData) {
+ float range = testData->fRandom->nextRangeF(0.001f, 0.05f);
+ return std::unique_ptr<GrFragmentProcessor>(new GrDitherEffect(range));
+}
diff --git a/src/gpu/effects/GrDitherEffect.h b/src/gpu/effects/GrDitherEffect.h
new file mode 100644
index 0000000000..70adc45e6a
--- /dev/null
+++ b/src/gpu/effects/GrDitherEffect.h
@@ -0,0 +1,67 @@
+/*
+ * 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 GrDitherEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrDitherEffect_DEFINED
+#define GrDitherEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrDitherEffect : public GrFragmentProcessor {
+public:
+ int rangeType() const { return fRangeType; }
+
+ static std::unique_ptr<GrFragmentProcessor> Make(GrPixelConfig dstConfig) {
+ int rangeType;
+ switch (dstConfig) {
+ case kGray_8_GrPixelConfig:
+ case kGray_8_as_Lum_GrPixelConfig:
+ case kGray_8_as_Red_GrPixelConfig:
+ case kRGBA_8888_GrPixelConfig:
+ case kRGB_888_GrPixelConfig:
+ case kBGRA_8888_GrPixelConfig:
+ rangeType = 0;
+ break;
+ case kRGB_565_GrPixelConfig:
+ rangeType = 1;
+ break;
+ case kRGBA_4444_GrPixelConfig:
+ rangeType = 2;
+ break;
+ case kUnknown_GrPixelConfig:
+ case kSRGBA_8888_GrPixelConfig:
+ case kSBGRA_8888_GrPixelConfig:
+ case kRGBA_1010102_GrPixelConfig:
+ case kAlpha_half_GrPixelConfig:
+ case kAlpha_half_as_Red_GrPixelConfig:
+ case kRGBA_float_GrPixelConfig:
+ case kRG_float_GrPixelConfig:
+ case kRGBA_half_GrPixelConfig:
+ case kAlpha_8_GrPixelConfig:
+ case kAlpha_8_as_Alpha_GrPixelConfig:
+ case kAlpha_8_as_Red_GrPixelConfig:
+ return nullptr;
+ }
+ return std::unique_ptr<GrFragmentProcessor>(new GrDitherEffect(rangeType));
+ }
+ GrDitherEffect(const GrDitherEffect& src);
+ std::unique_ptr<GrFragmentProcessor> clone() const override;
+ const char* name() const override { return "DitherEffect"; }
+
+private:
+ GrDitherEffect(int rangeType)
+ : INHERITED(kGrDitherEffect_ClassID, kNone_OptimizationFlags), fRangeType(rangeType) {}
+ GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+ void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+ bool onIsEqual(const GrFragmentProcessor&) const override;
+ GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+ int fRangeType;
+ typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/GrRectBlurEffect.cpp b/src/gpu/effects/GrRectBlurEffect.cpp
index d423b786ce..219fefa713 100644
--- a/src/gpu/effects/GrRectBlurEffect.cpp
+++ b/src/gpu/effects/GrRectBlurEffect.cpp
@@ -46,13 +46,13 @@ public:
fProfileSizeVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
kDefault_GrSLPrecision, "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 = 2.0 * floor(float(float(%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), ",
+ "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 = 2.0 * floor(float(float(%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)).%s.w",
(highPrecision ? "true" : "false"), args.fUniformHandler->getUniformCStr(fRectVar),
args.fUniformHandler->getUniformCStr(fRectVar),
args.fUniformHandler->getUniformCStr(fRectVar),
@@ -62,16 +62,16 @@ public:
args.fUniformHandler->getUniformCStr(fProfileSizeVar),
args.fUniformHandler->getUniformCStr(fProfileSizeVar),
args.fUniformHandler->getUniformCStr(fProfileSizeVar),
- fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str());
+ fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
+ fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
fragBuilder->codeAppendf(
- "0.5)).%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 = half(2.0 * floor(float(float(%s / 2.0) + "
- "0.25)) - 1.0);\n half2 wh = smallDims - half2(f",
- fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
+ ";\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 = half(2.0 * floor(float(float(%s / 2.0) + 0.25)) - 1.0);\n "
+ " half2 wh = smallDims - half2(float2(floa",
args.fUniformHandler->getUniformCStr(fProfileSizeVar),
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
@@ -85,7 +85,7 @@ public:
args.fUniformHandler->getUniformCStr(fProfileSizeVar),
args.fUniformHandler->getUniformCStr(fProfileSizeVar));
fragBuilder->codeAppendf(
- "loat2(float(center), float(center)));\n half hcoord = "
+ "t(center), float(center)));\n half hcoord = "
"half((abs(float(float(translatedPos.x) - 0.5 * float(width))) - 0.5 * "
"float(wh.x)) / float(%s));\n half hlookup = texture(%s, float2(float(hcoord), "
"0.5)).%s.w;\n half vcoord = half((abs(float(float(translatedPos.y) - 0.5 * "
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
deleted file mode 100644
index bc84c833d7..0000000000
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrSkSLFP.h"
-#include "glsl/GrGLSLFragmentProcessor.h"
-#include "glsl/GrGLSLFragmentShaderBuilder.h"
-#include "glsl/GrGLSLProgramBuilder.h"
-#include "GrContext.h"
-#include "GrContextPriv.h"
-#include "GrTexture.h"
-#include "SkSLUtil.h"
-
-GrSkSLFPFactory::GrSkSLFPFactory(const char* name, const GrShaderCaps* shaderCaps, const char* sksl)
- : fName(name) {
- SkSL::Program::Settings settings;
- settings.fCaps = shaderCaps;
- fBaseProgram = fCompiler.convertProgram(SkSL::Program::kPipelineStage_Kind,
- SkSL::String(sksl),
- settings);
- if (fCompiler.errorCount()) {
- SkDebugf("%s\n", fCompiler.errorText().c_str());
- }
- SkASSERT(fBaseProgram);
- SkASSERT(!fCompiler.errorCount());
- for (const auto& e : *fBaseProgram) {
- if (e.fKind == SkSL::ProgramElement::kVar_Kind) {
- SkSL::VarDeclarations& v = (SkSL::VarDeclarations&) e;
- for (const auto& varStatement : v.fVars) {
- const SkSL::Variable& var = *((SkSL::VarDeclaration&) *varStatement).fVar;
- if (var.fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
- fInputVars.push_back(&var);
- }
- if (var.fModifiers.fLayout.fKey) {
- fKeyVars.push_back(&var);
- }
- }
- }
- }
-}
-
-const SkSL::Program* GrSkSLFPFactory::getSpecialization(const SkSL::String& key, const void* inputs,
- size_t inputSize) {
- const auto& found = fSpecializations.find(key);
- if (found != fSpecializations.end()) {
- return found->second.get();
- }
-
- std::unordered_map<SkSL::String, SkSL::Program::Settings::Value> inputMap;
- size_t offset = 0;
- for (const auto& v : fInputVars) {
- SkSL::String name(v->fName);
- if (&v->fType == fCompiler.context().fInt_Type.get()) {
- offset = SkAlign4(offset);
- int32_t v = *(int32_t*) (((uint8_t*) inputs) + offset);
- inputMap.insert(std::make_pair(name, SkSL::Program::Settings::Value(v)));
- offset += sizeof(int32_t);
- }
- }
- SkASSERT(offset == inputSize);
-
- std::unique_ptr<SkSL::Program> specialized = fCompiler.specialize(*fBaseProgram, inputMap);
- SkAssertResult(fCompiler.optimize(*specialized));
- const SkSL::Program* result = specialized.get();
- fSpecializations.insert(std::make_pair(key, std::move(specialized)));
- return result;
-}
-
-class GrGLSLSkSLFP : public GrGLSLFragmentProcessor {
-public:
- GrGLSLSkSLFP(SkSL::String glsl, std::vector<SkSL::Compiler::FormatArg> formatArgs)
- : fGLSL(glsl)
- , fFormatArgs(formatArgs) {}
-
- void emitCode(EmitArgs& args) override {
- GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
- int substringStartIndex = 0;
- int formatArgIndex = 0;
- for (size_t i = 0; i < fGLSL.length(); ++i) {
- char c = fGLSL[i];
- if (c == '%') {
- fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
- i - substringStartIndex);
- ++i;
- c = fGLSL[i];
- switch (c) {
- case 's':
- switch (fFormatArgs[formatArgIndex++]) {
- case SkSL::Compiler::FormatArg::kInput:
- fragBuilder->codeAppend(args.fInputColor ? args.fInputColor
- : "half4(1)");
- break;
- case SkSL::Compiler::FormatArg::kOutput:
- fragBuilder->codeAppend(args.fOutputColor);
- break;
- }
- break;
- default:
- fragBuilder->codeAppendf("%c", c);
- }
- substringStartIndex = i + 1;
- }
- }
- fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
- fGLSL.length() - substringStartIndex);
- }
-
- // nearly-finished GLSL; still contains printf-style "%s" format tokens
- const SkSL::String fGLSL;
- std::vector<SkSL::Compiler::FormatArg> fFormatArgs;
-};
-
-std::unique_ptr<GrFragmentProcessor> GrSkSLFP::Make(GrContext* context, int index, const char* name,
- const char* sksl, const void* inputs,
- size_t inputSize) {
- return std::unique_ptr<GrFragmentProcessor>(new GrSkSLFP(
- context->contextPriv().getFPFactoryCache(),
- context->contextPriv().caps()->shaderCaps(),
- index, name, sksl, inputs, inputSize));
-}
-
-
-GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps,
- int index, const char* name, const char* sksl, const void* inputs,
- size_t inputSize)
- : INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
- , fFactoryCache(factoryCache)
- , fShaderCaps(sk_ref_sp(shaderCaps))
- , fIndex(index)
- , fName(name)
- , fSkSL(sksl)
- , fInputs(new int8_t[inputSize])
- , fInputSize(inputSize) {
- memcpy(fInputs.get(), inputs, inputSize);
-}
-
-GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
- : INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
- , fFactoryCache(other.fFactoryCache)
- , fShaderCaps(other.fShaderCaps)
- , fFactory(other.fFactory)
- , fIndex(other.fIndex)
- , fName(other.fName)
- , fSkSL(other.fSkSL)
- , fInputs(new int8_t[other.fInputSize])
- , fInputSize(other.fInputSize) {
- memcpy(fInputs.get(), other.fInputs.get(), fInputSize);
-}
-
-const char* GrSkSLFP::name() const {
- return fName;
-}
-
-void GrSkSLFP::createFactory() const {
- if (!fFactory) {
- fFactory = fFactoryCache->get(fIndex);
- if (!fFactory) {
- fFactory = sk_sp<GrSkSLFPFactory>(new GrSkSLFPFactory(fName, fShaderCaps.get(), fSkSL));
- fFactoryCache->set(fIndex, fFactory);
- }
- }
-}
-
-GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
- this->createFactory();
- const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs.get(), fInputSize);
- SkSL::String glsl;
- std::vector<SkSL::Compiler::FormatArg> formatArgs;
- if (!fFactory->fCompiler.toPipelineStage(*specialized, &glsl, &formatArgs)) {
- printf("%s\n", fFactory->fCompiler.errorText().c_str());
- abort();
- }
- return new GrGLSLSkSLFP(glsl, formatArgs);
-}
-
-void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
- GrProcessorKeyBuilder* b) const {
- this->createFactory();
- size_t offset = 0;
- char* inputs = (char*) fInputs.get();
- for (const auto& v : fFactory->fInputVars) {
- if (&v->fType == fFactory->fCompiler.context().fInt_Type.get()) {
- offset = SkAlign4(offset);
- if (v->fModifiers.fLayout.fKey) {
- fKey += inputs[offset + 0];
- fKey += inputs[offset + 1];
- fKey += inputs[offset + 2];
- fKey += inputs[offset + 3];
- b->add32(*(int32_t*) (inputs + offset));
- }
- offset += sizeof(int32_t);
- }
- else {
- // unsupported input var type
- SkASSERT(false);
- }
- }
- SkASSERT(offset == fInputSize);
-}
-
-bool GrSkSLFP::onIsEqual(const GrFragmentProcessor& other) const {
- const GrSkSLFP& sk = other.cast<GrSkSLFP>();
- SkASSERT(fIndex != sk.fIndex || fInputSize == sk.fInputSize);
- return fIndex == sk.fIndex &&
- !memcmp(fInputs.get(), sk.fInputs.get(), fInputSize);
-}
-
-std::unique_ptr<GrFragmentProcessor> GrSkSLFP::clone() const {
- return std::unique_ptr<GrFragmentProcessor>(new GrSkSLFP(*this));
-}
-
-// We have to do a bit of manual refcounting in the cache methods below. Ideally, we could just
-// define fFactories to contain sk_sp<GrSkSLFPFactory> rather than GrSkSLFPFactory*, but that would
-// require GrContext to include GrSkSLFP, which creates much bigger headaches than a few manual
-// refcounts.
-
-sk_sp<GrSkSLFPFactory> GrSkSLFPFactoryCache::get(int index) {
- if (index >= (int) fFactories.size()) {
- return nullptr;
- }
- GrSkSLFPFactory* result = fFactories[index];
- result->ref();
- return sk_sp<GrSkSLFPFactory>(result);
-}
-
-void GrSkSLFPFactoryCache::set(int index, sk_sp<GrSkSLFPFactory> factory) {
- while (index >= (int) fFactories.size()) {
- fFactories.emplace_back();
- }
- factory->ref();
- SkASSERT(!fFactories[index]);
- fFactories[index] = factory.get();
-}
-
-GrSkSLFPFactoryCache::~GrSkSLFPFactoryCache() {
- for (GrSkSLFPFactory* factory : fFactories) {
- if (factory) {
- factory->unref();
- }
- }
-}
-
-GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSkSLFP);
-
-#if GR_TEST_UTILS
-
-#include "SkGr.h"
-
-using Value = SkSL::Program::Settings::Value;
-
-std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d) {
- int type = d->fRandom->nextULessThan(1);
- switch (type) {
- case 0: {
- static int ditherIndex = NewIndex();
- int rangeType = d->fRandom->nextULessThan(3);
- return GrSkSLFP::Make(d->context(), ditherIndex, "Dither", SKSL_DITHER_SRC, &rangeType,
- sizeof(rangeType));
- }
- }
- SK_ABORT("unreachable");
- return nullptr;
-}
-
-#endif
diff --git a/src/gpu/effects/GrSkSLFP.h b/src/gpu/effects/GrSkSLFP.h
deleted file mode 100644
index 428e0892e0..0000000000
--- a/src/gpu/effects/GrSkSLFP.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrSkSLFP_DEFINED
-#define GrSkSLFP_DEFINED
-
-#include "GrCaps.h"
-#include "GrFragmentProcessor.h"
-#include "GrCoordTransform.h"
-#include "GrShaderCaps.h"
-#include "SkSLCompiler.h"
-#include "SkSLPipelineStageCodeGenerator.h"
-#include "SkRefCnt.h"
-#include "../private/GrSkSLFPFactoryCache.h"
-
-class GrContext;
-class GrSkSLFPFactory;
-
-class GrSkSLFP : public GrFragmentProcessor {
-public:
- /**
- * Returns a new unique identifier. Each different SkSL fragment processor should call
- * NewIndex once, statically, and use this index for all calls to Make.
- */
- static int NewIndex() {
- static int index = 0;
- return sk_atomic_inc(&index);
- }
-
- /**
- * Creates a new fragment processor from an SkSL source string and a struct of inputs to the
- * program. The input struct's type is derived from the 'in' variables in the SkSL source, so
- * e.g. the shader:
- *
- * in bool dither;
- * in float x;
- * in float y;
- * ....
- *
- * would expect a pointer to a struct set up like:
- *
- * struct {
- * bool dither;
- * float x;
- * float y;
- * };
- *
- * As turning SkSL into GLSL / SPIR-V / etc. is fairly expensive, and the output may differ
- * based on the inputs, internally the process is divided into two steps: we first parse and
- * semantically analyze the SkSL into an internal representation, and then "specialize" this
- * internal representation based on the inputs. The unspecialized internal representation of
- * the program is cached, so further specializations of the same code are much faster than the
- * first call.
- *
- * This caching is based on the 'index' parameter, which should be derived by statically calling
- * 'NewIndex()'. Each given SkSL string should have a single, statically defined index
- * associated with it.
- */
- static std::unique_ptr<GrFragmentProcessor> Make(
- GrContext* context,
- int index,
- const char* name,
- const char* sksl,
- const void* inputs,
- size_t inputSize);
-
- const char* name() const override;
-
- std::unique_ptr<GrFragmentProcessor> clone() const override;
-
-private:
- GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps, int fIndex,
- const char* name, const char* sksl, const void* inputs, size_t inputSize);
-
- GrSkSLFP(const GrSkSLFP& other);
-
- GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
-
- void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
-
- bool onIsEqual(const GrFragmentProcessor&) const override;
-
- void createFactory() const;
-
- sk_sp<GrSkSLFPFactoryCache> fFactoryCache;
-
- const sk_sp<GrShaderCaps> fShaderCaps;
-
- mutable sk_sp<GrSkSLFPFactory> fFactory;
-
- int fIndex;
-
- const char* fName;
-
- const char* fSkSL;
-
- const std::unique_ptr<int8_t[]> fInputs;
-
- size_t fInputSize;
-
- mutable SkSL::String fKey;
-
- GR_DECLARE_FRAGMENT_PROCESSOR_TEST
-
- typedef GrFragmentProcessor INHERITED;
-
- friend class GrSkSLFPFactory;
-};
-
-/**
- * Produces GrFragmentProcessors from SkSL code. As the shader code produced from the SkSL depends
- * upon the inputs to the SkSL (static if's, etc.) we first create a factory for a given SkSL
- * string, then use that to create the actual GrFragmentProcessor.
- */
-class GrSkSLFPFactory : public SkNVRefCnt<GrSkSLFPFactory> {
-public:
- /**
- * Constructs a GrSkSLFPFactory for a given SkSL source string. Creating a factory will
- * preprocess the SkSL and determine which of its inputs are declared "key" (meaning they cause
- * the produced shaders to differ), so it is important to reuse the same factory instance for
- * the same shader in order to avoid repeatedly re-parsing the SkSL.
- */
- GrSkSLFPFactory(const char* name, const GrShaderCaps* shaderCaps, const char* sksl);
-
- const SkSL::Program* getSpecialization(const SkSL::String& key, const void* inputs,
- size_t inputSize);
-
- const char* fName;
-
- SkSL::Compiler fCompiler;
-
- std::shared_ptr<SkSL::Program> fBaseProgram;
-
- std::vector<const SkSL::Variable*> fInputVars;
-
- std::vector<const SkSL::Variable*> fKeyVars;
-
- std::unordered_map<SkSL::String, std::unique_ptr<const SkSL::Program>> fSpecializations;
-
- friend class GrSkSLFP;
-};
-
-#endif