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
This commit is contained in:
wangyix 2015-08-12 09:40:47 -07:00 committed by Commit bot
parent cc34c41326
commit 58d890bd45
6 changed files with 49 additions and 55 deletions

View File

@ -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<const GrCoordTransform*, true>* 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<GrFragmentProcessor*, false>& 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<GrFragmentProcessor*, false> 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<GrFragmentStage, false> fChildProcessors;
typedef GrProcessor INHERITED;
};

View File

@ -15,6 +15,7 @@
#include "GrProcessorDataManager.h"
#include "GrXferProcessor.h"
#include "effects/GrPorterDuffXferProcessor.h"
#include "GrFragmentProcessor.h"
#include "SkRegion.h"
#include "SkXfermode.h"

View File

@ -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;

View File

@ -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

View File

@ -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;
}
}

View File

@ -179,18 +179,6 @@ const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
return fGpu->ctxInfo();
}
static void append_gr_fp_coord_transforms(const GrFragmentProcessor* processor,
SkTArray<const GrCoordTransform*, true>* 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);