#define GrFragmentStage_DEFINED
#include "GrFragmentProcessor.h"
-#include "SkMatrix.h"
/**
- * Wraps a GrFragmentProcessor. It also contains a coord change matrix. This matrix should be
- * concat'ed with all the processor's coord transforms that apply to local coords, unless
- * explicit local coords are provided with the draw.
+ * Wraps a GrFragmentProcessor, basically a copyable SkAutoTUnref
*/
class GrFragmentStage {
public:
- explicit GrFragmentStage(const GrFragmentProcessor* proc)
- : fProc(SkRef(proc)) {
- fCoordChangeMatrixSet = false;
- }
-
- GrFragmentStage(const GrFragmentStage& other) {
- fCoordChangeMatrixSet = other.fCoordChangeMatrixSet;
- if (other.fCoordChangeMatrixSet) {
- fCoordChangeMatrix = other.fCoordChangeMatrix;
- }
- fProc.reset(SkRef(other.fProc.get()));
- }
-
- static bool AreCompatible(const GrFragmentStage& a, const GrFragmentStage& b,
- bool usingExplicitLocalCoords) {
- SkASSERT(a.fProc.get());
- SkASSERT(b.fProc.get());
-
- if (!a.getProcessor()->isEqual(*b.getProcessor())) {
- return false;
- }
-
- // We always track the coord change matrix, but it has no effect when explicit local coords
- // are used.
- if (usingExplicitLocalCoords) {
- return true;
- }
-
- if (a.fCoordChangeMatrixSet != b.fCoordChangeMatrixSet) {
- return false;
- }
-
- if (!a.fCoordChangeMatrixSet) {
- return true;
- }
+ explicit GrFragmentStage(const GrFragmentProcessor* proc) : fProc(SkRef(proc)) {}
- return a.fCoordChangeMatrix == b.fCoordChangeMatrix;
- }
-
- /**
- * This is called when the coordinate system in which the geometry is specified will change.
- *
- * @param matrix The transformation from the old coord system in which geometry is specified
- * to the new one from which it will actually be drawn.
- */
- void localCoordChange(const SkMatrix& matrix) {
- if (fCoordChangeMatrixSet) {
- fCoordChangeMatrix.preConcat(matrix);
- } else {
- fCoordChangeMatrixSet = true;
- fCoordChangeMatrix = matrix;
- }
- }
-
- class SavedCoordChange {
- public:
- SkDEBUGCODE(SavedCoordChange() : fEffectUniqueID(SK_InvalidUniqueID) {})
- private:
- bool fCoordChangeMatrixSet;
- SkMatrix fCoordChangeMatrix;
- SkDEBUGCODE(mutable uint32_t fEffectUniqueID;)
+ GrFragmentStage(const GrFragmentStage& other) { fProc.reset(SkRef(other.fProc.get())); }
- friend class GrFragmentStage;
- };
-
- /**
- * This gets the current coordinate system change. It is the accumulation of
- * localCoordChange calls since the effect was installed. It is used when then caller
- * wants to temporarily change the source geometry coord system, draw something, and then
- * restore the previous coord system (e.g. temporarily draw in device coords).
- */
- void saveCoordChange(SavedCoordChange* savedCoordChange) const {
- savedCoordChange->fCoordChangeMatrixSet = fCoordChangeMatrixSet;
- if (fCoordChangeMatrixSet) {
- savedCoordChange->fCoordChangeMatrix = fCoordChangeMatrix;
- }
- SkASSERT(SK_InvalidUniqueID == savedCoordChange->fEffectUniqueID);
- SkDEBUGCODE(savedCoordChange->fEffectUniqueID = fProc->getUniqueID();)
- }
-
- /**
- * This balances the saveCoordChange call.
- */
- void restoreCoordChange(const SavedCoordChange& savedCoordChange) {
- fCoordChangeMatrixSet = savedCoordChange.fCoordChangeMatrixSet;
- if (fCoordChangeMatrixSet) {
- fCoordChangeMatrix = savedCoordChange.fCoordChangeMatrix;
- }
- SkASSERT(savedCoordChange.fEffectUniqueID == fProc->getUniqueID());
- SkDEBUGCODE(savedCoordChange.fEffectUniqueID = SK_InvalidUniqueID);
- }
+ const GrFragmentProcessor* processor() const { return fProc.get(); }
- /**
- * Gets the matrix representing all changes of coordinate system since the GrProcessor was
- * installed in the stage.
- */
- const SkMatrix& getCoordChangeMatrix() const {
- if (fCoordChangeMatrixSet) {
- return fCoordChangeMatrix;
- } else {
- return SkMatrix::I();
- }
+ bool operator==(const GrFragmentStage& that) const {
+ return this->processor() == that.processor();
}
- const GrFragmentProcessor* getProcessor() const { return fProc.get(); }
+ bool operator!=(const GrFragmentStage& that) const { return !(*this == that); }
protected:
- bool fCoordChangeMatrixSet;
- SkMatrix fCoordChangeMatrix;
SkAutoTUnref<const GrFragmentProcessor> fProc;
};
bool isOpaqueAndConstantColor(GrColor* constantColor) const;
private:
- friend class GrContext; // To access above two functions
- friend class GrStencilAndCoverTextContext; // To access above two functions
-
SkAutoTUnref<const GrXPFactory> fXPFactory;
SkSTArray<4, GrFragmentStage> fColorStages;
SkSTArray<2, GrFragmentStage> fCoverageStages;
}
for (int i = 0; i < this->numColorStages(); i++) {
- if (!GrFragmentStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
- explicitLocalCoords)) {
+ if (this->getColorStage(i) != that.getColorStage(i)) {
return false;
}
}
for (int i = 0; i < this->numCoverageStages(); i++) {
- if (!GrFragmentStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
- explicitLocalCoords)) {
+ if (this->getCoverageStage(i) != that.getCoverageStage(i)) {
return false;
}
}
return true;
}
-//////////////////////////////////////////////////////////////////////////////s
-
-GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) {
- SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
- *this = state;
- if (!preConcatMatrix.isIdentity()) {
- for (int i = 0; i < this->numColorStages(); ++i) {
- fColorStages[i].localCoordChange(preConcatMatrix);
- }
- for (int i = 0; i < this->numCoverageStages(); ++i) {
- fCoverageStages[i].localCoordChange(preConcatMatrix);
- }
- }
-}
+//////////////////////////////////////////////////////////////////////////////
GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get()));
*this = state;
}
- /**
- * Copies another draw state with a preconcat to the view matrix.
- **/
- GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix);
-
virtual ~GrDrawState();
/**
}
for (int s = 0; s < drawState.numColorStages(); ++s) {
- const GrProcessor* effect = drawState.getColorStage(s).getProcessor();
+ const GrProcessor* effect = drawState.getColorStage(s).processor();
int numTextures = effect->numTextures();
for (int t = 0; t < numTextures; ++t) {
GrTexture* texture = effect->texture(t);
}
}
for (int s = 0; s < drawState.numCoverageStages(); ++s) {
- const GrProcessor* effect = drawState.getCoverageStage(s).getProcessor();
+ const GrProcessor* effect = drawState.getCoverageStage(s).processor();
int numTextures = effect->numTextures();
for (int t = 0; t < numTextures; ++t) {
GrTexture* texture = effect->texture(t);
for (int i = firstColorStageIdx; i < drawState.numColorStages(); ++i) {
SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
GrPendingFragmentStage,
- (drawState.fColorStages[i], hasLocalCoords));
+ (drawState.fColorStages[i]));
usesLocalCoords = usesLocalCoords ||
- drawState.fColorStages[i].getProcessor()->usesLocalCoords();
+ drawState.fColorStages[i].processor()->usesLocalCoords();
}
fNumColorStages = fFragmentStages.count();
for (int i = firstCoverageStageIdx; i < drawState.numCoverageStages(); ++i) {
SkNEW_APPEND_TO_TARRAY(&fFragmentStages,
GrPendingFragmentStage,
- (drawState.fCoverageStages[i], hasLocalCoords));
+ (drawState.fCoverageStages[i]));
usesLocalCoords = usesLocalCoords ||
- drawState.fCoverageStages[i].getProcessor()->usesLocalCoords();
+ drawState.fCoverageStages[i].processor()->usesLocalCoords();
}
// let the GP init the batch tracker
}
void GrPaint::addColorTextureProcessor(GrTexture* texture,
- const SkMatrix& matrix,
- const GrTextureParams& params) {
+ const SkMatrix& matrix,
+ const GrTextureParams& params) {
this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
}
void GrPaint::addCoverageTextureProcessor(GrTexture* texture,
- const SkMatrix& matrix,
- const GrTextureParams& params) {
+ const SkMatrix& matrix,
+ const GrTextureParams& params) {
this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
}
#include "GrCoordTransform.h"
#include "GrFragmentProcessor.h"
#include "GrPendingProgramElement.h"
-#include "SkMatrix.h"
/**
* This a baked variant of GrFragmentStage, as recorded in GrOptDrawState.
*/
class GrPendingFragmentStage {
public:
- GrPendingFragmentStage(const GrFragmentStage& stage, bool ignoreMatrix)
- : fProc(stage.getProcessor())
- , fCoordChangeMatrix(ignoreMatrix ? SkMatrix::I() : stage.getCoordChangeMatrix()) {
- }
+ GrPendingFragmentStage(const GrFragmentStage& stage) : fProc(stage.processor()) {}
GrPendingFragmentStage(const GrPendingFragmentStage& that) { *this = that; }
GrPendingFragmentStage& operator=(const GrPendingFragmentStage& that) {
fProc.reset(that.fProc.get());
- fCoordChangeMatrix = that.fCoordChangeMatrix;
return *this;
}
bool operator==(const GrPendingFragmentStage& that) const {
- return this->getProcessor()->isEqual(*that.getProcessor()) &&
- fCoordChangeMatrix == that.fCoordChangeMatrix;
+ return this->processor()->isEqual(*that.processor());
}
bool operator!=(const GrPendingFragmentStage& that) const { return !(*this == that); }
- const SkMatrix& getCoordChangeMatrix() const { return fCoordChangeMatrix; }
-
/**
* For a coord transform on the fragment processor, does it or the coord change matrix (if
* relevant) contain perspective?
*/
bool isPerspectiveCoordTransform(int matrixIndex) const {
- const GrCoordTransform& coordTransform = this->getProcessor()->coordTransform(matrixIndex);
+ const GrCoordTransform& coordTransform = this->processor()->coordTransform(matrixIndex);
uint32_t type = coordTransform.getMatrix().getType();
- if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
- type |= this->getCoordChangeMatrix().getType();
- }
-
return SkToBool(SkMatrix::kPerspective_Mask & type);
}
const char* name() const { return fProc->name(); }
- const GrFragmentProcessor* getProcessor() const { return fProc.get(); }
+ const GrFragmentProcessor* processor() const { return fProc.get(); }
protected:
GrPendingProgramElement<const GrFragmentProcessor> fProc;
- SkMatrix fCoordChangeMatrix;
};
#endif
fReadsFragPosition = initWillReadFragmentPosition;
for (int i = 0; i < stageCount; ++i) {
- const GrFragmentProcessor* processor = stages[i].getProcessor();
+ const GrFragmentProcessor* processor = stages[i].processor();
fInOut.resetWillUseInputColor();
processor->computeInvariantOutput(&fInOut);
SkDEBUGCODE(fInOut.validate());
static SkMatrix get_transform_matrix(const GrPendingFragmentStage& stage,
int transformIdx,
const SkMatrix& localMatrix) {
- const GrCoordTransform& coordTransform = stage.getProcessor()->coordTransform(transformIdx);
+ const GrCoordTransform& coordTransform = stage.processor()->coordTransform(transformIdx);
SkMatrix combined;
+ // We only apply the localmatrix to localcoords
if (kLocal_GrCoordSet == coordTransform.sourceCoords()) {
- // If we have explicit local coords or are in device coords then we shouldn't need a coord
- // change.
- // TODO shortly we will get rid of coord change matrices entirely, and the PrimProc will
- // always have a local matrix, often Identity, which can be used to transform coord
- // transforms. Until we actually do this, we need some way for a PrimProc to say 'use my
- // matrix' instead of the coord change mechanism. Temporarily, we have overloaded
- // The identity matrix to be this value, ie if a primproc has an identity matrix for a
- // local matrix then use the coord change matrix, otherwise use the matrix on the primproc
- if (localMatrix.isIdentity()) {
- const SkMatrix& ccm = stage.getCoordChangeMatrix();
- combined.setConcat(coordTransform.getMatrix(), ccm);
- } else {
- combined.setConcat(coordTransform.getMatrix(), localMatrix);
- }
+ combined.setConcat(coordTransform.getMatrix(), localMatrix);
} else {
combined = coordTransform.getMatrix();
}
int numProcessors = fFragmentProcessors->fProcs.count();
for (int e = 0; e < numProcessors; ++e) {
const GrPendingFragmentStage& stage = optState.getFragmentStage(e);
- const GrProcessor& processor = *stage.getProcessor();
+ const GrProcessor& processor = *stage.processor();
fFragmentProcessors->fProcs[e]->fGLProc->setData(fProgramDataManager, processor);
const SkMatrix& localMatrix = optState.getPrimitiveProcessor()->localMatrix();
this->setTransformData(stage, localMatrix, fFragmentProcessors->fProcs[e]);
GrGLInstalledFragProc* ip) {
SkTArray<GrGLInstalledFragProc::Transform, true>& transforms = ip->fTransforms;
int numTransforms = transforms.count();
- SkASSERT(numTransforms == processor.getProcessor()->numTransforms());
+ SkASSERT(numTransforms == processor.processor()->numTransforms());
for (int t = 0; t < numTransforms; ++t) {
SkASSERT(transforms[t].fHandle.isValid());
const SkMatrix& matrix = get_transform_matrix(processor, t, localMatrix);
GrGLInstalledFragProc* ip) {
SkTArray<GrGLInstalledFragProc::Transform, true>& transforms = ip->fTransforms;
int numTransforms = transforms.count();
- SkASSERT(numTransforms == proc.getProcessor()->numTransforms());
+ SkASSERT(numTransforms == proc.processor()->numTransforms());
for (int t = 0; t < numTransforms; ++t) {
SkASSERT(transforms[t].fHandle.isValid());
const SkMatrix& transform = get_transform_matrix(proc, t, localMatrix);
GrGLInstalledFragProc* ip) {
// We've hidden the texcoord index in the first entry of the transforms array for each effect
int texCoordIndex = ip->fTransforms[0].fHandle.handle();
- int numTransforms = proc.getProcessor()->numTransforms();
+ int numTransforms = proc.processor()->numTransforms();
for (int t = 0; t < numTransforms; ++t) {
const SkMatrix& transform = get_transform_matrix(proc, t, localMatrix);
GrGLPathRendering::PathTexGenComponents components =
static uint32_t gen_transform_key(const GrPendingFragmentStage& stage, bool useExplicitLocalCoords) {
uint32_t totalKey = 0;
- int numTransforms = stage.getProcessor()->numTransforms();
+ int numTransforms = stage.processor()->numTransforms();
for (int t = 0; t < numTransforms; ++t) {
uint32_t key = 0;
if (stage.isPerspectiveCoordTransform(t)) {
key |= kNoPersp_MatrixType;
}
- const GrCoordTransform& coordTransform = stage.getProcessor()->coordTransform(t);
+ const GrCoordTransform& coordTransform = stage.processor()->coordTransform(t);
if (kLocal_GrCoordSet == coordTransform.sourceCoords() && !useExplicitLocalCoords) {
key |= kPositionCoords_Flag;
} else if (kDevice_GrCoordSet == coordTransform.sourceCoords()) {
for (int s = 0; s < optState.numFragmentStages(); ++s) {
const GrPendingFragmentStage& fps = optState.getFragmentStage(s);
- const GrFragmentProcessor& fp = *fps.getProcessor();
+ const GrFragmentProcessor& fp = *fps.processor();
fp.getGLProcessorKey(gpu->glCaps(), &b);
if (!get_meta_key(fp, gpu->glCaps(),
gen_transform_key(fps, requiresLocalCoordAttrib), &b)) {
void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrPendingFragmentStage& processorStage,
GrGLProcessor::TransformedCoordsArray* outCoords,
GrGLInstalledFragProc* ifp) {
- int numTransforms = processorStage.getProcessor()->numTransforms();
+ int numTransforms = processorStage.processor()->numTransforms();
int texCoordIndex = this->addTexCoordSets(numTransforms);
// Use the first uniform location as the texcoord index. This may seem a bit hacky but it
void GrGLNvprProgramBuilder::emitTransforms(const GrPendingFragmentStage& processorStage,
GrGLProcessor::TransformedCoordsArray* outCoords,
GrGLInstalledFragProc* ifp) {
- const GrFragmentProcessor* effect = processorStage.getProcessor();
+ const GrFragmentProcessor* effect = processorStage.processor();
int numTransforms = effect->numTransforms();
ifp->fTransforms.push_back_n(numTransforms);
const char* inColor) {
GrGLInstalledFragProc* ifp = SkNEW(GrGLInstalledFragProc);
- const GrFragmentProcessor& fp = *fs.getProcessor();
+ const GrFragmentProcessor& fp = *fs.processor();
ifp->fGLProc.reset(fp.createGLInstance());
SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures());
void GrGLProgramBuilder::emitTransforms(const GrPendingFragmentStage& stage,
GrGLProcessor::TransformedCoordsArray* outCoords,
GrGLInstalledFragProc* ifp) {
- const GrFragmentProcessor* processor = stage.getProcessor();
+ const GrFragmentProcessor* processor = stage.processor();
int numTransforms = processor->numTransforms();
ifp->fTransforms.push_back_n(numTransforms);
const char* uniName = "StageMatrix";
GrSLType varyingType;
- // TODO when we have deleted the coord change matrices we can get rid of the below check
GrCoordSet coordType = processor->coordTransform(t).sourceCoords();
const SkMatrix& localMatrix = fOptState.getPrimitiveProcessor()->localMatrix();
- if (localMatrix.isIdentity()) {
- varyingType = stage.isPerspectiveCoordTransform(t) ? kVec3f_GrSLType :
- kVec2f_GrSLType;
- } else {
- uint32_t type = processor->coordTransform(t).getMatrix().getType();
- if (kLocal_GrCoordSet == coordType) {
- type |= localMatrix.getType();
- }
- varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
- kVec2f_GrSLType;
+ uint32_t type = processor->coordTransform(t).getMatrix().getType();
+ if (kLocal_GrCoordSet == coordType) {
+ type |= localMatrix.getType();
}
+ varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
+ kVec2f_GrSLType;
GrSLPrecision precision = processor->coordTransform(t).precision();
SkString suffixedUniName;