removing coord change matrices

BUG=skia:

Review URL: https://codereview.chromium.org/821243003
This commit is contained in:
joshualitt 2014-12-29 09:04:40 -08:00 committed by Commit bot
parent d27f73ef27
commit 40d4bd8daf
14 changed files with 47 additions and 200 deletions

View File

@ -9,124 +9,25 @@
#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;
explicit GrFragmentStage(const GrFragmentProcessor* proc) : fProc(SkRef(proc)) {}
GrFragmentStage(const GrFragmentStage& other) { fProc.reset(SkRef(other.fProc.get())); }
const GrFragmentProcessor* processor() const { return fProc.get(); }
bool operator==(const GrFragmentStage& that) const {
return this->processor() == that.processor();
}
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;
}
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;)
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);
}
/**
* 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();
}
}
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;
};

View File

@ -148,9 +148,6 @@ public:
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;

View File

@ -30,14 +30,12 @@ bool GrDrawState::isEqual(const GrDrawState& that, bool explicitLocalCoords) con
}
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;
}
}
@ -45,20 +43,7 @@ bool GrDrawState::isEqual(const GrDrawState& that, bool explicitLocalCoords) con
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()));

View File

@ -48,11 +48,6 @@ public:
*this = state;
}
/**
* Copies another draw state with a preconcat to the view matrix.
**/
GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix);
virtual ~GrDrawState();
/**

View File

@ -359,7 +359,7 @@ bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
}
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);
@ -367,7 +367,7 @@ bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
}
}
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);

View File

@ -112,18 +112,18 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
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

View File

@ -21,14 +21,14 @@ void GrPaint::addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& ma
}
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();
}

View File

@ -12,55 +12,42 @@
#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

View File

@ -52,7 +52,7 @@ void GrProcOptInfo::internalCalc(const GrFragmentStage* stages,
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());

View File

@ -30,24 +30,12 @@
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();
}
@ -190,7 +178,7 @@ void GrGLProgram::setFragmentData(const GrOptDrawState& optState) {
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]);
@ -202,7 +190,7 @@ void GrGLProgram::setTransformData(const GrPendingFragmentStage& processor,
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);
@ -309,7 +297,7 @@ void GrGLNvprProgram::setTransformData(const GrPendingFragmentStage& proc,
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);
@ -354,7 +342,7 @@ GrGLLegacyNvprProgram::setTransformData(const GrPendingFragmentStage& proc,
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 =

View File

@ -69,7 +69,7 @@ enum MatrixType {
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)) {
@ -78,7 +78,7 @@ static uint32_t gen_transform_key(const GrPendingFragmentStage& stage, bool useE
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()) {
@ -170,7 +170,7 @@ bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState,
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)) {

View File

@ -24,7 +24,7 @@ int GrGLLegacyNvprProgramBuilder::addTexCoordSets(int count) {
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

View File

@ -20,7 +20,7 @@ GrGLNvprProgramBuilder::GrGLNvprProgramBuilder(GrGLGpu* gpu,
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);

View File

@ -277,7 +277,7 @@ void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& fs,
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());
@ -372,7 +372,7 @@ void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
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);
@ -380,20 +380,14 @@ void GrGLProgramBuilder::emitTransforms(const GrPendingFragmentStage& stage,
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;