Opt state takes a GP instead of a GeometryStage

BUG=skia:

Committed: https://skia.googlesource.com/skia/+/71856d520461ae025a0332aa0ce9735a096d9baf

Review URL: https://codereview.chromium.org/637003003
This commit is contained in:
joshualitt 2014-10-10 17:47:00 -07:00 committed by Commit bot
parent ba5fb932a1
commit a5305a110a
26 changed files with 409 additions and 625 deletions

View File

@ -124,12 +124,6 @@ public:
in generated shader code. */
const char* name() const;
int numTransforms() const { return fCoordTransforms.count(); }
/** Returns the coordinate transformation at index. index must be valid according to
numTransforms(). */
const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
int numTextures() const { return fTextureAccesses.count(); }
/** Returns the access pattern for the texture at index. index must be valid according to
@ -158,16 +152,6 @@ public:
template <typename T> const T& cast() const { return *static_cast<const T*>(this); }
protected:
/**
* Subclasses call this from their constructor to register coordinate transformations. The
* effect subclass manages the lifetime of the transformations (this function only stores a
* pointer). The GrCoordTransform is typically a member field of the GrProcessor subclass. When
* the matrix has perspective, the transformed coordinates will have 3 components. Otherwise
* they'll have 2. This must only be called from the constructor because GrProcessors are
* immutable.
*/
void addCoordTransform(const GrCoordTransform* coordTransform);
/**
* Subclasses call this from their constructor to register GrTextureAccesses. The effect
* subclass manages the lifetime of the accesses (this function only stores a pointer). The
@ -198,9 +182,7 @@ private:
* Subclass implements this to support getConstantColorComponents(...).
*/
virtual void onComputeInvariantOutput(InvariantOutput* inout) const = 0;
friend class GrGeometryProcessor; // to set fRequiresVertexShader and build fVertexAttribTypes.
SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses;
bool fWillReadFragmentPosition;
@ -216,6 +198,12 @@ public:
virtual const GrBackendFragmentProcessorFactory& getFactory() const = 0;
int numTransforms() const { return fCoordTransforms.count(); }
/** Returns the coordinate transformation at index. index must be valid according to
numTransforms(). */
const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
/** Will this effect read the destination pixel value? */
bool willReadDstColor() const { return fWillReadDstColor; }
@ -223,6 +211,16 @@ public:
bool willUseInputColor() const { return fWillUseInputColor; }
protected:
/**
* Fragment Processor subclasses call this from their constructor to register coordinate
* transformations. The processor subclass manages the lifetime of the transformations (this
* function only stores a pointer). The GrCoordTransform is typically a member field of the
* GrProcessor subclass. When the matrix has perspective, the transformed coordinates will have
* 3 components. Otherwise they'll have 2. This must only be called from the constructor because
* GrProcessors are immutable.
*/
void addCoordTransform(const GrCoordTransform*);
/**
* If the effect subclass will read the destination pixel value then it must call this function
* from its constructor. Otherwise, when its generated backend-specific effect class attempts
@ -238,6 +236,7 @@ protected:
void setWillNotUseInputColor() { fWillUseInputColor = false; }
private:
SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
bool fWillReadDstColor;
bool fWillUseInputColor;

View File

@ -24,16 +24,14 @@
// is immutable, and only owns pending execution refs. This requries removing the common base
// class from GrDrawState and GrOptDrawState called GrRODrawState and converting to GrOptDrawState
// when draws are enqueued in the GrInOrderDrawBuffer.
class GrProcessorStage {
class GrFragmentStage {
public:
explicit GrProcessorStage(const GrProcessor* proc)
explicit GrFragmentStage(const GrFragmentProcessor* proc)
: fProc(SkRef(proc)) {
fCoordChangeMatrixSet = false;
}
virtual ~GrProcessorStage() {}
GrProcessorStage(const GrProcessorStage& other) {
GrFragmentStage(const GrFragmentStage& other) {
fCoordChangeMatrixSet = other.fCoordChangeMatrixSet;
if (other.fCoordChangeMatrixSet) {
fCoordChangeMatrix = other.fCoordChangeMatrix;
@ -41,7 +39,7 @@ public:
fProc.initAndRef(other.fProc);
}
static bool AreCompatible(const GrProcessorStage& a, const GrProcessorStage& b,
static bool AreCompatible(const GrFragmentStage& a, const GrFragmentStage& b,
bool usingExplicitLocalCoords) {
SkASSERT(a.fProc.get());
SkASSERT(b.fProc.get());
@ -90,7 +88,7 @@ public:
SkMatrix fCoordChangeMatrix;
SkDEBUGCODE(mutable uint32_t fEffectUniqueID;)
friend class GrProcessorStage;
friend class GrFragmentStage;
};
/**
@ -149,38 +147,14 @@ public:
}
}
virtual const GrProcessor* getProcessor() const = 0;
const GrFragmentProcessor* getProcessor() const { return fProc.get(); }
void convertToPendingExec() { fProc.convertToPendingExec(); }
protected:
bool fCoordChangeMatrixSet;
SkMatrix fCoordChangeMatrix;
GrProgramElementRef<const GrProcessor> fProc;
};
class GrFragmentStage : public GrProcessorStage {
public:
GrFragmentStage(const GrFragmentProcessor* fp) : GrProcessorStage(fp) {}
virtual const GrFragmentProcessor* getProcessor() const {
return static_cast<const GrFragmentProcessor*>(fProc.get());
}
typedef GrFragmentProcessor Processor;
typedef GrGLFragmentProcessor GLProcessor;
};
class GrGeometryStage : public GrProcessorStage {
public:
GrGeometryStage(const GrGeometryProcessor* gp) : GrProcessorStage(gp) {}
virtual const GrGeometryProcessor* getProcessor() const {
return static_cast<const GrGeometryProcessor*>(fProc.get());
}
typedef GrGeometryProcessor Processor;
typedef GrGLGeometryProcessor GLProcessor;
bool fCoordChangeMatrixSet;
SkMatrix fCoordChangeMatrix;
GrProgramElementRef<const GrFragmentProcessor> fProc;
};
#endif

View File

@ -300,7 +300,7 @@ static inline int next_dither_toggle16(int toggle) {
#include "GrCoordTransform.h"
#include "gl/GrGLProcessor.h"
class GrProcessorStage;
class GrFragmentStage;
class GrBackendProcessorFactory;
/*

View File

@ -43,9 +43,7 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
if (this->hasGeometryProcessor()) {
if (!that.hasGeometryProcessor()) {
return false;
} else if (!GrProcessorStage::AreCompatible(*this->getGeometryProcessor(),
*that.getGeometryProcessor(),
explicitLocalCoords)) {
} else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
return false;
}
} else if (that.hasGeometryProcessor()) {
@ -53,13 +51,13 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
}
for (int i = 0; i < this->numColorStages(); i++) {
if (!GrProcessorStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
if (!GrFragmentStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
explicitLocalCoords)) {
return false;
}
}
for (int i = 0; i < this->numCoverageStages(); i++) {
if (!GrProcessorStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
if (!GrFragmentStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
explicitLocalCoords)) {
return false;
}
@ -116,9 +114,6 @@ GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr
SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
*this = state;
if (!preConcatMatrix.isIdentity()) {
if (this->hasGeometryProcessor()) {
fGeometryProcessor->localCoordChange(preConcatMatrix);
}
for (int i = 0; i < this->numColorStages(); ++i) {
fColorStages[i].localCoordChange(preConcatMatrix);
}
@ -147,7 +142,7 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
fCoverage = that.fCoverage;
fDrawFace = that.fDrawFace;
if (that.hasGeometryProcessor()) {
fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*that.fGeometryProcessor.get())));
fGeometryProcessor.initAndRef(that.fGeometryProcessor);
} else {
fGeometryProcessor.reset(NULL);
}
@ -202,9 +197,6 @@ bool GrDrawState::setIdentityViewMatrix() {
// sad trombone sound
return false;
}
if (this->hasGeometryProcessor()) {
fGeometryProcessor->localCoordChange(invVM);
}
for (int s = 0; s < this->numColorStages(); ++s) {
fColorStages[s].localCoordChange(invVM);
}
@ -265,9 +257,7 @@ bool GrDrawState::validateVertexAttribs() const {
}
if (this->hasGeometryProcessor()) {
const GrGeometryStage& stage = *this->getGeometryProcessor();
const GrGeometryProcessor* gp = stage.getProcessor();
SkASSERT(gp);
const GrGeometryProcessor* gp = this->getGeometryProcessor();
// make sure that any attribute indices have the correct binding type, that the attrib
// type and effect's shader lang type are compatible, and that attributes shared by
// multiple effects use the same shader lang type.
@ -410,8 +400,7 @@ bool GrDrawState::hasSolidCoverage() const {
// Run through the coverage stages and see if the coverage will be all ones at the end.
if (this->hasGeometryProcessor()) {
const GrGeometryProcessor* gp = fGeometryProcessor->getProcessor();
gp->computeInvariantOutput(&inout);
fGeometryProcessor->computeInvariantOutput(&inout);
}
for (int s = 0; s < this->numCoverageStages(); ++s) {
@ -456,7 +445,7 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
if (SK_InvalidUniqueID == fOriginalGPID) {
fDrawState->fGeometryProcessor.reset(NULL);
} else {
SkASSERT(fDrawState->getGeometryProcessor()->getProcessor()->getUniqueID() ==
SkASSERT(fDrawState->getGeometryProcessor()->getUniqueID() ==
fOriginalGPID);
fOriginalGPID = SK_InvalidUniqueID;
}
@ -477,7 +466,7 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
if (NULL != ds) {
SkASSERT(SK_InvalidUniqueID == fOriginalGPID);
if (NULL != ds->getGeometryProcessor()) {
fOriginalGPID = ds->getGeometryProcessor()->getProcessor()->getUniqueID();
fOriginalGPID = ds->getGeometryProcessor()->getUniqueID();
}
fColorEffectCnt = ds->numColorStages();
fCoverageEffectCnt = ds->numCoverageStages();
@ -515,14 +504,9 @@ void GrDrawState::AutoViewMatrixRestore::restore() {
fDrawState->fViewMatrix = fViewMatrix;
SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
numCoverageStages -= fHasGeometryProcessor ? 1 : 0;
SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
int i = 0;
if (fHasGeometryProcessor) {
SkASSERT(fDrawState->hasGeometryProcessor());
fDrawState->fGeometryProcessor->restoreCoordChange(fSavedCoordChanges[i++]);
}
for (int s = 0; s < fNumColorStages; ++s, ++i) {
fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
}
@ -568,7 +552,6 @@ bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
if (0 == drawState->numTotalStages()) {
drawState->fViewMatrix.reset();
fDrawState = drawState;
fHasGeometryProcessor = false;
fNumColorStages = 0;
fSavedCoordChanges.reset(0);
SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
@ -590,13 +573,6 @@ void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& co
fSavedCoordChanges.reset(fDrawState->numTotalStages());
int i = 0;
fHasGeometryProcessor = false;
if (fDrawState->hasGeometryProcessor()) {
fDrawState->fGeometryProcessor->saveCoordChange(&fSavedCoordChanges[i++]);
fDrawState->fGeometryProcessor->localCoordChange(coordChangeMatrix);
fHasGeometryProcessor = true;
}
fNumColorStages = fDrawState->numColorStages();
for (int s = 0; s < fNumColorStages; ++s, ++i) {
fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]);
@ -619,7 +595,7 @@ void GrDrawState::convertToPendingExec() {
fColorStages[i].convertToPendingExec();
}
if (fGeometryProcessor) {
fGeometryProcessor->convertToPendingExec();
fGeometryProcessor.convertToPendingExec();
}
for (int i = 0; i < fCoverageStages.count(); ++i) {
fCoverageStages[i].convertToPendingExec();

View File

@ -221,7 +221,7 @@ public:
const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
SkASSERT(geometryProcessor);
SkASSERT(!this->hasGeometryProcessor());
fGeometryProcessor.reset(new GrGeometryStage(geometryProcessor));
fGeometryProcessor.reset(SkRef(geometryProcessor));
this->invalidateOptState();
return geometryProcessor;
}
@ -254,7 +254,7 @@ public:
}
bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
const GrGeometryStage* getGeometryProcessor() const { return fGeometryProcessor.get(); }
const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
const GrFragmentStage& getColorStage(int idx) const { return fColorStages[idx]; }
const GrFragmentStage& getCoverageStage(int idx) const { return fCoverageStages[idx]; }
@ -485,8 +485,7 @@ public:
GrDrawState* fDrawState;
SkMatrix fViewMatrix;
int fNumColorStages;
bool fHasGeometryProcessor;
SkAutoSTArray<8, GrProcessorStage::SavedCoordChange> fSavedCoordChanges;
SkAutoSTArray<8, GrFragmentStage::SavedCoordChange> fSavedCoordChanges;
};
/// @}
@ -810,10 +809,11 @@ private:
GrBlendCoeff fSrcBlend;
GrBlendCoeff fDstBlend;
typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
SkAutoTDelete<GrGeometryStage> fGeometryProcessor;
FragmentStageArray fColorStages;
FragmentStageArray fCoverageStages;
typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
typedef GrProgramElementRef<const GrGeometryProcessor> ProgramGeometryProcessor;
ProgramGeometryProcessor fGeometryProcessor;
FragmentStageArray fColorStages;
FragmentStageArray fCoverageStages;
uint32_t fHints;

View File

@ -391,7 +391,7 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
SkASSERT(drawState.getRenderTarget());
if (drawState.hasGeometryProcessor()) {
const GrGeometryProcessor* gp = drawState.getGeometryProcessor()->getProcessor();
const GrGeometryProcessor* gp = drawState.getGeometryProcessor();
int numTextures = gp->numTextures();
for (int t = 0; t < numTextures; ++t) {
GrTexture* texture = gp->texture(t);

View File

@ -54,7 +54,7 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
// Copy GeometryProcesssor from DS or ODS
if (drawState.hasGeometryProcessor()) {
fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*drawState.getGeometryProcessor())));
fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
} else {
fGeometryProcessor.reset(NULL);
}
@ -305,8 +305,8 @@ void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx
get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
}
if (ds.hasGeometryProcessor()) {
const GrGeometryStage& stage = *ds.getGeometryProcessor();
fReadsFragPosition = fReadsFragPosition || stage.getProcessor()->willReadFragmentPosition();
const GrGeometryProcessor& gp = *ds.getGeometryProcessor();
fReadsFragPosition = fReadsFragPosition || gp.willReadFragmentPosition();
}
}
@ -354,9 +354,7 @@ bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
if (this->hasGeometryProcessor()) {
if (!that.hasGeometryProcessor()) {
return false;
} else if (!GrProcessorStage::AreCompatible(*this->getGeometryProcessor(),
*that.getGeometryProcessor(),
explicitLocalCoords)) {
} else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
return false;
}
} else if (that.hasGeometryProcessor()) {
@ -364,8 +362,8 @@ bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
}
for (int i = 0; i < this->numFragmentStages(); i++) {
if (!GrProcessorStage::AreCompatible(this->getFragmentStage(i), that.getFragmentStage(i),
explicitLocalCoords)) {
if (!GrFragmentStage::AreCompatible(this->getFragmentStage(i), that.getFragmentStage(i),
explicitLocalCoords)) {
return false;
}
}

View File

@ -127,7 +127,7 @@ public:
}
bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
const GrGeometryStage* getGeometryProcessor() const { return fGeometryProcessor.get(); }
const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
const GrFragmentStage& getColorStage(int idx) const {
SkASSERT(idx < this->numColorStages());
return fFragmentStages[idx];
@ -441,11 +441,12 @@ private:
GrBlendCoeff fDstBlend;
typedef SkSTArray<8, GrFragmentStage> FragmentStageArray;
SkAutoTDelete<GrGeometryStage> fGeometryProcessor;
FragmentStageArray fFragmentStages;
typedef GrProgramElementRef<const GrGeometryProcessor> ProgramGeometryProcessor;
ProgramGeometryProcessor fGeometryProcessor;
FragmentStageArray fFragmentStages;
// This function is equivalent to the offset into fFragmentStages where coverage stages begin.
int fNumColorStages;
int fNumColorStages;
// This is simply a different representation of info in fVertexAttribs and thus does
// not need to be compared in op==.

View File

@ -103,11 +103,6 @@ const char* GrProcessor::name() const {
return this->getFactory().name();
}
void GrProcessor::addCoordTransform(const GrCoordTransform* transform) {
fCoordTransforms.push_back(transform);
SkDEBUGCODE(transform->setInEffect();)
}
void GrProcessor::addTextureAccess(const GrTextureAccess* access) {
fTextureAccesses.push_back(access);
this->addGpuResource(access->getProgramTexture());
@ -123,10 +118,6 @@ void GrProcessor::operator delete(void* target) {
#ifdef SK_DEBUG
void GrProcessor::assertEquality(const GrProcessor& other) const {
SkASSERT(this->numTransforms() == other.numTransforms());
for (int i = 0; i < this->numTransforms(); ++i) {
SkASSERT(this->coordTransform(i) == other.coordTransform(i));
}
SkASSERT(this->numTextures() == other.numTextures());
for (int i = 0; i < this->numTextures(); ++i) {
SkASSERT(this->textureAccess(i) == other.textureAccess(i));
@ -173,5 +164,11 @@ bool GrProcessor::InvariantOutput::validPreMulColor() const {
}
return true;
}
#endif
#endif // end DEBUG
///////////////////////////////////////////////////////////////////////////////////////////////////
void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
fCoordTransforms.push_back(transform);
SkDEBUGCODE(transform->setInEffect();)
}

View File

@ -10,7 +10,7 @@
#include "GrSingleTextureEffect.h"
class GrProcessorStage;
class GrFragmentStage;
class GrGLConfigConversionEffect;
/**

View File

@ -10,6 +10,8 @@
#include "GrGLProcessor.h"
class GrGLGPBuilder;
/**
* If a GL effect needs a GrGLFullShaderBuilder* object to emit vertex code, then it must inherit
* from this class. Since paths don't have vertices, this class is only meant to be used internally

View File

@ -114,6 +114,7 @@ public:
@param samplers Contains one entry for each GrTextureAccess of the GrProcessor. These
can be passed to the builder to emit texture reads in the generated
code.
TODO this should take a struct
*/
virtual void emitCode(GrGLFPBuilder* builder,
const GrFragmentProcessor& effect,

View File

@ -10,6 +10,7 @@
#include "GrAllocator.h"
#include "GrProcessor.h"
#include "GrCoordTransform.h"
#include "GrGLGeometryProcessor.h"
#include "GrGLProcessor.h"
#include "GrGpuGL.h"
#include "GrGLPathRendering.h"
@ -24,7 +25,7 @@
/**
* Retrieves the final matrix that a transform needs to apply to its source coords.
*/
static SkMatrix get_transform_matrix(const GrProcessorStage& processorStage,
static SkMatrix get_transform_matrix(const GrFragmentStage& processorStage,
bool useExplicitLocalCoords,
int transformIdx) {
const GrCoordTransform& coordTransform =
@ -59,17 +60,15 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
GrGLInstalledProcessors* geometryProcessor,
GrGLInstalledProcessors* colorProcessors,
GrGLInstalledProcessors* coverageProcessors)
GrGLInstalledGeoProc* geometryProcessor,
GrGLInstalledFragProcs* fragmentProcessors)
: fColor(GrColor_ILLEGAL)
, fCoverage(GrColor_ILLEGAL)
, fDstCopyTexUnit(-1)
, fBuiltinUniformHandles(builtinUniforms)
, fProgramID(programID)
, fGeometryProcessor(SkSafeRef(geometryProcessor))
, fColorEffects(SkRef(colorProcessors))
, fCoverageEffects(SkRef(coverageProcessors))
, fGeometryProcessor(geometryProcessor)
, fFragmentProcessors(SkRef(fragmentProcessors))
, fDesc(desc)
, fGpu(gpu)
, fProgramDataManager(gpu, uniforms) {
@ -96,28 +95,24 @@ void GrGLProgram::initSamplerUniforms() {
if (fGeometryProcessor.get()) {
this->initSamplers(fGeometryProcessor.get(), &texUnitIdx);
}
this->initSamplers(fColorEffects.get(), &texUnitIdx);
this->initSamplers(fCoverageEffects.get(), &texUnitIdx);
}
void GrGLProgram::initSamplers(GrGLInstalledProcessors* ip, int* texUnitIdx) {
int numEffects = ip->fGLProcessors.count();
SkASSERT(numEffects == ip->fSamplers.count());
for (int e = 0; e < numEffects; ++e) {
SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = ip->fSamplers[e];
int numSamplers = samplers.count();
for (int s = 0; s < numSamplers; ++s) {
SkASSERT(samplers[s].fUniform.isValid());
fProgramDataManager.setSampler(samplers[s].fUniform, *texUnitIdx);
samplers[s].fTextureUnit = (*texUnitIdx)++;
}
int numProcs = fFragmentProcessors->fProcs.count();
for (int i = 0; i < numProcs; i++) {
this->initSamplers(fFragmentProcessors->fProcs[i], &texUnitIdx);
}
}
void GrGLProgram::bindTextures(const GrGLInstalledProcessors* ip,
const GrProcessor& processor,
int effectIdx) {
const SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = ip->fSamplers[effectIdx];
void GrGLProgram::initSamplers(GrGLInstalledProc* ip, int* texUnitIdx) {
SkTArray<GrGLInstalledProc::Sampler, true>& samplers = ip->fSamplers;
int numSamplers = samplers.count();
for (int s = 0; s < numSamplers; ++s) {
SkASSERT(samplers[s].fUniform.isValid());
fProgramDataManager.setSampler(samplers[s].fUniform, *texUnitIdx);
samplers[s].fTextureUnit = (*texUnitIdx)++;
}
}
void GrGLProgram::bindTextures(const GrGLInstalledProc* ip, const GrProcessor& processor) {
const SkTArray<GrGLInstalledProc::Sampler, true>& samplers = ip->fSamplers;
int numSamplers = samplers.count();
SkASSERT(numSamplers == processor.numTextures());
for (int s = 0; s < numSamplers; ++s) {
@ -134,9 +129,6 @@ void GrGLProgram::bindTextures(const GrGLInstalledProcessors* ip,
void GrGLProgram::setData(const GrOptDrawState& optState,
GrGpu::DrawType drawType,
const GrGeometryStage* geometryProcessor,
const GrFragmentStage* colorStages[],
const GrFragmentStage* coverageStages[],
const GrDeviceCoordTexture* dstCopy,
SharedGLState* sharedState) {
GrColor color = optState.getColor();
@ -170,25 +162,34 @@ void GrGLProgram::setData(const GrOptDrawState& optState,
// we set the textures, and uniforms for installed processors in a generic way, but subclasses
// of GLProgram determine how to set coord transforms
if (fGeometryProcessor.get()) {
SkASSERT(geometryProcessor);
this->setData<GrGeometryStage>(&geometryProcessor, fGeometryProcessor.get());
SkASSERT(optState.hasGeometryProcessor());
const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
fGeometryProcessor->fGLProc->setData(fProgramDataManager, gp);
this->bindTextures(fGeometryProcessor, gp);
}
this->setData<GrFragmentStage>(colorStages, fColorEffects.get());
this->setData<GrFragmentStage>(coverageStages, fCoverageEffects.get());
this->setFragmentData(optState);
// Some of GrGLProgram subclasses need to update state here
this->didSetData(drawType);
}
void GrGLProgram::setTransformData(const GrProcessorStage& processor,
int effectIdx,
GrGLInstalledProcessors* ip) {
SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = ip->fTransforms[effectIdx];
void GrGLProgram::setFragmentData(const GrOptDrawState& optState) {
int numProcessors = fFragmentProcessors->fProcs.count();
for (int e = 0; e < numProcessors; ++e) {
const GrFragmentStage& stage = optState.getFragmentStage(e);
const GrProcessor& processor = *stage.getProcessor();
fFragmentProcessors->fProcs[e]->fGLProc->setData(fProgramDataManager, processor);
this->setTransformData(stage, fFragmentProcessors->fProcs[e]);
this->bindTextures(fFragmentProcessors->fProcs[e], processor);
}
}
void GrGLProgram::setTransformData(const GrFragmentStage& processor, GrGLInstalledFragProc* ip) {
SkTArray<GrGLInstalledFragProc::Transform, true>& transforms = ip->fTransforms;
int numTransforms = transforms.count();
SkASSERT(numTransforms == processor.getProcessor()->numTransforms());
for (int t = 0; t < numTransforms; ++t) {
SkASSERT(transforms[t].fHandle.isValid());
const SkMatrix& matrix = get_transform_matrix(processor, ip->fHasExplicitLocalCoords, t);
const SkMatrix& matrix = get_transform_matrix(processor, ip->fLocalCoordAttrib, t);
if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) {
fProgramDataManager.setSkMatrix(transforms[t].fHandle.convertToUniformHandle(), matrix);
transforms[t].fCurrentValue = matrix;
@ -321,10 +322,8 @@ GrGLNvprProgramBase::GrGLNvprProgramBase(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
GrGLInstalledProcessors* colorProcessors,
GrGLInstalledProcessors* coverageProcessors)
: INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL, colorProcessors,
coverageProcessors) {
GrGLInstalledFragProcs* fragmentProcessors)
: INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL, fragmentProcessors) {
}
void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawType,
@ -343,11 +342,9 @@ GrGLNvprProgram::GrGLNvprProgram(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
GrGLInstalledProcessors* colorProcessors,
GrGLInstalledProcessors* coverageProcessors,
GrGLInstalledFragProcs* fragmentProcessors,
const SeparableVaryingInfoArray& separableVaryings)
: INHERITED(gpu, desc, builtinUniforms, programID, uniforms, colorProcessors,
coverageProcessors) {
: INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fragmentProcessors) {
int count = separableVaryings.count();
fVaryings.push_back_n(count);
for (int i = 0; i < count; i++) {
@ -365,15 +362,13 @@ void GrGLNvprProgram::didSetData(GrGpu::DrawType drawType) {
SkASSERT(GrGpu::IsPathRenderingDrawType(drawType));
}
void GrGLNvprProgram::setTransformData(const GrProcessorStage& processor,
int effectIdx,
GrGLInstalledProcessors* ip) {
SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = ip->fTransforms[effectIdx];
void GrGLNvprProgram::setTransformData(const GrFragmentStage& proc, GrGLInstalledFragProc* ip) {
SkTArray<GrGLInstalledFragProc::Transform, true>& transforms = ip->fTransforms;
int numTransforms = transforms.count();
SkASSERT(numTransforms == processor.getProcessor()->numTransforms());
SkASSERT(numTransforms == proc.getProcessor()->numTransforms());
for (int t = 0; t < numTransforms; ++t) {
SkASSERT(transforms[t].fHandle.isValid());
const SkMatrix& transform = get_transform_matrix(processor, ip->fHasExplicitLocalCoords, t);
const SkMatrix& transform = get_transform_matrix(proc, false, t);
if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
continue;
}
@ -392,15 +387,13 @@ void GrGLNvprProgram::setTransformData(const GrProcessorStage& processor,
//////////////////////////////////////////////////////////////////////////////////////
GrGLLegacyNvprProgram::GrGLLegacyNvprProgram(GrGpuGL* gpu,
const GrGLProgramDesc& desc,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
GrGLInstalledProcessors* colorProcessors,
GrGLInstalledProcessors* coverageProcessors,
int texCoordSetCnt)
: INHERITED(gpu, desc, builtinUniforms, programID, uniforms, colorProcessors,
coverageProcessors)
const GrGLProgramDesc& desc,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
GrGLInstalledFragProcs* fps,
int texCoordSetCnt)
: INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fps)
, fTexCoordSetCnt(texCoordSetCnt) {
}
@ -409,17 +402,16 @@ void GrGLLegacyNvprProgram::didSetData(GrGpu::DrawType drawType) {
fGpu->glPathRendering()->flushPathTexGenSettings(fTexCoordSetCnt);
}
void GrGLLegacyNvprProgram::setTransformData(const GrProcessorStage& processorStage,
int effectIdx,
GrGLInstalledProcessors* ip) {
void
GrGLLegacyNvprProgram::setTransformData(const GrFragmentStage& proc, GrGLInstalledFragProc* ip) {
// We've hidden the texcoord index in the first entry of the transforms array for each effect
int texCoordIndex = ip->fTransforms[effectIdx][0].fHandle.handle();
int numTransforms = processorStage.getProcessor()->numTransforms();
int texCoordIndex = ip->fTransforms[0].fHandle.handle();
int numTransforms = proc.getProcessor()->numTransforms();
for (int t = 0; t < numTransforms; ++t) {
const SkMatrix& transform = get_transform_matrix(processorStage, false, t);
const SkMatrix& transform = get_transform_matrix(proc, false, t);
GrGLPathRendering::PathTexGenComponents components =
GrGLPathRendering::kST_PathTexGenComponents;
if (processorStage.isPerspectiveCoordTransform(t, false)) {
if (proc.isPerspectiveCoordTransform(t, false)) {
components = GrGLPathRendering::kSTR_PathTexGenComponents;
}
fGpu->glPathRendering()->enablePathTexGen(texCoordIndex++, components, transform);

View File

@ -152,9 +152,6 @@ public:
*/
void setData(const GrOptDrawState&,
GrGpu::DrawType,
const GrGeometryStage* geometryProcessor,
const GrFragmentStage* colorStages[],
const GrFragmentStage* coverageStages[],
const GrDeviceCoordTexture* dstCopy, // can be NULL
SharedGLState*);
@ -167,13 +164,12 @@ protected:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
GrGLInstalledProcessors* geometryProcessor,
GrGLInstalledProcessors* colorProcessors,
GrGLInstalledProcessors* coverageProcessors);
GrGLInstalledGeoProc* geometryProcessor,
GrGLInstalledFragProcs* fragmentProcessors);
// Sets the texture units for samplers.
void initSamplerUniforms();
void initSamplers(GrGLInstalledProcessors* processors, int* texUnitIdx);
void initSamplers(GrGLInstalledProc*, int* texUnitIdx);
// Helper for setData(). Makes GL calls to specify the initial color when there is not
// per-vertex colors.
@ -184,23 +180,9 @@ protected:
void setCoverage(const GrOptDrawState&, GrColor coverage, SharedGLState*);
// A templated helper to loop over effects, set the transforms(via subclass) and bind textures
template <class ProcessorStage>
void setData(const ProcessorStage* effectStages[],
GrGLInstalledProcessors* installedProcessors) {
int numEffects = installedProcessors->fGLProcessors.count();
SkASSERT(numEffects == installedProcessors->fTransforms.count());
SkASSERT(numEffects == installedProcessors->fSamplers.count());
for (int e = 0; e < numEffects; ++e) {
const GrProcessor& effect = *effectStages[e]->getProcessor();
installedProcessors->fGLProcessors[e]->setData(fProgramDataManager, effect);
this->setTransformData(*effectStages[e], e, installedProcessors);
this->bindTextures(installedProcessors, effect, e);
}
}
virtual void setTransformData(const GrProcessorStage& effectStage,
int effectIdx,
GrGLInstalledProcessors* pe);
void bindTextures(const GrGLInstalledProcessors*, const GrProcessor&, int effectIdx);
void setFragmentData(const GrOptDrawState&);
virtual void setTransformData(const GrFragmentStage& effectStage, GrGLInstalledFragProc* pe);
void bindTextures(const GrGLInstalledProc*, const GrProcessor&);
/*
* Legacy NVPR needs a hook here to flush path tex gen settings.
@ -221,9 +203,8 @@ protected:
GrGLuint fProgramID;
// the installed effects
SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor;
SkAutoTUnref<GrGLInstalledProcessors> fColorEffects;
SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects;
SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
GrGLProgramDesc fDesc;
GrGpuGL* fGpu;
@ -248,8 +229,7 @@ protected:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
GrGLInstalledProcessors* colorProcessors,
GrGLInstalledProcessors* coverageProcessors);
GrGLInstalledFragProcs* fragmentProcessors);
virtual void onSetMatrixAndRenderTargetHeight(GrGpu::DrawType, const GrOptDrawState&);
typedef GrGLProgram INHERITED;
@ -267,13 +247,10 @@ private:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
GrGLInstalledProcessors* colorProcessors,
GrGLInstalledProcessors* coverageProcessors,
GrGLInstalledFragProcs* fragmentProcessors,
const SeparableVaryingInfoArray& separableVaryings);
virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
virtual void setTransformData(const GrProcessorStage&,
int effectIdx,
GrGLInstalledProcessors*) SK_OVERRIDE;
virtual void setTransformData(const GrFragmentStage&, GrGLInstalledFragProc*) SK_OVERRIDE;
struct Varying {
GrGLint fLocation;
@ -298,13 +275,10 @@ private:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
GrGLInstalledProcessors* colorProcessors,
GrGLInstalledProcessors* coverageProcessors,
GrGLInstalledFragProcs* fragmentProcessors,
int texCoordSetCnt);
virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
virtual void setTransformData(const GrProcessorStage&,
int effectIdx,
GrGLInstalledProcessors*) SK_OVERRIDE;
virtual void setTransformData(const GrFragmentStage&, GrGLInstalledFragProc*) SK_OVERRIDE;
int fTexCoordSetCnt;

View File

@ -60,10 +60,10 @@ static bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
return false;
}
static uint32_t gen_attrib_key(const GrGeometryProcessor* effect) {
static uint32_t gen_attrib_key(const GrGeometryProcessor& proc) {
uint32_t key = 0;
const GrGeometryProcessor::VertexAttribArray& vars = effect->getVertexAttribs();
const GrGeometryProcessor::VertexAttribArray& vars = proc.getVertexAttribs();
int numAttributes = vars.count();
SkASSERT(numAttributes <= 2);
for (int a = 0; a < numAttributes; ++a) {
@ -73,7 +73,7 @@ static uint32_t gen_attrib_key(const GrGeometryProcessor* effect) {
return key;
}
static uint32_t gen_transform_key(const GrProcessorStage& effectStage,
static uint32_t gen_transform_key(const GrFragmentStage& effectStage,
bool useExplicitLocalCoords) {
uint32_t totalKey = 0;
int numTransforms = effectStage.getProcessor()->numTransforms();
@ -96,11 +96,11 @@ static uint32_t gen_transform_key(const GrProcessorStage& effectStage,
return totalKey;
}
static uint32_t gen_texture_key(const GrProcessor* effect, const GrGLCaps& caps) {
static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) {
uint32_t key = 0;
int numTextures = effect->numTextures();
int numTextures = proc.numTextures();
for (int t = 0; t < numTextures; ++t) {
const GrTextureAccess& access = effect->textureAccess(t);
const GrTextureAccess& access = proc.textureAccess(t);
uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
key |= 1 << t;
@ -115,101 +115,61 @@ static uint32_t gen_texture_key(const GrProcessor* effect, const GrGLCaps& caps)
* in its key (e.g. the pixel format of textures used). So we create a meta-key for
* every effect using this function. It is also responsible for inserting the effect's class ID
* which must be different for every GrProcessor subclass. It can fail if an effect uses too many
* textures, transforms, etc, for the space allotted in the meta-key.
* textures, transforms, etc, for the space allotted in the meta-key. NOTE, both FPs and GPs share
* this function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
*/
static uint32_t* get_processor_meta_key(const GrProcessorStage& processorStage,
bool useExplicitLocalCoords,
const GrGLCaps& caps,
GrProcessorKeyBuilder* b) {
uint32_t textureKey = gen_texture_key(processorStage.getProcessor(), caps);
uint32_t transformKey = gen_transform_key(processorStage,useExplicitLocalCoords);
uint32_t classID = processorStage.getProcessor()->getFactory().effectClassID();
static bool get_meta_key(const GrProcessor& proc,
const GrGLCaps& caps,
uint32_t transformKey,
uint32_t attribKey,
GrProcessorKeyBuilder* b,
uint16_t* processorKeySize) {
const GrBackendProcessorFactory& factory = proc.getFactory();
factory.getGLProcessorKey(proc, caps, b);
size_t size = b->size();
if (size > SK_MaxU16) {
*processorKeySize = 0; // suppresses a warning.
return false;
}
*processorKeySize = SkToU16(size);
uint32_t textureKey = gen_texture_key(proc, caps);
uint32_t classID = proc.getFactory().effectClassID();
// Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
// don't fit.
static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) {
return NULL;
return false;
}
uint32_t* key = b->add32n(2);
key[0] = (textureKey << 16 | transformKey);
key[1] = (classID << 16);
return key;
}
static bool get_fp_key(const GrProcessorStage& stage,
const GrGLCaps& caps,
bool useExplicitLocalCoords,
GrProcessorKeyBuilder* b,
uint16_t* processorKeySize) {
const GrProcessor& effect = *stage.getProcessor();
const GrBackendProcessorFactory& factory = effect.getFactory();
factory.getGLProcessorKey(effect, caps, b);
size_t size = b->size();
if (size > SK_MaxU16) {
*processorKeySize = 0; // suppresses a warning.
return false;
}
*processorKeySize = SkToU16(size);
if (NULL == get_processor_meta_key(stage, useExplicitLocalCoords, caps, b)) {
return false;
}
return true;
}
static bool get_gp_key(const GrGeometryStage& stage,
const GrGLCaps& caps,
bool useExplicitLocalCoords,
GrProcessorKeyBuilder* b,
uint16_t* processorKeySize) {
const GrProcessor& effect = *stage.getProcessor();
const GrBackendProcessorFactory& factory = effect.getFactory();
factory.getGLProcessorKey(effect, caps, b);
size_t size = b->size();
if (size > SK_MaxU16) {
*processorKeySize = 0; // suppresses a warning.
return false;
}
*processorKeySize = SkToU16(size);
uint32_t* key = get_processor_meta_key(stage, useExplicitLocalCoords, caps, b);
if (NULL == key) {
return false;
}
uint32_t attribKey = gen_attrib_key(stage.getProcessor());
// Currently we allow 16 bits for each of the above portions of the meta-key. Fail if they
// don't fit.
static const uint32_t kMetaKeyInvalidMask = ~((uint32_t) SK_MaxU16);
if ((attribKey) & kMetaKeyInvalidMask) {
return false;
}
key[1] |= attribKey;
return true;
}
struct GeometryProcessorKeyBuilder {
typedef GrGeometryStage StagedProcessor;
static bool GetProcessorKey(const GrGeometryStage& gpStage,
typedef GrGeometryProcessor StagedProcessor;
static bool GetProcessorKey(const GrGeometryProcessor& gp,
const GrGLCaps& caps,
bool requiresLocalCoordAttrib,
bool,
GrProcessorKeyBuilder* b,
uint16_t* processorKeySize) {
return get_gp_key(gpStage, caps, requiresLocalCoordAttrib, b, processorKeySize);
uint16_t* keySize) {
/* 0 because no transforms on a GP */
return get_meta_key(gp, caps, 0, gen_attrib_key(gp), b, keySize);
}
};
struct FragmentProcessorKeyBuilder {
typedef GrFragmentStage StagedProcessor;
static bool GetProcessorKey(const GrFragmentStage& fpStage,
static bool GetProcessorKey(const GrFragmentStage& fps,
const GrGLCaps& caps,
bool requiresLocalCoordAttrib,
bool useLocalCoords,
GrProcessorKeyBuilder* b,
uint16_t* processorKeySize) {
return get_fp_key(fpStage, caps, requiresLocalCoordAttrib, b, processorKeySize);
uint16_t* keySize) {
/* 0 because no attribs on a fP */
return get_meta_key(*fps.getProcessor(), caps, gen_transform_key(fps, useLocalCoords), 0,
b, keySize);
}
};
@ -242,17 +202,9 @@ GrGLProgramDesc::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::Sta
bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
GrGpu::DrawType drawType,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff,
GrGpuGL* gpu,
const GrDeviceCoordTexture* dstCopy,
const GrGeometryStage** geometryProcessor,
SkTArray<const GrFragmentStage*, true>* colorStages,
SkTArray<const GrFragmentStage*, true>* coverageStages,
GrGLProgramDesc* desc) {
colorStages->reset();
coverageStages->reset();
bool inputColorIsUsed = optState.inputColorIsUsed();
bool inputCoverageIsUsed = optState.inputCoverageIsUsed();
@ -274,29 +226,17 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
// We can only have one effect which touches the vertex shader
if (optState.hasGeometryProcessor()) {
const GrGeometryStage& gpStage = *optState.getGeometryProcessor();
if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(gpStage,
if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(*optState.getGeometryProcessor(),
gpu->glCaps(),
requiresLocalCoordAttrib,
desc,
&offsetAndSizeIndex)) {
return false;
}
*geometryProcessor = &gpStage;
}
for (int s = 0; s < optState.numColorStages(); ++s) {
if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getColorStage(s),
gpu->glCaps(),
requiresLocalCoordAttrib,
false,
desc,
&offsetAndSizeIndex)) {
return false;
}
}
for (int s = 0; s < optState.numCoverageStages(); ++s) {
if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getCoverageStage(s),
for (int s = 0; s < optState.numFragmentStages(); ++s) {
if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getFragmentStage(s),
gpu->glCaps(),
requiresLocalCoordAttrib,
desc,
@ -399,15 +339,8 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
header->fPrimaryOutputType = optState.getPrimaryOutputType();
header->fSecondaryOutputType = optState.getSecondaryOutputType();
for (int s = 0; s < optState.numColorStages(); ++s) {
colorStages->push_back(&optState.getColorStage(s));
}
for (int s = 0; s < optState.numCoverageStages(); ++s) {
coverageStages->push_back(&optState.getCoverageStage(s));
}
header->fColorEffectCnt = colorStages->count();
header->fCoverageEffectCnt = coverageStages->count();
header->fColorEffectCnt = optState.numColorStages();
header->fCoverageEffectCnt = optState.numCoverageStages();
desc->finalize();
return true;
}

View File

@ -43,13 +43,8 @@ public:
*/
static bool Build(const GrOptDrawState&,
GrGpu::DrawType,
GrBlendCoeff srcCoeff,
GrBlendCoeff dstCoeff,
GrGpuGL*,
const GrDeviceCoordTexture* dstCopy,
const GrGeometryStage** geometryProcessor,
SkTArray<const GrFragmentStage*, true>* colorStages,
SkTArray<const GrFragmentStage*, true>* coverageStages,
const GrDeviceCoordTexture*,
GrGLProgramDesc*);
bool hasGeometryProcessor() const {
@ -160,26 +155,23 @@ private:
const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); }
/** Used to provide effects' keys to their emitCode() function. */
class EffectKeyProvider {
class ProcKeyProvider {
public:
enum EffectType {
kGeometryProcessor_EffectType,
kColor_EffectType,
kCoverage_EffectType,
enum ProcessorType {
kGeometry_ProcessorType,
kFragment_ProcessorType,
};
EffectKeyProvider(const GrGLProgramDesc* desc, EffectType type) : fDesc(desc) {
ProcKeyProvider(const GrGLProgramDesc* desc, ProcessorType type)
: fDesc(desc), fBaseIndex(0) {
switch (type) {
case kGeometryProcessor_EffectType:
case kGeometry_ProcessorType:
// there can be only one
fBaseIndex = 0;
break;
case kColor_EffectType:
case kFragment_ProcessorType:
fBaseIndex = desc->hasGeometryProcessor() ? 1 : 0;
break;
case kCoverage_EffectType:
fBaseIndex = desc->numColorEffects() + (desc->hasGeometryProcessor() ? 1 : 0);
break;
}
}

View File

@ -181,10 +181,7 @@ private:
void abandon();
GrGLProgram* getProgram(const GrOptDrawState&,
const GrGLProgramDesc&,
DrawType,
const GrGeometryStage* geometryProcessor,
const GrFragmentStage* colorStages[],
const GrFragmentStage* coverageStages[]);
DrawType);
private:
enum {

View File

@ -93,10 +93,7 @@ int GrGpuGL::ProgramCache::search(const GrGLProgramDesc& desc) const {
GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState,
const GrGLProgramDesc& desc,
DrawType type,
const GrGeometryStage* geometryProcessor,
const GrFragmentStage* colorStages[],
const GrFragmentStage* coverageStages[]) {
DrawType type) {
#ifdef PROGRAM_CACHE_STATS
++fTotalRequests;
#endif
@ -131,9 +128,7 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState,
#ifdef PROGRAM_CACHE_STATS
++fCacheMisses;
#endif
GrGLProgram* program = GrGLProgramBuilder::CreateProgram(optState, desc, type,
geometryProcessor, colorStages,
coverageStages, fGpu);
GrGLProgram* program = GrGLProgramBuilder::CreateProgram(optState, desc, type, fGpu);
if (NULL == program) {
return NULL;
}
@ -237,30 +232,13 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
return false;
}
const GrGeometryStage* geometryProcessor = NULL;
SkSTArray<8, const GrFragmentStage*, true> colorStages;
SkSTArray<8, const GrFragmentStage*, true> coverageStages;
GrGLProgramDesc desc;
if (!GrGLProgramDesc::Build(*optState.get(),
type,
srcCoeff,
dstCoeff,
this,
dstCopy,
&geometryProcessor,
&colorStages,
&coverageStages,
&desc)) {
if (!GrGLProgramDesc::Build(*optState.get(), type, this, dstCopy, &desc)) {
SkDEBUGFAIL("Failed to generate GL program descriptor");
return false;
}
fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(),
desc,
type,
geometryProcessor,
colorStages.begin(),
coverageStages.begin()));
fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(), desc, type));
if (NULL == fCurrentProgram.get()) {
SkDEBUGFAIL("Failed to create program!");
return false;
@ -276,13 +254,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
this->flushBlend(*optState.get(), kDrawLines_DrawType == type, srcCoeff, dstCoeff);
fCurrentProgram->setData(*optState.get(),
type,
geometryProcessor,
colorStages.begin(),
coverageStages.begin(),
dstCopy,
&fSharedGLProgramState);
fCurrentProgram->setData(*optState.get(), type, dstCopy, &fSharedGLProgramState);
}
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState->getRenderTarget());

View File

@ -24,20 +24,17 @@ int GrGLLegacyNvprProgramBuilder::addTexCoordSets(int count) {
return firstFreeCoordSet;
}
void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrProcessorStage& processorStage,
void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrFragmentStage& processorStage,
GrGLProcessor::TransformedCoordsArray* outCoords,
GrGLInstalledProcessors* installedProcessors) {
GrGLInstalledFragProc* ifp) {
int numTransforms = processorStage.getProcessor()->numTransforms();
int texCoordIndex = this->addTexCoordSets(numTransforms);
SkTArray<GrGLInstalledProcessors::Transform, true>& transforms =
installedProcessors->addTransforms();
// Use the first uniform location as the texcoord index. This may seem a bit hacky but it
// allows us to use one program effects object for all of our programs which really simplifies
// the code overall
transforms.push_back_n(1);
transforms[0].fHandle = GrGLInstalledProcessors::ShaderVarHandle(texCoordIndex);
ifp->fTransforms.push_back_n(1);
ifp->fTransforms[0].fHandle = GrGLInstalledFragProc::ShaderVarHandle(texCoordIndex);
SkString name;
for (int t = 0; t < numTransforms; ++t) {
@ -51,5 +48,5 @@ void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrProcessorStage& proces
GrGLProgram* GrGLLegacyNvprProgramBuilder::createProgram(GrGLuint programID) {
return SkNEW_ARGS(GrGLLegacyNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
fColorEffects, fCoverageEffects, fTexCoordSetCnt));
fFragmentProcessors.get(), fTexCoordSetCnt));
}

View File

@ -18,9 +18,9 @@ public:
private:
int addTexCoordSets(int count);
void emitTransforms(const GrProcessorStage&,
void emitTransforms(const GrFragmentStage&,
GrGLProcessor::TransformedCoordsArray* outCoords,
GrGLInstalledProcessors*);
GrGLInstalledFragProc*);
int fTexCoordSetCnt;

View File

@ -18,15 +18,13 @@ GrGLNvprProgramBuilder::GrGLNvprProgramBuilder(GrGpuGL* gpu,
, fSeparableVaryingInfos(kVarsPerBlock) {
}
void GrGLNvprProgramBuilder::emitTransforms(const GrProcessorStage& processorStage,
void GrGLNvprProgramBuilder::emitTransforms(const GrFragmentStage& processorStage,
GrGLProcessor::TransformedCoordsArray* outCoords,
GrGLInstalledProcessors* installedProcessors) {
const GrProcessor* effect = processorStage.getProcessor();
GrGLInstalledFragProc* ifp) {
const GrFragmentProcessor* effect = processorStage.getProcessor();
int numTransforms = effect->numTransforms();
SkTArray<GrGLInstalledProcessors::Transform, true>& transforms =
installedProcessors->addTransforms();
transforms.push_back_n(numTransforms);
ifp->fTransforms.push_back_n(numTransforms);
for (int t = 0; t < numTransforms; t++) {
GrSLType varyingType =
@ -43,24 +41,24 @@ void GrGLNvprProgramBuilder::emitTransforms(const GrProcessorStage& processorSta
}
const char* vsVaryingName;
const char* fsVaryingName;
transforms[t].fHandle = this->addSeparableVarying(varyingType, varyingName,
&vsVaryingName, &fsVaryingName);
transforms[t].fType = varyingType;
ifp->fTransforms[t].fHandle = this->addSeparableVarying(varyingType, varyingName,
&vsVaryingName, &fsVaryingName);
ifp->fTransforms[t].fType = varyingType;
SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
(SkString(fsVaryingName), varyingType));
}
}
GrGLInstalledProcessors::ShaderVarHandle
GrGLInstalledFragProc::ShaderVarHandle
GrGLNvprProgramBuilder::addSeparableVarying(GrSLType type,
const char* name,
const char** vsOutName,
const char** fsInName) {
const char* name,
const char** vsOutName,
const char** fsInName) {
addVarying(type, name, vsOutName, fsInName);
SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back();
varying.fVariable = fFS.fInputs.back();
return GrGLInstalledProcessors::ShaderVarHandle(fSeparableVaryingInfos.count() - 1);
return GrGLInstalledFragProc::ShaderVarHandle(fSeparableVaryingInfos.count() - 1);
}
void GrGLNvprProgramBuilder::resolveSeparableVaryings(GrGLuint programId) {
@ -80,5 +78,5 @@ GrGLProgram* GrGLNvprProgramBuilder::createProgram(GrGLuint programID) {
// building
this->resolveSeparableVaryings(programID);
return SkNEW_ARGS(GrGLNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
fColorEffects, fCoverageEffects, fSeparableVaryingInfos));
fFragmentProcessors.get(), fSeparableVaryingInfos));
}

View File

@ -28,11 +28,11 @@ public:
virtual GrGLProgram* createProgram(GrGLuint programID);
private:
virtual void emitTransforms(const GrProcessorStage&,
virtual void emitTransforms(const GrFragmentStage&,
GrGLProcessor::TransformedCoordsArray* outCoords,
GrGLInstalledProcessors*) SK_OVERRIDE;
GrGLInstalledFragProc*) SK_OVERRIDE;
typedef GrGLInstalledProcessors::ShaderVarHandle ShaderVarHandle;
typedef GrGLInstalledFragProc::ShaderVarHandle ShaderVarHandle;
/**
* Add a separable varying input variable to the current program.

View File

@ -6,7 +6,6 @@
*/
#include "GrGLProgramBuilder.h"
#include "gl/GrGLGeometryProcessor.h"
#include "gl/GrGLProgram.h"
#include "gl/GrGLSLPrettyPrint.h"
#include "gl/GrGLUniformHandle.h"
@ -32,16 +31,13 @@ const int GrGLProgramBuilder::kVarsPerBlock = 8;
GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
const GrGLProgramDesc& desc,
GrGpu::DrawType drawType,
const GrGeometryStage* geometryProcessor,
const GrFragmentStage* colorStages[],
const GrFragmentStage* coverageStages[],
GrGpuGL* gpu) {
// create a builder. This will be handed off to effects so they can use it to add
// uniforms, varyings, textures, etc
SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(desc,
optState,
drawType,
SkToBool(geometryProcessor),
optState.hasGeometryProcessor(),
gpu));
GrGLProgramBuilder* pb = builder.get();
@ -74,8 +70,7 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
}
}
pb->createAndEmitProcessors(geometryProcessor, colorStages, coverageStages, &inputColor,
&inputCoverage);
pb->emitAndInstallProcs(optState, &inputColor, &inputCoverage);
if (hasVertexShader) {
pb->fVS.transformSkiaToGLCoords();
@ -116,13 +111,15 @@ GrGLProgramBuilder::CreateProgramBuilder(const GrGLProgramDesc& desc,
/////////////////////////////////////////////////////////////////////////////
GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrOptDrawState& optState,
GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
const GrOptDrawState& optState,
const GrGLProgramDesc& desc)
: fVS(this)
, fGS(this)
, fFS(this, desc)
, fOutOfStage(true)
, fStageIndex(-1)
, fGeometryProcessor(NULL)
, fOptState(optState)
, fDesc(desc)
, fGpu(gpu)
@ -225,104 +222,106 @@ void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
}
}
void GrGLProgramBuilder::createAndEmitProcessors(const GrGeometryStage* geometryProcessor,
const GrFragmentStage* colorStages[],
const GrFragmentStage* coverageStages[],
GrGLSLExpr4* inputColor,
GrGLSLExpr4* inputCoverage) {
bool useLocalCoords = fVS.hasExplicitLocalCoords();
EffectKeyProvider colorKeyProvider(&fDesc, EffectKeyProvider::kColor_EffectType);
int numColorEffects = fDesc.numColorEffects();
GrGLInstalledProcessors* ip = SkNEW_ARGS(GrGLInstalledProcessors, (numColorEffects,
useLocalCoords));
this->createAndEmitProcessors<GrFragmentStage>(colorStages, numColorEffects, colorKeyProvider,
inputColor, ip);
fColorEffects.reset(ip);
if (geometryProcessor) {
fVS.emitAttributes(*geometryProcessor->getProcessor());
EffectKeyProvider gpKeyProvider(&fDesc, EffectKeyProvider::kGeometryProcessor_EffectType);
ip = SkNEW_ARGS(GrGLInstalledProcessors, (1, useLocalCoords));
this->createAndEmitProcessors<GrGeometryStage>(&geometryProcessor, 1, gpKeyProvider,
inputCoverage, ip);
fGeometryProcessor.reset(ip);
void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState,
GrGLSLExpr4* inputColor,
GrGLSLExpr4* inputCoverage) {
fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
int numProcs = optState.numFragmentStages();
this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor);
if (optState.hasGeometryProcessor()) {
const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
fVS.emitAttributes(gp);
ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kGeometry_ProcessorType);
GrGLSLExpr4 output;
this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &output);
*inputCoverage = output;
}
EffectKeyProvider coverageKeyProvider(&fDesc, EffectKeyProvider::kCoverage_EffectType);
int numCoverageEffects = fDesc.numCoverageEffects();
ip = SkNEW_ARGS(GrGLInstalledProcessors, (numCoverageEffects, useLocalCoords));
this->createAndEmitProcessors<GrFragmentStage>(coverageStages, numCoverageEffects,
coverageKeyProvider, inputCoverage, ip);
fCoverageEffects.reset(ip);
this->emitAndInstallFragProcs(optState.numColorStages(), numProcs, inputCoverage);
}
template <class ProcessorStage>
void GrGLProgramBuilder::createAndEmitProcessors(const ProcessorStage* processStages[],
int effectCnt,
const EffectKeyProvider& keyProvider,
GrGLSLExpr4* fsInOutColor,
GrGLInstalledProcessors* installedProcessors) {
bool effectEmitted = false;
GrGLSLExpr4 inColor = *fsInOutColor;
GrGLSLExpr4 outColor;
for (int e = 0; e < effectCnt; ++e) {
// Program builders have a bit of state we need to clear with each effect
AutoStageAdvance adv(this);
const ProcessorStage& stage = *processStages[e];
SkASSERT(stage.getProcessor());
if (inColor.isZeros()) {
SkString inColorName;
// Effects have no way to communicate zeros, they treat an empty string as ones.
this->nameVariable(&inColorName, '\0', "input");
fFS.codeAppendf("vec4 %s = %s;", inColorName.c_str(), inColor.c_str());
inColor = inColorName;
}
// create var to hold stage result
SkString outColorName;
this->nameVariable(&outColorName, '\0', "output");
fFS.codeAppendf("vec4 %s;", outColorName.c_str());
outColor = outColorName;
SkASSERT(installedProcessors);
const typename ProcessorStage::Processor& processor = *stage.getProcessor();
SkSTArray<2, GrGLProcessor::TransformedCoords> coords(processor.numTransforms());
SkSTArray<4, GrGLProcessor::TextureSampler> samplers(processor.numTextures());
this->emitTransforms(stage, &coords, installedProcessors);
this->emitSamplers(processor, &samplers, installedProcessors);
typename ProcessorStage::GLProcessor* glEffect =
processor.getFactory().createGLInstance(processor);
installedProcessors->addEffect(glEffect);
// Enclose custom code in a block to avoid namespace conflicts
SkString openBrace;
openBrace.printf("{ // Stage %d: %s\n", fStageIndex, glEffect->name());
fFS.codeAppend(openBrace.c_str());
fVS.codeAppend(openBrace.c_str());
glEffect->emitCode(this, processor, keyProvider.get(e), outColor.c_str(),
inColor.isOnes() ? NULL : inColor.c_str(), coords, samplers);
// We have to check that effects and the code they emit are consistent, ie if an effect
// asks for dst color, then the emit code needs to follow suit
verify(processor);
fFS.codeAppend("}");
fVS.codeAppend("}");
inColor = outColor;
effectEmitted = true;
void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut) {
ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kFragment_ProcessorType);
for (int e = procOffset; e < numProcs; ++e) {
GrGLSLExpr4 output;
const GrFragmentStage& stage = fOptState.getFragmentStage(e);
this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut, &output);
*inOut = output;
}
}
if (effectEmitted) {
*fsInOutColor = outColor;
}
// TODO Processors cannot output zeros because an empty string is all 1s
// the fix is to allow effects to take the GrGLSLExpr4 directly
template <class Proc>
void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
int index,
const ProcKeyProvider keyProvider,
const GrGLSLExpr4& input,
GrGLSLExpr4* output) {
// Program builders have a bit of state we need to clear with each effect
AutoStageAdvance adv(this);
// create var to hold stage result
SkString outColorName;
this->nameVariable(&outColorName, '\0', "output");
fFS.codeAppendf("vec4 %s;", outColorName.c_str());
*output = outColorName;
// Enclose custom code in a block to avoid namespace conflicts
SkString openBrace;
openBrace.printf("{ // Stage %d\n", fStageIndex);
fFS.codeAppend(openBrace.c_str());
this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(),
input.isOnes() ? NULL : input.c_str());
fFS.codeAppend("}");
}
void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentStage& fs,
const GrProcessorKey& key,
const char* outColor,
const char* inColor) {
GrGLInstalledFragProc* ifp = SkNEW_ARGS(GrGLInstalledFragProc, (fVS.hasLocalCoords()));
const GrFragmentProcessor& fp = *fs.getProcessor();
ifp->fGLProc.reset(fp.getFactory().createGLInstance(fp));
SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures());
this->emitSamplers(fp, &samplers, ifp);
// Fragment processors can have coord transforms
SkSTArray<2, GrGLProcessor::TransformedCoords> coords(fp.numTransforms());
this->emitTransforms(fs, &coords, ifp);
ifp->fGLProc->emitCode(this, fp, key, outColor, inColor, coords, samplers);
// We have to check that effects and the code they emit are consistent, ie if an effect
// asks for dst color, then the emit code needs to follow suit
verify(fp);
fFragmentProcessors->fProcs.push_back(ifp);
}
void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
const GrProcessorKey& key,
const char* outColor,
const char* inColor) {
SkASSERT(!fGeometryProcessor);
fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
fGeometryProcessor->fGLProc.reset(gp.getFactory().createGLInstance(gp));
SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
this->emitSamplers(gp, &samplers, fGeometryProcessor);
SkSTArray<2, GrGLProcessor::TransformedCoords> coords;
// TODO remove coords from emit code signature, probably best to use a struct here so these
// updates are less painful
fGeometryProcessor->fGLProc->emitCode(this, gp, key, outColor, inColor, coords, samplers);
// We have to check that effects and the code they emit are consistent, ie if an effect
// asks for dst color, then the emit code needs to follow suit
verify(gp);
}
void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) {
@ -334,19 +333,17 @@ void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor());
}
void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
GrGLProcessor::TransformedCoordsArray* outCoords,
GrGLInstalledProcessors* installedProcessors) {
SkTArray<GrGLInstalledProcessors::Transform, true>& transforms =
installedProcessors->addTransforms();
const GrProcessor* effect = effectStage.getProcessor();
GrGLInstalledFragProc* ifp) {
const GrFragmentProcessor* effect = effectStage.getProcessor();
int numTransforms = effect->numTransforms();
transforms.push_back_n(numTransforms);
ifp->fTransforms.push_back_n(numTransforms);
for (int t = 0; t < numTransforms; t++) {
const char* uniName = "StageMatrix";
GrSLType varyingType =
effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalCoords()) ?
effectStage.isPerspectiveCoordTransform(t, fVS.hasLocalCoords()) ?
kVec3f_GrSLType :
kVec2f_GrSLType;
@ -356,10 +353,10 @@ void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
suffixedUniName.appendf("_%i", t);
uniName = suffixedUniName.c_str();
}
transforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
kMat33f_GrSLType,
uniName,
&uniName).toShaderBuilderIndex();
ifp->fTransforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
kMat33f_GrSLType,
uniName,
&uniName).toShaderBuilderIndex();
const char* varyingName = "MatrixCoord";
SkString suffixedVaryingName;
@ -393,18 +390,17 @@ void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
GrGLProcessor::TextureSamplerArray* outSamplers,
GrGLInstalledProcessors* installedProcessors) {
SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = installedProcessors->addSamplers();
GrGLInstalledProc* ip) {
int numTextures = processor.numTextures();
samplers.push_back_n(numTextures);
ip->fSamplers.push_back_n(numTextures);
SkString name;
for (int t = 0; t < numTextures; ++t) {
name.printf("Sampler%d", t);
samplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kSampler2D_GrSLType,
name.c_str());
ip->fSamplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
kSampler2D_GrSLType,
name.c_str());
SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
(samplers[t].fUniform, processor.textureAccess(t)));
(ip->fSamplers[t].fUniform, processor.textureAccess(t)));
}
}
@ -506,14 +502,14 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
return SkNEW_ARGS(GrGLProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
fGeometryProcessor, fColorEffects, fCoverageEffects));
fGeometryProcessor, fFragmentProcessors.get()));
}
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
GrGLInstalledProcessors::~GrGLInstalledProcessors() {
int numEffects = fGLProcessors.count();
for (int e = 0; e < numEffects; ++e) {
SkDELETE(fGLProcessors[e]);
GrGLInstalledFragProcs::~GrGLInstalledFragProcs() {
int numProcs = fProcs.count();
for (int e = 0; e < numProcs; ++e) {
SkDELETE(fProcs[e]);
}
}

View File

@ -13,8 +13,7 @@
#include "GrGLVertexShaderBuilder.h"
#include "../GrGLProgramDataManager.h"
#include "../GrGLUniformHandle.h"
class GrGLInstalledProcessors;
#include "../GrGLGeometryProcessor.h"
/*
* This is the base class for a series of interfaces. This base class *MUST* remain abstract with
@ -98,6 +97,11 @@ public:
*/
};
struct GrGLInstalledProc;
struct GrGLInstalledGeoProc;
struct GrGLInstalledFragProc;
struct GrGLInstalledFragProcs;
/*
* Please note - no diamond problems because of virtual inheritance. Also, both base classes
* are pure virtual with no data members. This is the base class for program building.
@ -118,9 +122,6 @@ public:
static GrGLProgram* CreateProgram(const GrOptDrawState&,
const GrGLProgramDesc&,
GrGpu::DrawType,
const GrGeometryStage* inGeometryProcessor,
const GrFragmentStage* inColorStages[],
const GrFragmentStage* inCoverageStages[],
GrGpuGL* gpu);
virtual UniformHandle addUniform(uint32_t visibility,
@ -150,11 +151,12 @@ public:
virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() SK_OVERRIDE { return &fFS; }
virtual GrGLVertexBuilder* getVertexShaderBuilder() SK_OVERRIDE { return &fVS; }
virtual void addVarying(GrSLType type,
const char* name,
const char** vsOutName = NULL,
const char** fsInName = NULL,
GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision);
virtual void addVarying(
GrSLType type,
const char* name,
const char** vsOutName = NULL,
const char** fsInName = NULL,
GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) SK_OVERRIDE;
// Handles for program uniforms (other than per-effect uniforms)
struct BuiltinUniformHandles {
@ -174,6 +176,10 @@ public:
};
protected:
typedef GrGLProgramDesc::ProcKeyProvider ProcKeyProvider;
typedef GrGLProgramDataManager::UniformInfo UniformInfo;
typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&,
const GrOptDrawState&,
GrGpu::DrawType,
@ -191,32 +197,40 @@ protected:
// generating stage code.
void nameVariable(SkString* out, char prefix, const char* name);
void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage);
void createAndEmitProcessors(const GrGeometryStage* geometryProcessor,
const GrFragmentStage* colorStages[],
const GrFragmentStage* coverageStages[],
GrGLSLExpr4* inputColor,
GrGLSLExpr4* inputCoverage);
template <class ProcessorStage>
void createAndEmitProcessors(const ProcessorStage*[],
int effectCnt,
const GrGLProgramDesc::EffectKeyProvider&,
GrGLSLExpr4* fsInOutColor,
GrGLInstalledProcessors*);
void emitAndInstallProcs(const GrOptDrawState& optState,
GrGLSLExpr4* inputColor,
GrGLSLExpr4* inputCoverage);
void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
template <class Proc>
void emitAndInstallProc(const Proc&,
int index,
const ProcKeyProvider,
const GrGLSLExpr4& input,
GrGLSLExpr4* output);
// these emit functions help to keep the createAndEmitProcessors template general
void emitAndInstallProc(const GrFragmentStage&,
const GrProcessorKey&,
const char* outColor,
const char* inColor);
void emitAndInstallProc(const GrGeometryProcessor&,
const GrProcessorKey&,
const char* outColor,
const char* inColor);
void verify(const GrGeometryProcessor&);
void verify(const GrFragmentProcessor&);
void emitSamplers(const GrProcessor&,
GrGLProcessor::TextureSamplerArray* outSamplers,
GrGLInstalledProcessors*);
GrGLInstalledProc*);
// each specific program builder has a distinct transform and must override this function
virtual void emitTransforms(const GrProcessorStage&,
virtual void emitTransforms(const GrFragmentStage&,
GrGLProcessor::TransformedCoordsArray* outCoords,
GrGLInstalledProcessors*);
GrGLInstalledFragProc*);
GrGLProgram* finalize();
void bindUniformLocations(GrGLuint programID);
bool checkLinkStatus(GrGLuint programID);
void resolveUniformLocations(GrGLuint programID);
void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs);
void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs);
@ -256,10 +270,6 @@ protected:
void enterStage() { fOutOfStage = false; }
int stageIndex() const { return fStageIndex; }
typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider;
typedef GrGLProgramDataManager::UniformInfo UniformInfo;
typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
// number of each input/output type in a single allocation block, used by many builders
static const int kVarsPerBlock;
@ -270,9 +280,8 @@ protected:
bool fOutOfStage;
int fStageIndex;
SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor;
SkAutoTUnref<GrGLInstalledProcessors> fColorEffects;
SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects;
GrGLInstalledGeoProc* fGeometryProcessor;
SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
const GrOptDrawState& fOptState;
const GrGLProgramDesc& fDesc;
@ -286,32 +295,26 @@ protected:
};
/**
* This class encapsulates an array of GrGLProcessors and their supporting data (coord transforms
* and textures). It is built by GrGLProgramBuilder, then used to manage the necessary GL
* state and shader uniforms in GLPrograms. Its just Plain old data, and as such is entirely public
*
* TODO We really don't need this class to have an array of processors. It makes sense for it
* to just have one, also break out the transforms
* The below structs represent processors installed in programs. All processors can have texture
* samplers, but only frag processors have coord transforms, hence the need for different structs
*/
class GrGLInstalledProcessors : public SkRefCnt {
public:
GrGLInstalledProcessors(int reserveCount, bool hasExplicitLocalCoords = false)
: fGLProcessors(reserveCount)
, fSamplers(reserveCount)
, fTransforms(reserveCount)
, fHasExplicitLocalCoords(hasExplicitLocalCoords) {
}
struct GrGLInstalledProc {
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
virtual ~GrGLInstalledProcessors();
struct Sampler {
SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
UniformHandle fUniform;
int fTextureUnit;
};
SkSTArray<4, Sampler, true> fSamplers;
};
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
struct Sampler {
SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
UniformHandle fUniform;
int fTextureUnit;
};
struct GrGLInstalledGeoProc : public GrGLInstalledProc {
SkAutoTDelete<GrGLGeometryProcessor> fGLProc;
};
struct GrGLInstalledFragProc : public GrGLInstalledProc {
GrGLInstalledFragProc(bool useLocalCoords) : fGLProc(NULL), fLocalCoordAttrib(useLocalCoords) {}
class ShaderVarHandle {
public:
bool isValid() const { return fHandle > -1; }
@ -334,19 +337,14 @@ public:
GrSLType fType;
};
void addEffect(GrGLProcessor* effect) { fGLProcessors.push_back(effect); }
SkTArray<Sampler, true>& addSamplers() { return fSamplers.push_back(); }
SkTArray<Transform, true>& addTransforms() { return fTransforms.push_back(); }
SkAutoTDelete<GrGLFragmentProcessor> fGLProc;
SkSTArray<2, Transform, true> fTransforms;
bool fLocalCoordAttrib;
};
SkTArray<GrGLProcessor*> fGLProcessors;
SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
SkTArray<SkSTArray<2, Transform, true> > fTransforms;
bool fHasExplicitLocalCoords;
friend class GrGLShaderBuilder;
friend class GrGLVertexShaderBuilder;
friend class GrGLFragmentShaderBuilder;
friend class GrGLGeometryShaderBuilder;
struct GrGLInstalledFragProcs : public SkRefCnt {
virtual ~GrGLInstalledFragProcs();
SkSTArray<8, GrGLInstalledFragProc*, true> fProcs;
};
#endif

View File

@ -21,7 +21,7 @@ public:
/**
* Are explicit local coordinates provided as input to the vertex shader.
*/
bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
bool hasLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
/** Returns a vertex attribute that represents the local coords in the VS. This may be the same
as positionAttribute() or it may not be. It depends upon whether the rendering code

View File

@ -456,9 +456,6 @@ bool GrGpuGL::programUnitTest(int maxStages) {
ds->reset();
continue;
}
const GrGeometryStage* geometryProcessor = NULL;
SkSTArray<8, const GrFragmentStage*, true> colorStages;
SkSTArray<8, const GrFragmentStage*, true> coverageStages;
GrGLProgramDesc desc;
GrDeviceCoordTexture dstCopy;
@ -468,24 +465,14 @@ bool GrGpuGL::programUnitTest(int maxStages) {
}
if (!GrGLProgramDesc::Build(*ods,
drawType,
ods->getSrcBlendCoeff(),
ods->getDstBlendCoeff(),
this,
dstCopy.texture() ? &dstCopy : NULL,
&geometryProcessor,
&colorStages,
&coverageStages,
&desc)) {
SkDebugf("Failed to generate GL program descriptor");
return false;
}
SkAutoTUnref<GrGLProgram> program(GrGLProgramBuilder::CreateProgram(*ods,
desc,
drawType,
geometryProcessor,
colorStages.begin(),
coverageStages.begin(),
this));
SkAutoTUnref<GrGLProgram> program(
GrGLProgramBuilder::CreateProgram(*ods, desc, drawType, this));
if (NULL == program.get()) {
SkDebugf("Failed to create program!");
return false;