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
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
* 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;
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; }
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
void setWillNotUseInputColor() { fWillUseInputColor = false; }
private:
+ SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
bool fWillReadDstColor;
bool fWillUseInputColor;
// 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;
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());
SkMatrix fCoordChangeMatrix;
SkDEBUGCODE(mutable uint32_t fEffectUniqueID;)
- friend class GrProcessorStage;
+ friend class GrFragmentStage;
};
/**
}
}
- 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
#include "GrCoordTransform.h"
#include "gl/GrGLProcessor.h"
-class GrProcessorStage;
+class GrFragmentStage;
class GrBackendProcessorFactory;
/*
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()) {
}
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;
}
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);
}
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);
}
// sad trombone sound
return false;
}
- if (this->hasGeometryProcessor()) {
- fGeometryProcessor->localCoordChange(invVM);
- }
for (int s = 0; s < this->numColorStages(); ++s) {
fColorStages[s].localCoordChange(invVM);
}
}
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.
// 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) {
if (SK_InvalidUniqueID == fOriginalGPID) {
fDrawState->fGeometryProcessor.reset(NULL);
} else {
- SkASSERT(fDrawState->getGeometryProcessor()->getProcessor()->getUniqueID() ==
+ SkASSERT(fDrawState->getGeometryProcessor()->getUniqueID() ==
fOriginalGPID);
fOriginalGPID = SK_InvalidUniqueID;
}
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();
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]);
}
if (0 == drawState->numTotalStages()) {
drawState->fViewMatrix.reset();
fDrawState = drawState;
- fHasGeometryProcessor = false;
fNumColorStages = 0;
fSavedCoordChanges.reset(0);
SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
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]);
fColorStages[i].convertToPendingExec();
}
if (fGeometryProcessor) {
- fGeometryProcessor->convertToPendingExec();
+ fGeometryProcessor.convertToPendingExec();
}
for (int i = 0; i < fCoverageStages.count(); ++i) {
fCoverageStages[i].convertToPendingExec();
const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
SkASSERT(geometryProcessor);
SkASSERT(!this->hasGeometryProcessor());
- fGeometryProcessor.reset(new GrGeometryStage(geometryProcessor));
+ fGeometryProcessor.reset(SkRef(geometryProcessor));
this->invalidateOptState();
return geometryProcessor;
}
}
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]; }
GrDrawState* fDrawState;
SkMatrix fViewMatrix;
int fNumColorStages;
- bool fHasGeometryProcessor;
- SkAutoSTArray<8, GrProcessorStage::SavedCoordChange> fSavedCoordChanges;
+ SkAutoSTArray<8, GrFragmentStage::SavedCoordChange> fSavedCoordChanges;
};
/// @}
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;
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);
// Copy GeometryProcesssor from DS or ODS
if (drawState.hasGeometryProcessor()) {
- fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*drawState.getGeometryProcessor())));
+ fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
} else {
fGeometryProcessor.reset(NULL);
}
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();
}
}
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()) {
}
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;
}
}
}
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];
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==.
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());
#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));
}
return true;
}
-#endif
+#endif // end DEBUG
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
+ fCoordTransforms.push_back(transform);
+ SkDEBUGCODE(transform->setInEffect();)
+}
#include "GrSingleTextureEffect.h"
-class GrProcessorStage;
+class GrFragmentStage;
class GrGLConfigConversionEffect;
/**
@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,
#include "GrAllocator.h"
#include "GrProcessor.h"
#include "GrCoordTransform.h"
+#include "GrGLGeometryProcessor.h"
#include "GrGLProcessor.h"
#include "GrGpuGL.h"
#include "GrGLPathRendering.h"
/**
* 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 =
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) {
if (fGeometryProcessor.get()) {
this->initSamplers(fGeometryProcessor.get(), &texUnitIdx);
}
- this->initSamplers(fColorEffects.get(), &texUnitIdx);
- this->initSamplers(fCoverageEffects.get(), &texUnitIdx);
+ int numProcs = fFragmentProcessors->fProcs.count();
+ for (int i = 0; i < numProcs; i++) {
+ this->initSamplers(fFragmentProcessors->fProcs[i], &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)++;
- }
+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 GrGLInstalledProcessors* ip,
- const GrProcessor& processor,
- int effectIdx) {
- const SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = ip->fSamplers[effectIdx];
+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) {
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();
// 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;
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,
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++) {
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, ip->fLocalCoordAttrib, t);
if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
continue;
}
//////////////////////////////////////////////////////////////////////////////////////
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) {
}
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);
*/
void setData(const GrOptDrawState&,
GrGpu::DrawType,
- const GrGeometryStage* geometryProcessor,
- const GrFragmentStage* colorStages[],
- const GrFragmentStage* coverageStages[],
const GrDeviceCoordTexture* dstCopy, // can be NULL
SharedGLState*);
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.
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.
GrGLuint fProgramID;
// the installed effects
- SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor;
- SkAutoTUnref<GrGLInstalledProcessors> fColorEffects;
- SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects;
+ SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
+ SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
GrGLProgramDesc fDesc;
GrGpuGL* fGpu;
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
- GrGLInstalledProcessors* colorProcessors,
- GrGLInstalledProcessors* coverageProcessors);
+ GrGLInstalledFragProcs* fragmentProcessors);
virtual void onSetMatrixAndRenderTargetHeight(GrGpu::DrawType, const GrOptDrawState&);
typedef GrGLProgram INHERITED;
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;
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;
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) {
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();
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;
* 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();
-
- // 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;
- }
-
- 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);
+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* key = get_processor_meta_key(stage, useExplicitLocalCoords, caps, b);
- if (NULL == key) {
- return false;
- }
- uint32_t attribKey = gen_attrib_key(stage.getProcessor());
+ 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 ((attribKey) & kMetaKeyInvalidMask) {
- return false;
+ if ((textureKey | transformKey | classID) & kMetaKeyInvalidMask) {
+ return false;
}
- key[1] |= attribKey;
+ uint32_t* key = b->add32n(2);
+ key[0] = (textureKey << 16 | transformKey);
+ key[1] = (classID << 16);
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);
}
};
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();
// 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,
+ false,
desc,
&offsetAndSizeIndex)) {
return false;
}
- *geometryProcessor = &gpStage;
}
- for (int s = 0; s < optState.numColorStages(); ++s) {
- if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getColorStage(s),
- gpu->glCaps(),
- requiresLocalCoordAttrib,
- 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,
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;
}
*/
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 {
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;
}
}
void abandon();
GrGLProgram* getProgram(const GrOptDrawState&,
const GrGLProgramDesc&,
- DrawType,
- const GrGeometryStage* geometryProcessor,
- const GrFragmentStage* colorStages[],
- const GrFragmentStage* coverageStages[]);
+ DrawType);
private:
enum {
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
#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;
}
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;
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());
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) {
GrGLProgram* GrGLLegacyNvprProgramBuilder::createProgram(GrGLuint programID) {
return SkNEW_ARGS(GrGLLegacyNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fColorEffects, fCoverageEffects, fTexCoordSetCnt));
+ fFragmentProcessors.get(), fTexCoordSetCnt));
}
private:
int addTexCoordSets(int count);
- void emitTransforms(const GrProcessorStage&,
+ void emitTransforms(const GrFragmentStage&,
GrGLProcessor::TransformedCoordsArray* outCoords,
- GrGLInstalledProcessors*);
+ GrGLInstalledFragProc*);
int fTexCoordSetCnt;
, 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 =
}
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) {
// building
this->resolveSeparableVaryings(programID);
return SkNEW_ARGS(GrGLNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fColorEffects, fCoverageEffects, fSeparableVaryingInfos));
+ fFragmentProcessors.get(), fSeparableVaryingInfos));
}
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.
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();
}
}
- pb->createAndEmitProcessors(geometryProcessor, colorStages, coverageStages, &inputColor,
- &inputCoverage);
+ pb->emitAndInstallProcs(optState, &inputColor, &inputCoverage);
if (hasVertexShader) {
pb->fVS.transformSkiaToGLCoords();
/////////////////////////////////////////////////////////////////////////////
-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)
}
}
-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;
}
+ this->emitAndInstallFragProcs(optState.numColorStages(), numProcs, inputCoverage);
+}
- 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);
+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;
+ }
}
-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;
- }
+// 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("}");
+}
- // 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::emitAndInstallProc(const GrFragmentStage& fs,
+ const GrProcessorKey& key,
+ const char* outColor,
+ const char* inColor) {
+ GrGLInstalledFragProc* ifp = SkNEW_ARGS(GrGLInstalledFragProc, (fVS.hasLocalCoords()));
- if (effectEmitted) {
- *fsInOutColor = outColor;
- }
+ const GrFragmentProcessor& fp = *fs.getProcessor();
+ ifp->fGLProc = 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 = 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) {
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;
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;
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)));
}
}
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]->fGLProc);
}
}
#include "../GrGLProgramDataManager.h"
#include "../GrGLUniformHandle.h"
-class GrGLInstalledProcessors;
-
/*
* This is the base class for a series of interfaces. This base class *MUST* remain abstract with
* NO data members because it is used in multiple interface inheritance.
*/
};
+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.
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,
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 {
};
protected:
+ typedef GrGLProgramDesc::ProcKeyProvider ProcKeyProvider;
+ typedef GrGLProgramDataManager::UniformInfo UniformInfo;
+ typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
+
static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&,
const GrOptDrawState&,
GrGpu::DrawType,
// 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);
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;
bool fOutOfStage;
int fStageIndex;
- SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor;
- SkAutoTUnref<GrGLInstalledProcessors> fColorEffects;
- SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects;
+ GrGLInstalledGeoProc* fGeometryProcessor;
+ SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
const GrOptDrawState& fOptState;
const GrGLProgramDesc& fDesc;
};
/**
- * 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) {
- }
-
- virtual ~GrGLInstalledProcessors();
-
- typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+struct GrGLInstalledProc {
+ typedef GrGLProgramDataManager::UniformHandle UniformHandle;
+
+ struct Sampler {
+ SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
+ UniformHandle fUniform;
+ int fTextureUnit;
+ };
+ SkSTArray<4, Sampler, true> fSamplers;
+};
- struct Sampler {
- SkDEBUGCODE(Sampler() : fTextureUnit(-1) {})
- UniformHandle fUniform;
- int fTextureUnit;
- };
+struct GrGLInstalledGeoProc : public GrGLInstalledProc {
+ GrGLGeometryProcessor* fGLProc;
+};
+struct GrGLInstalledFragProc : public GrGLInstalledProc {
+ GrGLInstalledFragProc(bool useLocalCoords) : fGLProc(NULL), fLocalCoordAttrib(useLocalCoords) {}
class ShaderVarHandle {
public:
bool isValid() const { return fHandle > -1; }
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(); }
-
- SkTArray<GrGLProcessor*> fGLProcessors;
- SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
- SkTArray<SkSTArray<2, Transform, true> > fTransforms;
- bool fHasExplicitLocalCoords;
+ GrGLFragmentProcessor* fGLProc;
+ SkSTArray<2, Transform, true> fTransforms;
+ bool fLocalCoordAttrib;
+};
- friend class GrGLShaderBuilder;
- friend class GrGLVertexShaderBuilder;
- friend class GrGLFragmentShaderBuilder;
- friend class GrGLGeometryShaderBuilder;
+struct GrGLInstalledFragProcs : public SkRefCnt {
+ ~GrGLInstalledFragProcs();
+ SkSTArray<8, GrGLInstalledFragProc*, true> fProcs;
};
#endif
/**
* 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
ds->reset();
continue;
}
- const GrGeometryStage* geometryProcessor = NULL;
- SkSTArray<8, const GrFragmentStage*, true> colorStages;
- SkSTArray<8, const GrFragmentStage*, true> coverageStages;
GrGLProgramDesc desc;
GrDeviceCoordTexture dstCopy;
}
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;