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:
parent
cc34c41326
commit
58d890bd45
@ -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;
|
||||
};
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "GrProcessorDataManager.h"
|
||||
#include "GrXferProcessor.h"
|
||||
#include "effects/GrPorterDuffXferProcessor.h"
|
||||
#include "GrFragmentProcessor.h"
|
||||
|
||||
#include "SkRegion.h"
|
||||
#include "SkXfermode.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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user