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>
This commit is contained in:
Ethan Nicholas 2017-07-31 11:18:22 -04:00 committed by Skia Commit-Bot
parent 45b0f15688
commit f57c0d6761
20 changed files with 158 additions and 4 deletions

View File

@ -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(

View File

@ -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:

View File

@ -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(

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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) {

View File

@ -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:

View File

@ -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) {

View File

@ -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:

View File

@ -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) {

View File

@ -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:

View File

@ -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) {

View File

@ -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:

View File

@ -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

View File

@ -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");

View File

@ -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;

View File

@ -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&,"

View File

@ -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) ||

View File

@ -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);"
"}",