Move ProgramImpl definitions into Processor subclass headers.
Move ProgramImpl function definitions into Processor subclass cpp files.
Delete separate h/cpp files.
Modify GrGLSLVaryingHandler::addPassThroughAttribute to break #include
cycle. It now takes a ShaderVar rather than a GP::Attribute, making
it slightly more flexible as the input can be any variable defined
in the vertex shader.
Bug: skia:11358
Change-Id: I94ee8cd44d29e194216592ecae5fd28de785c975
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/438596
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/core/SkBlurMF.cpp b/src/core/SkBlurMF.cpp
index c844c8c..6300b06 100644
--- a/src/core/SkBlurMF.cpp
+++ b/src/core/SkBlurMF.cpp
@@ -36,7 +36,6 @@
#include "src/gpu/effects/GrSkSLFP.h"
#include "src/gpu/effects/GrTextureEffect.h"
#include "src/gpu/geometry/GrStyledShape.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 3876f7f..e0e1cb8 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -108,7 +108,6 @@
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
class ColorTableEffect : public GrFragmentProcessor {
diff --git a/src/effects/imagefilters/SkDisplacementMapImageFilter.cpp b/src/effects/imagefilters/SkDisplacementMapImageFilter.cpp
index fc0d856..920195f 100644
--- a/src/effects/imagefilters/SkDisplacementMapImageFilter.cpp
+++ b/src/effects/imagefilters/SkDisplacementMapImageFilter.cpp
@@ -18,13 +18,13 @@
#include "include/gpu/GrRecordingContext.h"
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrColorSpaceXform.h"
+#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrTexture.h"
#include "src/gpu/GrTextureProxy.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/SurfaceFillContext.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
diff --git a/src/effects/imagefilters/SkLightingImageFilter.cpp b/src/effects/imagefilters/SkLightingImageFilter.cpp
index a05e4a4..ca42f53 100644
--- a/src/effects/imagefilters/SkLightingImageFilter.cpp
+++ b/src/effects/imagefilters/SkLightingImageFilter.cpp
@@ -27,7 +27,6 @@
#include "src/gpu/SkGr.h"
#include "src/gpu/SurfaceFillContext.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
diff --git a/src/effects/imagefilters/SkMorphologyImageFilter.cpp b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
index ca3c55d..3ee3cd8 100644
--- a/src/effects/imagefilters/SkMorphologyImageFilter.cpp
+++ b/src/effects/imagefilters/SkMorphologyImageFilter.cpp
@@ -18,13 +18,13 @@
#if SK_SUPPORT_GPU
#include "include/gpu/GrRecordingContext.h"
#include "src/gpu/GrDirectContextPriv.h"
+#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrTexture.h"
#include "src/gpu/GrTextureProxy.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/SurfaceFillContext.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
diff --git a/src/gpu/GrColorSpaceXform.cpp b/src/gpu/GrColorSpaceXform.cpp
index e1af8fa..701665d 100644
--- a/src/gpu/GrColorSpaceXform.cpp
+++ b/src/gpu/GrColorSpaceXform.cpp
@@ -11,7 +11,6 @@
#include "src/core/SkColorSpacePriv.h"
#include "src/gpu/GrColorInfo.h"
#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
sk_sp<GrColorSpaceXform> GrColorSpaceXform::Make(SkColorSpace* src, SkAlphaType srcAT,
diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp
index 587814a..27c0965 100644
--- a/src/gpu/GrDefaultGeoProcFactory.cpp
+++ b/src/gpu/GrDefaultGeoProcFactory.cpp
@@ -10,8 +10,8 @@
#include "include/core/SkRefCnt.h"
#include "src/core/SkArenaAlloc.h"
#include "src/gpu/GrCaps.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
@@ -163,7 +163,7 @@
// Setup coverage as pass through
if (gp.hasVertexCoverage() && !tweakAlpha) {
fragBuilder->codeAppendf("half alpha = 1.0;");
- varyingHandler->addPassThroughAttribute(gp.fInCoverage, "alpha");
+ varyingHandler->addPassThroughAttribute(gp.fInCoverage.asShaderVar(), "alpha");
if (coverageNeedsSaturate) {
fragBuilder->codeAppendf("half4 %s = half4(saturate(alpha));",
args.fOutputCoverage);
diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp
index edc5850..856e011 100644
--- a/src/gpu/GrFragmentProcessor.cpp
+++ b/src/gpu/GrFragmentProcessor.cpp
@@ -5,15 +5,17 @@
* found in the LICENSE file.
*/
-#include "src/core/SkRuntimeEffectPriv.h"
#include "src/gpu/GrFragmentProcessor.h"
+
+#include "src/core/SkRuntimeEffectPriv.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrProcessorAnalysis.h"
+#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/effects/GrBlendFragmentProcessor.h"
#include "src/gpu/effects/GrSkSLFP.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
@@ -925,3 +927,132 @@
return HighPrecisionFragmentProcessor::Make(std::move(fp));
}
+
+//////////////////////////////////////////////////////////////////////////////
+
+using ProgramImpl = GrFragmentProcessor::ProgramImpl;
+
+void ProgramImpl::setData(const GrGLSLProgramDataManager& pdman,
+ const GrFragmentProcessor& processor) {
+ this->onSetData(pdman, processor);
+}
+
+void ProgramImpl::emitChildFunctions(EmitArgs& args) {
+ for (int i = 0; i < this->numChildProcessors(); ++i) {
+ ProgramImpl* childGLSLFP = this->childProcessor(i);
+ if (!childGLSLFP) {
+ continue;
+ }
+
+ const GrFragmentProcessor* childFP = args.fFp.childProcessor(i);
+ SkASSERT(childFP);
+
+ EmitArgs childArgs(args.fFragBuilder,
+ args.fUniformHandler,
+ args.fShaderCaps,
+ *childFP,
+ childFP->isBlendFunction() ? "_src" : "_input",
+ "_dst",
+ "_coords");
+ args.fFragBuilder->writeProcessorFunction(childGLSLFP, childArgs);
+ }
+}
+
+SkString ProgramImpl::invokeChild(int childIndex,
+ const char* inputColor,
+ const char* destColor,
+ EmitArgs& args,
+ SkSL::String skslCoords) {
+ SkASSERT(childIndex >= 0);
+
+ if (!inputColor) {
+ inputColor = args.fInputColor;
+ }
+
+ const GrFragmentProcessor* childProc = args.fFp.childProcessor(childIndex);
+ if (!childProc) {
+ // If no child processor is provided, return the input color as-is.
+ return SkString(inputColor);
+ }
+
+ auto invocation = SkStringPrintf("%s(%s", this->childProcessor(childIndex)->functionName(),
+ inputColor);
+
+ if (childProc->isBlendFunction()) {
+ if (!destColor) {
+ destColor = args.fFp.isBlendFunction() ? args.fDestColor : "half4(1)";
+ }
+ invocation.appendf(", %s", destColor);
+ }
+
+ // Assert that the child has no sample matrix. A uniform matrix sample call would go through
+ // invokeChildWithMatrix, not here.
+ SkASSERT(!childProc->sampleUsage().isUniformMatrix());
+
+ if (args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
+ SkASSERT(!childProc->sampleUsage().isFragCoord() || skslCoords == "sk_FragCoord.xy");
+ // The child's function takes a half4 color and a float2 coordinate
+ invocation.appendf(", %s", skslCoords.empty() ? args.fSampleCoord : skslCoords.c_str());
+ }
+
+ invocation.append(")");
+ return invocation;
+}
+
+SkString ProgramImpl::invokeChildWithMatrix(int childIndex,
+ const char* inputColor,
+ const char* destColor,
+ EmitArgs& args) {
+ SkASSERT(childIndex >= 0);
+
+ if (!inputColor) {
+ inputColor = args.fInputColor;
+ }
+
+ const GrFragmentProcessor* childProc = args.fFp.childProcessor(childIndex);
+ if (!childProc) {
+ // If no child processor is provided, return the input color as-is.
+ return SkString(inputColor);
+ }
+
+ SkASSERT(childProc->sampleUsage().isUniformMatrix());
+
+ // Every uniform matrix has the same (initial) name. Resolve that into the mangled name:
+ GrShaderVar uniform = args.fUniformHandler->getUniformMapping(
+ args.fFp, SkString(SkSL::SampleUsage::MatrixUniformName()));
+ SkASSERT(uniform.getType() == kFloat3x3_GrSLType);
+ const SkString& matrixName(uniform.getName());
+
+ auto invocation = SkStringPrintf("%s(%s", this->childProcessor(childIndex)->functionName(),
+ inputColor);
+
+ if (childProc->isBlendFunction()) {
+ if (!destColor) {
+ destColor = args.fFp.isBlendFunction() ? args.fDestColor : "half4(1)";
+ }
+ invocation.appendf(", %s", destColor);
+ }
+
+ // Produce a string containing the call to the helper function. We have a uniform variable
+ // containing our transform (matrixName). If the parent coords were produced by uniform
+ // transforms, then the entire expression (matrixName * coords) is lifted to a vertex shader
+ // and is stored in a varying. In that case, childProc will not be sampled explicitly, so its
+ // function signature will not take in coords.
+ //
+ // In all other cases, we need to insert sksl to compute matrix * parent coords and then invoke
+ // the function.
+ if (args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
+ // Only check perspective for this specific matrix transform, not the aggregate FP property.
+ // Any parent perspective will have already been applied when evaluated in the FS.
+ if (childProc->sampleUsage().hasPerspective()) {
+ invocation.appendf(", proj((%s) * %s.xy1)", matrixName.c_str(), args.fSampleCoord);
+ } else if (args.fShaderCaps->nonsquareMatrixSupport()) {
+ invocation.appendf(", float3x2(%s) * %s.xy1", matrixName.c_str(), args.fSampleCoord);
+ } else {
+ invocation.appendf(", ((%s) * %s.xy1).xy", matrixName.c_str(), args.fSampleCoord);
+ }
+ }
+
+ invocation.append(")");
+ return invocation;
+}
diff --git a/src/gpu/GrFragmentProcessor.h b/src/gpu/GrFragmentProcessor.h
index 759aae1..1a49197 100644
--- a/src/gpu/GrFragmentProcessor.h
+++ b/src/gpu/GrFragmentProcessor.h
@@ -8,11 +8,15 @@
#ifndef GrFragmentProcessor_DEFINED
#define GrFragmentProcessor_DEFINED
+#include "include/private/SkSLSampleUsage.h"
+#include "include/private/SkSLString.h"
+#include "src/gpu/GrProcessor.h"
+#include "src/gpu/glsl/GrGLSLUniformHandler.h"
+
#include <tuple>
-#include "include/private/SkSLSampleUsage.h"
-#include "src/gpu/GrProcessor.h"
-
+class GrGLSLFPFragmentBuilder;
+class GrGLSLProgramDataManager;
class GrPaint;
class GrPipeline;
class GrProcessorKeyBuilder;
@@ -488,6 +492,192 @@
//////////////////////////////////////////////////////////////////////////////
+class GrFragmentProcessor::ProgramImpl {
+public:
+ ProgramImpl() = default;
+
+ virtual ~ProgramImpl() = default;
+
+ using UniformHandle = GrGLSLUniformHandler::UniformHandle;
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+
+ /** Called when the program stage should insert its code into the shaders. The code in each
+ shader will be in its own block ({}) and so locally scoped names will not collide across
+ stages.
+
+ @param fragBuilder Interface used to emit code in the shaders.
+ @param uniformHandler Interface used for accessing information about our uniforms
+ @param caps The capabilities of the GPU which will render this FP
+ @param fp The processor that generated this program stage.
+ @param inputColor A half4 that holds the input color to the stage in the FS (or the
+ source color, for blend processors). nullptr inputs are converted
+ to "half4(1.0)" (solid white) during construction.
+ TODO: Better system for communicating optimization info
+ (e.g. input color is solid white, trans black, known to be opaque,
+ etc.) that allows the processor to communicate back similar known
+ info about its output.
+ @param destColor A half4 that holds the dest color to the stage. Only meaningful
+ when the "is blend processor" FP flag is set.
+ @param sampleCoord The name of a local coord reference to a float2 variable. Only
+ meaningful when the "references sample coords" FP flag is set.
+ */
+ struct EmitArgs {
+ EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderCaps* caps,
+ const GrFragmentProcessor& fp,
+ const char* inputColor,
+ const char* destColor,
+ const char* sampleCoord)
+ : fFragBuilder(fragBuilder)
+ , fUniformHandler(uniformHandler)
+ , fShaderCaps(caps)
+ , fFp(fp)
+ , fInputColor(inputColor ? inputColor : "half4(1.0)")
+ , fDestColor(destColor)
+ , fSampleCoord(sampleCoord) {}
+ GrGLSLFPFragmentBuilder* fFragBuilder;
+ GrGLSLUniformHandler* fUniformHandler;
+ const GrShaderCaps* fShaderCaps;
+ const GrFragmentProcessor& fFp;
+ const char* fInputColor;
+ const char* fDestColor;
+ const char* fSampleCoord;
+ };
+
+ virtual void emitCode(EmitArgs&) = 0;
+
+ // This does not recurse to any attached child processors. Recursing the entire processor tree
+ // is the responsibility of the caller.
+ void setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor);
+
+ int numChildProcessors() const { return fChildProcessors.count(); }
+
+ ProgramImpl* childProcessor(int index) const { return fChildProcessors[index].get(); }
+
+ void setFunctionName(SkString name) {
+ SkASSERT(fFunctionName.isEmpty());
+ fFunctionName = std::move(name);
+ }
+
+ const char* functionName() const {
+ SkASSERT(!fFunctionName.isEmpty());
+ return fFunctionName.c_str();
+ }
+
+ void emitChildFunctions(EmitArgs& parentArgs);
+
+ // Invoke the child with the default input and destination colors (solid white)
+ inline SkString invokeChild(int childIndex,
+ EmitArgs& parentArgs,
+ SkSL::String skslCoords = "") {
+ return this->invokeChild(childIndex,
+ /*inputColor=*/nullptr,
+ /*destColor=*/nullptr,
+ parentArgs,
+ skslCoords);
+ }
+
+ inline SkString invokeChildWithMatrix(int childIndex, EmitArgs& parentArgs) {
+ return this->invokeChildWithMatrix(childIndex,
+ /*inputColor=*/nullptr,
+ /*destColor=*/nullptr,
+ parentArgs);
+ }
+
+ // Invoke the child with the default destination color (solid white)
+ inline SkString invokeChild(int childIndex,
+ const char* inputColor,
+ EmitArgs& parentArgs,
+ SkSL::String skslCoords = "") {
+ return this->invokeChild(childIndex,
+ inputColor,
+ /*destColor=*/nullptr,
+ parentArgs,
+ skslCoords);
+ }
+
+ inline SkString invokeChildWithMatrix(int childIndex,
+ const char* inputColor,
+ EmitArgs& parentArgs) {
+ return this->invokeChildWithMatrix(childIndex,
+ inputColor,
+ /*destColor=*/nullptr,
+ parentArgs);
+ }
+
+ /** Invokes a child proc in its own scope. Pass in the parent's EmitArgs and invokeChild will
+ * automatically extract the coords and samplers of that child and pass them on to the child's
+ * emitCode(). Also, any uniforms or functions emitted by the child will have their names
+ * mangled to prevent redefinitions. The returned string contains the output color (as a call
+ * to the child's helper function). It is legal to pass nullptr as inputColor, since all
+ * fragment processors are required to work without an input color.
+ *
+ * When skslCoords is empty, invokeChild corresponds to a call to "sample(child, color)"
+ * in SkSL. When skslCoords is not empty, invokeChild corresponds to a call to
+ * "sample(child, color, float2)", where skslCoords is an SkSL expression that evaluates to a
+ * float2 and is passed in as the 3rd argument.
+ */
+ SkString invokeChild(int childIndex,
+ const char* inputColor,
+ const char* destColor,
+ EmitArgs& parentArgs,
+ SkSL::String skslCoords = "");
+
+ /**
+ * As invokeChild, but transforms the coordinates according to the matrix expression attached
+ * to the child's SampleUsage object. This is only valid if the child is sampled with a
+ * const-uniform matrix.
+ */
+ SkString invokeChildWithMatrix(int childIndex,
+ const char* inputColor,
+ const char* destColor,
+ EmitArgs& parentArgs);
+
+ /**
+ * Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
+ * GLSLFPS. If initialized with an array color followed by coverage processors installed in a
+ * program thenthe iteration order will agree with a GrFragmentProcessor::Iter initialized with
+ * a GrPipeline that produces the same program key.
+ */
+ class Iter {
+ public:
+ Iter(std::unique_ptr<ProgramImpl> fps[], int cnt);
+ Iter(ProgramImpl& fp) { fFPStack.push_back(&fp); }
+
+ ProgramImpl& operator*() const;
+ ProgramImpl* operator->() const;
+ Iter& operator++();
+ operator bool() const { return !fFPStack.empty(); }
+
+ // Because each iterator carries a stack we want to avoid copies.
+ Iter(const Iter&) = delete;
+ Iter& operator=(const Iter&) = delete;
+
+ private:
+ SkSTArray<4, ProgramImpl*, true> fFPStack;
+ };
+
+private:
+ /**
+ * A ProgramImpl instance can be reused with any GrFragmentProcessor that produces the same
+ * the same key; this function reads data from a GrFragmentProcessor and uploads any
+ * uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
+ * parameter is guaranteed to be of the same type that created this ProgramImpl and
+ * to have an identical key as the one that created this ProgramImpl.
+ */
+ virtual void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) {}
+
+ // The (mangled) name of our entry-point function
+ SkString fFunctionName;
+
+ SkTArray<std::unique_ptr<ProgramImpl>, true> fChildProcessors;
+
+ friend class GrFragmentProcessor;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
GR_MAKE_BITFIELD_OPS(GrFragmentProcessor::OptimizationFlags)
static inline GrFPResult GrFPFailure(std::unique_ptr<GrFragmentProcessor> fp) {
diff --git a/src/gpu/GrGeometryProcessor.cpp b/src/gpu/GrGeometryProcessor.cpp
index 61f46f3..d87ee46 100644
--- a/src/gpu/GrGeometryProcessor.cpp
+++ b/src/gpu/GrGeometryProcessor.cpp
@@ -7,8 +7,14 @@
#include "src/gpu/GrGeometryProcessor.h"
-#include "src/gpu/GrFragmentProcessor.h"
+#include "src/core/SkMatrixPriv.h"
+#include "src/gpu/GrPipeline.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
+#include "src/gpu/glsl/GrGLSLUniformHandler.h"
+#include "src/gpu/glsl/GrGLSLVarying.h"
+#include <queue>
GrGeometryProcessor::GrGeometryProcessor(ClassID classID) : GrProcessor(classID) {}
@@ -52,3 +58,443 @@
fSwizzle = swizzle;
fIsInitialized = true;
}
+
+//////////////////////////////////////////////////////////////////////////////
+
+using ProgramImpl = GrGeometryProcessor::ProgramImpl;
+
+ProgramImpl::FPCoordsMap ProgramImpl::emitCode(EmitArgs& args, const GrPipeline& pipeline) {
+ GrGPArgs gpArgs;
+ this->onEmitCode(args, &gpArgs);
+
+ GrShaderVar positionVar = gpArgs.fPositionVar;
+ // skia:12198
+ if (args.fGeomProc.willUseGeoShader() || args.fGeomProc.willUseTessellationShaders()) {
+ positionVar = {};
+ }
+ FPCoordsMap transformMap = this->collectTransforms(args.fVertBuilder,
+ args.fVaryingHandler,
+ args.fUniformHandler,
+ gpArgs.fLocalCoordVar,
+ positionVar,
+ pipeline);
+
+ if (args.fGeomProc.willUseTessellationShaders()) {
+ // Tessellation shaders are temporarily responsible for integrating their own code strings
+ // while we work out full support.
+ return transformMap;
+ }
+
+ GrGLSLVertexBuilder* vBuilder = args.fVertBuilder;
+ if (!args.fGeomProc.willUseGeoShader()) {
+ // Emit the vertex position to the hardware in the normalized window coordinates it expects.
+ SkASSERT(kFloat2_GrSLType == gpArgs.fPositionVar.getType() ||
+ kFloat3_GrSLType == gpArgs.fPositionVar.getType());
+ vBuilder->emitNormalizedSkPosition(gpArgs.fPositionVar.c_str(),
+ gpArgs.fPositionVar.getType());
+ if (kFloat2_GrSLType == gpArgs.fPositionVar.getType()) {
+ args.fVaryingHandler->setNoPerspective();
+ }
+ } else {
+ // Since we have a geometry shader, leave the vertex position in Skia device space for now.
+ // The geometry Shader will operate in device space, and then convert the final positions to
+ // normalized hardware window coordinates under the hood, once everything else has finished.
+ // The subclass must call setNoPerspective on the varying handler, if applicable.
+ vBuilder->codeAppendf("sk_Position = float4(%s", gpArgs.fPositionVar.c_str());
+ switch (gpArgs.fPositionVar.getType()) {
+ case kFloat_GrSLType:
+ vBuilder->codeAppend(", 0");
+ [[fallthrough]];
+ case kFloat2_GrSLType:
+ vBuilder->codeAppend(", 0");
+ [[fallthrough]];
+ case kFloat3_GrSLType:
+ vBuilder->codeAppend(", 1");
+ [[fallthrough]];
+ case kFloat4_GrSLType:
+ vBuilder->codeAppend(");");
+ break;
+ default:
+ SK_ABORT("Invalid position var type");
+ break;
+ }
+ }
+ return transformMap;
+}
+
+ProgramImpl::FPCoordsMap ProgramImpl::collectTransforms(GrGLSLVertexBuilder* vb,
+ GrGLSLVaryingHandler* varyingHandler,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderVar& localCoordsVar,
+ const GrShaderVar& positionVar,
+ const GrPipeline& pipeline) {
+ SkASSERT(localCoordsVar.getType() == kFloat2_GrSLType ||
+ localCoordsVar.getType() == kFloat3_GrSLType ||
+ localCoordsVar.getType() == kVoid_GrSLType);
+ SkASSERT(positionVar.getType() == kFloat2_GrSLType ||
+ positionVar.getType() == kFloat3_GrSLType ||
+ positionVar.getType() == kVoid_GrSLType);
+
+ enum class BaseCoord { kNone, kLocal, kPosition };
+
+ auto baseLocalCoordFSVar = [&, baseLocalCoord = GrGLSLVarying()]() mutable {
+ SkASSERT(GrSLTypeIsFloatType(localCoordsVar.getType()));
+ if (baseLocalCoord.type() == kVoid_GrSLType) {
+ // Initialize to the GP provided coordinate
+ baseLocalCoord = GrGLSLVarying(localCoordsVar.getType());
+ varyingHandler->addVarying("LocalCoord", &baseLocalCoord);
+ vb->codeAppendf("%s = %s;\n", baseLocalCoord.vsOut(), localCoordsVar.getName().c_str());
+ }
+ return baseLocalCoord.fsInVar();
+ };
+
+ bool canUsePosition = positionVar.getType() != kVoid_GrSLType;
+
+ FPCoordsMap result;
+ // Performs a pre-order traversal of FP hierarchy rooted at fp and identifies FPs that are
+ // sampled with a series of matrices applied to local coords. For each such FP a varying is
+ // added to the varying handler and added to 'result'.
+ auto liftTransforms = [&, traversalIndex = 0](
+ auto& self,
+ const GrFragmentProcessor& fp,
+ bool hasPerspective,
+ const GrFragmentProcessor* lastMatrixFP = nullptr,
+ int lastMatrixTraversalIndex = -1,
+ BaseCoord baseCoord = BaseCoord::kLocal) mutable -> void {
+ ++traversalIndex;
+ switch (fp.sampleUsage().kind()) {
+ case SkSL::SampleUsage::Kind::kNone:
+ // This should only happen at the root. Otherwise how did this FP get added?
+ SkASSERT(!fp.parent());
+ break;
+ case SkSL::SampleUsage::Kind::kPassThrough:
+ break;
+ case SkSL::SampleUsage::Kind::kUniformMatrix:
+ // Update tracking of last matrix and matrix props.
+ hasPerspective |= fp.sampleUsage().hasPerspective();
+ lastMatrixFP = &fp;
+ lastMatrixTraversalIndex = traversalIndex;
+ break;
+ case SkSL::SampleUsage::Kind::kFragCoord:
+ hasPerspective = positionVar.getType() == kFloat3_GrSLType;
+ lastMatrixFP = nullptr;
+ lastMatrixTraversalIndex = -1;
+ baseCoord = BaseCoord::kPosition;
+ break;
+ case SkSL::SampleUsage::Kind::kExplicit:
+ baseCoord = BaseCoord::kNone;
+ break;
+ }
+
+ auto& [varyingFSVar, hasCoordsParam] = result[&fp];
+ hasCoordsParam = fp.usesSampleCoordsDirectly();
+
+ // We add a varying if we're in a chain of matrices multiplied by local or device coords.
+ // If the coord is the untransformed local coord we add a varying. We don't if it is
+ // untransformed device coords since it doesn't save us anything over "sk_FragCoord.xy". Of
+ // course, if the FP doesn't directly use its coords then we don't add a varying.
+ if (fp.usesSampleCoordsDirectly() &&
+ (baseCoord == BaseCoord::kLocal ||
+ (baseCoord == BaseCoord::kPosition && lastMatrixFP && canUsePosition))) {
+ // Associate the varying with the highest possible node in the FP tree that shares the
+ // same coordinates so that multiple FPs in a subtree can share. If there are no matrix
+ // sample nodes on the way up the tree then directly use the local coord.
+ if (!lastMatrixFP) {
+ varyingFSVar = baseLocalCoordFSVar();
+ } else {
+ // If there is an already a varying that incorporates all matrices from the root to
+ // lastMatrixFP just use it. Otherwise, we add it.
+ auto& [varying, inputCoords, varyingIdx] = fTransformVaryingsMap[lastMatrixFP];
+ if (varying.type() == kVoid_GrSLType) {
+ varying = GrGLSLVarying(hasPerspective ? kFloat3_GrSLType : kFloat2_GrSLType);
+ SkString strVaryingName = SkStringPrintf("TransformedCoords_%d",
+ lastMatrixTraversalIndex);
+ varyingHandler->addVarying(strVaryingName.c_str(), &varying);
+ inputCoords = baseCoord == BaseCoord::kLocal ? localCoordsVar : positionVar;
+ varyingIdx = lastMatrixTraversalIndex;
+ }
+ SkASSERT(varyingIdx == lastMatrixTraversalIndex);
+ // The FP will use the varying in the fragment shader as its coords.
+ varyingFSVar = varying.fsInVar();
+ }
+ hasCoordsParam = false;
+ }
+
+ for (int c = 0; c < fp.numChildProcessors(); ++c) {
+ if (auto* child = fp.childProcessor(c)) {
+ self(self,
+ *child,
+ hasPerspective,
+ lastMatrixFP,
+ lastMatrixTraversalIndex,
+ baseCoord);
+ // If we have a varying then we never need a param. Otherwise, if one of our
+ // children takes a non-explicit coord then we'll need our coord.
+ hasCoordsParam |= varyingFSVar.getType() == kVoid_GrSLType &&
+ !child->sampleUsage().isExplicit() &&
+ !child->sampleUsage().isFragCoord() &&
+ result[child].hasCoordsParam;
+ }
+ }
+ };
+
+ bool hasPerspective = GrSLTypeVecLength(localCoordsVar.getType()) == 3;
+ for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
+ liftTransforms(liftTransforms, pipeline.getFragmentProcessor(i), hasPerspective);
+ }
+ return result;
+}
+
+void ProgramImpl::emitTransformCode(GrGLSLVertexBuilder* vb, GrGLSLUniformHandler* uniformHandler) {
+ // Because descendant varyings may be computed using the varyings of ancestor FPs we make
+ // sure to visit the varyings according to FP pre-order traversal by dumping them into a
+ // priority queue.
+ using FPAndInfo = std::tuple<const GrFragmentProcessor*, TransformInfo>;
+ auto compare = [](const FPAndInfo& a, const FPAndInfo& b) {
+ return std::get<1>(a).traversalOrder > std::get<1>(b).traversalOrder;
+ };
+ std::priority_queue<FPAndInfo, std::vector<FPAndInfo>, decltype(compare)> pq(compare);
+ std::for_each(fTransformVaryingsMap.begin(), fTransformVaryingsMap.end(), [&pq](auto entry) {
+ pq.push(entry);
+ });
+ for (; !pq.empty(); pq.pop()) {
+ const auto& [fp, info] = pq.top();
+ // If we recorded a transform info, its sample matrix must be uniform
+ SkASSERT(fp->sampleUsage().isUniformMatrix());
+ GrShaderVar uniform = uniformHandler->liftUniformToVertexShader(
+ *fp->parent(), SkString(SkSL::SampleUsage::MatrixUniformName()));
+ // Start with this matrix and accumulate additional matrices as we walk up the FP tree
+ // to either the base coords or an ancestor FP that has an associated varying.
+ SkString transformExpression = uniform.getName();
+
+ // If we hit an ancestor with a varying on our walk up then save off the varying as the
+ // input to our accumulated transformExpression. Start off assuming we'll reach the root.
+ GrShaderVar inputCoords = info.inputCoords;
+
+ for (const auto* base = fp->parent(); base; base = base->parent()) {
+ if (auto iter = fTransformVaryingsMap.find(base); iter != fTransformVaryingsMap.end()) {
+ // Can stop here, as this varying already holds all transforms from higher FPs
+ // We'll apply the residual transformExpression we've accumulated up from our
+ // starting FP to this varying.
+ inputCoords = iter->second.varying.vsOutVar();
+ break;
+ } else if (base->sampleUsage().isUniformMatrix()) {
+ // Accumulate any matrices along the path to either the original local/device coords
+ // or a parent varying. Getting here means this FP was sampled with a uniform matrix
+ // but all uses of coords below here in the FP hierarchy are beneath additional
+ // matrix samples and thus this node wasn't assigned a varying.
+ GrShaderVar parentUniform = uniformHandler->liftUniformToVertexShader(
+ *base->parent(), SkString(SkSL::SampleUsage::MatrixUniformName()));
+ transformExpression.appendf(" * %s", parentUniform.getName().c_str());
+ } else if (base->sampleUsage().isFragCoord()) {
+ // Our chain of matrices starts here and is based on the device space position.
+ break;
+ } else {
+ // This intermediate FP is just a pass through and doesn't need to be built
+ // in to the expression, but we must visit its parents in case they add transforms.
+ SkASSERT(base->sampleUsage().isPassThrough() || !base->sampleUsage().isSampled());
+ }
+ }
+
+ SkString inputStr;
+ if (inputCoords.getType() == kFloat2_GrSLType) {
+ inputStr = SkStringPrintf("%s.xy1", inputCoords.getName().c_str());
+ } else {
+ SkASSERT(inputCoords.getType() == kFloat3_GrSLType);
+ inputStr = inputCoords.getName();
+ }
+
+ vb->codeAppend("{\n");
+ if (info.varying.type() == kFloat2_GrSLType) {
+ if (vb->getProgramBuilder()->shaderCaps()->nonsquareMatrixSupport()) {
+ vb->codeAppendf("%s = float3x2(%s) * %s",
+ info.varying.vsOut(),
+ transformExpression.c_str(),
+ inputStr.c_str());
+ } else {
+ vb->codeAppendf("%s = (%s * %s).xy",
+ info.varying.vsOut(),
+ transformExpression.c_str(),
+ inputStr.c_str());
+ }
+ } else {
+ SkASSERT(info.varying.type() == kFloat3_GrSLType);
+ vb->codeAppendf("%s = %s * %s",
+ info.varying.vsOut(),
+ transformExpression.c_str(),
+ inputStr.c_str());
+ }
+ vb->codeAppend(";\n");
+ vb->codeAppend("}\n");
+ }
+ // We don't need this map anymore.
+ fTransformVaryingsMap.clear();
+}
+
+void ProgramImpl::setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const char* outputName,
+ UniformHandle* colorUniform) {
+ SkASSERT(colorUniform);
+ const char* stagedLocalVarName;
+ *colorUniform = uniformHandler->addUniform(nullptr,
+ kFragment_GrShaderFlag,
+ kHalf4_GrSLType,
+ "Color",
+ &stagedLocalVarName);
+ fragBuilder->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
+ if (fragBuilder->getProgramBuilder()->shaderCaps()->mustObfuscateUniformColor()) {
+ fragBuilder->codeAppendf("%s = max(%s, half4(0));", outputName, outputName);
+ }
+}
+
+void ProgramImpl::SetTransform(const GrGLSLProgramDataManager& pdman,
+ const GrShaderCaps& shaderCaps,
+ const UniformHandle& uniform,
+ const SkMatrix& matrix,
+ SkMatrix* state) {
+ if (!uniform.isValid() || (state && SkMatrixPriv::CheapEqual(*state, matrix))) {
+ // No update needed
+ return;
+ }
+ if (state) {
+ *state = matrix;
+ }
+ if (matrix.isScaleTranslate() && !shaderCaps.reducedShaderMode()) {
+ // ComputeMatrixKey and writeX() assume the uniform is a float4 (can't assert since nothing
+ // is exposed on a handle, but should be caught lower down).
+ float values[4] = {matrix.getScaleX(), matrix.getTranslateX(),
+ matrix.getScaleY(), matrix.getTranslateY()};
+ pdman.set4fv(uniform, 1, values);
+ } else {
+ pdman.setSkMatrix(uniform, matrix);
+ }
+}
+
+static void write_passthrough_vertex_position(GrGLSLVertexBuilder* vertBuilder,
+ const GrShaderVar& inPos,
+ GrShaderVar* outPos) {
+ SkASSERT(inPos.getType() == kFloat3_GrSLType || inPos.getType() == kFloat2_GrSLType);
+ SkString outName = vertBuilder->newTmpVarName(inPos.getName().c_str());
+ outPos->set(inPos.getType(), outName.c_str());
+ vertBuilder->codeAppendf("float%d %s = %s;",
+ GrSLTypeVecLength(inPos.getType()),
+ outName.c_str(),
+ inPos.getName().c_str());
+}
+
+static void write_vertex_position(GrGLSLVertexBuilder* vertBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderCaps& shaderCaps,
+ const GrShaderVar& inPos,
+ const SkMatrix& matrix,
+ const char* matrixName,
+ GrShaderVar* outPos,
+ ProgramImpl::UniformHandle* matrixUniform) {
+ SkASSERT(inPos.getType() == kFloat3_GrSLType || inPos.getType() == kFloat2_GrSLType);
+ SkString outName = vertBuilder->newTmpVarName(inPos.getName().c_str());
+
+ if (matrix.isIdentity() && !shaderCaps.reducedShaderMode()) {
+ write_passthrough_vertex_position(vertBuilder, inPos, outPos);
+ return;
+ }
+ SkASSERT(matrixUniform);
+
+ bool useCompactTransform = matrix.isScaleTranslate() && !shaderCaps.reducedShaderMode();
+ const char* mangledMatrixName;
+ *matrixUniform = uniformHandler->addUniform(nullptr,
+ kVertex_GrShaderFlag,
+ useCompactTransform ? kFloat4_GrSLType
+ : kFloat3x3_GrSLType,
+ matrixName,
+ &mangledMatrixName);
+
+ if (inPos.getType() == kFloat3_GrSLType) {
+ // A float3 stays a float3 whether or not the matrix adds perspective
+ if (useCompactTransform) {
+ vertBuilder->codeAppendf("float3 %s = %s.xz1 * %s + %s.yw0;\n",
+ outName.c_str(),
+ mangledMatrixName,
+ inPos.getName().c_str(),
+ mangledMatrixName);
+ } else {
+ vertBuilder->codeAppendf("float3 %s = %s * %s;\n",
+ outName.c_str(),
+ mangledMatrixName,
+ inPos.getName().c_str());
+ }
+ outPos->set(kFloat3_GrSLType, outName.c_str());
+ return;
+ }
+ if (matrix.hasPerspective()) {
+ // A float2 is promoted to a float3 if we add perspective via the matrix
+ SkASSERT(!useCompactTransform);
+ vertBuilder->codeAppendf("float3 %s = (%s * %s.xy1);",
+ outName.c_str(),
+ mangledMatrixName,
+ inPos.getName().c_str());
+ outPos->set(kFloat3_GrSLType, outName.c_str());
+ return;
+ }
+ if (useCompactTransform) {
+ vertBuilder->codeAppendf("float2 %s = %s.xz * %s + %s.yw;\n",
+ outName.c_str(),
+ mangledMatrixName,
+ inPos.getName().c_str(),
+ mangledMatrixName);
+ } else if (shaderCaps.nonsquareMatrixSupport()) {
+ vertBuilder->codeAppendf("float2 %s = float3x2(%s) * %s.xy1;\n",
+ outName.c_str(),
+ mangledMatrixName,
+ inPos.getName().c_str());
+ } else {
+ vertBuilder->codeAppendf("float2 %s = (%s * %s.xy1).xy;\n",
+ outName.c_str(),
+ mangledMatrixName,
+ inPos.getName().c_str());
+ }
+ outPos->set(kFloat2_GrSLType, outName.c_str());
+}
+
+void ProgramImpl::WriteOutputPosition(GrGLSLVertexBuilder* vertBuilder,
+ GrGPArgs* gpArgs,
+ const char* posName) {
+ // writeOutputPosition assumes the incoming pos name points to a float2 variable
+ GrShaderVar inPos(posName, kFloat2_GrSLType);
+ write_passthrough_vertex_position(vertBuilder, inPos, &gpArgs->fPositionVar);
+}
+
+void ProgramImpl::WriteOutputPosition(GrGLSLVertexBuilder* vertBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderCaps& shaderCaps,
+ GrGPArgs* gpArgs,
+ const char* posName,
+ const SkMatrix& mat,
+ UniformHandle* viewMatrixUniform) {
+ GrShaderVar inPos(posName, kFloat2_GrSLType);
+ write_vertex_position(vertBuilder,
+ uniformHandler,
+ shaderCaps,
+ inPos,
+ mat,
+ "viewMatrix",
+ &gpArgs->fPositionVar,
+ viewMatrixUniform);
+}
+
+void ProgramImpl::WriteLocalCoord(GrGLSLVertexBuilder* vertBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderCaps& shaderCaps,
+ GrGPArgs* gpArgs,
+ GrShaderVar localVar,
+ const SkMatrix& localMatrix,
+ UniformHandle* localMatrixUniform) {
+ write_vertex_position(vertBuilder,
+ uniformHandler,
+ shaderCaps,
+ localVar,
+ localMatrix,
+ "localMatrix",
+ &gpArgs->fLocalCoordVar,
+ localMatrixUniform);
+}
diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h
index 37138f9..733b5ad 100644
--- a/src/gpu/GrGeometryProcessor.h
+++ b/src/gpu/GrGeometryProcessor.h
@@ -9,12 +9,23 @@
#define GrGeometryProcessor_DEFINED
#include "src/gpu/GrColor.h"
+#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrNonAtomicRef.h"
#include "src/gpu/GrProcessor.h"
+#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/GrShaderVar.h"
#include "src/gpu/GrSwizzle.h"
+#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
+#include "src/gpu/glsl/GrGLSLUniformHandler.h"
+#include "src/gpu/glsl/GrGLSLVarying.h"
+#include <unordered_map>
+
+class GrGLSLFPFragmentBuilder;
+class GrGLSLGeometryBuilder;
+class GrGLSLVaryingHandler;
class GrGLSLUniformHandler;
+class GrGLSLVertexBuilder;
/**
* The GrGeometryProcessor represents some kind of geometric primitive. This includes the shape
@@ -273,6 +284,216 @@
//////////////////////////////////////////////////////////////////////////////
+class GrGeometryProcessor::ProgramImpl {
+public:
+ using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+ /**
+ * Struct of optional varying that replaces the input coords and bool indicating whether the FP
+ * should take a coord param as an argument. The latter may be false if the coords are simply
+ * unused or if the GP has lifted their computation to a varying emitted by the VS.
+ */
+ struct FPCoords {GrShaderVar coordsVarying; bool hasCoordsParam;};
+ using FPCoordsMap = std::unordered_map<const GrFragmentProcessor*, FPCoords>;
+
+ virtual ~ProgramImpl() = default;
+
+ struct EmitArgs {
+ EmitArgs(GrGLSLVertexBuilder* vertBuilder,
+ GrGLSLGeometryBuilder* geomBuilder,
+ GrGLSLFPFragmentBuilder* fragBuilder,
+ GrGLSLVaryingHandler* varyingHandler,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderCaps* caps,
+ const GrGeometryProcessor& geomProc,
+ const char* outputColor,
+ const char* outputCoverage,
+ const SamplerHandle* texSamplers)
+ : fVertBuilder(vertBuilder)
+ , fGeomBuilder(geomBuilder)
+ , fFragBuilder(fragBuilder)
+ , fVaryingHandler(varyingHandler)
+ , fUniformHandler(uniformHandler)
+ , fShaderCaps(caps)
+ , fGeomProc(geomProc)
+ , fOutputColor(outputColor)
+ , fOutputCoverage(outputCoverage)
+ , fTexSamplers(texSamplers) {}
+ GrGLSLVertexBuilder* fVertBuilder;
+ GrGLSLGeometryBuilder* fGeomBuilder;
+ GrGLSLFPFragmentBuilder* fFragBuilder;
+ GrGLSLVaryingHandler* fVaryingHandler;
+ GrGLSLUniformHandler* fUniformHandler;
+ const GrShaderCaps* fShaderCaps;
+ const GrGeometryProcessor& fGeomProc;
+ const char* fOutputColor;
+ const char* fOutputCoverage;
+ const SamplerHandle* fTexSamplers;
+ };
+
+ /**
+ * Emits the code from this geometry processor into the shaders. For any FP in the pipeline that
+ * has its input coords implemented by the GP as a varying, the varying will be accessible in
+ * the returned map and should be used when the FP code is emitted.
+ **/
+ FPCoordsMap emitCode(EmitArgs&, const GrPipeline& pipeline);
+
+ /**
+ * Called after all effect emitCode() functions, to give the processor a chance to write out
+ * additional transformation code now that all uniforms have been emitted.
+ * It generates the final code for assigning transformed coordinates to the varyings recorded
+ * in the call to collectTransforms(). This must happen after FP code emission so that it has
+ * access to any uniforms the FPs registered for uniform sample matrix invocations.
+ */
+ void emitTransformCode(GrGLSLVertexBuilder* vb, GrGLSLUniformHandler* uniformHandler);
+
+ /**
+ * A ProgramImpl instance can be reused with any GrGeometryProcessor that produces the same key.
+ * This function reads data from a GrGeometryProcessor and updates any uniform variables
+ * required by the shaders created in emitCode(). The GrGeometryProcessor parameter is
+ * guaranteed to be of the same type and to have an identical processor key as the
+ * GrGeometryProcessor that created this ProgramImpl.
+ */
+ virtual void setData(const GrGLSLProgramDataManager&,
+ const GrShaderCaps&,
+ const GrGeometryProcessor&) = 0;
+
+ // We use these methods as a temporary back door to inject OpenGL tessellation code. Once
+ // tessellation is supported by SkSL we can remove these.
+ virtual SkString getTessControlShaderGLSL(const GrGeometryProcessor&,
+ const char* versionAndExtensionDecls,
+ const GrGLSLUniformHandler&,
+ const GrShaderCaps&) const {
+ SK_ABORT("Not implemented.");
+ }
+ virtual SkString getTessEvaluationShaderGLSL(const GrGeometryProcessor&,
+ const char* versionAndExtensionDecls,
+ const GrGLSLUniformHandler&,
+ const GrShaderCaps&) const {
+ SK_ABORT("Not implemented.");
+ }
+
+ // GPs that use writeOutputPosition and/or writeLocalCoord must incorporate the matrix type
+ // into their key, and should use this function or one of the other related helpers.
+ static uint32_t ComputeMatrixKey(const GrShaderCaps& caps, const SkMatrix& mat) {
+ if (!caps.reducedShaderMode()) {
+ if (mat.isIdentity()) {
+ return 0b00;
+ }
+ if (mat.isScaleTranslate()) {
+ return 0b01;
+ }
+ }
+ if (!mat.hasPerspective()) {
+ return 0b10;
+ }
+ return 0b11;
+ }
+
+ static uint32_t ComputeMatrixKeys(const GrShaderCaps& shaderCaps,
+ const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix) {
+ return (ComputeMatrixKey(shaderCaps, viewMatrix) << kMatrixKeyBits) |
+ ComputeMatrixKey(shaderCaps, localMatrix);
+ }
+
+ static uint32_t AddMatrixKeys(const GrShaderCaps& shaderCaps,
+ uint32_t flags,
+ const SkMatrix& viewMatrix,
+ const SkMatrix& localMatrix) {
+ // Shifting to make room for the matrix keys shouldn't lose bits
+ SkASSERT(((flags << (2 * kMatrixKeyBits)) >> (2 * kMatrixKeyBits)) == flags);
+ return (flags << (2 * kMatrixKeyBits)) |
+ ComputeMatrixKeys(shaderCaps, viewMatrix, localMatrix);
+ }
+ static constexpr int kMatrixKeyBits = 2;
+
+protected:
+ void setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const char* outputName,
+ UniformHandle* colorUniform);
+
+ // A helper for setting the matrix on a uniform handle initialized through
+ // writeOutputPosition or writeLocalCoord. Automatically handles elided uniforms,
+ // scale+translate matrices, and state tracking (if provided state pointer is non-null).
+ static void SetTransform(const GrGLSLProgramDataManager&,
+ const GrShaderCaps&,
+ const UniformHandle& uniform,
+ const SkMatrix& matrix,
+ SkMatrix* state = nullptr);
+
+ struct GrGPArgs {
+ // Used to specify the output variable used by the GP to store its device position. It can
+ // either be a float2 or a float3 (in order to handle perspective). The subclass sets this
+ // in its onEmitCode().
+ GrShaderVar fPositionVar;
+ // Used to specify the variable storing the draw's local coordinates. It can be either a
+ // float2, float3, or void. It can only be void when no FP needs local coordinates. This
+ // variable can be an attribute or local variable, but should not itself be a varying.
+ // ProgramImpl automatically determines if this must be passed to a FS.
+ GrShaderVar fLocalCoordVar;
+ };
+
+ // Helpers for adding code to write the transformed vertex position. The first simple version
+ // just writes a variable named by 'posName' into the position output variable with the
+ // assumption that the position is 2D. The second version transforms the input position by a
+ // view matrix and the output variable is 2D or 3D depending on whether the view matrix is
+ // perspective. Both versions declare the output position variable and will set
+ // GrGPArgs::fPositionVar.
+ static void WriteOutputPosition(GrGLSLVertexBuilder*, GrGPArgs*, const char* posName);
+ static void WriteOutputPosition(GrGLSLVertexBuilder*,
+ GrGLSLUniformHandler*,
+ const GrShaderCaps&,
+ GrGPArgs*,
+ const char* posName,
+ const SkMatrix& viewMatrix,
+ UniformHandle* viewMatrixUniform);
+
+ // Helper to transform an existing variable by a given local matrix (e.g. the inverse view
+ // matrix). It will declare the transformed local coord variable and will set
+ // GrGPArgs::fLocalCoordVar.
+ static void WriteLocalCoord(GrGLSLVertexBuilder*,
+ GrGLSLUniformHandler*,
+ const GrShaderCaps&,
+ GrGPArgs*,
+ GrShaderVar localVar,
+ const SkMatrix& localMatrix,
+ UniformHandle* localMatrixUniform);
+
+private:
+ virtual void onEmitCode(EmitArgs&, GrGPArgs*) = 0;
+
+ // Iterates over the FPs beginning with the passed iter to register additional varyings and
+ // uniforms to support VS-promoted local coord evaluation for the FPs.
+ //
+ // This must happen before FP code emission so that the FPs can find the appropriate varying
+ // handles they use in place of explicit coord sampling; it is automatically called after
+ // onEmitCode() returns using the value stored in GpArgs::fLocalCoordVar and
+ // GpArgs::fPositionVar.
+ FPCoordsMap collectTransforms(GrGLSLVertexBuilder* vb,
+ GrGLSLVaryingHandler* varyingHandler,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderVar& localCoordsVar,
+ const GrShaderVar& positionVar,
+ const GrPipeline& pipeline);
+ struct TransformInfo {
+ // The varying that conveys the coordinates to one or more FPs in the FS.
+ GrGLSLVarying varying;
+ // The coordinate to be transformed. varying is computed from this.
+ GrShaderVar inputCoords;
+ // Used to sort so that ancestor FP varyings are initialized before descendant FP varyings.
+ int traversalOrder;
+ };
+ // Populated by collectTransforms() for use in emitTransformCode(). When we lift the computation
+ // of a FP's input coord to a varying we propagate that varying up the FP tree to the highest
+ // node that shares the same coordinates. This allows multiple FPs in a subtree to share a
+ // varying.
+ std::unordered_map<const GrFragmentProcessor*, TransformInfo> fTransformVaryingsMap;
+};
+
+///////////////////////////////////////////////////////////////////////////
+
/**
* Used to capture the properties of the GrTextureProxies required/expected by a primitiveProcessor
* along with an associated GrSamplerState. The actual proxies used are stored in either the
diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp
index a8ebd02..8ef9f08 100644
--- a/src/gpu/GrProgramDesc.cpp
+++ b/src/gpu/GrProgramDesc.cpp
@@ -9,6 +9,7 @@
#include "include/private/SkChecksum.h"
#include "include/private/SkTo.h"
+#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrProcessor.h"
@@ -17,7 +18,6 @@
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/GrTexture.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
enum {
diff --git a/src/gpu/GrXferProcessor.cpp b/src/gpu/GrXferProcessor.cpp
index d6574f7..c36048a 100644
--- a/src/gpu/GrXferProcessor.cpp
+++ b/src/gpu/GrXferProcessor.cpp
@@ -9,6 +9,8 @@
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrPipeline.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
GrXferProcessor::GrXferProcessor(ClassID classID)
: INHERITED(classID)
@@ -184,3 +186,124 @@
return GrPorterDuffXPFactory::MakeSrcOverXferProcessor(color, coverage, caps);
}
}
+
+//////////////////////////////////////////////////////////////////////////////
+
+using ProgramImpl = GrXferProcessor::ProgramImpl;
+
+// This is only called for cases where we are doing LCD coverage and not using in shader blending.
+// For these cases we assume the the src alpha is 1, thus we can just use the max for the alpha
+// coverage since src alpha will always be greater than or equal to dst alpha.
+static void adjust_for_lcd_coverage(GrGLSLXPFragmentBuilder* fragBuilder,
+ const char* srcCoverage,
+ const GrXferProcessor& proc) {
+ if (srcCoverage && proc.isLCD()) {
+ fragBuilder->codeAppendf("%s.a = max(max(%s.r, %s.g), %s.b);",
+ srcCoverage,
+ srcCoverage,
+ srcCoverage,
+ srcCoverage);
+ }
+}
+
+void ProgramImpl::emitCode(const EmitArgs& args) {
+ if (!args.fXP.willReadDstColor()) {
+ adjust_for_lcd_coverage(args.fXPFragBuilder, args.fInputCoverage, args.fXP);
+ this->emitOutputsForBlendState(args);
+ } else {
+ GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
+ GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
+ const char* dstColor = fragBuilder->dstColor();
+
+ bool needsLocalOutColor = false;
+
+ if (args.fDstTextureSamplerHandle.isValid()) {
+ if (args.fInputCoverage) {
+ // We don't think any shaders actually output negative coverage, but just as a
+ // safety check for floating point precision errors, we compare with <= here. We
+ // just check the RGB values of the coverage, since the alpha may not have been set
+ // when using LCD. If we are using single-channel coverage, alpha will be equal to
+ // RGB anyway.
+ //
+ // The discard here also helps for batching text-draws together, which need to read
+ // from a dst copy for blends. However, this only helps the case where the outer
+ // bounding boxes of each letter overlap and not two actually parts of the text.
+ fragBuilder->codeAppendf("if (all(lessThanEqual(%s.rgb, half3(0)))) {"
+ " discard;"
+ "}",
+ args.fInputCoverage);
+ }
+ } else {
+ needsLocalOutColor = args.fShaderCaps->requiresLocalOutputColorForFBFetch();
+ }
+
+ const char* outColor = "_localColorOut";
+ if (!needsLocalOutColor) {
+ outColor = args.fOutputPrimary;
+ } else {
+ fragBuilder->codeAppendf("half4 %s;", outColor);
+ }
+
+ this->emitBlendCodeForDstRead(fragBuilder,
+ uniformHandler,
+ args.fInputColor,
+ args.fInputCoverage,
+ dstColor,
+ outColor,
+ args.fOutputSecondary,
+ args.fXP);
+ if (needsLocalOutColor) {
+ fragBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, outColor);
+ }
+ }
+
+ // Swizzle the fragment shader outputs if necessary.
+ this->emitWriteSwizzle(args.fXPFragBuilder,
+ args.fWriteSwizzle,
+ args.fOutputPrimary,
+ args.fOutputSecondary);
+}
+
+void ProgramImpl::emitWriteSwizzle(GrGLSLXPFragmentBuilder* x,
+ const GrSwizzle& swizzle,
+ const char* outColor,
+ const char* outColorSecondary) const {
+ if (GrSwizzle::RGBA() != swizzle) {
+ x->codeAppendf("%s = %s.%s;", outColor, outColor, swizzle.asString().c_str());
+ if (outColorSecondary) {
+ x->codeAppendf("%s = %s.%s;",
+ outColorSecondary,
+ outColorSecondary,
+ swizzle.asString().c_str());
+ }
+ }
+}
+
+void ProgramImpl::setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp) {
+ this->onSetData(pdm, xp);
+}
+
+void ProgramImpl::DefaultCoverageModulation(GrGLSLXPFragmentBuilder* fragBuilder,
+ const char* srcCoverage,
+ const char* dstColor,
+ const char* outColor,
+ const char* outColorSecondary,
+ const GrXferProcessor& proc) {
+ if (srcCoverage) {
+ if (proc.isLCD()) {
+ fragBuilder->codeAppendf("half3 lerpRGB = mix(%s.aaa, %s.aaa, %s.rgb);",
+ dstColor,
+ outColor,
+ srcCoverage);
+ }
+ fragBuilder->codeAppendf("%s = %s * %s + (half4(1.0) - %s) * %s;",
+ outColor,
+ srcCoverage,
+ outColor,
+ srcCoverage,
+ dstColor);
+ if (proc.isLCD()) {
+ fragBuilder->codeAppendf("%s.a = max(max(lerpRGB.r, lerpRGB.b), lerpRGB.g);", outColor);
+ }
+ }
+}
diff --git a/src/gpu/GrXferProcessor.h b/src/gpu/GrXferProcessor.h
index 3dea132..439895d 100644
--- a/src/gpu/GrXferProcessor.h
+++ b/src/gpu/GrXferProcessor.h
@@ -14,8 +14,10 @@
#include "src/gpu/GrProcessor.h"
#include "src/gpu/GrProcessorAnalysis.h"
#include "src/gpu/GrSurfaceProxyView.h"
+#include "src/gpu/glsl/GrGLSLUniformHandler.h"
-class GrProcessorSet;
+class GrGLSLXPFragmentBuilder;
+class GrGLSLProgramDataManager;
class GrShaderCaps;
/**
@@ -275,4 +277,106 @@
GR_MAKE_BITFIELD_CLASS_OPS(GrXPFactory::AnalysisProperties)
+//////////////////////////////////////////////////////////////////////////////
+
+class GrXferProcessor::ProgramImpl {
+public:
+ virtual ~ProgramImpl() = default;
+
+ using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
+
+ struct EmitArgs {
+ EmitArgs(GrGLSLXPFragmentBuilder* fragBuilder,
+ GrGLSLUniformHandler* uniformHandler,
+ const GrShaderCaps* caps,
+ const GrXferProcessor& xp,
+ const char* inputColor,
+ const char* inputCoverage,
+ const char* outputPrimary,
+ const char* outputSecondary,
+ const SamplerHandle dstTextureSamplerHandle,
+ GrSurfaceOrigin dstTextureOrigin,
+ const GrSwizzle& writeSwizzle)
+ : fXPFragBuilder(fragBuilder)
+ , fUniformHandler(uniformHandler)
+ , fShaderCaps(caps)
+ , fXP(xp)
+ , fInputColor(inputColor ? inputColor : "half4(1.0)")
+ , fInputCoverage(inputCoverage)
+ , fOutputPrimary(outputPrimary)
+ , fOutputSecondary(outputSecondary)
+ , fDstTextureSamplerHandle(dstTextureSamplerHandle)
+ , fDstTextureOrigin(dstTextureOrigin)
+ , fWriteSwizzle(writeSwizzle) {}
+ GrGLSLXPFragmentBuilder* fXPFragBuilder;
+ GrGLSLUniformHandler* fUniformHandler;
+ const GrShaderCaps* fShaderCaps;
+ const GrXferProcessor& fXP;
+ const char* fInputColor;
+ const char* fInputCoverage;
+ const char* fOutputPrimary;
+ const char* fOutputSecondary;
+ const SamplerHandle fDstTextureSamplerHandle;
+ GrSurfaceOrigin fDstTextureOrigin;
+ GrSwizzle fWriteSwizzle;
+ };
+ /**
+ * This is similar to emitCode() in the base class, except it takes a full shader builder.
+ * This allows the effect subclass to emit vertex code.
+ */
+ void emitCode(const EmitArgs&);
+
+ /** A ProgramImpl instance can be reused with any GrXferProcessor that produces the same key.
+ This function reads data from a GrXferProcessor and uploads any uniform variables required
+ by the shaders created in emitCode(). The GrXferProcessor parameter is guaranteed to be of
+ the same type that created this ProgramImpl and to have an identical processor key as the
+ one that created this ProgramImpl. This function calls onSetData on the subclass of
+ ProgramImpl.
+ */
+ void setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp);
+
+protected:
+ ProgramImpl() = default;
+
+ static void DefaultCoverageModulation(GrGLSLXPFragmentBuilder* fragBuilder,
+ const char* srcCoverage,
+ const char* dstColor,
+ const char* outColor,
+ const char* outColorSecondary,
+ const GrXferProcessor& proc);
+
+private:
+ /**
+ * Called by emitCode() when the XP will not be performing a dst read. This method is
+ * responsible for both blending and coverage. A subclass only needs to implement this method if
+ * it can construct a GrXferProcessor that will not read the dst color.
+ */
+ virtual void emitOutputsForBlendState(const EmitArgs&) {
+ SK_ABORT("emitOutputsForBlendState not implemented.");
+ }
+
+ /**
+ * Called by emitCode() when the XP will perform a dst read. This method only needs to supply
+ * the blending logic. The base class applies coverage. A subclass only needs to implement this
+ * method if it can construct a GrXferProcessor that reads the dst color.
+ */
+ virtual void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder*,
+ GrGLSLUniformHandler*,
+ const char* srcColor,
+ const char* srcCoverage,
+ const char* dstColor,
+ const char* outColor,
+ const char* outColorSecondary,
+ const GrXferProcessor&) {
+ SK_ABORT("emitBlendCodeForDstRead not implemented.");
+ }
+
+ virtual void emitWriteSwizzle(GrGLSLXPFragmentBuilder*,
+ const GrSwizzle&,
+ const char* outColor,
+ const char* outColorSecondary) const;
+
+ virtual void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) {}
+};
+
#endif
diff --git a/src/gpu/d3d/GrD3DPipelineState.cpp b/src/gpu/d3d/GrD3DPipelineState.cpp
index a23b2f7..9db5ddf 100644
--- a/src/gpu/d3d/GrD3DPipelineState.cpp
+++ b/src/gpu/d3d/GrD3DPipelineState.cpp
@@ -8,17 +8,17 @@
#include "src/gpu/d3d/GrD3DPipelineState.h"
#include "include/private/SkTemplates.h"
+#include "src/gpu/GrFragmentProcessor.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrStencilSettings.h"
+#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/d3d/GrD3DBuffer.h"
#include "src/gpu/d3d/GrD3DGpu.h"
#include "src/gpu/d3d/GrD3DPipeline.h"
#include "src/gpu/d3d/GrD3DRootSignature.h"
#include "src/gpu/d3d/GrD3DTexture.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
GrD3DPipelineState::GrD3DPipelineState(
sk_sp<GrD3DPipeline> pipeline,
diff --git a/src/gpu/effects/GrAtlasedShaderHelpers.h b/src/gpu/effects/GrAtlasedShaderHelpers.h
index 960a57a..ec45610 100644
--- a/src/gpu/effects/GrAtlasedShaderHelpers.h
+++ b/src/gpu/effects/GrAtlasedShaderHelpers.h
@@ -11,7 +11,6 @@
#include "src/gpu/GrDrawOpAtlas.h"
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index 3af009e..150992b 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -8,7 +8,6 @@
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/effects/GrBezierEffect.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
diff --git a/src/gpu/effects/GrBicubicEffect.h b/src/gpu/effects/GrBicubicEffect.h
index a98a6e5..c193300 100644
--- a/src/gpu/effects/GrBicubicEffect.h
+++ b/src/gpu/effects/GrBicubicEffect.h
@@ -8,7 +8,7 @@
#ifndef GrBicubicTextureEffect_DEFINED
#define GrBicubicTextureEffect_DEFINED
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/GrFragmentProcessor.h"
class GrInvariantOutput;
diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp
index 4961b8a..1603e8d 100644
--- a/src/gpu/effects/GrBitmapTextGeoProc.cpp
+++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp
@@ -12,7 +12,6 @@
#include "src/gpu/GrTexture.h"
#include "src/gpu/effects/GrAtlasedShaderHelpers.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
@@ -70,7 +69,7 @@
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
if (btgp.hasVertexColor()) {
- varyingHandler->addPassThroughAttribute(btgp.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(btgp.fInColor.asShaderVar(), args.fOutputColor);
} else {
this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
&fColorUniform);
diff --git a/src/gpu/effects/GrBlendFragmentProcessor.cpp b/src/gpu/effects/GrBlendFragmentProcessor.cpp
index 833ade4..75defca 100644
--- a/src/gpu/effects/GrBlendFragmentProcessor.cpp
+++ b/src/gpu/effects/GrBlendFragmentProcessor.cpp
@@ -10,7 +10,6 @@
#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/glsl/GrGLSLBlend.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
// Some of the CPU implementations of blend modes differ from the GPU enough that
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index 9e1a44f..8a8fe39 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -7,7 +7,6 @@
#include "src/core/SkPathPriv.h"
#include "src/gpu/effects/GrConvexPolyEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
diff --git a/src/gpu/effects/GrCoverageSetOpXP.cpp b/src/gpu/effects/GrCoverageSetOpXP.cpp
index 64d7db0..9bf5bd4 100644
--- a/src/gpu/effects/GrCoverageSetOpXP.cpp
+++ b/src/gpu/effects/GrCoverageSetOpXP.cpp
@@ -5,15 +5,15 @@
* found in the LICENSE file.
*/
+#include "src/gpu/effects/GrCoverageSetOpXP.h"
+
#include "src/gpu/GrCaps.h"
#include "src/gpu/GrColor.h"
#include "src/gpu/GrPipeline.h"
-#include "src/gpu/GrProcessor.h"
-#include "src/gpu/effects/GrCoverageSetOpXP.h"
+#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/glsl/GrGLSLBlend.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
class CoverageSetOpXP : public GrXferProcessor {
public:
diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp
index 9ef3961..043485a 100644
--- a/src/gpu/effects/GrCustomXfermode.cpp
+++ b/src/gpu/effects/GrCustomXfermode.cpp
@@ -12,12 +12,11 @@
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/GrShaderCaps.h"
+#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/glsl/GrGLSLBlend.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
bool GrCustomXfermode::IsSupportedMode(SkBlendMode mode) {
return (int)mode > (int)SkBlendMode::kLastCoeffMode &&
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp
index d59e920..cab527e 100644
--- a/src/gpu/effects/GrDisableColorXP.cpp
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -5,13 +5,14 @@
* found in the LICENSE file.
*/
+#include "src/gpu/effects/GrDisableColorXP.h"
+
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/GrShaderCaps.h"
-#include "src/gpu/effects/GrDisableColorXP.h"
+#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
/**
* This xfer processor disables color writing. Thus color and coverage and ignored and no blending
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
index e4f0e96..d125cc6 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
@@ -12,7 +12,6 @@
#include "src/gpu/effects/GrAtlasedShaderHelpers.h"
#include "src/gpu/effects/GrDistanceFieldGeoProc.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
@@ -78,7 +77,8 @@
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;\n", args.fOutputColor);
- varyingHandler->addPassThroughAttribute(dfTexEffect.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(dfTexEffect.fInColor.asShaderVar(),
+ args.fOutputColor);
// Setup position
gpArgs->fPositionVar = dfTexEffect.fInPosition.asShaderVar();
@@ -366,7 +366,8 @@
// setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
- varyingHandler->addPassThroughAttribute(dfPathEffect.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(dfPathEffect.fInColor.asShaderVar(),
+ args.fOutputColor);
if (dfPathEffect.fMatrix.hasPerspective()) {
// Setup position (output position is transformed, local coords are pass through)
@@ -624,7 +625,8 @@
// setup pass through color
fragBuilder->codeAppendf("half4 %s;\n", args.fOutputColor);
- varyingHandler->addPassThroughAttribute(dfTexEffect.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(dfTexEffect.fInColor.asShaderVar(),
+ args.fOutputColor);
// Setup position
gpArgs->fPositionVar = dfTexEffect.fInPosition.asShaderVar();
diff --git a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
index 755b372..ed4b5a5 100644
--- a/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
+++ b/src/gpu/effects/GrGaussianConvolutionFragmentProcessor.cpp
@@ -11,7 +11,6 @@
#include "src/gpu/GrTexture.h"
#include "src/gpu/GrTextureProxy.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
index ae16a49..ba8b973 100644
--- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp
+++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp
@@ -15,7 +15,6 @@
#include "src/gpu/GrThreadSafeCache.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
diff --git a/src/gpu/effects/GrMatrixEffect.cpp b/src/gpu/effects/GrMatrixEffect.cpp
index 8d2ad7b..5ba70ae 100644
--- a/src/gpu/effects/GrMatrixEffect.cpp
+++ b/src/gpu/effects/GrMatrixEffect.cpp
@@ -9,7 +9,6 @@
#include "src/gpu/GrTexture.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/sksl/SkSLUtil.h"
diff --git a/src/gpu/effects/GrPorterDuffXferProcessor.cpp b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
index 99dfad3..d9da5aa 100644
--- a/src/gpu/effects/GrPorterDuffXferProcessor.cpp
+++ b/src/gpu/effects/GrPorterDuffXferProcessor.cpp
@@ -19,7 +19,6 @@
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
/**
* Wraps the shader outputs and HW blend state that comprise a Porter Duff blend mode with coverage.
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 03a651b..7b8258c 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -13,7 +13,6 @@
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/effects/GrConvexPolyEffect.h"
#include "src/gpu/effects/GrOvalEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
diff --git a/src/gpu/effects/GrShadowGeoProc.cpp b/src/gpu/effects/GrShadowGeoProc.cpp
index 3af4a84..4d2528f 100644
--- a/src/gpu/effects/GrShadowGeoProc.cpp
+++ b/src/gpu/effects/GrShadowGeoProc.cpp
@@ -9,7 +9,6 @@
#include "src/gpu/GrSurfaceProxyView.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
@@ -30,11 +29,12 @@
// emit attributes
varyingHandler->emitAttributes(rsgp);
fragBuilder->codeAppend("half3 shadowParams;");
- varyingHandler->addPassThroughAttribute(rsgp.inShadowParams(), "shadowParams");
+ varyingHandler->addPassThroughAttribute(rsgp.inShadowParams().asShaderVar(),
+ "shadowParams");
// setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
- varyingHandler->addPassThroughAttribute(rsgp.inColor(), args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(rsgp.inColor().asShaderVar(), args.fOutputColor);
// Setup position
WriteOutputPosition(vertBuilder, gpArgs, rsgp.inPosition().name());
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index 3db9740..3239ec4 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -15,14 +15,12 @@
#include "src/gpu/GrBaseContextPriv.h"
#include "src/gpu/GrColorInfo.h"
#include "src/gpu/GrTexture.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/sksl/SkSLUtil.h"
#include "src/sksl/codegen/SkSLPipelineStageCodeGenerator.h"
#include "src/sksl/ir/SkSLVarDeclarations.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
-#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
-
class GrSkSLFP::Impl : public ProgramImpl {
public:
void emitCode(EmitArgs& args) override {
diff --git a/src/gpu/effects/GrTextureEffect.h b/src/gpu/effects/GrTextureEffect.h
index 5b1c2d5..71c8040 100644
--- a/src/gpu/effects/GrTextureEffect.h
+++ b/src/gpu/effects/GrTextureEffect.h
@@ -12,7 +12,6 @@
#include "include/core/SkMatrix.h"
#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrSurfaceProxyView.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
class GrTextureEffect : public GrFragmentProcessor {
diff --git a/src/gpu/effects/GrYUVtoRGBEffect.cpp b/src/gpu/effects/GrYUVtoRGBEffect.cpp
index 69bb1ec..61abd4c 100644
--- a/src/gpu/effects/GrYUVtoRGBEffect.cpp
+++ b/src/gpu/effects/GrYUVtoRGBEffect.cpp
@@ -13,7 +13,6 @@
#include "src/gpu/GrYUVATextureProxies.h"
#include "src/gpu/effects/GrMatrixEffect.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/sksl/SkSLUtil.h"
diff --git a/src/gpu/gl/GrGLGpuProgramCache.cpp b/src/gpu/gl/GrGLGpuProgramCache.cpp
index 9ee1b80..dbdac14 100644
--- a/src/gpu/gl/GrGLGpuProgramCache.cpp
+++ b/src/gpu/gl/GrGLGpuProgramCache.cpp
@@ -12,10 +12,10 @@
#include "include/gpu/GrContextOptions.h"
#include "include/gpu/GrDirectContext.h"
#include "src/gpu/GrDirectContextPriv.h"
+#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/GrProgramDesc.h"
#include "src/gpu/gl/builders/GrGLProgramBuilder.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
struct GrGLGpu::ProgramCache::Entry {
Entry(sk_sp<GrGLProgram> program)
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 6c43a18..b590d8c 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -7,6 +7,8 @@
#include "src/gpu/gl/GrGLProgram.h"
+#include "src/gpu/GrFragmentProcessor.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/GrProgramInfo.h"
@@ -15,9 +17,6 @@
#include "src/gpu/effects/GrTextureEffect.h"
#include "src/gpu/gl/GrGLBuffer.h"
#include "src/gpu/gl/GrGLGpu.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
#include "src/sksl/SkSLCompiler.h"
#define GL_CALL(X) GR_GL_CALL(fGpu->glInterface(), X)
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index 3df3fe0..0a570f8 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -15,21 +15,21 @@
#include "src/core/SkWriteBuffer.h"
#include "src/gpu/GrAutoLocaleSetter.h"
#include "src/gpu/GrDirectContextPriv.h"
+#include "src/gpu/GrFragmentProcessor.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrPersistentCacheUtils.h"
#include "src/gpu/GrProgramDesc.h"
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/GrShaderUtils.h"
#include "src/gpu/GrSwizzle.h"
+#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/gl/GrGLGpu.h"
#include "src/gpu/gl/GrGLProgram.h"
#include "src/gpu/gl/builders/GrGLProgramBuilder.h"
#include <memory>
#include "src/gpu/gl/builders/GrGLShaderStringBuilder.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
deleted file mode 100644
index a9d4e81..0000000
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
-
-#include "src/gpu/GrFragmentProcessor.h"
-#include "src/gpu/GrProcessor.h"
-#include "src/gpu/GrShaderCaps.h"
-#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
-#include "src/gpu/glsl/GrGLSLUniformHandler.h"
-
-using ProgramImpl = GrFragmentProcessor::ProgramImpl;
-
-void ProgramImpl::setData(const GrGLSLProgramDataManager& pdman,
- const GrFragmentProcessor& processor) {
- this->onSetData(pdman, processor);
-}
-
-void ProgramImpl::emitChildFunctions(EmitArgs& args) {
- for (int i = 0; i < this->numChildProcessors(); ++i) {
- ProgramImpl* childGLSLFP = this->childProcessor(i);
- if (!childGLSLFP) {
- continue;
- }
-
- const GrFragmentProcessor* childFP = args.fFp.childProcessor(i);
- SkASSERT(childFP);
-
- EmitArgs childArgs(args.fFragBuilder,
- args.fUniformHandler,
- args.fShaderCaps,
- *childFP,
- childFP->isBlendFunction() ? "_src" : "_input",
- "_dst",
- "_coords");
- args.fFragBuilder->writeProcessorFunction(childGLSLFP, childArgs);
- }
-}
-
-SkString ProgramImpl::invokeChild(int childIndex,
- const char* inputColor,
- const char* destColor,
- EmitArgs& args,
- SkSL::String skslCoords) {
- SkASSERT(childIndex >= 0);
-
- if (!inputColor) {
- inputColor = args.fInputColor;
- }
-
- const GrFragmentProcessor* childProc = args.fFp.childProcessor(childIndex);
- if (!childProc) {
- // If no child processor is provided, return the input color as-is.
- return SkString(inputColor);
- }
-
- auto invocation = SkStringPrintf("%s(%s", this->childProcessor(childIndex)->functionName(),
- inputColor);
-
- if (childProc->isBlendFunction()) {
- if (!destColor) {
- destColor = args.fFp.isBlendFunction() ? args.fDestColor : "half4(1)";
- }
- invocation.appendf(", %s", destColor);
- }
-
- // Assert that the child has no sample matrix. A uniform matrix sample call would go through
- // invokeChildWithMatrix, not here.
- SkASSERT(!childProc->sampleUsage().isUniformMatrix());
-
- if (args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
- SkASSERT(!childProc->sampleUsage().isFragCoord() || skslCoords == "sk_FragCoord.xy");
- // The child's function takes a half4 color and a float2 coordinate
- invocation.appendf(", %s", skslCoords.empty() ? args.fSampleCoord : skslCoords.c_str());
- }
-
- invocation.append(")");
- return invocation;
-}
-
-SkString ProgramImpl::invokeChildWithMatrix(int childIndex,
- const char* inputColor,
- const char* destColor,
- EmitArgs& args) {
- SkASSERT(childIndex >= 0);
-
- if (!inputColor) {
- inputColor = args.fInputColor;
- }
-
- const GrFragmentProcessor* childProc = args.fFp.childProcessor(childIndex);
- if (!childProc) {
- // If no child processor is provided, return the input color as-is.
- return SkString(inputColor);
- }
-
- SkASSERT(childProc->sampleUsage().isUniformMatrix());
-
- // Every uniform matrix has the same (initial) name. Resolve that into the mangled name:
- GrShaderVar uniform = args.fUniformHandler->getUniformMapping(
- args.fFp, SkString(SkSL::SampleUsage::MatrixUniformName()));
- SkASSERT(uniform.getType() == kFloat3x3_GrSLType);
- const SkString& matrixName(uniform.getName());
-
- auto invocation = SkStringPrintf("%s(%s", this->childProcessor(childIndex)->functionName(),
- inputColor);
-
- if (childProc->isBlendFunction()) {
- if (!destColor) {
- destColor = args.fFp.isBlendFunction() ? args.fDestColor : "half4(1)";
- }
- invocation.appendf(", %s", destColor);
- }
-
- // Produce a string containing the call to the helper function. We have a uniform variable
- // containing our transform (matrixName). If the parent coords were produced by uniform
- // transforms, then the entire expression (matrixName * coords) is lifted to a vertex shader
- // and is stored in a varying. In that case, childProc will not be sampled explicitly, so its
- // function signature will not take in coords.
- //
- // In all other cases, we need to insert sksl to compute matrix * parent coords and then invoke
- // the function.
- if (args.fFragBuilder->getProgramBuilder()->fragmentProcessorHasCoordsParam(childProc)) {
- // Only check perspective for this specific matrix transform, not the aggregate FP property.
- // Any parent perspective will have already been applied when evaluated in the FS.
- if (childProc->sampleUsage().hasPerspective()) {
- invocation.appendf(", proj((%s) * %s.xy1)", matrixName.c_str(), args.fSampleCoord);
- } else if (args.fShaderCaps->nonsquareMatrixSupport()) {
- invocation.appendf(", float3x2(%s) * %s.xy1", matrixName.c_str(), args.fSampleCoord);
- } else {
- invocation.appendf(", ((%s) * %s.xy1).xy", matrixName.c_str(), args.fSampleCoord);
- }
- }
-
- invocation.append(")");
- return invocation;
-}
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
deleted file mode 100644
index 8839702..0000000
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGLSLFragmentProcessor_DEFINED
-#define GrGLSLFragmentProcessor_DEFINED
-
-#include "include/private/SkSLString.h"
-#include "src/gpu/GrFragmentProcessor.h"
-#include "src/gpu/GrShaderVar.h"
-#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
-#include "src/gpu/glsl/GrGLSLUniformHandler.h"
-
-class GrGLSLFPFragmentBuilder;
-
-class GrFragmentProcessor::ProgramImpl {
-public:
- ProgramImpl() = default;
-
- virtual ~ProgramImpl() = default;
-
- using UniformHandle = GrGLSLUniformHandler::UniformHandle;
- using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
-
- /** Called when the program stage should insert its code into the shaders. The code in each
- shader will be in its own block ({}) and so locally scoped names will not collide across
- stages.
-
- @param fragBuilder Interface used to emit code in the shaders.
- @param uniformHandler Interface used for accessing information about our uniforms
- @param caps The capabilities of the GPU which will render this FP
- @param fp The processor that generated this program stage.
- @param inputColor A half4 that holds the input color to the stage in the FS (or the
- source color, for blend processors). nullptr inputs are converted
- to "half4(1.0)" (solid white) during construction.
- TODO: Better system for communicating optimization info
- (e.g. input color is solid white, trans black, known to be opaque,
- etc.) that allows the processor to communicate back similar known
- info about its output.
- @param destColor A half4 that holds the dest color to the stage. Only meaningful
- when the "is blend processor" FP flag is set.
- @param sampleCoord The name of a local coord reference to a float2 variable. Only
- meaningful when the "references sample coords" FP flag is set.
- */
- struct EmitArgs {
- EmitArgs(GrGLSLFPFragmentBuilder* fragBuilder,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderCaps* caps,
- const GrFragmentProcessor& fp,
- const char* inputColor,
- const char* destColor,
- const char* sampleCoord)
- : fFragBuilder(fragBuilder)
- , fUniformHandler(uniformHandler)
- , fShaderCaps(caps)
- , fFp(fp)
- , fInputColor(inputColor ? inputColor : "half4(1.0)")
- , fDestColor(destColor)
- , fSampleCoord(sampleCoord) {}
- GrGLSLFPFragmentBuilder* fFragBuilder;
- GrGLSLUniformHandler* fUniformHandler;
- const GrShaderCaps* fShaderCaps;
- const GrFragmentProcessor& fFp;
- const char* fInputColor;
- const char* fDestColor;
- const char* fSampleCoord;
- };
-
- virtual void emitCode(EmitArgs&) = 0;
-
- // This does not recurse to any attached child processors. Recursing the entire processor tree
- // is the responsibility of the caller.
- void setData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& processor);
-
- int numChildProcessors() const { return fChildProcessors.count(); }
-
- ProgramImpl* childProcessor(int index) const { return fChildProcessors[index].get(); }
-
- void setFunctionName(SkString name) {
- SkASSERT(fFunctionName.isEmpty());
- fFunctionName = std::move(name);
- }
-
- const char* functionName() const {
- SkASSERT(!fFunctionName.isEmpty());
- return fFunctionName.c_str();
- }
-
- void emitChildFunctions(EmitArgs& parentArgs);
-
- // Invoke the child with the default input and destination colors (solid white)
- inline SkString invokeChild(int childIndex, EmitArgs& parentArgs,
- SkSL::String skslCoords = "") {
- return this->invokeChild(childIndex, /*inputColor=*/nullptr, /*destColor=*/nullptr,
- parentArgs, skslCoords);
- }
-
- inline SkString invokeChildWithMatrix(int childIndex, EmitArgs& parentArgs) {
- return this->invokeChildWithMatrix(childIndex, /*inputColor=*/nullptr,
- /*destColor=*/nullptr, parentArgs);
- }
-
- // Invoke the child with the default destination color (solid white)
- inline SkString invokeChild(int childIndex, const char* inputColor, EmitArgs& parentArgs,
- SkSL::String skslCoords = "") {
- return this->invokeChild(childIndex, inputColor, /*destColor=*/nullptr, parentArgs,
- skslCoords);
- }
-
- inline SkString invokeChildWithMatrix(int childIndex, const char* inputColor,
- EmitArgs& parentArgs) {
- return this->invokeChildWithMatrix(childIndex, inputColor, /*destColor=*/nullptr,
- parentArgs);
- }
-
- /** Invokes a child proc in its own scope. Pass in the parent's EmitArgs and invokeChild will
- * automatically extract the coords and samplers of that child and pass them on to the child's
- * emitCode(). Also, any uniforms or functions emitted by the child will have their names
- * mangled to prevent redefinitions. The returned string contains the output color (as a call
- * to the child's helper function). It is legal to pass nullptr as inputColor, since all
- * fragment processors are required to work without an input color.
- *
- * When skslCoords is empty, invokeChild corresponds to a call to "sample(child, color)"
- * in SkSL. When skslCoords is not empty, invokeChild corresponds to a call to
- * "sample(child, color, float2)", where skslCoords is an SkSL expression that evaluates to a
- * float2 and is passed in as the 3rd argument.
- */
- SkString invokeChild(int childIndex, const char* inputColor, const char* destColor,
- EmitArgs& parentArgs, SkSL::String skslCoords = "");
-
- /**
- * As invokeChild, but transforms the coordinates according to the matrix expression attached
- * to the child's SampleUsage object. This is only valid if the child is sampled with a
- * const-uniform matrix.
- */
- SkString invokeChildWithMatrix(int childIndex, const char* inputColor, const char* destColor,
- EmitArgs& parentArgs);
-
- /**
- * Pre-order traversal of a GLSLFP hierarchy, or of multiple trees with roots in an array of
- * GLSLFPS. If initialized with an array color followed by coverage processors installed in a
- * program thenthe iteration order will agree with a GrFragmentProcessor::Iter initialized with
- * a GrPipeline that produces the same program key.
- */
- class Iter {
- public:
- Iter(std::unique_ptr<ProgramImpl> fps[], int cnt);
- Iter(ProgramImpl& fp) { fFPStack.push_back(&fp); }
-
- ProgramImpl& operator*() const;
- ProgramImpl* operator->() const;
- Iter& operator++();
- operator bool() const { return !fFPStack.empty(); }
-
- // Because each iterator carries a stack we want to avoid copies.
- Iter(const Iter&) = delete;
- Iter& operator=(const Iter&) = delete;
-
- private:
- SkSTArray<4, ProgramImpl*, true> fFPStack;
- };
-
-private:
- /**
- * A ProgramImpl instance can be reused with any GrFragmentProcessor that produces the same
- * the same key; this function reads data from a GrFragmentProcessor and uploads any
- * uniform variables required by the shaders created in emitCode(). The GrFragmentProcessor
- * parameter is guaranteed to be of the same type that created this ProgramImpl and
- * to have an identical key as the one that created this ProgramImpl.
- */
- virtual void onSetData(const GrGLSLProgramDataManager&, const GrFragmentProcessor&) {}
-
- // The (mangled) name of our entry-point function
- SkString fFunctionName;
-
- SkTArray<std::unique_ptr<ProgramImpl>, true> fChildProcessors;
-
- friend class GrFragmentProcessor;
-};
-
-#endif
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
index bfb0375..bfde859 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h
@@ -9,8 +9,8 @@
#define GrGLSLFragmentShaderBuilder_DEFINED
#include "src/gpu/GrBlend.h"
+#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrProcessor.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLShaderBuilder.h"
class GrRenderTarget;
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
deleted file mode 100644
index 4111753..0000000
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
-
-#include "src/core/SkMatrixPriv.h"
-#include "src/gpu/GrPipeline.h"
-#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
-#include "src/gpu/glsl/GrGLSLUniformHandler.h"
-#include "src/gpu/glsl/GrGLSLVarying.h"
-#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
-
-#include <queue>
-
-using ProgramImpl = GrGeometryProcessor::ProgramImpl;
-
-ProgramImpl::FPCoordsMap ProgramImpl::emitCode(EmitArgs& args, const GrPipeline& pipeline) {
- GrGPArgs gpArgs;
- this->onEmitCode(args, &gpArgs);
-
- GrShaderVar positionVar = gpArgs.fPositionVar;
- // skia:12198
- if (args.fGeomProc.willUseGeoShader() || args.fGeomProc.willUseTessellationShaders()) {
- positionVar = {};
- }
- FPCoordsMap transformMap = this->collectTransforms(args.fVertBuilder,
- args.fVaryingHandler,
- args.fUniformHandler,
- gpArgs.fLocalCoordVar,
- positionVar,
- pipeline);
-
- if (args.fGeomProc.willUseTessellationShaders()) {
- // Tessellation shaders are temporarily responsible for integrating their own code strings
- // while we work out full support.
- return transformMap;
- }
-
- GrGLSLVertexBuilder* vBuilder = args.fVertBuilder;
- if (!args.fGeomProc.willUseGeoShader()) {
- // Emit the vertex position to the hardware in the normalized window coordinates it expects.
- SkASSERT(kFloat2_GrSLType == gpArgs.fPositionVar.getType() ||
- kFloat3_GrSLType == gpArgs.fPositionVar.getType());
- vBuilder->emitNormalizedSkPosition(gpArgs.fPositionVar.c_str(),
- gpArgs.fPositionVar.getType());
- if (kFloat2_GrSLType == gpArgs.fPositionVar.getType()) {
- args.fVaryingHandler->setNoPerspective();
- }
- } else {
- // Since we have a geometry shader, leave the vertex position in Skia device space for now.
- // The geometry Shader will operate in device space, and then convert the final positions to
- // normalized hardware window coordinates under the hood, once everything else has finished.
- // The subclass must call setNoPerspective on the varying handler, if applicable.
- vBuilder->codeAppendf("sk_Position = float4(%s", gpArgs.fPositionVar.c_str());
- switch (gpArgs.fPositionVar.getType()) {
- case kFloat_GrSLType:
- vBuilder->codeAppend(", 0");
- [[fallthrough]];
- case kFloat2_GrSLType:
- vBuilder->codeAppend(", 0");
- [[fallthrough]];
- case kFloat3_GrSLType:
- vBuilder->codeAppend(", 1");
- [[fallthrough]];
- case kFloat4_GrSLType:
- vBuilder->codeAppend(");");
- break;
- default:
- SK_ABORT("Invalid position var type");
- break;
- }
- }
- return transformMap;
-}
-
-ProgramImpl::FPCoordsMap ProgramImpl::collectTransforms(GrGLSLVertexBuilder* vb,
- GrGLSLVaryingHandler* varyingHandler,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderVar& localCoordsVar,
- const GrShaderVar& positionVar,
- const GrPipeline& pipeline) {
- SkASSERT(localCoordsVar.getType() == kFloat2_GrSLType ||
- localCoordsVar.getType() == kFloat3_GrSLType ||
- localCoordsVar.getType() == kVoid_GrSLType);
- SkASSERT(positionVar.getType() == kFloat2_GrSLType ||
- positionVar.getType() == kFloat3_GrSLType ||
- positionVar.getType() == kVoid_GrSLType);
-
- enum class BaseCoord { kNone, kLocal, kPosition };
-
- auto baseLocalCoordFSVar = [&, baseLocalCoord = GrGLSLVarying()]() mutable {
- SkASSERT(GrSLTypeIsFloatType(localCoordsVar.getType()));
- if (baseLocalCoord.type() == kVoid_GrSLType) {
- // Initialize to the GP provided coordinate
- baseLocalCoord = GrGLSLVarying(localCoordsVar.getType());
- varyingHandler->addVarying("LocalCoord", &baseLocalCoord);
- vb->codeAppendf("%s = %s;\n", baseLocalCoord.vsOut(), localCoordsVar.getName().c_str());
- }
- return baseLocalCoord.fsInVar();
- };
-
- bool canUsePosition = positionVar.getType() != kVoid_GrSLType;
-
- FPCoordsMap result;
- // Performs a pre-order traversal of FP hierarchy rooted at fp and identifies FPs that are
- // sampled with a series of matrices applied to local coords. For each such FP a varying is
- // added to the varying handler and added to 'result'.
- auto liftTransforms = [&, traversalIndex = 0](
- auto& self,
- const GrFragmentProcessor& fp,
- bool hasPerspective,
- const GrFragmentProcessor* lastMatrixFP = nullptr,
- int lastMatrixTraversalIndex = -1,
- BaseCoord baseCoord = BaseCoord::kLocal) mutable -> void {
- ++traversalIndex;
- switch (fp.sampleUsage().kind()) {
- case SkSL::SampleUsage::Kind::kNone:
- // This should only happen at the root. Otherwise how did this FP get added?
- SkASSERT(!fp.parent());
- break;
- case SkSL::SampleUsage::Kind::kPassThrough:
- break;
- case SkSL::SampleUsage::Kind::kUniformMatrix:
- // Update tracking of last matrix and matrix props.
- hasPerspective |= fp.sampleUsage().hasPerspective();
- lastMatrixFP = &fp;
- lastMatrixTraversalIndex = traversalIndex;
- break;
- case SkSL::SampleUsage::Kind::kFragCoord:
- hasPerspective = positionVar.getType() == kFloat3_GrSLType;
- lastMatrixFP = nullptr;
- lastMatrixTraversalIndex = -1;
- baseCoord = BaseCoord::kPosition;
- break;
- case SkSL::SampleUsage::Kind::kExplicit:
- baseCoord = BaseCoord::kNone;
- break;
- }
-
- auto& [varyingFSVar, hasCoordsParam] = result[&fp];
- hasCoordsParam = fp.usesSampleCoordsDirectly();
-
- // We add a varying if we're in a chain of matrices multiplied by local or device coords.
- // If the coord is the untransformed local coord we add a varying. We don't if it is
- // untransformed device coords since it doesn't save us anything over "sk_FragCoord.xy". Of
- // course, if the FP doesn't directly use its coords then we don't add a varying.
- if (fp.usesSampleCoordsDirectly() &&
- (baseCoord == BaseCoord::kLocal ||
- (baseCoord == BaseCoord::kPosition && lastMatrixFP && canUsePosition))) {
- // Associate the varying with the highest possible node in the FP tree that shares the
- // same coordinates so that multiple FPs in a subtree can share. If there are no matrix
- // sample nodes on the way up the tree then directly use the local coord.
- if (!lastMatrixFP) {
- varyingFSVar = baseLocalCoordFSVar();
- } else {
- // If there is an already a varying that incorporates all matrices from the root to
- // lastMatrixFP just use it. Otherwise, we add it.
- auto& [varying, inputCoords, varyingIdx] = fTransformVaryingsMap[lastMatrixFP];
- if (varying.type() == kVoid_GrSLType) {
- varying = GrGLSLVarying(hasPerspective ? kFloat3_GrSLType : kFloat2_GrSLType);
- SkString strVaryingName = SkStringPrintf("TransformedCoords_%d",
- lastMatrixTraversalIndex);
- varyingHandler->addVarying(strVaryingName.c_str(), &varying);
- inputCoords = baseCoord == BaseCoord::kLocal ? localCoordsVar : positionVar;
- varyingIdx = lastMatrixTraversalIndex;
- }
- SkASSERT(varyingIdx == lastMatrixTraversalIndex);
- // The FP will use the varying in the fragment shader as its coords.
- varyingFSVar = varying.fsInVar();
- }
- hasCoordsParam = false;
- }
-
- for (int c = 0; c < fp.numChildProcessors(); ++c) {
- if (auto* child = fp.childProcessor(c)) {
- self(self,
- *child,
- hasPerspective,
- lastMatrixFP,
- lastMatrixTraversalIndex,
- baseCoord);
- // If we have a varying then we never need a param. Otherwise, if one of our
- // children takes a non-explicit coord then we'll need our coord.
- hasCoordsParam |= varyingFSVar.getType() == kVoid_GrSLType &&
- !child->sampleUsage().isExplicit() &&
- !child->sampleUsage().isFragCoord() &&
- result[child].hasCoordsParam;
- }
- }
- };
-
- bool hasPerspective = GrSLTypeVecLength(localCoordsVar.getType()) == 3;
- for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
- liftTransforms(liftTransforms, pipeline.getFragmentProcessor(i), hasPerspective);
- }
- return result;
-}
-
-void ProgramImpl::emitTransformCode(GrGLSLVertexBuilder* vb, GrGLSLUniformHandler* uniformHandler) {
- // Because descendant varyings may be computed using the varyings of ancestor FPs we make
- // sure to visit the varyings according to FP pre-order traversal by dumping them into a
- // priority queue.
- using FPAndInfo = std::tuple<const GrFragmentProcessor*, TransformInfo>;
- auto compare = [](const FPAndInfo& a, const FPAndInfo& b) {
- return std::get<1>(a).traversalOrder > std::get<1>(b).traversalOrder;
- };
- std::priority_queue<FPAndInfo, std::vector<FPAndInfo>, decltype(compare)> pq(compare);
- std::for_each(fTransformVaryingsMap.begin(), fTransformVaryingsMap.end(), [&pq](auto entry) {
- pq.push(entry);
- });
- for (; !pq.empty(); pq.pop()) {
- const auto& [fp, info] = pq.top();
- // If we recorded a transform info, its sample matrix must be uniform
- SkASSERT(fp->sampleUsage().isUniformMatrix());
- GrShaderVar uniform = uniformHandler->liftUniformToVertexShader(
- *fp->parent(), SkString(SkSL::SampleUsage::MatrixUniformName()));
- // Start with this matrix and accumulate additional matrices as we walk up the FP tree
- // to either the base coords or an ancestor FP that has an associated varying.
- SkString transformExpression = uniform.getName();
-
- // If we hit an ancestor with a varying on our walk up then save off the varying as the
- // input to our accumulated transformExpression. Start off assuming we'll reach the root.
- GrShaderVar inputCoords = info.inputCoords;
-
- for (const auto* base = fp->parent(); base; base = base->parent()) {
- if (auto iter = fTransformVaryingsMap.find(base); iter != fTransformVaryingsMap.end()) {
- // Can stop here, as this varying already holds all transforms from higher FPs
- // We'll apply the residual transformExpression we've accumulated up from our
- // starting FP to this varying.
- inputCoords = iter->second.varying.vsOutVar();
- break;
- } else if (base->sampleUsage().isUniformMatrix()) {
- // Accumulate any matrices along the path to either the original local/device coords
- // or a parent varying. Getting here means this FP was sampled with a uniform matrix
- // but all uses of coords below here in the FP hierarchy are beneath additional
- // matrix samples and thus this node wasn't assigned a varying.
- GrShaderVar parentUniform = uniformHandler->liftUniformToVertexShader(
- *base->parent(), SkString(SkSL::SampleUsage::MatrixUniformName()));
- transformExpression.appendf(" * %s", parentUniform.getName().c_str());
- } else if (base->sampleUsage().isFragCoord()) {
- // Our chain of matrices starts here and is based on the device space position.
- break;
- } else {
- // This intermediate FP is just a pass through and doesn't need to be built
- // in to the expression, but we must visit its parents in case they add transforms.
- SkASSERT(base->sampleUsage().isPassThrough() || !base->sampleUsage().isSampled());
- }
- }
-
- SkString inputStr;
- if (inputCoords.getType() == kFloat2_GrSLType) {
- inputStr = SkStringPrintf("%s.xy1", inputCoords.getName().c_str());
- } else {
- SkASSERT(inputCoords.getType() == kFloat3_GrSLType);
- inputStr = inputCoords.getName();
- }
-
- vb->codeAppend("{\n");
- if (info.varying.type() == kFloat2_GrSLType) {
- if (vb->getProgramBuilder()->shaderCaps()->nonsquareMatrixSupport()) {
- vb->codeAppendf("%s = float3x2(%s) * %s", info.varying.vsOut(),
- transformExpression.c_str(),
- inputStr.c_str());
- } else {
- vb->codeAppendf("%s = (%s * %s).xy", info.varying.vsOut(),
- transformExpression.c_str(),
- inputStr.c_str());
- }
- } else {
- SkASSERT(info.varying.type() == kFloat3_GrSLType);
- vb->codeAppendf("%s = %s * %s", info.varying.vsOut(),
- transformExpression.c_str(),
- inputStr.c_str());
- }
- vb->codeAppend(";\n");
- vb->codeAppend("}\n");
- }
- // We don't need this map anymore.
- fTransformVaryingsMap.clear();
-}
-
-void ProgramImpl::setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
- GrGLSLUniformHandler* uniformHandler,
- const char* outputName,
- UniformHandle* colorUniform) {
- SkASSERT(colorUniform);
- const char* stagedLocalVarName;
- *colorUniform = uniformHandler->addUniform(nullptr,
- kFragment_GrShaderFlag,
- kHalf4_GrSLType,
- "Color",
- &stagedLocalVarName);
- fragBuilder->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
- if (fragBuilder->getProgramBuilder()->shaderCaps()->mustObfuscateUniformColor()) {
- fragBuilder->codeAppendf("%s = max(%s, half4(0));", outputName, outputName);
- }
-}
-
-void ProgramImpl::SetTransform(const GrGLSLProgramDataManager& pdman,
- const GrShaderCaps& shaderCaps,
- const UniformHandle& uniform,
- const SkMatrix& matrix,
- SkMatrix* state) {
- if (!uniform.isValid() || (state && SkMatrixPriv::CheapEqual(*state, matrix))) {
- // No update needed
- return;
- }
- if (state) {
- *state = matrix;
- }
- if (matrix.isScaleTranslate() && !shaderCaps.reducedShaderMode()) {
- // ComputeMatrixKey and writeX() assume the uniform is a float4 (can't assert since nothing
- // is exposed on a handle, but should be caught lower down).
- float values[4] = {matrix.getScaleX(), matrix.getTranslateX(),
- matrix.getScaleY(), matrix.getTranslateY()};
- pdman.set4fv(uniform, 1, values);
- } else {
- pdman.setSkMatrix(uniform, matrix);
- }
-}
-
-static void write_passthrough_vertex_position(GrGLSLVertexBuilder* vertBuilder,
- const GrShaderVar& inPos,
- GrShaderVar* outPos) {
- SkASSERT(inPos.getType() == kFloat3_GrSLType || inPos.getType() == kFloat2_GrSLType);
- SkString outName = vertBuilder->newTmpVarName(inPos.getName().c_str());
- outPos->set(inPos.getType(), outName.c_str());
- vertBuilder->codeAppendf("float%d %s = %s;",
- GrSLTypeVecLength(inPos.getType()),
- outName.c_str(),
- inPos.getName().c_str());
-}
-
-static void write_vertex_position(GrGLSLVertexBuilder* vertBuilder,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderCaps& shaderCaps,
- const GrShaderVar& inPos,
- const SkMatrix& matrix,
- const char* matrixName,
- GrShaderVar* outPos,
- ProgramImpl::UniformHandle* matrixUniform) {
- SkASSERT(inPos.getType() == kFloat3_GrSLType || inPos.getType() == kFloat2_GrSLType);
- SkString outName = vertBuilder->newTmpVarName(inPos.getName().c_str());
-
- if (matrix.isIdentity() && !shaderCaps.reducedShaderMode()) {
- write_passthrough_vertex_position(vertBuilder, inPos, outPos);
- return;
- }
- SkASSERT(matrixUniform);
-
- bool useCompactTransform = matrix.isScaleTranslate() && !shaderCaps.reducedShaderMode();
- const char* mangledMatrixName;
- *matrixUniform = uniformHandler->addUniform(nullptr,
- kVertex_GrShaderFlag,
- useCompactTransform ? kFloat4_GrSLType
- : kFloat3x3_GrSLType,
- matrixName,
- &mangledMatrixName);
-
- if (inPos.getType() == kFloat3_GrSLType) {
- // A float3 stays a float3 whether or not the matrix adds perspective
- if (useCompactTransform) {
- vertBuilder->codeAppendf("float3 %s = %s.xz1 * %s + %s.yw0;\n",
- outName.c_str(),
- mangledMatrixName,
- inPos.getName().c_str(),
- mangledMatrixName);
- } else {
- vertBuilder->codeAppendf("float3 %s = %s * %s;\n",
- outName.c_str(),
- mangledMatrixName,
- inPos.getName().c_str());
- }
- outPos->set(kFloat3_GrSLType, outName.c_str());
- return;
- }
- if (matrix.hasPerspective()) {
- // A float2 is promoted to a float3 if we add perspective via the matrix
- SkASSERT(!useCompactTransform);
- vertBuilder->codeAppendf("float3 %s = (%s * %s.xy1);",
- outName.c_str(),
- mangledMatrixName,
- inPos.getName().c_str());
- outPos->set(kFloat3_GrSLType, outName.c_str());
- return;
- }
- if (useCompactTransform) {
- vertBuilder->codeAppendf("float2 %s = %s.xz * %s + %s.yw;\n",
- outName.c_str(),
- mangledMatrixName,
- inPos.getName().c_str(),
- mangledMatrixName);
- } else if (shaderCaps.nonsquareMatrixSupport()) {
- vertBuilder->codeAppendf("float2 %s = float3x2(%s) * %s.xy1;\n",
- outName.c_str(),
- mangledMatrixName,
- inPos.getName().c_str());
- } else {
- vertBuilder->codeAppendf("float2 %s = (%s * %s.xy1).xy;\n",
- outName.c_str(),
- mangledMatrixName,
- inPos.getName().c_str());
- }
- outPos->set(kFloat2_GrSLType, outName.c_str());
-}
-
-void ProgramImpl::WriteOutputPosition(GrGLSLVertexBuilder* vertBuilder,
- GrGPArgs* gpArgs,
- const char* posName) {
- // writeOutputPosition assumes the incoming pos name points to a float2 variable
- GrShaderVar inPos(posName, kFloat2_GrSLType);
- write_passthrough_vertex_position(vertBuilder, inPos, &gpArgs->fPositionVar);
-}
-
-void ProgramImpl::WriteOutputPosition(GrGLSLVertexBuilder* vertBuilder,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderCaps& shaderCaps,
- GrGPArgs* gpArgs,
- const char* posName,
- const SkMatrix& mat,
- UniformHandle* viewMatrixUniform) {
- GrShaderVar inPos(posName, kFloat2_GrSLType);
- write_vertex_position(vertBuilder,
- uniformHandler,
- shaderCaps,
- inPos,
- mat,
- "viewMatrix",
- &gpArgs->fPositionVar,
- viewMatrixUniform);
-}
-
-void ProgramImpl::WriteLocalCoord(GrGLSLVertexBuilder* vertBuilder,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderCaps& shaderCaps,
- GrGPArgs* gpArgs,
- GrShaderVar localVar,
- const SkMatrix& localMatrix,
- UniformHandle* localMatrixUniform) {
- write_vertex_position(vertBuilder,
- uniformHandler,
- shaderCaps,
- localVar,
- localMatrix,
- "localMatrix",
- &gpArgs->fLocalCoordVar,
- localMatrixUniform);
-}
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.h b/src/gpu/glsl/GrGLSLGeometryProcessor.h
deleted file mode 100644
index 8e1b96f..0000000
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright 2013 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGLSLGeometryProcessor_DEFINED
-#define GrGLSLGeometryProcessor_DEFINED
-
-#include "src/gpu/GrFragmentProcessor.h"
-#include "src/gpu/GrGeometryProcessor.h"
-#include "src/gpu/GrShaderCaps.h"
-#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
-#include "src/gpu/glsl/GrGLSLUniformHandler.h"
-#include "src/gpu/glsl/GrGLSLVarying.h"
-
-#include <unordered_map>
-
-class GrGeometryProcessor;
-class GrGLSLFPFragmentBuilder;
-class GrGLSLGeometryBuilder;
-class GrGLSLVaryingHandler;
-class GrGLSLVertexBuilder;
-class GrShaderCaps;
-
-class GrGeometryProcessor::ProgramImpl {
-public:
- using UniformHandle = GrGLSLProgramDataManager::UniformHandle;
- using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
- /**
- * Struct of optional varying that replaces the input coords and bool indicating whether the FP
- * should take a coord param as an argument. The latter may be false if the coords are simply
- * unused or if the GP has lifted their computation to a varying emitted by the VS.
- */
- struct FPCoords {GrShaderVar coordsVarying; bool hasCoordsParam;};
- using FPCoordsMap = std::unordered_map<const GrFragmentProcessor*, FPCoords>;
-
- virtual ~ProgramImpl() = default;
-
- struct EmitArgs {
- EmitArgs(GrGLSLVertexBuilder* vertBuilder,
- GrGLSLGeometryBuilder* geomBuilder,
- GrGLSLFPFragmentBuilder* fragBuilder,
- GrGLSLVaryingHandler* varyingHandler,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderCaps* caps,
- const GrGeometryProcessor& geomProc,
- const char* outputColor,
- const char* outputCoverage,
- const SamplerHandle* texSamplers)
- : fVertBuilder(vertBuilder)
- , fGeomBuilder(geomBuilder)
- , fFragBuilder(fragBuilder)
- , fVaryingHandler(varyingHandler)
- , fUniformHandler(uniformHandler)
- , fShaderCaps(caps)
- , fGeomProc(geomProc)
- , fOutputColor(outputColor)
- , fOutputCoverage(outputCoverage)
- , fTexSamplers(texSamplers) {}
- GrGLSLVertexBuilder* fVertBuilder;
- GrGLSLGeometryBuilder* fGeomBuilder;
- GrGLSLFPFragmentBuilder* fFragBuilder;
- GrGLSLVaryingHandler* fVaryingHandler;
- GrGLSLUniformHandler* fUniformHandler;
- const GrShaderCaps* fShaderCaps;
- const GrGeometryProcessor& fGeomProc;
- const char* fOutputColor;
- const char* fOutputCoverage;
- const SamplerHandle* fTexSamplers;
- };
-
- /**
- * Emits the code from this geometry processor into the shaders. For any FP in the pipeline that
- * has its input coords implemented by the GP as a varying, the varying will be accessible in
- * the returned map and should be used when the FP code is emitted.
- **/
- FPCoordsMap emitCode(EmitArgs&, const GrPipeline& pipeline);
-
- /**
- * Called after all effect emitCode() functions, to give the processor a chance to write out
- * additional transformation code now that all uniforms have been emitted.
- * It generates the final code for assigning transformed coordinates to the varyings recorded
- * in the call to collectTransforms(). This must happen after FP code emission so that it has
- * access to any uniforms the FPs registered for uniform sample matrix invocations.
- */
- void emitTransformCode(GrGLSLVertexBuilder* vb,
- GrGLSLUniformHandler* uniformHandler);
-
- /**
- * A ProgramImpl instance can be reused with any GrGeometryProcessor that produces the same key.
- * This function reads data from a GrGeometryProcessor and updates any uniform variables
- * required by the shaders created in emitCode(). The GrGeometryProcessor parameter is
- * guaranteed to be of the same type and to have an identical processor key as the
- * GrGeometryProcessor that created this ProgramImpl.
- */
- virtual void setData(const GrGLSLProgramDataManager&,
- const GrShaderCaps&,
- const GrGeometryProcessor&) = 0;
-
- // We use these methods as a temporary back door to inject OpenGL tessellation code. Once
- // tessellation is supported by SkSL we can remove these.
- virtual SkString getTessControlShaderGLSL(const GrGeometryProcessor&,
- const char* versionAndExtensionDecls,
- const GrGLSLUniformHandler&,
- const GrShaderCaps&) const {
- SK_ABORT("Not implemented.");
- }
- virtual SkString getTessEvaluationShaderGLSL(const GrGeometryProcessor&,
- const char* versionAndExtensionDecls,
- const GrGLSLUniformHandler&,
- const GrShaderCaps&) const {
- SK_ABORT("Not implemented.");
- }
-
- // GPs that use writeOutputPosition and/or writeLocalCoord must incorporate the matrix type
- // into their key, and should use this function or one of the other related helpers.
- static uint32_t ComputeMatrixKey(const GrShaderCaps& caps, const SkMatrix& mat) {
- if (!caps.reducedShaderMode()) {
- if (mat.isIdentity()) {
- return 0b00;
- }
- if (mat.isScaleTranslate()) {
- return 0b01;
- }
- }
- if (!mat.hasPerspective()) {
- return 0b10;
- }
- return 0b11;
- }
-
- static uint32_t ComputeMatrixKeys(const GrShaderCaps& shaderCaps,
- const SkMatrix& viewMatrix,
- const SkMatrix& localMatrix) {
- return (ComputeMatrixKey(shaderCaps, viewMatrix ) << kMatrixKeyBits) |
- ComputeMatrixKey(shaderCaps, localMatrix);
- }
-
- static uint32_t AddMatrixKeys(const GrShaderCaps& shaderCaps,
- uint32_t flags,
- const SkMatrix& viewMatrix,
- const SkMatrix& localMatrix) {
- // Shifting to make room for the matrix keys shouldn't lose bits
- SkASSERT(((flags << (2 * kMatrixKeyBits)) >> (2 * kMatrixKeyBits)) == flags);
- return (flags << (2 * kMatrixKeyBits)) |
- ComputeMatrixKeys(shaderCaps, viewMatrix, localMatrix);
- }
- static constexpr int kMatrixKeyBits = 2;
-
-protected:
- void setupUniformColor(GrGLSLFPFragmentBuilder* fragBuilder,
- GrGLSLUniformHandler* uniformHandler,
- const char* outputName,
- UniformHandle* colorUniform);
-
- // A helper for setting the matrix on a uniform handle initialized through
- // writeOutputPosition or writeLocalCoord. Automatically handles elided uniforms,
- // scale+translate matrices, and state tracking (if provided state pointer is non-null).
- static void SetTransform(const GrGLSLProgramDataManager&,
- const GrShaderCaps&,
- const UniformHandle& uniform,
- const SkMatrix& matrix,
- SkMatrix* state = nullptr);
-
- struct GrGPArgs {
- // Used to specify the output variable used by the GP to store its device position. It can
- // either be a float2 or a float3 (in order to handle perspective). The subclass sets this
- // in its onEmitCode().
- GrShaderVar fPositionVar;
- // Used to specify the variable storing the draw's local coordinates. It can be either a
- // float2, float3, or void. It can only be void when no FP needs local coordinates. This
- // variable can be an attribute or local variable, but should not itself be a varying.
- // ProgramImpl automatically determines if this must be passed to a FS.
- GrShaderVar fLocalCoordVar;
- };
-
- // Helpers for adding code to write the transformed vertex position. The first simple version
- // just writes a variable named by 'posName' into the position output variable with the
- // assumption that the position is 2D. The second version transforms the input position by a
- // view matrix and the output variable is 2D or 3D depending on whether the view matrix is
- // perspective. Both versions declare the output position variable and will set
- // GrGPArgs::fPositionVar.
- static void WriteOutputPosition(GrGLSLVertexBuilder*, GrGPArgs*, const char* posName);
- static void WriteOutputPosition(GrGLSLVertexBuilder*,
- GrGLSLUniformHandler*,
- const GrShaderCaps&,
- GrGPArgs*,
- const char* posName,
- const SkMatrix& viewMatrix,
- UniformHandle* viewMatrixUniform);
-
- // Helper to transform an existing variable by a given local matrix (e.g. the inverse view
- // matrix). It will declare the transformed local coord variable and will set
- // GrGPArgs::fLocalCoordVar.
- static void WriteLocalCoord(GrGLSLVertexBuilder*,
- GrGLSLUniformHandler*,
- const GrShaderCaps&,
- GrGPArgs*,
- GrShaderVar localVar,
- const SkMatrix& localMatrix,
- UniformHandle* localMatrixUniform);
-
-private:
- virtual void onEmitCode(EmitArgs&, GrGPArgs*) = 0;
-
- // Iterates over the FPs beginning with the passed iter to register additional varyings and
- // uniforms to support VS-promoted local coord evaluation for the FPs.
- //
- // This must happen before FP code emission so that the FPs can find the appropriate varying
- // handles they use in place of explicit coord sampling; it is automatically called after
- // onEmitCode() returns using the value stored in GpArgs::fLocalCoordVar and
- // GpArgs::fPositionVar.
- FPCoordsMap collectTransforms(GrGLSLVertexBuilder* vb,
- GrGLSLVaryingHandler* varyingHandler,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderVar& localCoordsVar,
- const GrShaderVar& positionVar,
- const GrPipeline& pipeline);
- struct TransformInfo {
- // The varying that conveys the coordinates to one or more FPs in the FS.
- GrGLSLVarying varying;
- // The coordinate to be transformed. varying is computed from this.
- GrShaderVar inputCoords;
- // Used to sort so that ancestor FP varyings are initialized before descendant FP varyings.
- int traversalOrder;
- };
- // Populated by collectTransforms() for use in emitTransformCode(). When we lift the computation
- // of a FP's input coord to a varying we propagate that varying up the FP tree to the highest
- // node that shares the same coordinates. This allows multiple FPs in a subtree to share a
- // varying.
- std::unordered_map<const GrFragmentProcessor*, TransformInfo> fTransformVaryingsMap;
-};
-
-#endif
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index c9cbc93..8a75f0a 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -10,15 +10,15 @@
#include <memory>
#include "src/gpu/GrCaps.h"
+#include "src/gpu/GrFragmentProcessor.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrShaderCaps.h"
#include "src/gpu/GrTexture.h"
+#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/dsl/priv/DSLFPs.h"
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index a0c1d30..fba0236 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -9,15 +9,14 @@
#define GrGLSLProgramBuilder_DEFINED
#include "src/gpu/GrCaps.h"
+#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrProgramInfo.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
#include "src/sksl/SkSLCompiler.h"
#include <vector>
diff --git a/src/gpu/glsl/GrGLSLVarying.cpp b/src/gpu/glsl/GrGLSLVarying.cpp
index 4670fcc..a334d63 100644
--- a/src/gpu/glsl/GrGLSLVarying.cpp
+++ b/src/gpu/glsl/GrGLSLVarying.cpp
@@ -9,14 +9,14 @@
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
-void GrGLSLVaryingHandler::addPassThroughAttribute(const GrGeometryProcessor::Attribute& input,
+void GrGLSLVaryingHandler::addPassThroughAttribute(const GrShaderVar& vsVar,
const char* output,
Interpolation interpolation) {
- SkASSERT(input.isInitialized());
+ SkASSERT(vsVar.getType() != kVoid_GrSLType);
SkASSERT(!fProgramBuilder->geometryProcessor().willUseGeoShader());
- GrGLSLVarying v(input.gpuType());
- this->addVarying(input.name(), &v, interpolation);
- fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), input.name());
+ GrGLSLVarying v(vsVar.getType());
+ this->addVarying(vsVar.c_str(), &v, interpolation);
+ fProgramBuilder->fVS.codeAppendf("%s = %s;", v.vsOut(), vsVar.c_str());
fProgramBuilder->fFS.codeAppendf("%s = %s;", output, v.fsIn());
}
diff --git a/src/gpu/glsl/GrGLSLVarying.h b/src/gpu/glsl/GrGLSLVarying.h
index 5a489e7..148a651 100644
--- a/src/gpu/glsl/GrGLSLVarying.h
+++ b/src/gpu/glsl/GrGLSLVarying.h
@@ -9,11 +9,11 @@
#define GrGLSLVarying_DEFINED
#include "include/private/GrTypesPriv.h"
-#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrShaderVar.h"
#include "src/gpu/GrTBlockList.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
+class GrGeometryProcessor;
class GrGLSLProgramBuilder;
#ifdef SK_DEBUG
@@ -104,7 +104,7 @@
virtual ~GrGLSLVaryingHandler() {}
- /*
+ /**
* Notifies the varying handler that this shader will never emit geometry in perspective and
* therefore does not require perspective-correct interpolation. When supported, this allows
* varyings to use the "noperspective" keyword, which means the GPU can use cheaper math for
@@ -118,7 +118,7 @@
kMustBeFlat // Use "flat" even if it is known to be slow.
};
- /*
+ /**
* addVarying allows fine grained control for setting up varyings between stages. Calling this
* function will make sure all necessary decls are setup for the client. The client however is
* responsible for setting up all shader code (e.g "vOut = vIn;") If you just need to take an
@@ -129,15 +129,15 @@
void addVarying(const char* name, GrGLSLVarying* varying,
Interpolation = Interpolation::kInterpolated);
- /*
- * The GP can use these calls to pass an attribute through all shaders directly to 'output' in
- * the fragment shader. Though these calls affect both the vertex shader and fragment shader,
- * they expect 'output' to be defined in the fragment shader before the call is made. If there
- * is a geometry shader, we will simply take the value of the varying from the first vertex and
- * that will be set as the output varying for all emitted vertices.
+ /**
+ * The GP can use these calls to pass a vertex shader variable directly to 'output' in the
+ * fragment shader. Though this adds code to vertex and fragment stages, 'output' is expected to
+ * be defined in the fragment shader before the call is made. This cannot be used with a
+ * geometry shader.
* TODO it might be nicer behavior to have a flag to declare output inside these calls
*/
- void addPassThroughAttribute(const GrGeometryProcessor::Attribute&, const char* output,
+ void addPassThroughAttribute(const GrShaderVar& vsVar,
+ const char* output,
Interpolation = Interpolation::kInterpolated);
void emitAttributes(const GrGeometryProcessor&);
diff --git a/src/gpu/glsl/GrGLSLXferProcessor.cpp b/src/gpu/glsl/GrGLSLXferProcessor.cpp
deleted file mode 100644
index c981232..0000000
--- a/src/gpu/glsl/GrGLSLXferProcessor.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2014 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
-
-#include "src/gpu/GrShaderCaps.h"
-#include "src/gpu/GrTexture.h"
-#include "src/gpu/GrXferProcessor.h"
-#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
-#include "src/gpu/glsl/GrGLSLUniformHandler.h"
-
-using ProgramImpl = GrXferProcessor::ProgramImpl;
-
-// This is only called for cases where we are doing LCD coverage and not using in shader blending.
-// For these cases we assume the the src alpha is 1, thus we can just use the max for the alpha
-// coverage since src alpha will always be greater than or equal to dst alpha.
-static void adjust_for_lcd_coverage(GrGLSLXPFragmentBuilder* fragBuilder,
- const char* srcCoverage,
- const GrXferProcessor& proc) {
- if (srcCoverage && proc.isLCD()) {
- fragBuilder->codeAppendf("%s.a = max(max(%s.r, %s.g), %s.b);",
- srcCoverage, srcCoverage, srcCoverage, srcCoverage);
- }
-}
-
-void ProgramImpl::emitCode(const EmitArgs& args) {
- if (!args.fXP.willReadDstColor()) {
- adjust_for_lcd_coverage(args.fXPFragBuilder, args.fInputCoverage, args.fXP);
- this->emitOutputsForBlendState(args);
- } else {
- GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
- GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
- const char* dstColor = fragBuilder->dstColor();
-
- bool needsLocalOutColor = false;
-
- if (args.fDstTextureSamplerHandle.isValid()) {
- if (args.fInputCoverage) {
- // We don't think any shaders actually output negative coverage, but just as a
- // safety check for floating point precision errors, we compare with <= here. We
- // just check the RGB values of the coverage, since the alpha may not have been set
- // when using LCD. If we are using single-channel coverage, alpha will be equal to
- // RGB anyway.
- //
- // The discard here also helps for batching text-draws together, which need to read
- // from a dst copy for blends. However, this only helps the case where the outer
- // bounding boxes of each letter overlap and not two actually parts of the text.
- fragBuilder->codeAppendf("if (all(lessThanEqual(%s.rgb, half3(0)))) {"
- " discard;"
- "}", args.fInputCoverage);
- }
- } else {
- needsLocalOutColor = args.fShaderCaps->requiresLocalOutputColorForFBFetch();
- }
-
- const char* outColor = "_localColorOut";
- if (!needsLocalOutColor) {
- outColor = args.fOutputPrimary;
- } else {
- fragBuilder->codeAppendf("half4 %s;", outColor);
- }
-
- this->emitBlendCodeForDstRead(fragBuilder,
- uniformHandler,
- args.fInputColor,
- args.fInputCoverage,
- dstColor,
- outColor,
- args.fOutputSecondary,
- args.fXP);
- if (needsLocalOutColor) {
- fragBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, outColor);
- }
- }
-
- // Swizzle the fragment shader outputs if necessary.
- this->emitWriteSwizzle(args.fXPFragBuilder, args.fWriteSwizzle, args.fOutputPrimary,
- args.fOutputSecondary);
-}
-
-void ProgramImpl::emitWriteSwizzle(GrGLSLXPFragmentBuilder* x,
- const GrSwizzle& swizzle,
- const char* outColor,
- const char* outColorSecondary) const {
- if (GrSwizzle::RGBA() != swizzle) {
- x->codeAppendf("%s = %s.%s;", outColor, outColor, swizzle.asString().c_str());
- if (outColorSecondary) {
- x->codeAppendf("%s = %s.%s;", outColorSecondary, outColorSecondary,
- swizzle.asString().c_str());
- }
- }
-}
-
-void ProgramImpl::setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp) {
- this->onSetData(pdm, xp);
-}
-
-void ProgramImpl::DefaultCoverageModulation(GrGLSLXPFragmentBuilder* fragBuilder,
- const char* srcCoverage,
- const char* dstColor,
- const char* outColor,
- const char* outColorSecondary,
- const GrXferProcessor& proc) {
- if (srcCoverage) {
- if (proc.isLCD()) {
- fragBuilder->codeAppendf("half3 lerpRGB = mix(%s.aaa, %s.aaa, %s.rgb);",
- dstColor, outColor, srcCoverage);
- }
- fragBuilder->codeAppendf("%s = %s * %s + (half4(1.0) - %s) * %s;",
- outColor, srcCoverage, outColor, srcCoverage, dstColor);
- if (proc.isLCD()) {
- fragBuilder->codeAppendf("%s.a = max(max(lerpRGB.r, lerpRGB.b), lerpRGB.g);", outColor);
- }
- }
-}
diff --git a/src/gpu/glsl/GrGLSLXferProcessor.h b/src/gpu/glsl/GrGLSLXferProcessor.h
deleted file mode 100644
index f063440..0000000
--- a/src/gpu/glsl/GrGLSLXferProcessor.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrGLSLXferProcessor_DEFINED
-#define GrGLSLXferProcessor_DEFINED
-
-#include "include/core/SkPoint.h"
-#include "src/gpu/GrXferProcessor.h"
-#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
-#include "src/gpu/glsl/GrGLSLUniformHandler.h"
-
-class GrXferProcessor;
-class GrGLSLXPFragmentBuilder;
-class GrShaderCaps;
-class GrTexture;
-
-class GrXferProcessor::ProgramImpl {
-public:
- virtual ~ProgramImpl() = default;
-
- using SamplerHandle = GrGLSLUniformHandler::SamplerHandle;
-
- struct EmitArgs {
- EmitArgs(GrGLSLXPFragmentBuilder* fragBuilder,
- GrGLSLUniformHandler* uniformHandler,
- const GrShaderCaps* caps,
- const GrXferProcessor& xp,
- const char* inputColor,
- const char* inputCoverage,
- const char* outputPrimary,
- const char* outputSecondary,
- const SamplerHandle dstTextureSamplerHandle,
- GrSurfaceOrigin dstTextureOrigin,
- const GrSwizzle& writeSwizzle)
- : fXPFragBuilder(fragBuilder)
- , fUniformHandler(uniformHandler)
- , fShaderCaps(caps)
- , fXP(xp)
- , fInputColor(inputColor ? inputColor : "half4(1.0)")
- , fInputCoverage(inputCoverage)
- , fOutputPrimary(outputPrimary)
- , fOutputSecondary(outputSecondary)
- , fDstTextureSamplerHandle(dstTextureSamplerHandle)
- , fDstTextureOrigin(dstTextureOrigin)
- , fWriteSwizzle(writeSwizzle) {}
- GrGLSLXPFragmentBuilder* fXPFragBuilder;
- GrGLSLUniformHandler* fUniformHandler;
- const GrShaderCaps* fShaderCaps;
- const GrXferProcessor& fXP;
- const char* fInputColor;
- const char* fInputCoverage;
- const char* fOutputPrimary;
- const char* fOutputSecondary;
- const SamplerHandle fDstTextureSamplerHandle;
- GrSurfaceOrigin fDstTextureOrigin;
- GrSwizzle fWriteSwizzle;
- };
- /**
- * This is similar to emitCode() in the base class, except it takes a full shader builder.
- * This allows the effect subclass to emit vertex code.
- */
- void emitCode(const EmitArgs&);
-
- /** A ProgramImpl instance can be reused with any GrXferProcessor that produces the same key.
- This function reads data from a GrXferProcessor and uploads any uniform variables required
- by the shaders created in emitCode(). The GrXferProcessor parameter is guaranteed to be of
- the same type that created this ProgramImpl and to have an identical processor key as the
- one that created this ProgramImpl. This function calls onSetData on the subclass of
- ProgramImpl.
- */
- void setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp);
-
-protected:
- ProgramImpl() = default;
-
- static void DefaultCoverageModulation(GrGLSLXPFragmentBuilder* fragBuilder,
- const char* srcCoverage,
- const char* dstColor,
- const char* outColor,
- const char* outColorSecondary,
- const GrXferProcessor& proc);
-
-private:
- /**
- * Called by emitCode() when the XP will not be performing a dst read. This method is
- * responsible for both blending and coverage. A subclass only needs to implement this method if
- * it can construct a GrXferProcessor that will not read the dst color.
- */
- virtual void emitOutputsForBlendState(const EmitArgs&) {
- SK_ABORT("emitOutputsForBlendState not implemented.");
- }
-
- /**
- * Called by emitCode() when the XP will perform a dst read. This method only needs to supply
- * the blending logic. The base class applies coverage. A subclass only needs to implement this
- * method if it can construct a GrXferProcessor that reads the dst color.
- */
- virtual void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder*,
- GrGLSLUniformHandler*,
- const char* srcColor,
- const char* srcCoverage,
- const char* dstColor,
- const char* outColor,
- const char* outColorSecondary,
- const GrXferProcessor&) {
- SK_ABORT("emitBlendCodeForDstRead not implemented.");
- }
-
- virtual void emitWriteSwizzle(GrGLSLXPFragmentBuilder*,
- const GrSwizzle&,
- const char* outColor,
- const char* outColorSecondary) const;
-
- virtual void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) {}
-};
-#endif
diff --git a/src/gpu/mtl/GrMtlPipelineState.mm b/src/gpu/mtl/GrMtlPipelineState.mm
index cb371fe..fd581d4 100644
--- a/src/gpu/mtl/GrMtlPipelineState.mm
+++ b/src/gpu/mtl/GrMtlPipelineState.mm
@@ -8,13 +8,12 @@
#include "src/gpu/mtl/GrMtlPipelineState.h"
#include "src/gpu/GrBackendUtils.h"
-#include "src/gpu/GrPipeline.h"
+#include "src/gpu/GrFragmentProcessor.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrTexture.h"
+#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
#include "src/gpu/mtl/GrMtlBuffer.h"
#include "src/gpu/mtl/GrMtlFramebuffer.h"
#include "src/gpu/mtl/GrMtlGpu.h"
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index 58d5bd2..9b98913 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -21,7 +21,6 @@
#include "src/gpu/geometry/GrPathUtils.h"
#include "src/gpu/geometry/GrStyledShape.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
@@ -624,7 +623,7 @@
// Setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
- varyingHandler->addPassThroughAttribute(qe.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(qe.fInColor.asShaderVar(), args.fOutputColor);
// Setup position
WriteOutputPosition(vertBuilder, gpArgs, qe.fInPosition.name());
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
index 7576d58..9a48f83 100644
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
@@ -21,7 +21,6 @@
#include "src/gpu/GrVertexWriter.h"
#include "src/gpu/geometry/GrPathUtils.h"
#include "src/gpu/geometry/GrStyledShape.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/ops/GrAAConvexTessellator.h"
#include "src/gpu/ops/GrAALinearizingConvexPathRenderer.h"
#include "src/gpu/ops/GrMeshDrawOp.h"
diff --git a/src/gpu/ops/GrAtlasInstancedHelper.h b/src/gpu/ops/GrAtlasInstancedHelper.h
index 8a20934..b7ca2de 100644
--- a/src/gpu/ops/GrAtlasInstancedHelper.h
+++ b/src/gpu/ops/GrAtlasInstancedHelper.h
@@ -11,7 +11,6 @@
#include "src/core/SkIPoint16.h"
#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrSurfaceProxyView.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
struct GrVertexWriter;
diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp
index 72ecaf6..86d2433 100644
--- a/src/gpu/ops/GrDashOp.cpp
+++ b/src/gpu/ops/GrDashOp.cpp
@@ -23,7 +23,6 @@
#include "src/gpu/SkGr.h"
#include "src/gpu/geometry/GrQuad.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
diff --git a/src/gpu/ops/GrDrawAtlasPathOp.cpp b/src/gpu/ops/GrDrawAtlasPathOp.cpp
index fc4c2fb..eb5b74b 100644
--- a/src/gpu/ops/GrDrawAtlasPathOp.cpp
+++ b/src/gpu/ops/GrDrawAtlasPathOp.cpp
@@ -7,13 +7,13 @@
#include "src/gpu/ops/GrDrawAtlasPathOp.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrOpsRenderPass.h"
#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrResourceProvider.h"
#include "src/gpu/GrVertexWriter.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
@@ -104,7 +104,8 @@
args.fFragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
args.fVaryingHandler->addPassThroughAttribute(
- shader.fAttribs[shader.colorAttribIdx()], args.fOutputColor,
+ shader.fAttribs[shader.colorAttribIdx()].asShaderVar(),
+ args.fOutputColor,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
}
diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp
index 1eea29a..894fc40 100644
--- a/src/gpu/ops/GrDrawVerticesOp.cpp
+++ b/src/gpu/ops/GrDrawVerticesOp.cpp
@@ -5,22 +5,23 @@
* found in the LICENSE file.
*/
+#include "src/gpu/ops/GrDrawVerticesOp.h"
+
#include "include/core/SkM44.h"
#include "include/effects/SkRuntimeEffect.h"
#include "src/core/SkArenaAlloc.h"
#include "src/core/SkDevice.h"
#include "src/core/SkMatrixPriv.h"
#include "src/core/SkVerticesPriv.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrProgramInfo.h"
#include "src/gpu/GrVertexWriter.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
-#include "src/gpu/ops/GrDrawVerticesOp.h"
#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
namespace {
diff --git a/src/gpu/ops/GrDrawVerticesOp.h b/src/gpu/ops/GrDrawVerticesOp.h
index bd5cfa3..bd9e304 100644
--- a/src/gpu/ops/GrDrawVerticesOp.h
+++ b/src/gpu/ops/GrDrawVerticesOp.h
@@ -10,6 +10,7 @@
#include "include/core/SkRefCnt.h"
#include "include/private/GrTypesPriv.h"
+#include "src/gpu/ops/GrOp.h"
class GrColorSpaceXform;
class GrDrawOp;
diff --git a/src/gpu/ops/GrFillRRectOp.cpp b/src/gpu/ops/GrFillRRectOp.cpp
index eab0c8e..5464a8e 100644
--- a/src/gpu/ops/GrFillRRectOp.cpp
+++ b/src/gpu/ops/GrFillRRectOp.cpp
@@ -10,6 +10,7 @@
#include "include/gpu/GrRecordingContext.h"
#include "src/core/SkRRectPriv.h"
#include "src/gpu/GrCaps.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrMemoryPool.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrOpsRenderPass.h"
@@ -20,7 +21,6 @@
#include "src/gpu/GrVx.h"
#include "src/gpu/geometry/GrShape.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
#include "src/gpu/ops/GrMeshDrawOp.h"
@@ -585,7 +585,8 @@
GrGLSLVaryingHandler* varyings = args.fVaryingHandler;
varyings->emitAttributes(proc);
f->codeAppendf("half4 %s;", args.fOutputColor);
- varyings->addPassThroughAttribute(*proc.fColorAttrib, args.fOutputColor,
+ varyings->addPassThroughAttribute(proc.fColorAttrib->asShaderVar(),
+ args.fOutputColor,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
// Emit the vertex shader.
diff --git a/src/gpu/ops/GrFillRectOp.cpp b/src/gpu/ops/GrFillRectOp.cpp
index b8ab4a3..8d9ecc5 100644
--- a/src/gpu/ops/GrFillRectOp.cpp
+++ b/src/gpu/ops/GrFillRectOp.cpp
@@ -19,7 +19,6 @@
#include "src/gpu/geometry/GrQuadBuffer.h"
#include "src/gpu/geometry/GrQuadUtils.h"
#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/ops/GrMeshDrawOp.h"
#include "src/gpu/ops/GrQuadPerEdgeAA.h"
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index 91138dc..5e5e956 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -5,11 +5,14 @@
* found in the LICENSE file.
*/
+#include "src/gpu/ops/GrLatticeOp.h"
+
#include "include/core/SkBitmap.h"
#include "include/core/SkRect.h"
#include "src/core/SkLatticeIter.h"
#include "src/core/SkMatrixPriv.h"
#include "src/gpu/GrDrawOpTest.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrGpu.h"
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrProgramInfo.h"
@@ -19,9 +22,7 @@
#include "src/gpu/SkGr.h"
#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
-#include "src/gpu/ops/GrLatticeOp.h"
#include "src/gpu/ops/GrMeshDrawOp.h"
#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
@@ -67,13 +68,16 @@
gpArgs->fLocalCoordVar = latticeGP.fInTextureCoords.asShaderVar();
args.fFragBuilder->codeAppend("float2 textureCoords;");
- args.fVaryingHandler->addPassThroughAttribute(latticeGP.fInTextureCoords,
- "textureCoords");
+ args.fVaryingHandler->addPassThroughAttribute(
+ latticeGP.fInTextureCoords.asShaderVar(),
+ "textureCoords");
args.fFragBuilder->codeAppend("float4 textureDomain;");
args.fVaryingHandler->addPassThroughAttribute(
- latticeGP.fInTextureDomain, "textureDomain", Interpolation::kCanBeFlat);
+ latticeGP.fInTextureDomain.asShaderVar(),
+ "textureDomain",
+ Interpolation::kCanBeFlat);
args.fFragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
- args.fVaryingHandler->addPassThroughAttribute(latticeGP.fInColor,
+ args.fVaryingHandler->addPassThroughAttribute(latticeGP.fInColor.asShaderVar(),
args.fOutputColor,
Interpolation::kCanBeFlat);
args.fFragBuilder->codeAppendf("%s = ", args.fOutputColor);
diff --git a/src/gpu/ops/GrLatticeOp.h b/src/gpu/ops/GrLatticeOp.h
index 9bceccf..559dbb0 100644
--- a/src/gpu/ops/GrLatticeOp.h
+++ b/src/gpu/ops/GrLatticeOp.h
@@ -11,6 +11,7 @@
#include <memory>
#include "include/core/SkRefCnt.h"
#include "src/gpu/GrSamplerState.h"
+#include "src/gpu/ops/GrOp.h"
class GrColorSpaceXform;
class GrDrawOp;
diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp
index a43a452..1c7cee1 100644
--- a/src/gpu/ops/GrOvalOpFactory.cpp
+++ b/src/gpu/ops/GrOvalOpFactory.cpp
@@ -19,7 +19,6 @@
#include "src/gpu/GrStyle.h"
#include "src/gpu/GrVertexWriter.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
@@ -141,24 +140,28 @@
// emit attributes
varyingHandler->emitAttributes(cgp);
fragBuilder->codeAppend("float4 circleEdge;");
- varyingHandler->addPassThroughAttribute(cgp.fInCircleEdge, "circleEdge");
+ varyingHandler->addPassThroughAttribute(cgp.fInCircleEdge.asShaderVar(), "circleEdge");
if (cgp.fInClipPlane.isInitialized()) {
fragBuilder->codeAppend("half3 clipPlane;");
- varyingHandler->addPassThroughAttribute(cgp.fInClipPlane, "clipPlane");
+ varyingHandler->addPassThroughAttribute(cgp.fInClipPlane.asShaderVar(),
+ "clipPlane");
}
if (cgp.fInIsectPlane.isInitialized()) {
fragBuilder->codeAppend("half3 isectPlane;");
- varyingHandler->addPassThroughAttribute(cgp.fInIsectPlane, "isectPlane");
+ varyingHandler->addPassThroughAttribute(cgp.fInIsectPlane.asShaderVar(),
+ "isectPlane");
}
if (cgp.fInUnionPlane.isInitialized()) {
SkASSERT(cgp.fInClipPlane.isInitialized());
fragBuilder->codeAppend("half3 unionPlane;");
- varyingHandler->addPassThroughAttribute(cgp.fInUnionPlane, "unionPlane");
+ varyingHandler->addPassThroughAttribute(cgp.fInUnionPlane.asShaderVar(),
+ "unionPlane");
}
GrGLSLVarying capRadius(kFloat_GrSLType);
if (cgp.fInRoundCapCenters.isInitialized()) {
fragBuilder->codeAppend("float4 roundCapCenters;");
- varyingHandler->addPassThroughAttribute(cgp.fInRoundCapCenters, "roundCapCenters");
+ varyingHandler->addPassThroughAttribute(cgp.fInRoundCapCenters.asShaderVar(),
+ "roundCapCenters");
varyingHandler->addVarying("capRadius", &capRadius,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
// This is the cap radius in normalized space where the outer radius is 1 and
@@ -169,7 +172,7 @@
// setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
- varyingHandler->addPassThroughAttribute(cgp.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(cgp.fInColor.asShaderVar(), args.fOutputColor);
// Setup position
WriteOutputPosition(vertBuilder, gpArgs, cgp.fInPosition.name());
@@ -318,11 +321,13 @@
// emit attributes
varyingHandler->emitAttributes(bcscgp);
fragBuilder->codeAppend("float4 circleEdge;");
- varyingHandler->addPassThroughAttribute(bcscgp.fInCircleEdge, "circleEdge");
+ varyingHandler->addPassThroughAttribute(bcscgp.fInCircleEdge.asShaderVar(),
+ "circleEdge");
fragBuilder->codeAppend("float4 dashParams;");
varyingHandler->addPassThroughAttribute(
- bcscgp.fInDashParams, "dashParams",
+ bcscgp.fInDashParams.asShaderVar(),
+ "dashParams",
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
GrGLSLVarying wrapDashes(kHalf4_GrSLType);
varyingHandler->addVarying("wrapDashes", &wrapDashes,
@@ -393,7 +398,8 @@
// setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
varyingHandler->addPassThroughAttribute(
- bcscgp.fInColor, args.fOutputColor,
+ bcscgp.fInColor.asShaderVar(),
+ args.fOutputColor,
GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
// Setup position
@@ -587,7 +593,7 @@
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// setup pass through color
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
- varyingHandler->addPassThroughAttribute(egp.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(egp.fInColor.asShaderVar(), args.fOutputColor);
// Setup position
WriteOutputPosition(vertBuilder, gpArgs, egp.fInPosition.name());
@@ -785,7 +791,8 @@
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
- varyingHandler->addPassThroughAttribute(diegp.fInColor, args.fOutputColor);
+ varyingHandler->addPassThroughAttribute(diegp.fInColor.asShaderVar(),
+ args.fOutputColor);
// Setup position
WriteOutputPosition(vertBuilder,
diff --git a/src/gpu/ops/GrQuadPerEdgeAA.cpp b/src/gpu/ops/GrQuadPerEdgeAA.cpp
index e95663c..6e62009 100644
--- a/src/gpu/ops/GrQuadPerEdgeAA.cpp
+++ b/src/gpu/ops/GrQuadPerEdgeAA.cpp
@@ -14,7 +14,6 @@
#include "src/gpu/geometry/GrQuadUtils.h"
#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
@@ -650,9 +649,12 @@
SkASSERT(gp.fCoverageMode != CoverageMode::kWithColor || !gp.fNeedsPerspective);
// The color cannot be flat if the varying coverage has been modulated into it
args.fFragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
- args.fVaryingHandler->addPassThroughAttribute(gp.fColor, args.fOutputColor,
- gp.fCoverageMode == CoverageMode::kWithColor ?
- Interpolation::kInterpolated : Interpolation::kCanBeFlat);
+ args.fVaryingHandler->addPassThroughAttribute(
+ gp.fColor.asShaderVar(),
+ args.fOutputColor,
+ gp.fCoverageMode == CoverageMode::kWithColor
+ ? Interpolation::kInterpolated
+ : Interpolation::kCanBeFlat);
blendDst = args.fOutputColor;
} else {
// Output color must be initialized to something
@@ -675,13 +677,15 @@
args.fFragBuilder->codeAppendf("texCoord = %s.xy / %s.z;",
v.fsIn(), v.fsIn());
} else {
- args.fVaryingHandler->addPassThroughAttribute(gp.fLocalCoord, "texCoord");
+ args.fVaryingHandler->addPassThroughAttribute(gp.fLocalCoord.asShaderVar(),
+ "texCoord");
}
// Clamp the now 2D localCoordName variable by the subset if it is provided
if (gp.fTexSubset.isInitialized()) {
args.fFragBuilder->codeAppend("float4 subset;");
- args.fVaryingHandler->addPassThroughAttribute(gp.fTexSubset, "subset",
+ args.fVaryingHandler->addPassThroughAttribute(gp.fTexSubset.asShaderVar(),
+ "subset",
Interpolation::kCanBeFlat);
args.fFragBuilder->codeAppend(
"texCoord = clamp(texCoord, subset.LT, subset.RB);");
@@ -726,8 +730,9 @@
// coverage. This only has to be done in the exterior triangles, the
// interior of the quad geometry can never be clipped by the subset box.
args.fFragBuilder->codeAppend("float4 geoSubset;");
- args.fVaryingHandler->addPassThroughAttribute(gp.fGeomSubset, "geoSubset",
- Interpolation::kCanBeFlat);
+ args.fVaryingHandler->addPassThroughAttribute(gp.fGeomSubset.asShaderVar(),
+ "geoSubset",
+ Interpolation::kCanBeFlat);
#ifdef SK_USE_LEGACY_AA_QUAD_SUBSET
args.fFragBuilder->codeAppend(
"if (coverage < 0.5) {"
diff --git a/src/gpu/tessellate/shaders/GrPathTessellationShader.h b/src/gpu/tessellate/shaders/GrPathTessellationShader.h
index 1563419..9c5d5a7 100644
--- a/src/gpu/tessellate/shaders/GrPathTessellationShader.h
+++ b/src/gpu/tessellate/shaders/GrPathTessellationShader.h
@@ -8,7 +8,6 @@
#ifndef GrPathTessellationShader_DEFINED
#define GrPathTessellationShader_DEFINED
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/tessellate/GrTessellationPathRenderer.h"
#include "src/gpu/tessellate/shaders/GrTessellationShader.h"
diff --git a/src/gpu/tessellate/shaders/GrPathTessellationShader_Hardware.cpp b/src/gpu/tessellate/shaders/GrPathTessellationShader_Hardware.cpp
index d5b234d..5f2b75e 100644
--- a/src/gpu/tessellate/shaders/GrPathTessellationShader_Hardware.cpp
+++ b/src/gpu/tessellate/shaders/GrPathTessellationShader_Hardware.cpp
@@ -8,7 +8,6 @@
#include "src/gpu/tessellate/shaders/GrPathTessellationShader.h"
#include "src/gpu/geometry/GrWangsFormula.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
namespace {
diff --git a/src/gpu/tessellate/shaders/GrStrokeTessellationShader.cpp b/src/gpu/tessellate/shaders/GrStrokeTessellationShader.cpp
index 510631b..20dc354 100644
--- a/src/gpu/tessellate/shaders/GrStrokeTessellationShader.cpp
+++ b/src/gpu/tessellate/shaders/GrStrokeTessellationShader.cpp
@@ -8,7 +8,6 @@
#include "src/gpu/tessellate/shaders/GrStrokeTessellationShader.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
#include "src/gpu/tessellate/GrStrokeTessellator.h"
diff --git a/src/gpu/tessellate/shaders/GrStrokeTessellationShader.h b/src/gpu/tessellate/shaders/GrStrokeTessellationShader.h
index e58e8c5..88a6880 100644
--- a/src/gpu/tessellate/shaders/GrStrokeTessellationShader.h
+++ b/src/gpu/tessellate/shaders/GrStrokeTessellationShader.h
@@ -12,7 +12,6 @@
#include "include/core/SkStrokeRec.h"
#include "src/gpu/GrVx.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/tessellate/GrTessellationPathRenderer.h"
diff --git a/src/gpu/tessellate/shaders/GrStrokeTessellationShader_InstancedImpl.cpp b/src/gpu/tessellate/shaders/GrStrokeTessellationShader_InstancedImpl.cpp
index 42081f0..dd82e90 100644
--- a/src/gpu/tessellate/shaders/GrStrokeTessellationShader_InstancedImpl.cpp
+++ b/src/gpu/tessellate/shaders/GrStrokeTessellationShader_InstancedImpl.cpp
@@ -9,7 +9,6 @@
#include "src/gpu/geometry/GrWangsFormula.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
void GrStrokeTessellationShader::InstancedImpl::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp
index 6ca5279..199853b 100644
--- a/src/gpu/vk/GrVkPipelineState.cpp
+++ b/src/gpu/vk/GrVkPipelineState.cpp
@@ -8,13 +8,13 @@
#include "src/gpu/vk/GrVkPipelineState.h"
#include "src/core/SkMipmap.h"
+#include "src/gpu/GrFragmentProcessor.h"
+#include "src/gpu/GrGeometryProcessor.h"
#include "src/gpu/GrPipeline.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrTexture.h"
+#include "src/gpu/GrXferProcessor.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
-#include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
-#include "src/gpu/glsl/GrGLSLXferProcessor.h"
#include "src/gpu/vk/GrVkBuffer.h"
#include "src/gpu/vk/GrVkCommandBuffer.h"
#include "src/gpu/vk/GrVkDescriptorPool.h"
diff --git a/src/gpu/vk/GrVkPipelineStateCache.cpp b/src/gpu/vk/GrVkPipelineStateCache.cpp
index f051ff6..ce0499d 100644
--- a/src/gpu/vk/GrVkPipelineStateCache.cpp
+++ b/src/gpu/vk/GrVkPipelineStateCache.cpp
@@ -5,15 +5,14 @@
* found in the LICENSE file.
*/
-
#include "include/gpu/GrContextOptions.h"
#include "include/gpu/GrDirectContext.h"
#include "src/core/SkOpts.h"
#include "src/gpu/GrDirectContextPriv.h"
+#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrProcessor.h"
#include "src/gpu/GrRenderTarget.h"
#include "src/gpu/GrStencilSettings.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/vk/GrVkGpu.h"
#include "src/gpu/vk/GrVkPipelineState.h"
diff --git a/src/shaders/SkPerlinNoiseShader.cpp b/src/shaders/SkPerlinNoiseShader.cpp
index 516d185..6ae6041 100644
--- a/src/shaders/SkPerlinNoiseShader.cpp
+++ b/src/shaders/SkPerlinNoiseShader.cpp
@@ -21,11 +21,11 @@
#if SK_SUPPORT_GPU
#include "include/gpu/GrRecordingContext.h"
+#include "src/gpu/GrFragmentProcessor.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/SkGr.h"
#include "src/gpu/effects/GrMatrixEffect.h"
#include "src/gpu/effects/GrTextureEffect.h"
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"
diff --git a/src/sksl/dsl/priv/DSLFPs.h b/src/sksl/dsl/priv/DSLFPs.h
index 372e921..3fa801d 100644
--- a/src/sksl/dsl/priv/DSLFPs.h
+++ b/src/sksl/dsl/priv/DSLFPs.h
@@ -12,7 +12,7 @@
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/GrFragmentProcessor.h"
namespace SkSL {
diff --git a/src/sksl/dsl/priv/DSLWriter.h b/src/sksl/dsl/priv/DSLWriter.h
index ae79be6..56b1db3 100644
--- a/src/sksl/dsl/priv/DSLWriter.h
+++ b/src/sksl/dsl/priv/DSLWriter.h
@@ -20,7 +20,7 @@
#include "src/sksl/ir/SkSLExpressionStatement.h"
#include "src/sksl/ir/SkSLProgram.h"
#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
-#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
+#include "src/gpu/GrFragmentProcessor.h"
#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
#include <list>
#include <stack>