From a624bf3d1cb454c1959c5bbbf23a3afdfa3481f3 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Tue, 20 Sep 2016 09:12:47 -0700 Subject: [PATCH] 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 Committed: https://skia.googlesource.com/skia/+/d91237ee051523f439238042674ade99207fe4a6 Review-Url: https://codereview.chromium.org/2339203002 --- include/gpu/GrFragmentProcessor.h | 57 ++++++++++++--- src/gpu/GrDefaultGeoProcFactory.cpp | 18 ++--- src/gpu/GrFragmentProcessor.cpp | 49 ++++++++++--- src/gpu/GrOvalRenderer.cpp | 37 ++++------ src/gpu/GrPathProcessor.cpp | 77 +++++++++----------- src/gpu/GrProgramDesc.cpp | 2 +- src/gpu/batches/GrAAConvexPathRenderer.cpp | 15 +--- src/gpu/batches/GrAnalyticRectBatch.cpp | 17 ++--- src/gpu/batches/GrMSAAPathRenderer.cpp | 9 ++- src/gpu/batches/GrPLSPathRenderer.cpp | 53 +++++--------- src/gpu/effects/GrBezierEffect.cpp | 40 +++------- src/gpu/effects/GrBitmapTextGeoProc.cpp | 15 +--- src/gpu/effects/GrDashingEffect.cpp | 37 +++------- src/gpu/effects/GrDistanceFieldGeoProc.cpp | 22 +++--- src/gpu/gl/GrGLProgram.cpp | 11 +-- src/gpu/gl/GrGLProgram.h | 1 - src/gpu/glsl/GrGLSLFragmentProcessor.cpp | 53 ++++++++------ src/gpu/glsl/GrGLSLFragmentProcessor.h | 32 +++++++- src/gpu/glsl/GrGLSLGeometryProcessor.cpp | 113 ++++++++++++++++------------- src/gpu/glsl/GrGLSLGeometryProcessor.h | 32 ++------ src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp | 13 ++++ src/gpu/glsl/GrGLSLPrimitiveProcessor.h | 72 ++++++++++++------ src/gpu/glsl/GrGLSLProgramBuilder.cpp | 42 +++++------ src/gpu/glsl/GrGLSLProgramBuilder.h | 12 +-- src/gpu/instanced/InstanceProcessor.cpp | 7 +- src/gpu/vk/GrVkPipelineState.cpp | 5 +- tests/PrimitiveProcessorTest.cpp | 3 +- 27 files changed, 439 insertions(+), 405 deletions(-) diff --git a/include/gpu/GrFragmentProcessor.h b/include/gpu/GrFragmentProcessor.h index 6864702..270ee16 100644 --- a/include/gpu/GrFragmentProcessor.h +++ b/include/gpu/GrFragmentProcessor.h @@ -14,6 +14,7 @@ class GrCoordTransform; class GrGLSLCaps; class GrGLSLFragmentProcessor; class GrInvariantOutput; +class GrPipeline; class GrProcessorKeyBuilder; /** Provides custom fragment shader code. Fragment processors receive an input color (vec4f) and @@ -68,8 +69,7 @@ public: , fUsesDistanceVectorField(false) , fUsesLocalCoords(false) , fNumTexturesExclChildren(0) - , fNumBuffersExclChildren(0) - , fNumTransformsExclChildren(0) {} + , fNumBuffersExclChildren(0) {} ~GrFragmentProcessor() override; @@ -86,9 +86,7 @@ public: int numBuffersExclChildren() const { return fNumBuffersExclChildren; } - int numTransformsExclChildren() const { return fNumTransformsExclChildren; } - - int numTransforms() const { return fCoordTransforms.count(); } + int numCoordTransforms() const { return fCoordTransforms.count(); } /** Returns the coordinate transformation at index. index must be valid according to numTransforms(). */ @@ -135,6 +133,40 @@ public: this->onComputeInvariantOutput(inout); } + /** + * Pre-order traversal of a FP hierarchy, or of the forest of FPs in a GrPipeline. In the latter + * case the tree rooted at each FP in the GrPipeline is visited successively. + * */ + class Iter : public SkNoncopyable { + public: + explicit Iter(const GrFragmentProcessor* fp) { fFPStack.push_back(fp); } + explicit Iter(const GrPipeline& pipeline); + const GrFragmentProcessor* next(); + + private: + SkSTArray<4, const GrFragmentProcessor*, true> fFPStack; + }; + + /** + * Iterates over all the GrCoordTransforms in a GrPipeline's GrFragmentProcessors. FPs are + * visited in the same order as Iter and each of an FP's coord transforms are visited linearly. + */ + class CoordTransformIter : public SkNoncopyable { + public: + explicit CoordTransformIter(const GrPipeline& pipeline) + : fCurrFP(nullptr) + , fCTIdx(0) + , fFPIter(pipeline) { + fCurrFP = fFPIter.next(); + } + const GrCoordTransform* next(); + + private: + const GrFragmentProcessor* fCurrFP; + int fCTIdx; + GrFragmentProcessor::Iter fFPIter; + }; + protected: void addTextureAccess(const GrTextureAccess* textureAccess) override; void addBufferAccess(const GrBufferAccess*) override; @@ -206,15 +238,18 @@ private: bool fUsesLocalCoords; + SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms; + /** - * fCoordTransforms stores the transforms of this proc, followed by all the transforms of this - * proc's children. In other words, each proc stores all the transforms of its subtree as if + * A processor stores the texture accesses of this proc, followed by all the accesses of this + * proc's children. In other words, each proc stores all the accesses of its subtree as if * they were collected using preorder traversal. * * 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. Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 transforms - * respectively. The following shows what the fCoordTransforms array of each proc would contain: + * two children E and F. Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 accesses + * respectively. The following shows what the array of each proc's texture accesses would + * contain: * * (A) * [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2] @@ -227,12 +262,10 @@ private: * (C) (E) (F) * [c1] [e1,e2,e3] [f1,f2] * - * The same goes for fTextureAccesses with textures. + * The same goes for buffer accesses. */ - SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms; int fNumTexturesExclChildren; int fNumBuffersExclChildren; - int fNumTransformsExclChildren; /** * This is not SkSTArray<1, sk_sp> because this class holds strong diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp index 1b496b3..497f6b7 100644 --- a/src/gpu/GrDefaultGeoProcFactory.cpp +++ b/src/gpu/GrDefaultGeoProcFactory.cpp @@ -99,8 +99,7 @@ public: gpArgs->fPositionVar, gp.inLocalCoords()->fName, gp.localMatrix(), - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); } else { // emit transforms with position this->emitTransforms(vertBuilder, @@ -109,8 +108,7 @@ public: gpArgs->fPositionVar, gp.inPosition()->fName, gp.localMatrix(), - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); } // Setup coverage as pass through @@ -150,7 +148,8 @@ public: } void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& gp) override { + const GrPrimitiveProcessor& gp, + FPCoordTransformIter&& transformIter) override { const DefaultGeoProc& dgp = gp.cast(); if (!dgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dgp.viewMatrix())) { @@ -172,14 +171,7 @@ public: pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(dgp.coverage())); fCoverage = dgp.coverage(); } - } - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().fLocalMatrix, pdman, index, - transforms); + this->setTransformDataHelper(dgp.fLocalMatrix, pdman, &transformIter); } private: diff --git a/src/gpu/GrFragmentProcessor.cpp b/src/gpu/GrFragmentProcessor.cpp index a9d4a5e..3dfe25e 100644 --- a/src/gpu/GrFragmentProcessor.cpp +++ b/src/gpu/GrFragmentProcessor.cpp @@ -8,6 +8,7 @@ #include "GrFragmentProcessor.h" #include "GrCoordTransform.h" #include "GrInvariantOutput.h" +#include "GrPipeline.h" #include "GrProcOptInfo.h" #include "glsl/GrGLSLFragmentProcessor.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" @@ -81,16 +82,10 @@ void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) { fCoordTransforms.push_back(transform); fUsesLocalCoords = fUsesLocalCoords || transform->sourceCoords() == kLocal_GrCoordSet; SkDEBUGCODE(transform->setInProcessor();) - fNumTransformsExclChildren++; } int GrFragmentProcessor::registerChildProcessor(sk_sp child) { - // Append the child's transforms to our transforms array and the child's textures array to our - // textures array - if (!child->fCoordTransforms.empty()) { - fCoordTransforms.push_back_n(child->fCoordTransforms.count(), - child->fCoordTransforms.begin()); - } + // Append the child's textures array to our textures array if (!child->fTextureAccesses.empty()) { fTextureAccesses.push_back_n(child->fTextureAccesses.count(), child->fTextureAccesses.begin()); @@ -120,10 +115,10 @@ void GrFragmentProcessor::notifyRefCntIsZero() const { } bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const { - if (this->numTransforms() != that.numTransforms()) { + if (this->numCoordTransforms() != that.numCoordTransforms()) { return false; } - int count = this->numTransforms(); + int count = this->numCoordTransforms(); for (int i = 0; i < count; ++i) { if (this->coordTransform(i) != that.coordTransform(i)) { return false; @@ -408,3 +403,39 @@ sk_sp GrFragmentProcessor::RunInSeries(sk_sp(new SeriesFragmentProcessor(series, cnt)); } + +////////////////////////////////////////////////////////////////////////////// + +GrFragmentProcessor::Iter::Iter(const GrPipeline& pipeline) { + for (int i = pipeline.numFragmentProcessors() - 1; i >= 0; --i) { + fFPStack.push_back(&pipeline.getFragmentProcessor(i)); + } +} + +const GrFragmentProcessor* GrFragmentProcessor::Iter::next() { + if (fFPStack.empty()) { + return nullptr; + } + const GrFragmentProcessor* back = fFPStack.back(); + fFPStack.pop_back(); + for (int i = back->numChildProcessors() - 1; i >= 0; --i) { + fFPStack.push_back(&back->childProcessor(i)); + } + return back; +} + +////////////////////////////////////////////////////////////////////////////// + +const GrCoordTransform* GrFragmentProcessor::CoordTransformIter::next() { + if (!fCurrFP) { + return nullptr; + } + while (fCTIdx == fCurrFP->numCoordTransforms()) { + fCTIdx = 0; + fCurrFP = fFPIter.next(); + if (!fCurrFP) { + return nullptr; + } + } + return &fCurrFP->coordTransform(fCTIdx++); +} diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index a04aa00..90b2d8e 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -161,8 +161,7 @@ private: gpArgs->fPositionVar, cgp.fInPosition->fName, cgp.fLocalMatrix, - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); fragBuilder->codeAppend("float d = length(circleEdge.xy);"); fragBuilder->codeAppend("float distanceToOuterEdge = circleEdge.z * (1.0 - d);"); @@ -210,14 +209,10 @@ private: b->add32(key); } - void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) override {} - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc, + FPCoordTransformIter&& transformIter) override { this->setTransformDataHelper(primProc.cast().fLocalMatrix, - pdman, index, transforms); + pdman, &transformIter); } private: @@ -319,8 +314,7 @@ private: gpArgs->fPositionVar, egp.fInPosition->fName, egp.fLocalMatrix, - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); // for outer curve fragBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(), @@ -357,15 +351,10 @@ private: b->add32(key); } - void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp) override { - } - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().fLocalMatrix, - pdman, index, transforms); + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc, + FPCoordTransformIter&& transformIter) override { + const EllipseGeometryProcessor& egp = primProc.cast(); + this->setTransformDataHelper(egp.fLocalMatrix, pdman, &transformIter); } private: @@ -472,8 +461,7 @@ private: uniformHandler, gpArgs->fPositionVar, diegp.fInPosition->fName, - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); SkAssertResult(fragBuilder->enableFeature( GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); @@ -525,8 +513,8 @@ private: b->add32(key); } - void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& gp) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, + FPCoordTransformIter&& transformIter) override { const DIEllipseGeometryProcessor& diegp = gp.cast(); if (!diegp.fViewMatrix.isIdentity() && !fViewMatrix.cheapEqualTo(diegp.fViewMatrix)) { @@ -535,6 +523,7 @@ private: GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } + this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); } private: diff --git a/src/gpu/GrPathProcessor.cpp b/src/gpu/GrPathProcessor.cpp index aa776ec..c90481b 100644 --- a/src/gpu/GrPathProcessor.cpp +++ b/src/gpu/GrPathProcessor.cpp @@ -34,7 +34,7 @@ public: } // emit transforms - this->emitTransforms(args.fVaryingHandler, args.fTransformsIn, args.fTransformsOut); + this->emitTransforms(args.fVaryingHandler, args.fFPCoordTransformHandler); // Setup uniform color if (pathProc.overrides().readsColor()) { @@ -54,34 +54,30 @@ public: } void emitTransforms(GrGLSLVaryingHandler* varyingHandler, - 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++) { - GrSLType varyingType = - coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType : - kVec2f_GrSLType; - - SkString strVaryingName("MatrixCoord"); - strVaryingName.appendf("_%i_%i", i, t); - GrGLSLVertToFrag v(varyingType); - GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler; - fInstalledTransforms[i][t].fHandle = - glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(), - &v).toIndex(); - fInstalledTransforms[i][t].fType = varyingType; - - (*tout)[i].emplace_back(SkString(v.fsIn()), varyingType); - } + FPCoordTransformHandler* transformHandler) { + int i = 0; + while (const GrCoordTransform* coordTransform = transformHandler->nextCoordTransform()) { + GrSLType varyingType = + coordTransform->getMatrix().hasPerspective() ? kVec3f_GrSLType + : kVec2f_GrSLType; + + SkString strVaryingName; + strVaryingName.printf("TransformedCoord_%d", i); + GrGLSLVertToFrag v(varyingType); + GrGLVaryingHandler* glVaryingHandler = (GrGLVaryingHandler*) varyingHandler; + fInstalledTransforms.push_back().fHandle = + glVaryingHandler->addPathProcessingVarying(strVaryingName.c_str(), + &v).toIndex(); + fInstalledTransforms.back().fType = varyingType; + + transformHandler->specifyCoordsForCurrCoordTransform(SkString(v.fsIn()), varyingType); + ++i; } } void setData(const GrGLSLProgramDataManager& pd, - const GrPrimitiveProcessor& primProc) override { + const GrPrimitiveProcessor& primProc, + FPCoordTransformIter&& transformIter) override { const GrPathProcessor& pathProc = primProc.cast(); if (pathProc.overrides().readsColor() && pathProc.color() != fColor) { float c[4]; @@ -89,28 +85,21 @@ public: pd.set4fv(fColorUniform, 1, c); fColor = pathProc.color(); } - } - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& coordTransforms) override { - const GrPathProcessor& pathProc = primProc.cast(); - SkTArray& transforms = fInstalledTransforms[index]; - int numTransforms = transforms.count(); - for (int t = 0; t < numTransforms; ++t) { - SkASSERT(transforms[t].fHandle.isValid()); - const SkMatrix& transform = GetTransformMatrix(pathProc.localMatrix(), - *coordTransforms[t]); - if (transforms[t].fCurrentValue.cheapEqualTo(transform)) { + int t = 0; + while (const GrCoordTransform* coordTransform = transformIter.next()) { + SkASSERT(fInstalledTransforms[t].fHandle.isValid()); + const SkMatrix& m = GetTransformMatrix(pathProc.localMatrix(), *coordTransform); + if (fInstalledTransforms[t].fCurrentValue.cheapEqualTo(m)) { continue; } - transforms[t].fCurrentValue = transform; + fInstalledTransforms[t].fCurrentValue = m; - SkASSERT(transforms[t].fType == kVec2f_GrSLType || - transforms[t].fType == kVec3f_GrSLType); - unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3; - pdman.setPathFragmentInputTransform(transforms[t].fHandle, components, transform); + SkASSERT(fInstalledTransforms[t].fType == kVec2f_GrSLType || + fInstalledTransforms[t].fType == kVec3f_GrSLType); + unsigned components = fInstalledTransforms[t].fType == kVec2f_GrSLType ? 2 : 3; + pd.setPathFragmentInputTransform(fInstalledTransforms[t].fHandle, components, m); + ++t; } } @@ -122,7 +111,7 @@ private: GrSLType fType = kVoid_GrSLType; }; - SkSTArray<8, SkSTArray<2, TransformVarying, true> > fInstalledTransforms; + SkTArray fInstalledTransforms; UniformHandle fColorUniform; GrColor fColor; diff --git a/src/gpu/GrProgramDesc.cpp b/src/gpu/GrProgramDesc.cpp index a22063c..c452d34 100644 --- a/src/gpu/GrProgramDesc.cpp +++ b/src/gpu/GrProgramDesc.cpp @@ -101,7 +101,7 @@ static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc, fp.getGLSLProcessorKey(glslCaps, b); return gen_meta_key(fp, glslCaps, primProc.getTransformKey(fp.coordTransforms(), - fp.numTransformsExclChildren()), b); + fp.numCoordTransforms()), b); } bool GrProgramDesc::Build(GrProgramDesc* desc, diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp index a24a0c5..224567a 100644 --- a/src/gpu/batches/GrAAConvexPathRenderer.cpp +++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp @@ -577,8 +577,7 @@ public: gpArgs->fPositionVar, qe.inPosition()->fName, qe.localMatrix(), - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); SkAssertResult(fragBuilder->enableFeature( GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); @@ -614,7 +613,8 @@ public: } void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& gp) override { + const GrPrimitiveProcessor& gp, + FPCoordTransformIter&& transformIter) override { const QuadEdgeEffect& qe = gp.cast(); if (qe.color() != fColor) { float c[4]; @@ -622,14 +622,7 @@ public: pdman.set4fv(fColorUniform, 1, c); fColor = qe.color(); } - } - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().fLocalMatrix, pdman, index, - transforms); + this->setTransformDataHelper(qe.fLocalMatrix, pdman, &transformIter); } private: diff --git a/src/gpu/batches/GrAnalyticRectBatch.cpp b/src/gpu/batches/GrAnalyticRectBatch.cpp index 7be0ad3..8c0f419 100644 --- a/src/gpu/batches/GrAnalyticRectBatch.cpp +++ b/src/gpu/batches/GrAnalyticRectBatch.cpp @@ -18,6 +18,7 @@ #include "batches/GrVertexBatch.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLGeometryProcessor.h" +#include "glsl/GrGLSLGeometryProcessor.h" #include "glsl/GrGLSLProgramDataManager.h" #include "glsl/GrGLSLVarying.h" #include "glsl/GrGLSLVertexShaderBuilder.h" @@ -120,8 +121,7 @@ public: gpArgs->fPositionVar, rgp.inPosition()->fName, rgp.localMatrix(), - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); // TODO: compute all these offsets, spans, and scales in the VS fragBuilder->codeAppendf("float insetW = min(1.0, %s.x) - 0.5;", @@ -194,15 +194,10 @@ public: b->add32(0x0); } - void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& gp) override {} - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().fLocalMatrix, pdman, - index, transforms); + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc, + FPCoordTransformIter&& transformIter) override { + const RectGeometryProcessor& rgp = primProc.cast(); + this->setTransformDataHelper(rgp.fLocalMatrix, pdman,&transformIter); } private: diff --git a/src/gpu/batches/GrMSAAPathRenderer.cpp b/src/gpu/batches/GrMSAAPathRenderer.cpp index d6b5578..19dd366 100644 --- a/src/gpu/batches/GrMSAAPathRenderer.cpp +++ b/src/gpu/batches/GrMSAAPathRenderer.cpp @@ -148,8 +148,8 @@ public: // emit transforms this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar, - qp.inPosition()->fName, SkMatrix::I(), args.fTransformsIn, - args.fTransformsOut); + qp.inPosition()->fName, SkMatrix::I(), + args.fFPCoordTransformHandler); GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder; fsBuilder->codeAppendf("if (%s.x * %s.x >= %s.y) discard;", uv.fsIn(), uv.fsIn(), @@ -167,14 +167,15 @@ public: b->add32(key); } - virtual void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& gp) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, + FPCoordTransformIter&& transformIter) override { const MSAAQuadProcessor& qp = gp.cast(); if (!qp.viewMatrix().isIdentity()) { float viewMatrix[3 * 3]; GrGLSLGetMatrix<3>(viewMatrix, qp.viewMatrix()); pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } + this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); } private: diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp index 81009a6..e8711c0 100644 --- a/src/gpu/batches/GrPLSPathRenderer.cpp +++ b/src/gpu/batches/GrPLSPathRenderer.cpp @@ -333,8 +333,8 @@ public: // emit transforms this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar, - te.inPosition()->fName, te.localMatrix(), args.fTransformsIn, - args.fTransformsOut); + te.inPosition()->fName, te.localMatrix(), + args.fFPCoordTransformHandler); GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder; SkAssertResult(fsBuilder->enableFeature( @@ -391,16 +391,10 @@ public: b->add32(key); } - virtual void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& gp) override { - } - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().fLocalMatrix, pdman, - index, transforms); + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, + FPCoordTransformIter&& transformIter) override { + this->setTransformDataHelper(gp.cast().fLocalMatrix, pdman, + &transformIter); } private: @@ -522,8 +516,8 @@ public: // emit transforms this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar, - qe.inPosition()->fName, qe.localMatrix(), args.fTransformsIn, - args.fTransformsOut); + qe.inPosition()->fName, qe.localMatrix(), + args.fFPCoordTransformHandler); GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder; SkAssertResult(fsBuilder->enableFeature( @@ -581,16 +575,10 @@ public: b->add32(key); } - virtual void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& gp) override { - } - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().fLocalMatrix, pdman, - index, transforms); + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, + FPCoordTransformIter&& transformIter) override { + this->setTransformDataHelper(gp.cast().fLocalMatrix, pdman, + &transformIter); } private: @@ -680,8 +668,8 @@ public: varyingHandler->emitAttributes(fe); this->setupPosition(vsBuilder, gpArgs, fe.inPosition()->fName); this->emitTransforms(vsBuilder, varyingHandler, uniformHandler, gpArgs->fPositionVar, - fe.inPosition()->fName, fe.localMatrix(), args.fTransformsIn, - args.fTransformsOut); + fe.inPosition()->fName, fe.localMatrix(), + args.fFPCoordTransformHandler); GrGLSLPPFragmentBuilder* fsBuilder = args.fFragBuilder; SkAssertResult(fsBuilder->enableFeature( @@ -716,8 +704,8 @@ public: b->add32(key); } - virtual void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& gp) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, + FPCoordTransformIter&& transformIter) override { const PLSFinishEffect& fe = gp.cast(); pdman.set1f(fUseEvenOdd, fe.fUseEvenOdd); if (fe.color() != fColor && !fe.colorIgnored()) { @@ -726,14 +714,7 @@ public: pdman.set4fv(fColorUniform, 1, c); fColor = fe.color(); } - } - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().fLocalMatrix, pdman, - index, transforms); + this->setTransformDataHelper(fe.fLocalMatrix, pdman, &transformIter); } private: diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index 1894192..798695d 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -25,8 +25,8 @@ public: const GrGLSLCaps&, GrProcessorKeyBuilder*); - void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& primProc) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc, + FPCoordTransformIter&& transformIter) override { const GrConicEffect& ce = primProc.cast(); if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) { @@ -47,14 +47,7 @@ public: pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(ce.coverageScale())); fCoverageScale = ce.coverageScale(); } - } - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().localMatrix(), pdman, index, - transforms); + this->setTransformDataHelper(ce.localMatrix(), pdman, &transformIter); } private: @@ -109,8 +102,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { gpArgs->fPositionVar, gp.inPosition()->fName, gp.localMatrix(), - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); // TODO: this precision check should actually be a check on the number of bits // high and medium provide and the selection of the lowest level that suffices. @@ -299,8 +291,8 @@ public: const GrGLSLCaps&, GrProcessorKeyBuilder*); - void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& primProc) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc, + FPCoordTransformIter&& transformIter) override { const GrQuadEffect& qe = primProc.cast(); if (!qe.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(qe.viewMatrix())) { @@ -321,14 +313,7 @@ public: pdman.set1f(fCoverageScaleUniform, GrNormalizeByteToFloat(qe.coverageScale())); fCoverageScale = qe.coverageScale(); } - } - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().localMatrix(), pdman, index, - transforms); + this->setTransformDataHelper(qe.localMatrix(), pdman, &transformIter); } private: @@ -383,8 +368,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { gpArgs->fPositionVar, gp.inPosition()->fName, gp.localMatrix(), - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); fragBuilder->codeAppendf("float edgeAlpha;"); @@ -516,8 +500,8 @@ public: const GrGLSLCaps&, GrProcessorKeyBuilder*); - void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& primProc) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& primProc, + FPCoordTransformIter&& transformIter) override { const GrCubicEffect& ce = primProc.cast(); if (!ce.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(ce.viewMatrix())) { @@ -533,6 +517,7 @@ public: pdman.set4fv(fColorUniform, 1, c); fColor = ce.color(); } + this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); } private: @@ -584,8 +569,7 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { uniformHandler, gpArgs->fPositionVar, gp.inPosition()->fName, - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); GrGLSLShaderVar edgeAlpha("edgeAlpha", kFloat_GrSLType, 0, kHigh_GrSLPrecision); diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index 20a4e93..7f53663 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -60,8 +60,7 @@ public: gpArgs->fPositionVar, cte.inPosition()->fName, cte.localMatrix(), - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); if (cte.maskFormat() == kARGB_GrMaskFormat) { fragBuilder->codeAppendf("%s = ", args.fOutputColor); @@ -84,7 +83,8 @@ public: } } - void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp, + FPCoordTransformIter&& transformIter) override { const GrBitmapTextGeoProc& btgp = gp.cast(); if (btgp.color() != fColor && !btgp.hasVertexColor()) { float c[4]; @@ -92,14 +92,7 @@ public: pdman.set4fv(fColorUniform, 1, c); fColor = btgp.color(); } - } - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().localMatrix(), pdman, - index, transforms); + this->setTransformDataHelper(btgp.localMatrix(), pdman, &transformIter); } static inline void GenKey(const GrGeometryProcessor& proc, diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index 167cefa..9ce725b 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -817,16 +817,8 @@ public: const GrGLSLCaps&, GrProcessorKeyBuilder*); - void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) override; - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().localMatrix(), pdman, - index, transforms); - } - + void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&, + FPCoordTransformIter&& transformIter) override; private: UniformHandle fParamUniform; UniformHandle fColorUniform; @@ -879,8 +871,7 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { gpArgs->fPositionVar, dce.inPosition()->fName, dce.localMatrix(), - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); // transforms all points so that we can compare them to our test circle fragBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;", @@ -901,7 +892,8 @@ void GLDashingCircleEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { } void GLDashingCircleEffect::setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& processor) { + const GrPrimitiveProcessor& processor, + FPCoordTransformIter&& transformIter) { const DashingCircleEffect& dce = processor.cast(); if (dce.color() != fColor) { float c[4]; @@ -909,6 +901,7 @@ void GLDashingCircleEffect::setData(const GrGLSLProgramDataManager& pdman, pdman.set4fv(fColorUniform, 1, c); fColor = dce.color(); } + this->setTransformDataHelper(dce.localMatrix(), pdman, &transformIter); } void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& gp, @@ -1037,15 +1030,8 @@ public: const GrGLSLCaps&, GrProcessorKeyBuilder*); - void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) override; - - void setTransformData(const GrPrimitiveProcessor& primProc, - const GrGLSLProgramDataManager& pdman, - int index, - const SkTArray& transforms) override { - this->setTransformDataHelper(primProc.cast().localMatrix(), pdman, index, - transforms); - } + void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&, + FPCoordTransformIter&& iter) override; private: GrColor fColor; @@ -1094,8 +1080,7 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { gpArgs->fPositionVar, de.inPosition()->fName, de.localMatrix(), - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); // transforms all points so that we can compare them to our test rect fragBuilder->codeAppendf("float xShifted = %s.x - floor(%s.x / %s.z) * %s.z;", @@ -1134,7 +1119,8 @@ void GLDashingLineEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { } void GLDashingLineEffect::setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& processor) { + const GrPrimitiveProcessor& processor, + FPCoordTransformIter&& transformIter) { const DashingLineEffect& de = processor.cast(); if (de.color() != fColor) { float c[4]; @@ -1142,6 +1128,7 @@ void GLDashingLineEffect::setData(const GrGLSLProgramDataManager& pdman, pdman.set4fv(fColorUniform, 1, c); fColor = de.color(); } + this->setTransformDataHelper(de.localMatrix(), pdman, &transformIter); } void GLDashingLineEffect::GenKey(const GrGeometryProcessor& gp, diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp index c74c5ce..5404b0c 100644 --- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp +++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp @@ -73,8 +73,7 @@ public: uniformHandler, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); // add varyings GrGLSLVertToFrag recipScale(kFloat_GrSLType); @@ -179,7 +178,8 @@ public: fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); } - void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc, + FPCoordTransformIter&& transformIter) override { #ifdef SK_GAMMA_APPLY_TO_A8 const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast(); float distanceAdjust = dfTexEffect.getDistanceAdjust(); @@ -196,6 +196,7 @@ public: GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } + this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); } static inline void GenKey(const GrGeometryProcessor& gp, @@ -345,8 +346,7 @@ public: uniformHandler, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); const char* textureSizeUniName = nullptr; fTextureSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag, @@ -433,7 +433,8 @@ public: fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); } - void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc, + FPCoordTransformIter&& transformIter) override { SkASSERT(fTextureSizeUni.isValid()); GrTexture* texture = proc.texture(0); @@ -453,6 +454,7 @@ public: GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } + this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); } static inline void GenKey(const GrGeometryProcessor& gp, @@ -582,8 +584,7 @@ public: uniformHandler, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, - args.fTransformsIn, - args.fTransformsOut); + args.fFPCoordTransformHandler); // set up varyings bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) == @@ -732,8 +733,8 @@ public: fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage); } - void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& processor) override { + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& processor, + FPCoordTransformIter&& transformIter) override { SkASSERT(fDistanceAdjustUni.isValid()); const GrDistanceFieldLCDTextGeoProc& dflcd = processor.cast(); @@ -752,6 +753,7 @@ public: GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); } + this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); } static inline void GenKey(const GrGeometryProcessor& gp, diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index a87aa5a..f34fce4 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -70,7 +70,8 @@ void GrGLProgram::setData(const GrPrimitiveProcessor& primProc, const GrPipeline // we set the textures, and uniforms for installed processors in a generic way, but subclasses // of GLProgram determine how to set coord transforms int nextSamplerIdx = 0; - fGeometryProcessor->setData(fProgramDataManager, primProc); + fGeometryProcessor->setData(fProgramDataManager, primProc, + GrFragmentProcessor::CoordTransformIter(pipeline)); this->bindTextures(primProc, pipeline.getAllowSRGBInputs(), &nextSamplerIdx); this->setFragmentData(primProc, pipeline, &nextSamplerIdx); @@ -107,16 +108,10 @@ void GrGLProgram::setFragmentData(const GrPrimitiveProcessor& primProc, for (int i = 0; i < numProcessors; ++i) { const GrFragmentProcessor& processor = pipeline.getFragmentProcessor(i); fFragmentProcessors[i]->setData(fProgramDataManager, processor); - this->setTransformData(primProc, processor, i); this->bindTextures(processor, pipeline.getAllowSRGBInputs(), nextSamplerIdx); } } -void GrGLProgram::setTransformData(const GrPrimitiveProcessor& primProc, - const GrFragmentProcessor& processor, - int index) { - fGeometryProcessor->setTransformData(primProc, fProgramDataManager, index, - processor.coordTransforms()); -} + void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc, const GrPipeline& pipeline) { diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index ea98d87..34037a2 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -120,7 +120,6 @@ protected: // A helper to loop over effects, set the transforms (via subclass) and bind textures void setFragmentData(const GrPrimitiveProcessor&, const GrPipeline&, int* nextSamplerIdx); - void setTransformData(const GrPrimitiveProcessor&, const GrFragmentProcessor&, int index); // Helper for setData() that sets the view matrix and loads the render target height uniform void setRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&); diff --git a/src/gpu/glsl/GrGLSLFragmentProcessor.cpp b/src/gpu/glsl/GrGLSLFragmentProcessor.cpp index 9a58db7..82a07ca 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 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]; } @@ -99,13 +93,14 @@ void GrGLSLFragmentProcessor::internalEmitChild(int childIndex, const char* inpu fragBuilder->codeAppend("{\n"); fragBuilder->codeAppendf("// Child Index %d (mangle: %s): %s\n", childIndex, fragBuilder->getMangleString().c_str(), childProc.name()); + TransformedCoordVars coordVars = args.fTransformedCoords.childTransforms(childIndex); EmitArgs childArgs(fragBuilder, args.fUniformHandler, args.fGLSLCaps, childProc, outputColor, inputColor, - childCoords, + coordVars, childTexSamplers, childBufferSamplers, args.fGpImplementsDistanceVector); @@ -114,3 +109,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 f4a93eb..9889bcc 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& 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& 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 ddbe8e1..bea49e5 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 d1e715f..6777620 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& 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& transforms) { - SkTArray& 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 fInstalledTransforms; typedef GrGLSLPrimitiveProcessor INHERITED; }; diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp index c19239a..5ae28a0 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 6f3381f..d270fa1 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> 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* transformedCoordVars) + : fIter(pipeline) + , fTransformedCoordVars(transformedCoordVars) {} + + ~FPCoordTransformHandler() { SkASSERT(!this->nextCoordTransform());} + + const GrCoordTransform* nextCoordTransform(); + + // 'args' are constructor params to GrShaderVar. + template + void specifyCoordsForCurrCoordTransform(Args&&... args) { + SkASSERT(!fAddedCoord); + fTransformedCoordVars->emplace_back(std::forward(args)...); + SkDEBUGCODE(fAddedCoord = true;) + } + + private: + GrFragmentProcessor::CoordTransformIter fIter; + SkDEBUGCODE(bool fAddedCoord = false;) + SkDEBUGCODE(const GrCoordTransform* fCurr = nullptr;) + SkTArray* 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& transforms) = 0; - protected: void setupUniformColor(GrGLSLPPFragmentBuilder* fragBuilder, GrGLSLUniformHandler* uniformHandler, diff --git a/src/gpu/glsl/GrGLSLProgramBuilder.cpp b/src/gpu/glsl/GrGLSLProgramBuilder.cpp index 4d442f9..29470c4 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& 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 27c8437..8a8cff5 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 diff --git a/src/gpu/instanced/InstanceProcessor.cpp b/src/gpu/instanced/InstanceProcessor.cpp index 2b05ec1..480155b 100644 --- a/src/gpu/instanced/InstanceProcessor.cpp +++ b/src/gpu/instanced/InstanceProcessor.cpp @@ -80,7 +80,10 @@ public: void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override; private: - void setData(const GrGLSLProgramDataManager&, const GrPrimitiveProcessor&) override {} + void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&, + FPCoordTransformIter&& transformIter) override { + this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); + } class VertexInputs; class Backend; @@ -388,7 +391,7 @@ void GLSLInstanceProcessor::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) { gpArgs->fPositionVar.set(positionType, "deviceCoords"); this->emitTransforms(v, varyingHandler, uniHandler, gpArgs->fPositionVar, localCoords, - args.fTransformsIn, args.fTransformsOut); + args.fFPCoordTransformHandler); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/vk/GrVkPipelineState.cpp b/src/gpu/vk/GrVkPipelineState.cpp index 2398385..50250a5 100644 --- a/src/gpu/vk/GrVkPipelineState.cpp +++ b/src/gpu/vk/GrVkPipelineState.cpp @@ -194,14 +194,13 @@ void GrVkPipelineState::setData(GrVkGpu* gpu, SkSTArray<8, const GrTextureAccess*> textureBindings; - fGeometryProcessor->setData(fDataManager, primProc); + fGeometryProcessor->setData(fDataManager, primProc, + GrFragmentProcessor::CoordTransformIter(pipeline)); append_texture_bindings(primProc, &textureBindings); for (int i = 0; i < fFragmentProcessors.count(); ++i) { const GrFragmentProcessor& processor = pipeline.getFragmentProcessor(i); fFragmentProcessors[i]->setData(fDataManager, processor); - fGeometryProcessor->setTransformData(primProc, fDataManager, i, - processor.coordTransforms()); append_texture_bindings(processor, &textureBindings); } diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp index 55049ea..fc53f18 100644 --- a/tests/PrimitiveProcessorTest.cpp +++ b/tests/PrimitiveProcessorTest.cpp @@ -70,7 +70,8 @@ private: this->setupPosition(args.fVertBuilder, gpArgs, gp.fAttribs[0].fName); } void setData(const GrGLSLProgramDataManager& pdman, - const GrPrimitiveProcessor& primProc) override {} + const GrPrimitiveProcessor& primProc, + FPCoordTransformIter&&) override {} }; return new GLSLGP(); } -- 2.7.4