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:
parent
ba5fb932a1
commit
a5305a110a
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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==.
|
||||
|
@ -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();)
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "GrSingleTextureEffect.h"
|
||||
|
||||
class GrProcessorStage;
|
||||
class GrFragmentStage;
|
||||
class GrGLConfigConversionEffect;
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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());
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user