diff options
author | 2016-07-29 09:53:56 -0700 | |
---|---|---|
committer | 2016-07-29 09:53:56 -0700 | |
commit | 4ef6dfa7089c092c67b0d5ec34e89c1e319af196 (patch) | |
tree | dea8644d31df5b148fc95469c74fe761bc018260 /src/core | |
parent | 5db44aa2aa4a3a1b9ce1fe7e22c54c8d9b61f51d (diff) |
GrFP can express distance vector field req., program builder declares variable for it
This update allows fragment processors to require a field of vectors to the nearest edge. This requirement propagates:
- from child FPs to their parent
- from parent FPs to the GrPaint
- from GrPaint through the PipelineBuilder into GrPipeline
- acessed from GrPipeline by GrGLSLProgramBuilder
GrGLSL generates a variable for the distance vector and passes it down to the GeometryProcessor->emitCode() method.
This CL's base is the CL for adding the BevelNormalSource API: https://codereview.chromium.org/2080993002
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2114993002
Review-Url: https://codereview.chromium.org/2114993002
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkNormalBevelSource.cpp | 14 | ||||
-rw-r--r-- | src/core/SkNormalFlatSource.cpp | 10 | ||||
-rw-r--r-- | src/core/SkNormalMapSource.cpp | 10 | ||||
-rw-r--r-- | src/core/SkNormalSource.h | 2 | ||||
-rw-r--r-- | src/core/SkNormalSourcePriv.h | 57 |
5 files changed, 79 insertions, 14 deletions
diff --git a/src/core/SkNormalBevelSource.cpp b/src/core/SkNormalBevelSource.cpp index feccb0cce8..a63e434c3f 100644 --- a/src/core/SkNormalBevelSource.cpp +++ b/src/core/SkNormalBevelSource.cpp @@ -8,6 +8,7 @@ #include "SkNormalBevelSource.h" #include "SkNormalSource.h" +#include "SkNormalSourcePriv.h" #include "SkPoint3.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" @@ -25,17 +26,19 @@ public: , fWidth(width) , fHeight(height) { this->initClassID<NormalBevelFP>(); + + fUsesDistanceVectorField = true; } - class GLSLNormalBevelFP : public GrGLSLFragmentProcessor { + class GLSLNormalBevelFP : public GLSLNormalFP { public: GLSLNormalBevelFP() { fPrevWidth = SkFloatToScalar(0.0f); fPrevHeight = SkFloatToScalar(0.0f); } - void emitCode(EmitArgs& args) override { - GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; + void onEmitCode(EmitArgs& args) override { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; const char* widthUniName = nullptr; @@ -46,7 +49,7 @@ public: fHeightUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "Height", &heightUniName); - fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor); + fragBuilder->codeAppendf("%s = vec4(0.0, 0.0, 1.0, 0.0);", args.fOutputColor); } static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, @@ -56,7 +59,8 @@ public: } protected: - void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override { + void setNormalData(const GrGLSLProgramDataManager& pdman, + const GrProcessor& proc) override { const NormalBevelFP& normalBevelFP = proc.cast<NormalBevelFP>(); if (fPrevWidth != normalBevelFP.fWidth) { diff --git a/src/core/SkNormalFlatSource.cpp b/src/core/SkNormalFlatSource.cpp index fcb1a4f3ad..bdd65b03e9 100644 --- a/src/core/SkNormalFlatSource.cpp +++ b/src/core/SkNormalFlatSource.cpp @@ -8,6 +8,7 @@ #include "SkNormalFlatSource.h" #include "SkNormalSource.h" +#include "SkNormalSourcePriv.h" #include "SkPoint3.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" @@ -23,12 +24,12 @@ public: this->initClassID<NormalFlatFP>(); } - class GLSLNormalFlatFP : public GrGLSLFragmentProcessor { + class GLSLNormalFlatFP : public GLSLNormalFP { public: GLSLNormalFlatFP() {} - void emitCode(EmitArgs& args) override { - GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; + void onEmitCode(EmitArgs& args) override { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor); } @@ -39,7 +40,8 @@ public: } protected: - void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {} + void setNormalData(const GrGLSLProgramDataManager& pdman, + const GrProcessor& proc) override {} }; void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { diff --git a/src/core/SkNormalMapSource.cpp b/src/core/SkNormalMapSource.cpp index 2ecf1d310d..c2cda099ab 100644 --- a/src/core/SkNormalMapSource.cpp +++ b/src/core/SkNormalMapSource.cpp @@ -10,6 +10,7 @@ #include "SkLightingShader.h" #include "SkMatrix.h" #include "SkNormalSource.h" +#include "SkNormalSourcePriv.h" #include "SkPM4f.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" @@ -31,13 +32,13 @@ public: this->initClassID<NormalMapFP>(); } - class GLSLNormalMapFP : public GrGLSLFragmentProcessor { + class GLSLNormalMapFP : public GLSLNormalFP { public: GLSLNormalMapFP() : fColumnMajorInvCTM22{0.0f} {} - void emitCode(EmitArgs& args) override { - GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; + void onEmitCode(EmitArgs& args) override { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; // add uniform @@ -78,7 +79,8 @@ public: } protected: - void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override { + void setNormalData(const GrGLSLProgramDataManager& pdman, + const GrProcessor& proc) override { const NormalMapFP& normalMapFP = proc.cast<NormalMapFP>(); const SkMatrix& invCTM = normalMapFP.invCTM(); diff --git a/src/core/SkNormalSource.h b/src/core/SkNormalSource.h index 8cbb3e4fae..4b09d0b411 100644 --- a/src/core/SkNormalSource.h +++ b/src/core/SkNormalSource.h @@ -111,7 +111,7 @@ public: /** Returns a normal source that generates a bevel for the given shape. UNIMPLEMENTED: Will return straight-up normals only. - @param type the type of bevel to add + @param type the type of bevel to add. @param width the width of the bevel, in source space. Must be positive. @param height the height of the plateau, in source space. Can be positive, negative, or zero. A negative height means the simulated bevels slope downwards. diff --git a/src/core/SkNormalSourcePriv.h b/src/core/SkNormalSourcePriv.h new file mode 100644 index 0000000000..ce8baf61e4 --- /dev/null +++ b/src/core/SkNormalSourcePriv.h @@ -0,0 +1,57 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkNormalSourcePriv_DEFINED +#define SkNormalSourcePriv_DEFINED + +#if SK_SUPPORT_GPU +#include "glsl/GrGLSLFragmentProcessor.h" +#include "glsl/GrGLSLFragmentShaderBuilder.h" + +/* GLSLFragmentProcessors for NormalSourceImpls must sub-class this class and override onEmitCode, + * and setNormalData calls, as well as all other calls FPs normally override, except for the 2 + * defined in this superclass. + * This class exists to intercept emitCode calls and emit <0, 0, 1> if the FP requires a distance + * vector but the GP doesn't provide it. onSetData calls need to be intercepted too because + * uniform handlers will be invalid in subclasses where onEmitCode isn't called. + * We don't need to adjust the key here since the use of a given GP (through its class ID already in + * the key), will determine what code gets emitted here. + */ +class GLSLNormalFP : public GrGLSLFragmentProcessor { +public: + GLSLNormalFP() + : fDidIntercept(false) {} + + void emitCode(EmitArgs& args) final override { + if (args.fFp.usesDistanceVectorField() && !args.fGpImplementsDistanceVector) { + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; + fragBuilder->codeAppendf("// GLSLNormalFP intercepted emitCode call, GP does not " + "implement required distance vector feature\n"); + fragBuilder->codeAppendf("%s = vec4(0, 0, 1, 0);", args.fOutputColor); + + fDidIntercept = true; + } else { + this->onEmitCode(args); + } + } + + void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) final override { + if (!fDidIntercept) { + this->setNormalData(pdman, proc); + } + } + +protected: + virtual void onEmitCode(EmitArgs& args) = 0; + virtual void setNormalData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) = 0; + +private: + bool fDidIntercept; +}; +#endif + +#endif |