aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/glsl
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2016-09-19 08:36:58 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-09-19 08:36:58 -0700
commitd91237ee051523f439238042674ade99207fe4a6 (patch)
treee53b2b1e356e1945863bc6a6446187ee1f4d76f2 /src/gpu/glsl
parent122fac306189940a4135e884eaef71a9aa0d5c8a (diff)
Stop flattening GrCoordTransforms in parent GrFragmentProcessors.
This changes moves to a model that iterates over GrCTs in a GrFP hierarchy when inserting transformations by GrGLSLPrimitiveProcessors. GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2339203002 Review-Url: https://codereview.chromium.org/2339203002
Diffstat (limited to 'src/gpu/glsl')
-rw-r--r--src/gpu/glsl/GrGLSLFragmentProcessor.cpp52
-rw-r--r--src/gpu/glsl/GrGLSLFragmentProcessor.h32
-rw-r--r--src/gpu/glsl/GrGLSLGeometryProcessor.cpp113
-rw-r--r--src/gpu/glsl/GrGLSLGeometryProcessor.h32
-rw-r--r--src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp13
-rw-r--r--src/gpu/glsl/GrGLSLPrimitiveProcessor.h72
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.cpp42
-rw-r--r--src/gpu/glsl/GrGLSLProgramBuilder.h12
8 files changed, 217 insertions, 151 deletions
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
index 9a58db77bd..25cc14abca 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp
@@ -43,16 +43,16 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
const GrFragmentProcessor& childProc = args.fFp.childProcessor(childIndex);
/*
- * We now want to find the subset of coords and samplers that belong to the child and its
- * descendants and put that into childCoords and childSamplers. To do so, we'll do a forwards
- * linear search.
+ * TODO: Move textures and buffers to the iterator model used by coords.
+ * We now want to find the subset of samplers that belong to the child and its descendants and
+ * put that into childSamplers. To do so, we'll do a forwards linear search.
*
* Explanation:
- * Each GrFragmentProcessor has a copy of all the transforms and textures of itself and
- * all procs in its subtree. For example, suppose we have frag proc A, who has two children B
- * and D. B has a child C, and D has two children E and F. Each frag proc's transforms array
- * contains its own transforms, followed by the transforms of all its descendants (i.e. preorder
- * traversal). Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 transforms respectively.
+ * Each GrFragmentProcessor has a copy of all the textures of itself and all procs in its
+ * subtree. For example, suppose we have frag proc A, who has two children B and D. B has a
+ * child C, and D has two children E and F. Each frag proc's textures array contains its own
+ * textures, followed by the textures of all its descendants (i.e. preorder traversal). Suppose
+ * procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 textures respectively.
*
* (A)
* [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2]
@@ -66,28 +66,22 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
* [c1] [e1,e2,e3] [f1,f2]
*
* So if we're inside proc A's emitCode, and A is about to call emitCode on proc D, we want the
- * EmitArgs that's passed onto D to only contain its and its descendants' coords. The
- * EmitArgs given to A would contain the transforms [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2], and we want
+ * EmitArgs that's passed onto D to only contain its and its descendants' textures. The
+ * EmitArgs given to A would contain the textures [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2], and we want
* to extract the subset [d1,e1,e2,e3,f1,f2] to pass on to D. We can do this with a linear
- * search since we know that A has 1 transform (using A.numTransformsExclChildren()), and B's
- * subtree has 3 transforms (using B.numTransforms()), so we know the start of D's transforms is
- * 4 after the start of A's transforms.
- * Textures work the same way as transforms.
+ * search since we know that A has 1 texture (using A.numTexturesExclChildren()), and B's
+ * subtree has 3 textures (using B.numTextures()), so we know the start of D's textures is
+ * 4 after the start of A's textures.
+ * Textures work the same way as textures.
*/
- int firstCoordAt = args.fFp.numTransformsExclChildren();
int firstTextureAt = args.fFp.numTexturesExclChildren();
int firstBufferAt = args.fFp.numBuffersExclChildren();
for (int i = 0; i < childIndex; ++i) {
- firstCoordAt += args.fFp.childProcessor(i).numTransforms();
firstTextureAt += args.fFp.childProcessor(i).numTextures();
firstBufferAt += args.fFp.childProcessor(i).numBuffers();
}
- SkTArray<GrShaderVar> childCoords;
const SamplerHandle* childTexSamplers = nullptr;
const SamplerHandle* childBufferSamplers = nullptr;
- if (childProc.numTransforms() > 0) {
- childCoords.push_back_n(childProc.numTransforms(), &args.fTransformedCoords[firstCoordAt]);
- }
if (childProc.numTextures() > 0) {
childTexSamplers = &args.fTexSamplers[firstTextureAt];
}
@@ -105,7 +99,7 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
childProc,
outputColor,
inputColor,
- childCoords,
+ args.fTransformedCoords.childTransforms(childIndex),
childTexSamplers,
childBufferSamplers,
args.fGpImplementsDistanceVector);
@@ -114,3 +108,19 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu
fragBuilder->onAfterChildProcEmitCode();
}
+
+//////////////////////////////////////////////////////////////////////////////
+
+using TransformedCoordVars = GrGLSLFragmentProcessor::TransformedCoordVars;
+TransformedCoordVars TransformedCoordVars::childTransforms(int childIdx) const {
+ const GrFragmentProcessor* child = &fFP->childProcessor(childIdx);
+ GrFragmentProcessor::Iter iter(fFP);
+ int numToSkip = 0;
+ while (true) {
+ const GrFragmentProcessor* fp = iter.next();
+ if (fp == child) {
+ return TransformedCoordVars(child, fTransformedVars + numToSkip);
+ }
+ numToSkip += fp->numCoordTransforms();
+ }
+}
diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.h b/src/gpu/glsl/GrGLSLFragmentProcessor.h
index f4a93ebe71..9889bcc9c6 100644
--- a/src/gpu/glsl/GrGLSLFragmentProcessor.h
+++ b/src/gpu/glsl/GrGLSLFragmentProcessor.h
@@ -33,6 +33,30 @@ public:
typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
+ /**
+ * When building a program from a GrPipeline this is used to provide the GrShaderVars that
+ * contain the resulting transformed coords from each of a GrFragmentProcessor's
+ * GrCoordTransforms. This allows the GrFragmentProcessor subclasses to refer to the transformed
+ * coords in fragment code.
+ */
+ class TransformedCoordVars {
+ public:
+ TransformedCoordVars(const GrFragmentProcessor* fp, const GrShaderVar* vars)
+ : fFP(fp)
+ , fTransformedVars(vars) {}
+
+ const GrShaderVar& operator[] (int i) const {
+ SkASSERT(i >= 0 && i < fFP->numCoordTransforms());
+ return fTransformedVars[i];
+ }
+
+ TransformedCoordVars childTransforms(int childIdx) const;
+
+ private:
+ const GrFragmentProcessor* fFP;
+ const GrShaderVar* fTransformedVars;
+ };
+
/** 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.
@@ -50,7 +74,7 @@ public:
etc.) that allows the processor to communicate back similar known
info about its output.
@param transformedCoords Fragment shader variables containing the coords computed using
- each of the GrFragmentProcessor's Coord Transforms.
+ each of the GrFragmentProcessor's GrCoordTransforms.
@param texSamplers Contains one entry for each GrTextureAccess of the GrProcessor.
These can be passed to the builder to emit texture reads in the
generated code.
@@ -65,7 +89,7 @@ public:
const GrFragmentProcessor& fp,
const char* outputColor,
const char* inputColor,
- const SkTArray<GrShaderVar>& transformedCoords,
+ const TransformedCoordVars& transformedCoordVars,
const SamplerHandle* texSamplers,
const SamplerHandle* bufferSamplers,
bool gpImplementsDistanceVector)
@@ -75,7 +99,7 @@ public:
, fFp(fp)
, fOutputColor(outputColor)
, fInputColor(inputColor)
- , fTransformedCoords(transformedCoords)
+ , fTransformedCoords(transformedCoordVars)
, fTexSamplers(texSamplers)
, fBufferSamplers(bufferSamplers)
, fGpImplementsDistanceVector(gpImplementsDistanceVector) {}
@@ -85,7 +109,7 @@ public:
const GrFragmentProcessor& fFp;
const char* fOutputColor;
const char* fInputColor;
- const SkTArray<GrShaderVar>& fTransformedCoords;
+ const TransformedCoordVars& fTransformedCoords;
const SamplerHandle* fTexSamplers;
const SamplerHandle* fBufferSamplers;
bool fGpImplementsDistanceVector;
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
index ddbe8e133a..bea49e5069 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.cpp
@@ -29,71 +29,82 @@ void GrGLSLGeometryProcessor::emitTransforms(GrGLSLVertexBuilder* vb,
const GrShaderVar& posVar,
const char* localCoords,
const SkMatrix& localMatrix,
- const TransformsIn& tin,
- TransformsOut* tout) {
- tout->push_back_n(tin.count());
- fInstalledTransforms.push_back_n(tin.count());
- for (int i = 0; i < tin.count(); i++) {
- const ProcCoords& coordTransforms = tin[i];
- fInstalledTransforms[i].push_back_n(coordTransforms.count());
- for (int t = 0; t < coordTransforms.count(); t++) {
- SkString strUniName("StageMatrix");
- strUniName.appendf("_%i_%i", i, t);
- GrSLType varyingType;
+ FPCoordTransformHandler* handler) {
+ int i = 0;
+ while (const GrCoordTransform* coordTransform = handler->nextCoordTransform()) {
+ SkString strUniName;
+ strUniName.printf("CoordTransformMatrix_%d", i);
+ GrSLType varyingType;
- GrCoordSet coordType = coordTransforms[t]->sourceCoords();
- uint32_t type = coordTransforms[t]->getMatrix().getType();
- if (kLocal_GrCoordSet == coordType) {
- type |= localMatrix.getType();
- }
- varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
- kVec2f_GrSLType;
- GrSLPrecision precision = coordTransforms[t]->precision();
+ GrCoordSet coordType = coordTransform->sourceCoords();
+ uint32_t type = coordTransform->getMatrix().getType();
+ if (kLocal_GrCoordSet == coordType) {
+ type |= localMatrix.getType();
+ }
+ varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
+ kVec2f_GrSLType;
+ GrSLPrecision precision = coordTransform->precision();
+
+ const char* uniName;
- const char* uniName;
- fInstalledTransforms[i][t].fHandle =
- uniformHandler->addUniform(kVertex_GrShaderFlag,
- kMat33f_GrSLType, precision,
- strUniName.c_str(),
- &uniName).toIndex();
- SkString strVaryingName("MatrixCoord");
- strVaryingName.appendf("_%i_%i", i, t);
+ fInstalledTransforms.push_back().fHandle = uniformHandler->addUniform(kVertex_GrShaderFlag,
+ kMat33f_GrSLType,
+ precision,
+ strUniName.c_str(),
+ &uniName).toIndex();
+ SkString strVaryingName;
+ strVaryingName.printf("TransformedCoords_%d", i);
- GrGLSLVertToFrag v(varyingType);
- varyingHandler->addVarying(strVaryingName.c_str(), &v, precision);
+ GrGLSLVertToFrag v(varyingType);
+ varyingHandler->addVarying(strVaryingName.c_str(), &v, precision);
- SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
- (*tout)[i].emplace_back(SkString(v.fsIn()), varyingType);
+ SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
+ handler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType);
- // varying = matrix * coords (logically)
- if (kDevice_GrCoordSet == coordType) {
- if (kVec2f_GrSLType == varyingType) {
- if (kVec2f_GrSLType == posVar.getType()) {
- vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
- v.vsOut(), uniName, posVar.c_str());
- } else {
- // The brackets here are just to scope the temp variable
- vb->codeAppendf("{ vec3 temp = %s * %s;", uniName, posVar.c_str());
- vb->codeAppendf("%s = vec2(temp.x/temp.z, temp.y/temp.z); }", v.vsOut());
- }
+ // varying = matrix * coords (logically)
+ if (kDevice_GrCoordSet == coordType) {
+ if (kVec2f_GrSLType == varyingType) {
+ if (kVec2f_GrSLType == posVar.getType()) {
+ vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
+ v.vsOut(), uniName, posVar.c_str());
} else {
- if (kVec2f_GrSLType == posVar.getType()) {
- vb->codeAppendf("%s = %s * vec3(%s, 1);",
- v.vsOut(), uniName, posVar.c_str());
- } else {
- vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, posVar.c_str());
- }
+ // The brackets here are just to scope the temp variable
+ vb->codeAppendf("{ vec3 temp = %s * %s;", uniName, posVar.c_str());
+ vb->codeAppendf("%s = vec2(temp.x/temp.z, temp.y/temp.z); }", v.vsOut());
}
} else {
- if (kVec2f_GrSLType == varyingType) {
- vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords);
+ if (kVec2f_GrSLType == posVar.getType()) {
+ vb->codeAppendf("%s = %s * vec3(%s, 1);",
+ v.vsOut(), uniName, posVar.c_str());
} else {
- vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords);
+ vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, posVar.c_str());
}
}
+ } else {
+ if (kVec2f_GrSLType == varyingType) {
+ vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords);
+ } else {
+ vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords);
+ }
+ }
+ ++i;
+ }
+}
+
+void GrGLSLGeometryProcessor::setTransformDataHelper(const SkMatrix& localMatrix,
+ const GrGLSLProgramDataManager& pdman,
+ FPCoordTransformIter* transformIter) {
+ int i = 0;
+ while (const GrCoordTransform* coordTransform = transformIter->next()) {
+ const SkMatrix& m = GetTransformMatrix(localMatrix, *coordTransform);
+ if (!fInstalledTransforms[i].fCurrentValue.cheapEqualTo(m)) {
+ pdman.setSkMatrix(fInstalledTransforms[i].fHandle.toIndex(), m);
+ fInstalledTransforms[i].fCurrentValue = m;
}
+ ++i;
}
+ SkASSERT(i == fInstalledTransforms.count());
}
void GrGLSLGeometryProcessor::setupPosition(GrGLSLVertexBuilder* vertBuilder,
diff --git a/src/gpu/glsl/GrGLSLGeometryProcessor.h b/src/gpu/glsl/GrGLSLGeometryProcessor.h
index d1e715f78a..6777620a88 100644
--- a/src/gpu/glsl/GrGLSLGeometryProcessor.h
+++ b/src/gpu/glsl/GrGLSLGeometryProcessor.h
@@ -22,31 +22,11 @@ public:
/* Any general emit code goes in the base class emitCode. Subclasses override onEmitCode */
void emitCode(EmitArgs&) override;
- // By default we use the identity matrix
- void setTransformData(const GrPrimitiveProcessor&,
- const GrGLSLProgramDataManager& pdman,
- int index,
- const SkTArray<const GrCoordTransform*, true>& transforms) override {
- this->setTransformDataHelper(SkMatrix::I(), pdman, index, transforms);
- }
-
protected:
// A helper which subclasses can use if needed and used above in the default setTransformData().
void setTransformDataHelper(const SkMatrix& localMatrix,
const GrGLSLProgramDataManager& pdman,
- int index,
- const SkTArray<const GrCoordTransform*, true>& transforms) {
- SkTArray<TransformUniform, true>& procTransforms = fInstalledTransforms[index];
- int numTransforms = transforms.count();
- for (int t = 0; t < numTransforms; ++t) {
- SkASSERT(procTransforms[t].fHandle.isValid());
- const SkMatrix& transform = GetTransformMatrix(localMatrix, *transforms[t]);
- if (!procTransforms[t].fCurrentValue.cheapEqualTo(transform)) {
- pdman.setSkMatrix(procTransforms[t].fHandle.toIndex(), transform);
- procTransforms[t].fCurrentValue = transform;
- }
- }
- }
+ FPCoordTransformIter*);
// Emit a uniform matrix for each coord transform.
void emitTransforms(GrGLSLVertexBuilder* vb,
@@ -54,10 +34,9 @@ protected:
GrGLSLUniformHandler* uniformHandler,
const GrShaderVar& posVar,
const char* localCoords,
- const TransformsIn& tin,
- TransformsOut* tout) {
+ FPCoordTransformHandler* handler) {
this->emitTransforms(vb, varyingHandler, uniformHandler,
- posVar, localCoords, SkMatrix::I(), tin, tout);
+ posVar, localCoords, SkMatrix::I(), handler);
}
// Emit pre-transformed coords as a vertex attribute per coord-transform.
@@ -67,8 +46,7 @@ protected:
const GrShaderVar& posVar,
const char* localCoords,
const SkMatrix& localMatrix,
- const TransformsIn&,
- TransformsOut*);
+ FPCoordTransformHandler*);
struct GrGPArgs {
// The variable used by a GP to store its position. It can be
@@ -103,7 +81,7 @@ private:
SkMatrix fCurrentValue = SkMatrix::InvalidMatrix();
};
- SkSTArray<8, SkSTArray<2, TransformUniform, true> > fInstalledTransforms;
+ SkTArray<TransformUniform, true> fInstalledTransforms;
typedef GrGLSLPrimitiveProcessor INHERITED;
};
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
index c19239a5d5..5ae28a0bbc 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
@@ -47,3 +47,16 @@ void GrGLSLPrimitiveProcessor::setupUniformColor(GrGLSLPPFragmentBuilder* fragBu
&stagedLocalVarName);
fragBuilder->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
}
+
+//////////////////////////////////////////////////////////////////////////////
+
+const GrCoordTransform* GrGLSLPrimitiveProcessor::FPCoordTransformHandler::nextCoordTransform() {
+#ifdef SK_DEBUG
+ SkASSERT(nullptr == fCurr || fAddedCoord);
+ fAddedCoord = false;
+ fCurr = fIter.next();
+ return fCurr;
+#else
+ return fIter.next();
+#endif
+}
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
index 6f3381f996..d270fa18fe 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.h
@@ -8,6 +8,7 @@
#ifndef GrGLSLPrimitiveProcessor_DEFINED
#define GrGLSLPrimitiveProcessor_DEFINED
+#include "GrFragmentProcessor.h"
#include "GrPrimitiveProcessor.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLSampler.h"
@@ -23,14 +24,45 @@ class GrGLSLVertexBuilder;
class GrGLSLPrimitiveProcessor {
public:
+ using FPCoordTransformIter = GrFragmentProcessor::CoordTransformIter;
+
virtual ~GrGLSLPrimitiveProcessor() {}
typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
typedef GrGLSLProgramDataManager::UniformHandle SamplerHandle;
- typedef SkSTArray<2, const GrCoordTransform*, true> ProcCoords;
- typedef SkSTArray<8, ProcCoords> TransformsIn;
- typedef SkSTArray<8, SkTArray<GrShaderVar>> TransformsOut;
+ /**
+ * This class provides access to the GrCoordTransforms across all GrFragmentProcessors in a
+ * GrPipeline. It is also used by the primitive processor to specify the fragment shader
+ * variable that will hold the transformed coords for each GrCoordTransform. It is required that
+ * the primitive processor iterate over each coord transform and insert a shader var result for
+ * each. The GrGLSLFragmentProcessors will reference these variables in their fragment code.
+ */
+ class FPCoordTransformHandler : public SkNoncopyable {
+ public:
+ FPCoordTransformHandler(const GrPipeline& pipeline,
+ SkTArray<GrShaderVar>* transformedCoordVars)
+ : fIter(pipeline)
+ , fTransformedCoordVars(transformedCoordVars) {}
+
+ ~FPCoordTransformHandler() { SkASSERT(!this->nextCoordTransform());}
+
+ const GrCoordTransform* nextCoordTransform();
+
+ // 'args' are constructor params to GrShaderVar.
+ template<typename... Args>
+ void specifyCoordsForCurrCoordTransform(Args&&... args) {
+ SkASSERT(!fAddedCoord);
+ fTransformedCoordVars->emplace_back(std::forward<Args>(args)...);
+ SkDEBUGCODE(fAddedCoord = true;)
+ }
+
+ private:
+ GrFragmentProcessor::CoordTransformIter fIter;
+ SkDEBUGCODE(bool fAddedCoord = false;)
+ SkDEBUGCODE(const GrCoordTransform* fCurr = nullptr;)
+ SkTArray<GrShaderVar>* fTransformedCoordVars;
+ };
struct EmitArgs {
EmitArgs(GrGLSLVertexBuilder* vertBuilder,
@@ -44,8 +76,7 @@ public:
const char* distanceVectorName,
const SamplerHandle* texSamplers,
const SamplerHandle* bufferSamplers,
- const TransformsIn& transformsIn,
- TransformsOut* transformsOut)
+ FPCoordTransformHandler* transformHandler)
: fVertBuilder(vertBuilder)
, fFragBuilder(fragBuilder)
, fVaryingHandler(varyingHandler)
@@ -57,8 +88,7 @@ public:
, fDistanceVectorName(distanceVectorName)
, fTexSamplers(texSamplers)
, fBufferSamplers(bufferSamplers)
- , fTransformsIn(transformsIn)
- , fTransformsOut(transformsOut) {}
+ , fFPCoordTransformHandler(transformHandler) {}
GrGLSLVertexBuilder* fVertBuilder;
GrGLSLPPFragmentBuilder* fFragBuilder;
GrGLSLVaryingHandler* fVaryingHandler;
@@ -70,8 +100,7 @@ public:
const char* fDistanceVectorName;
const SamplerHandle* fTexSamplers;
const SamplerHandle* fBufferSamplers;
- const TransformsIn& fTransformsIn;
- TransformsOut* fTransformsOut;
+ FPCoordTransformHandler* fFPCoordTransformHandler;
};
/**
@@ -80,21 +109,22 @@ public:
*/
virtual void emitCode(EmitArgs&) = 0;
- /** A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that
- produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and
- uploads any uniform variables required by the shaders created in emitCode(). The
- GrPrimitiveProcessor parameter is guaranteed to be of the same type that created this
- GrGLSLPrimitiveProcessor and to have an identical processor key as the one that created this
- GrGLSLPrimitiveProcessor. */
- virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) = 0;
+ /**
+ * A GrGLSLPrimitiveProcessor instance can be reused with any GrGLSLPrimitiveProcessor that
+ * produces the same stage key; this function reads data from a GrGLSLPrimitiveProcessor and
+ * uploads any uniform variables required by the shaders created in emitCode(). The
+ * GrPrimitiveProcessor parameter is guaranteed to be of the same type and to have an
+ * identical processor key as the GrPrimitiveProcessor that created this
+ * GrGLSLPrimitiveProcessor.
+ * The subclass may use the transform iterator to perform any setup required for the particular
+ * set of fp transform matrices, such as uploading via uniforms. The iterator will iterate over
+ * the transforms in the same order as the TransformHandler passed to emitCode.
+ */
+ virtual void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&,
+ FPCoordTransformIter&&) = 0;
static SkMatrix GetTransformMatrix(const SkMatrix& localMatrix, const GrCoordTransform&);
- virtual void setTransformData(const GrPrimitiveProcessor&,
- const GrGLSLProgramDataManager& pdman,
- int index,
- const SkTArray<const GrCoordTransform*, true>& transforms) = 0;
-
protected:
void setupUniformColor(GrGLSLPPFragmentBuilder* fragBuilder,
GrGLSLUniformHandler* uniformHandler,
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
index 4d442f9752..29470c4e2b 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.cpp
@@ -53,19 +53,9 @@ bool GrGLSLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor,
// be sent to the GrGLSLPrimitiveProcessor in its emitCode function
const GrPrimitiveProcessor& primProc = this->primitiveProcessor();
- for (int i = 0; i < this->pipeline().numFragmentProcessors(); i++) {
- const GrFragmentProcessor& processor = this->pipeline().getFragmentProcessor(i);
-
- SkTArray<const GrCoordTransform*, true>& procCoords = fCoordTransforms.push_back();
- processor.gatherCoordTransforms(&procCoords);
- }
-
this->emitAndInstallPrimProc(primProc, inputColor, inputCoverage);
- int numProcs = this->pipeline().numFragmentProcessors();
- this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentProcessors(), inputColor);
- this->emitAndInstallFragProcs(this->pipeline().numColorFragmentProcessors(), numProcs,
- inputCoverage);
+ this->emitAndInstallFragProcs(inputColor, inputCoverage);
if (primProc.getPixelLocalStorageState() !=
GrPixelLocalStorageState::kDraw_GrPixelLocalStorageState) {
this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *inputColor,
@@ -109,6 +99,8 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
SkSTArray<2, SamplerHandle> bufferSamplers(proc.numBuffers());
this->emitSamplers(proc, &texSamplers, &bufferSamplers);
+ GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline,
+ &fTransformedCoordVars);
GrGLSLGeometryProcessor::EmitArgs args(&fVS,
&fFS,
this->varyingHandler(),
@@ -120,8 +112,7 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
distanceVectorName,
texSamplers.begin(),
bufferSamplers.begin(),
- fCoordTransforms,
- &fOutCoords);
+ &transformHandler);
fGeometryProcessor->emitCode(args);
// We have to check that effects and the code they emit are consistent, ie if an effect
@@ -131,14 +122,21 @@ void GrGLSLProgramBuilder::emitAndInstallPrimProc(const GrPrimitiveProcessor& pr
fFS.codeAppend("}");
}
-void GrGLSLProgramBuilder::emitAndInstallFragProcs(int procOffset,
- int numProcs,
- GrGLSLExpr4* inOut) {
- for (int i = procOffset; i < numProcs; ++i) {
+void GrGLSLProgramBuilder::emitAndInstallFragProcs(GrGLSLExpr4* color, GrGLSLExpr4* coverage) {
+ int transformedCoordVarsIdx = 0;
+ GrGLSLExpr4** inOut = &color;
+ for (int i = 0; i < this->pipeline().numFragmentProcessors(); ++i) {
+ if (i == this->pipeline().numColorFragmentProcessors()) {
+ inOut = &coverage;
+ }
GrGLSLExpr4 output;
const GrFragmentProcessor& fp = this->pipeline().getFragmentProcessor(i);
- this->emitAndInstallFragProc(fp, i, *inOut, &output);
- *inOut = output;
+ this->emitAndInstallFragProc(fp, i, transformedCoordVarsIdx, **inOut, &output);
+ GrFragmentProcessor::Iter iter(&fp);
+ while (const GrFragmentProcessor* fp = iter.next()) {
+ transformedCoordVarsIdx += fp->numCoordTransforms();
+ }
+ **inOut = output;
}
}
@@ -146,6 +144,7 @@ void GrGLSLProgramBuilder::emitAndInstallFragProcs(int procOffset,
// the fix is to allow effects to take the GrGLSLExpr4 directly
void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
int index,
+ int transformedCoordVarsIdx,
const GrGLSLExpr4& input,
GrGLSLExpr4* output) {
// Program builders have a bit of state we need to clear with each effect
@@ -163,13 +162,15 @@ void GrGLSLProgramBuilder::emitAndInstallFragProc(const GrFragmentProcessor& fp,
SkSTArray<2, SamplerHandle> bufferSamplers(fp.numBuffers());
this->emitSamplers(fp, &texSamplers, &bufferSamplers);
+ const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx;
+ GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars);
GrGLSLFragmentProcessor::EmitArgs args(&fFS,
this->uniformHandler(),
this->glslCaps(),
fp,
output->c_str(),
input.isOnes() ? nullptr : input.c_str(),
- fOutCoords[index],
+ coords,
texSamplers.begin(),
bufferSamplers.begin(),
this->primitiveProcessor().implementsDistanceVector());
@@ -418,5 +419,4 @@ void GrGLSLProgramBuilder::finalizeShaders() {
this->varyingHandler()->finalize();
fVS.finalize(kVertex_GrShaderFlag);
fFS.finalize(kFragment_GrShaderFlag);
-
}
diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.h b/src/gpu/glsl/GrGLSLProgramBuilder.h
index 27c84372c1..8a8cff55ad 100644
--- a/src/gpu/glsl/GrGLSLProgramBuilder.h
+++ b/src/gpu/glsl/GrGLSLProgramBuilder.h
@@ -139,9 +139,10 @@ private:
void emitAndInstallPrimProc(const GrPrimitiveProcessor&,
GrGLSLExpr4* outputColor,
GrGLSLExpr4* outputCoverage);
- void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
+ void emitAndInstallFragProcs(GrGLSLExpr4* colorInOut, GrGLSLExpr4* coverageInOut);
void emitAndInstallFragProc(const GrFragmentProcessor&,
int index,
+ int transformedCoordVarsIdx,
const GrGLSLExpr4& input,
GrGLSLExpr4* output);
void emitAndInstallXferProc(const GrXferProcessor&,
@@ -167,11 +168,10 @@ private:
void verify(const GrFragmentProcessor&);
#endif
- GrGLSLPrimitiveProcessor::TransformsIn fCoordTransforms;
- GrGLSLPrimitiveProcessor::TransformsOut fOutCoords;
- int fNumVertexSamplers;
- int fNumGeometrySamplers;
- int fNumFragmentSamplers;
+ int fNumVertexSamplers;
+ int fNumGeometrySamplers;
+ int fNumFragmentSamplers;
+ SkSTArray<4, GrShaderVar> fTransformedCoordVars;
};
#endif