From 58d890bd45a201477ec6c4ba0ae61c574b4e5aef Mon Sep 17 00:00:00 2001 From: wangyix Date: Wed, 12 Aug 2015 09:40:47 -0700 Subject: [PATCH] All child GrFragmentProcs' transforms and textures will be stored in the root GrFragmentProc in preorder Changed childProcessor(i) to return const referencd Fixed rootProc/parentProc offset issues; renamed a few things. added nonempty check to gatherTransforms to avoid segfault removed recursive append_gr_coord_transforms() from GrGLProgramBuilder BUILDS! Changed num*includeProc() calls to num() calls added gatherCoordTransforms(). added coordTransforms() for root proc only Modified GrFragmentProcessor to append child proc transforms and textures to root proc's arrays. BUG=skia:4182 Review URL: https://codereview.chromium.org/1275853005 --- include/gpu/GrFragmentProcessor.h | 52 +++++++++------------- include/gpu/GrPaint.h | 1 + include/gpu/GrProcessor.h | 2 +- include/gpu/GrStagedProcessor.h | 3 +- src/gpu/GrProcessor.cpp | 27 ++++++++--- src/gpu/gl/builders/GrGLProgramBuilder.cpp | 19 ++------ 6 files changed, 49 insertions(+), 55 deletions(-) diff --git a/include/gpu/GrFragmentProcessor.h b/include/gpu/GrFragmentProcessor.h index 2dc7980964..bbc2f2bb07 100644 --- a/include/gpu/GrFragmentProcessor.h +++ b/include/gpu/GrFragmentProcessor.h @@ -9,6 +9,7 @@ #define GrFragmentProcessor_DEFINED #include "GrProcessor.h" +#include "GrStagedProcessor.h" class GrCoordTransform; class GrGLSLCaps; @@ -38,20 +39,12 @@ public: void getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const { this->onGetGLProcessorKey(caps, b); for (int i = 0; i < fChildProcessors.count(); ++i) { - fChildProcessors[i]->getGLProcessorKey(caps, b); + fChildProcessors[i].processor()->getGLProcessorKey(caps, b); } } int numTransforms() const { return fCoordTransforms.count(); } - int numTransformsIncludeChildProcs() const { - int numTransforms = fCoordTransforms.count(); - for (int i = 0; i < fChildProcessors.count(); ++i) { - numTransforms += fChildProcessors[i]->numTransformsIncludeChildProcs(); - } - return numTransforms; - } - /** Returns the coordinate transformation at index. index must be valid according to numTransforms(). */ const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; } @@ -60,29 +53,16 @@ public: return fCoordTransforms; } - /** Gather the coord transforms into an array. We use preorder traversal */ void gatherCoordTransforms(SkTArray* outTransforms) const { - SkASSERT(outTransforms); - outTransforms->push_back_n(fCoordTransforms.count(), fCoordTransforms.begin()); - for (int i = 0; i < fChildProcessors.count(); ++i) { - fChildProcessors[i]->gatherCoordTransforms(outTransforms); + if (!fCoordTransforms.empty()) { + outTransforms->push_back_n(fCoordTransforms.count(), fCoordTransforms.begin()); } } int numChildProcessors() const { return fChildProcessors.count(); } - GrFragmentProcessor* childProcessor(int index) const { return fChildProcessors[index]; } - - const SkTArray& childProcessors() const { - return fChildProcessors; - } - - int numTexturesIncludeChildProcs() const { - int numTextures = this->numTextures(); - for (int i = 0; i < fChildProcessors.count(); ++i) { - numTextures += fChildProcessors[i]->numTexturesIncludeChildProcs(); - } - return numTextures; + const GrFragmentProcessor& childProcessor(int index) const { + return *fChildProcessors[index].processor(); } /** Do any of the coordtransforms for this processor require local coords? */ @@ -140,13 +120,14 @@ protected: void addCoordTransform(const GrCoordTransform*); /** - * FragmentProcessor subclasses call this to register any child FragmentProcessors they have. + * FragmentProcessor subclasses call this from their constructor to register any child + * FragmentProcessors they have. * This is for processors whose shader code will be composed of nested processors whose output * colors will be combined somehow to produce its output color. Registering these child - * processors will allow the ProgramBuilder to automatically add their transformed coords and - * texture accesses and mangle their uniform and output color names and + * processors will allow the ProgramBuilder to automatically handle their transformed coords and + * texture accesses and mangle their uniform and output color names. */ - void registerChildProcessor(GrFragmentProcessor* child); + int registerChildProcessor(const GrFragmentProcessor* child); /** * Subclass implements this to support getConstantColorComponents(...). @@ -168,9 +149,16 @@ private: bool hasSameTransforms(const GrFragmentProcessor&) const; - SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms; bool fUsesLocalCoords; - SkTArray fChildProcessors; + + /** + * This 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. + * The same goes for fTextureAccesses with textures. + */ + SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms; + + SkTArray fChildProcessors; typedef GrProcessor INHERITED; }; diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h index efb3010286..e4b2b099d1 100644 --- a/include/gpu/GrPaint.h +++ b/include/gpu/GrPaint.h @@ -15,6 +15,7 @@ #include "GrProcessorDataManager.h" #include "GrXferProcessor.h" #include "effects/GrPorterDuffXferProcessor.h" +#include "GrFragmentProcessor.h" #include "SkRegion.h" #include "SkXfermode.h" diff --git a/include/gpu/GrProcessor.h b/include/gpu/GrProcessor.h index 719577377d..29d648cec8 100644 --- a/include/gpu/GrProcessor.h +++ b/include/gpu/GrProcessor.h @@ -118,6 +118,7 @@ protected: } uint32_t fClassID; + SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; private: static uint32_t GenClassID() { @@ -137,7 +138,6 @@ private: }; static int32_t gCurrProcessorClassID; - SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; bool fWillReadFragmentPosition; typedef GrProgramElement INHERITED; diff --git a/include/gpu/GrStagedProcessor.h b/include/gpu/GrStagedProcessor.h index a9f23b485b..fe3afcccb0 100644 --- a/include/gpu/GrStagedProcessor.h +++ b/include/gpu/GrStagedProcessor.h @@ -8,9 +8,10 @@ #ifndef GrStagedProcessorStage_DEFINED #define GrStagedProcessorStage_DEFINED -#include "GrFragmentProcessor.h" #include "SkRefCnt.h" +class GrFragmentProcessor; + /** * Wraps a GrFragmentProcessor, basically a copyable SkAutoTUnref * Templatized based on the ref type so backends can use the same wrapper diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index b990f9b285..6cc2a20d71 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -135,17 +135,34 @@ void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) { SkDEBUGCODE(transform->setInProcessor();) } -void GrFragmentProcessor::registerChildProcessor(GrFragmentProcessor* child) { - fChildProcessors.push_back(child); +int GrFragmentProcessor::registerChildProcessor(const GrFragmentProcessor* 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()); + } + if (!child->fTextureAccesses.empty()) { + fTextureAccesses.push_back_n(child->fTextureAccesses.count(), + child->fTextureAccesses.begin()); + } + + int index = fChildProcessors.count(); + fChildProcessors.push_back(GrFragmentStage(child)); + + if (child->willReadFragmentPosition()) + this->setWillReadFragmentPosition(); + + return index; } bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) const { - if (fCoordTransforms.count() != that.fCoordTransforms.count()) { + if (this->numTransforms() != that.numTransforms()) { return false; } - int count = fCoordTransforms.count(); + int count = this->numTransforms(); for (int i = 0; i < count; ++i) { - if (*fCoordTransforms[i] != *that.fCoordTransforms[i]) { + if (this->coordTransform(i) != that.coordTransform(i)) { return false; } } diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index c7528f0d4d..079b129cb1 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -179,18 +179,6 @@ const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const { return fGpu->ctxInfo(); } -static void append_gr_fp_coord_transforms(const GrFragmentProcessor* processor, - SkTArray* procCoords) { - // add the coord transforms of this processor - for (int i = 0; i < processor->numTransforms(); ++i) { - procCoords->push_back(&processor->coordTransform(i)); - } - // recursively add the coord transforms of this processor's child processors - for (int i = 0; i < processor->numChildProcessors(); ++i) { - append_gr_fp_coord_transforms(processor->childProcessor(i), procCoords); - } -} - bool GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) { // First we loop over all of the installed processors and collect coord transforms. These will // be sent to the GrGLPrimitiveProcessor in its emitCode function @@ -203,11 +191,10 @@ bool GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr if (!primProc.hasTransformedLocalCoords()) { SkSTArray<2, const GrCoordTransform*, true>& procCoords = fCoordTransforms.push_back(); - - append_gr_fp_coord_transforms(processor, &procCoords); + processor->gatherCoordTransforms(&procCoords); } - totalTextures += processor->numTexturesIncludeChildProcs(); + totalTextures += processor->numTextures(); if (totalTextures >= maxTextureUnits) { GrCapsDebugf(fGpu->caps(), "Program would use too many texture units\n"); return false; @@ -298,7 +285,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& fs, const GrFragmentProcessor& fp = *fs.processor(); ifp->fGLProc.reset(fp.createGLInstance()); - SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTexturesIncludeChildProcs()); + SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures()); this->emitSamplers(fp, &samplers, ifp); GrGLFragmentProcessor::EmitArgs args(this, fp, outColor, inColor, fOutCoords[index], samplers);