diff options
author | Ethan Nicholas <ethannicholas@google.com> | 2017-07-31 11:18:22 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-07-31 15:44:32 +0000 |
commit | f57c0d67611186ba74179b53b421e64b63a579c7 (patch) | |
tree | 6e9cdae25bdc158bcd1a0b667bc95bb8185182f8 | |
parent | 45b0f15688c1c508204143a3239e0691abd14032 (diff) |
automatically generate clone() methods for SkSL fragment processors
Bug: skia:
Change-Id: Ib7b90f20d2b1558aad14f38f95c7c884e654c96d
Reviewed-on: https://skia-review.googlesource.com/28620
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r-- | src/effects/GrAlphaThresholdFragmentProcessor.cpp | 19 | ||||
-rw-r--r-- | src/effects/GrAlphaThresholdFragmentProcessor.h | 2 | ||||
-rw-r--r-- | src/effects/GrCircleBlurFragmentProcessor.cpp | 13 | ||||
-rw-r--r-- | src/effects/GrCircleBlurFragmentProcessor.h | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp | 8 | ||||
-rw-r--r-- | src/gpu/effects/GrBlurredEdgeFragmentProcessor.h | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrCircleEffect.cpp | 10 | ||||
-rw-r--r-- | src/gpu/effects/GrCircleEffect.h | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrDitherEffect.cpp | 7 | ||||
-rw-r--r-- | src/gpu/effects/GrDitherEffect.h | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrEllipseEffect.cpp | 10 | ||||
-rw-r--r-- | src/gpu/effects/GrEllipseEffect.h | 2 | ||||
-rw-r--r-- | src/gpu/effects/GrSimpleTextureEffect.cpp | 13 | ||||
-rw-r--r-- | src/gpu/effects/GrSimpleTextureEffect.h | 2 | ||||
-rw-r--r-- | src/sksl/README | 1 | ||||
-rw-r--r-- | src/sksl/SkSLCPPCodeGenerator.cpp | 45 | ||||
-rw-r--r-- | src/sksl/SkSLCPPCodeGenerator.h | 4 | ||||
-rw-r--r-- | src/sksl/SkSLHCodeGenerator.cpp | 6 | ||||
-rw-r--r-- | src/sksl/SkSLSectionAndParameterHelper.h | 2 | ||||
-rw-r--r-- | tests/SkSLFPTest.cpp | 10 |
20 files changed, 158 insertions, 4 deletions
diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.cpp b/src/effects/GrAlphaThresholdFragmentProcessor.cpp index fab78cea9d..731ca99d3b 100644 --- a/src/effects/GrAlphaThresholdFragmentProcessor.cpp +++ b/src/effects/GrAlphaThresholdFragmentProcessor.cpp @@ -107,6 +107,25 @@ bool GrAlphaThresholdFragmentProcessor::onIsEqual(const GrFragmentProcessor& oth if (fOuterThreshold != that.fOuterThreshold) return false; return true; } +GrAlphaThresholdFragmentProcessor::GrAlphaThresholdFragmentProcessor( + const GrAlphaThresholdFragmentProcessor& src) + : INHERITED(src.optimizationFlags()) + , fImage(src.fImage) + , fColorXform(src.fColorXform) + , fMask(src.fMask) + , fInnerThreshold(src.fInnerThreshold) + , fOuterThreshold(src.fOuterThreshold) + , fImageCoordTransform(src.fImageCoordTransform) + , fMaskCoordTransform(src.fMaskCoordTransform) { + this->initClassID<GrAlphaThresholdFragmentProcessor>(); + this->addTextureSampler(&fImage); + this->addTextureSampler(&fMask); + this->addCoordTransform(&fImageCoordTransform); + this->addCoordTransform(&fMaskCoordTransform); +} +sk_sp<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::clone() const { + return sk_sp<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor(*this)); +} GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAlphaThresholdFragmentProcessor); #if GR_TEST_UTILS sk_sp<GrFragmentProcessor> GrAlphaThresholdFragmentProcessor::TestCreate( diff --git a/src/effects/GrAlphaThresholdFragmentProcessor.h b/src/effects/GrAlphaThresholdFragmentProcessor.h index e2b10e8cb7..78424d0359 100644 --- a/src/effects/GrAlphaThresholdFragmentProcessor.h +++ b/src/effects/GrAlphaThresholdFragmentProcessor.h @@ -35,6 +35,8 @@ public: return sk_sp<GrFragmentProcessor>(new GrAlphaThresholdFragmentProcessor( image, colorXform, mask, innerThreshold, outerThreshold, bounds)); } + GrAlphaThresholdFragmentProcessor(const GrAlphaThresholdFragmentProcessor& src); + sk_sp<GrFragmentProcessor> clone() const override; const char* name() const override { return "AlphaThresholdFragmentProcessor"; } private: diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp index 1d281f045e..68ba0af0d4 100644 --- a/src/effects/GrCircleBlurFragmentProcessor.cpp +++ b/src/effects/GrCircleBlurFragmentProcessor.cpp @@ -285,6 +285,19 @@ bool GrCircleBlurFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) if (fBlurProfileSampler != that.fBlurProfileSampler) return false; return true; } +GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor( + const GrCircleBlurFragmentProcessor& src) + : INHERITED(src.optimizationFlags()) + , fCircleRect(src.fCircleRect) + , fTextureRadius(src.fTextureRadius) + , fSolidRadius(src.fSolidRadius) + , fBlurProfileSampler(src.fBlurProfileSampler) { + this->initClassID<GrCircleBlurFragmentProcessor>(); + this->addTextureSampler(&fBlurProfileSampler); +} +sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::clone() const { + return sk_sp<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(*this)); +} GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCircleBlurFragmentProcessor); #if GR_TEST_UTILS sk_sp<GrFragmentProcessor> GrCircleBlurFragmentProcessor::TestCreate( diff --git a/src/effects/GrCircleBlurFragmentProcessor.h b/src/effects/GrCircleBlurFragmentProcessor.h index 4a450d7a66..9ef204d403 100644 --- a/src/effects/GrCircleBlurFragmentProcessor.h +++ b/src/effects/GrCircleBlurFragmentProcessor.h @@ -23,6 +23,8 @@ public: static sk_sp<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider, const SkRect& circle, float sigma); + GrCircleBlurFragmentProcessor(const GrCircleBlurFragmentProcessor& src); + sk_sp<GrFragmentProcessor> clone() const override; const char* name() const override { return "CircleBlurFragmentProcessor"; } private: diff --git a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp index f63422ffcd..8c0ff64d27 100644 --- a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp +++ b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp @@ -50,4 +50,12 @@ bool GrBlurredEdgeFragmentProcessor::onIsEqual(const GrFragmentProcessor& other) if (fMode != that.fMode) return false; return true; } +GrBlurredEdgeFragmentProcessor::GrBlurredEdgeFragmentProcessor( + const GrBlurredEdgeFragmentProcessor& src) + : INHERITED(src.optimizationFlags()), fMode(src.fMode) { + this->initClassID<GrBlurredEdgeFragmentProcessor>(); +} +sk_sp<GrFragmentProcessor> GrBlurredEdgeFragmentProcessor::clone() const { + return sk_sp<GrFragmentProcessor>(new GrBlurredEdgeFragmentProcessor(*this)); +} #endif diff --git a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h index 733fd8342c..677c285114 100644 --- a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h +++ b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h @@ -22,6 +22,8 @@ public: static sk_sp<GrFragmentProcessor> Make(int mode) { return sk_sp<GrFragmentProcessor>(new GrBlurredEdgeFragmentProcessor(mode)); } + GrBlurredEdgeFragmentProcessor(const GrBlurredEdgeFragmentProcessor& src); + sk_sp<GrFragmentProcessor> clone() const override; const char* name() const override { return "BlurredEdgeFragmentProcessor"; } private: diff --git a/src/gpu/effects/GrCircleEffect.cpp b/src/gpu/effects/GrCircleEffect.cpp index 97bfda4dbb..6fc47558c9 100644 --- a/src/gpu/effects/GrCircleEffect.cpp +++ b/src/gpu/effects/GrCircleEffect.cpp @@ -88,6 +88,16 @@ bool GrCircleEffect::onIsEqual(const GrFragmentProcessor& other) const { if (fRadius != that.fRadius) return false; return true; } +GrCircleEffect::GrCircleEffect(const GrCircleEffect& src) + : INHERITED(src.optimizationFlags()) + , fEdgeType(src.fEdgeType) + , fCenter(src.fCenter) + , fRadius(src.fRadius) { + this->initClassID<GrCircleEffect>(); +} +sk_sp<GrFragmentProcessor> GrCircleEffect::clone() const { + return sk_sp<GrFragmentProcessor>(new GrCircleEffect(*this)); +} GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCircleEffect); #if GR_TEST_UTILS sk_sp<GrFragmentProcessor> GrCircleEffect::TestCreate(GrProcessorTestData* testData) { diff --git a/src/gpu/effects/GrCircleEffect.h b/src/gpu/effects/GrCircleEffect.h index fae8155389..46e46f9575 100644 --- a/src/gpu/effects/GrCircleEffect.h +++ b/src/gpu/effects/GrCircleEffect.h @@ -23,6 +23,8 @@ public: static sk_sp<GrFragmentProcessor> Make(int edgeType, SkPoint center, float radius) { return sk_sp<GrFragmentProcessor>(new GrCircleEffect(edgeType, center, radius)); } + GrCircleEffect(const GrCircleEffect& src); + sk_sp<GrFragmentProcessor> clone() const override; const char* name() const override { return "CircleEffect"; } private: diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp index 38e4c77564..3b70493338 100644 --- a/src/gpu/effects/GrDitherEffect.cpp +++ b/src/gpu/effects/GrDitherEffect.cpp @@ -57,6 +57,13 @@ bool GrDitherEffect::onIsEqual(const GrFragmentProcessor& other) const { if (fRangeType != that.fRangeType) return false; return true; } +GrDitherEffect::GrDitherEffect(const GrDitherEffect& src) + : INHERITED(src.optimizationFlags()), fRangeType(src.fRangeType) { + this->initClassID<GrDitherEffect>(); +} +sk_sp<GrFragmentProcessor> GrDitherEffect::clone() const { + return sk_sp<GrFragmentProcessor>(new GrDitherEffect(*this)); +} GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrDitherEffect); #if GR_TEST_UTILS sk_sp<GrFragmentProcessor> GrDitherEffect::TestCreate(GrProcessorTestData* testData) { diff --git a/src/gpu/effects/GrDitherEffect.h b/src/gpu/effects/GrDitherEffect.h index d3a4e86486..529b5ec457 100644 --- a/src/gpu/effects/GrDitherEffect.h +++ b/src/gpu/effects/GrDitherEffect.h @@ -46,6 +46,8 @@ public: } return sk_sp<GrFragmentProcessor>(new GrDitherEffect(rangeType)); } + GrDitherEffect(const GrDitherEffect& src); + sk_sp<GrFragmentProcessor> clone() const override; const char* name() const override { return "DitherEffect"; } private: diff --git a/src/gpu/effects/GrEllipseEffect.cpp b/src/gpu/effects/GrEllipseEffect.cpp index ebc3bf7e37..edf12d27dd 100644 --- a/src/gpu/effects/GrEllipseEffect.cpp +++ b/src/gpu/effects/GrEllipseEffect.cpp @@ -113,6 +113,16 @@ bool GrEllipseEffect::onIsEqual(const GrFragmentProcessor& other) const { if (fRadii != that.fRadii) return false; return true; } +GrEllipseEffect::GrEllipseEffect(const GrEllipseEffect& src) + : INHERITED(src.optimizationFlags()) + , fEdgeType(src.fEdgeType) + , fCenter(src.fCenter) + , fRadii(src.fRadii) { + this->initClassID<GrEllipseEffect>(); +} +sk_sp<GrFragmentProcessor> GrEllipseEffect::clone() const { + return sk_sp<GrFragmentProcessor>(new GrEllipseEffect(*this)); +} GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrEllipseEffect); #if GR_TEST_UTILS sk_sp<GrFragmentProcessor> GrEllipseEffect::TestCreate(GrProcessorTestData* testData) { diff --git a/src/gpu/effects/GrEllipseEffect.h b/src/gpu/effects/GrEllipseEffect.h index 980ba533be..28586561da 100644 --- a/src/gpu/effects/GrEllipseEffect.h +++ b/src/gpu/effects/GrEllipseEffect.h @@ -23,6 +23,8 @@ public: static sk_sp<GrFragmentProcessor> Make(int edgeType, SkPoint center, SkPoint radii) { return sk_sp<GrFragmentProcessor>(new GrEllipseEffect(edgeType, center, radii)); } + GrEllipseEffect(const GrEllipseEffect& src); + sk_sp<GrFragmentProcessor> clone() const override; const char* name() const override { return "EllipseEffect"; } private: diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp index bbac5b5f4c..bd2b80529a 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.cpp +++ b/src/gpu/effects/GrSimpleTextureEffect.cpp @@ -70,6 +70,19 @@ bool GrSimpleTextureEffect::onIsEqual(const GrFragmentProcessor& other) const { if (fMatrix != that.fMatrix) return false; return true; } +GrSimpleTextureEffect::GrSimpleTextureEffect(const GrSimpleTextureEffect& src) + : INHERITED(src.optimizationFlags()) + , fImage(src.fImage) + , fColorXform(src.fColorXform) + , fMatrix(src.fMatrix) + , fImageCoordTransform(src.fImageCoordTransform) { + this->initClassID<GrSimpleTextureEffect>(); + this->addTextureSampler(&fImage); + this->addCoordTransform(&fImageCoordTransform); +} +sk_sp<GrFragmentProcessor> GrSimpleTextureEffect::clone() const { + return sk_sp<GrFragmentProcessor>(new GrSimpleTextureEffect(*this)); +} GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSimpleTextureEffect); #if GR_TEST_UTILS sk_sp<GrFragmentProcessor> GrSimpleTextureEffect::TestCreate(GrProcessorTestData* testData) { diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h index 41d7af772c..25ef1c5bd0 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.h +++ b/src/gpu/effects/GrSimpleTextureEffect.h @@ -47,6 +47,8 @@ public: return sk_sp<GrFragmentProcessor>( new GrSimpleTextureEffect(std::move(proxy), std::move(colorSpaceXform), matrix, p)); } + GrSimpleTextureEffect(const GrSimpleTextureEffect& src); + sk_sp<GrFragmentProcessor> clone() const override; const char* name() const override { return "SimpleTextureEffect"; } private: diff --git a/src/sksl/README b/src/sksl/README index 012895412e..329fa08ad7 100644 --- a/src/sksl/README +++ b/src/sksl/README @@ -83,6 +83,7 @@ Within an '.fp' fragment processor file: @emitCode (extra code for the emitCode function) @fields (extra private fields, each terminated with a semicolon) @make (replaces the default Make function) + @clone (replaces the default clone() function) @setData(<pdman>) (extra code for the setData function, where <pdman> is the name of the GrGLSLProgramDataManager) @test(<testData>) (the body of the TestCreate function, where <testData> is diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp index 7c10606f79..2276ce372e 100644 --- a/src/sksl/SkSLCPPCodeGenerator.cpp +++ b/src/sksl/SkSLCPPCodeGenerator.cpp @@ -302,11 +302,13 @@ void CPPCodeGenerator::writeSetting(const Setting& s) { } } -void CPPCodeGenerator::writeSection(const char* name, const char* prefix) { +bool CPPCodeGenerator::writeSection(const char* name, const char* prefix) { const Section* s = fSectionAndParameterHelper.getSection(name); if (s) { this->writef("%s%s", prefix, s->fText.c_str()); + return true; } + return false; } void CPPCodeGenerator::writeProgramElement(const ProgramElement& p) { @@ -503,6 +505,46 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) { this->write(" }\n"); } +void CPPCodeGenerator::writeClone() { + if (!this->writeSection(CLONE_SECTION)) { + if (fSectionAndParameterHelper.getSection(FIELDS_SECTION)) { + fErrors.error(Position(1, 1), "fragment processors with custom @fields must also have " + "a custom @clone"); + } + this->writef("%s::%s(const %s& src)\n" + ": INHERITED(src.optimizationFlags())", fFullName.c_str(), fFullName.c_str(), + fFullName.c_str()); + for (const auto& param : fSectionAndParameterHelper.getParameters()) { + String fieldName = HCodeGenerator::FieldName(param->fName.c_str()); + this->writef("\n, %s(%s)", + fieldName.c_str(), + ("src." + fieldName).c_str()); + } + for (const Section* s : fSectionAndParameterHelper.getSections(COORD_TRANSFORM_SECTION)) { + String fieldName = HCodeGenerator::FieldName(s->fArgument.c_str()); + this->writef("\n, %sCoordTransform(src.%sCoordTransform)", fieldName.c_str(), + fieldName.c_str()); + } + this->writef(" {\n" + " this->initClassID<%s>();\n", + fFullName.c_str()); + for (const auto& param : fSectionAndParameterHelper.getParameters()) { + if (param->fType.kind() == Type::kSampler_Kind) { + this->writef(" this->addTextureSampler(&%s);\n", + HCodeGenerator::FieldName(param->fName.c_str()).c_str()); + } + } + for (const Section* s : fSectionAndParameterHelper.getSections(COORD_TRANSFORM_SECTION)) { + String field = HCodeGenerator::FieldName(s->fArgument.c_str()); + this->writef(" this->addCoordTransform(&%sCoordTransform);\n", field.c_str()); + } + this->write("}\n"); + this->writef("sk_sp<GrFragmentProcessor> %s::clone() const {\n", fFullName.c_str()); + this->writef(" return sk_sp<GrFragmentProcessor>(new %s(*this));\n", fFullName.c_str()); + this->write("}\n"); + } +} + void CPPCodeGenerator::writeTest() { const Section* test = fSectionAndParameterHelper.getSection(TEST_CODE_SECTION); if (test) { @@ -639,6 +681,7 @@ bool CPPCodeGenerator::generateCode() { } this->write(" return true;\n" "}\n"); + this->writeClone(); this->writeTest(); this->writeSection(CPP_END_SECTION); this->write("#endif\n"); diff --git a/src/sksl/SkSLCPPCodeGenerator.h b/src/sksl/SkSLCPPCodeGenerator.h index 8b30151c71..b4f31ba1b0 100644 --- a/src/sksl/SkSLCPPCodeGenerator.h +++ b/src/sksl/SkSLCPPCodeGenerator.h @@ -27,7 +27,7 @@ private: void writef(const char* s, ...) SKSL_PRINTF_LIKE(2, 3); - void writeSection(const char* name, const char* prefix = ""); + bool writeSection(const char* name, const char* prefix = ""); void writeHeader() override; @@ -72,6 +72,8 @@ private: void writeGetKey(); + void writeClone(); + void writeTest(); String fName; diff --git a/src/sksl/SkSLHCodeGenerator.cpp b/src/sksl/SkSLHCodeGenerator.cpp index 65dbf78025..22f4fd80ce 100644 --- a/src/sksl/SkSLHCodeGenerator.cpp +++ b/src/sksl/SkSLHCodeGenerator.cpp @@ -250,9 +250,11 @@ bool HCodeGenerator::generateCode() { FieldType(param->fType).c_str(), name, FieldName(name).c_str()); } this->writeMake(); - this->writef(" const char* name() const override { return \"%s\"; }\n" + this->writef(" %s(const %s& src);\n" + " sk_sp<GrFragmentProcessor> clone() const override;\n" + " const char* name() const override { return \"%s\"; }\n" "private:\n", - fName.c_str()); + fFullName.c_str(), fFullName.c_str(), fName.c_str()); this->writeConstructor(); this->writef(" GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;\n" " void onGetGLSLProcessorKey(const GrShaderCaps&," diff --git a/src/sksl/SkSLSectionAndParameterHelper.h b/src/sksl/SkSLSectionAndParameterHelper.h index bbe007c46e..f70b82c439 100644 --- a/src/sksl/SkSLSectionAndParameterHelper.h +++ b/src/sksl/SkSLSectionAndParameterHelper.h @@ -18,6 +18,7 @@ namespace SkSL { #define CLASS_SECTION "class" +#define CLONE_SECTION "clone" #define CONSTRUCTOR_SECTION "constructor" #define CONSTRUCTOR_CODE_SECTION "constructorCode" #define CONSTRUCTOR_PARAMS_SECTION "constructorParams" @@ -110,6 +111,7 @@ public: static bool IsSupportedSection(const char* name) { return !strcmp(name, CLASS_SECTION) || + !strcmp(name, CLONE_SECTION) || !strcmp(name, CONSTRUCTOR_SECTION) || !strcmp(name, CONSTRUCTOR_CODE_SECTION) || !strcmp(name, CONSTRUCTOR_PARAMS_SECTION) || diff --git a/tests/SkSLFPTest.cpp b/tests/SkSLFPTest.cpp index 7a1d371738..82bcb10b71 100644 --- a/tests/SkSLFPTest.cpp +++ b/tests/SkSLFPTest.cpp @@ -88,6 +88,8 @@ DEF_TEST(SkSLFPHelloWorld, r) { " static sk_sp<GrFragmentProcessor> Make() {\n" " return sk_sp<GrFragmentProcessor>(new GrTest());\n" " }\n" + " GrTest(const GrTest& src);\n" + " sk_sp<GrFragmentProcessor> clone() const override;\n" " const char* name() const override { return \"Test\"; }\n" "private:\n" " GrTest()\n" @@ -148,6 +150,13 @@ DEF_TEST(SkSLFPHelloWorld, r) { " (void) that;\n" " return true;\n" "}\n" + "GrTest::GrTest(const GrTest& src)\n" + ": INHERITED(src.optimizationFlags()) {\n" + " this->initClassID<GrTest>();\n" + "}\n" + "sk_sp<GrFragmentProcessor> GrTest::clone() const {\n" + " return sk_sp<GrFragmentProcessor>(new GrTest(*this));\n" + "}\n" "#endif\n" }); } @@ -287,6 +296,7 @@ DEF_TEST(SkSLFPSections, r) { }); test(r, "@fields { fields section }" + "@clone { }" "void main() {" "sk_OutColor = float4(1);" "}", |