aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar joshualitt <joshualitt@chromium.org>2014-10-10 17:47:00 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-10-10 17:47:00 -0700
commita5305a110ab5201d5dadd40cbe711582d5ac4996 (patch)
tree239878bf237402e4fb7d88081d4f1289c5824d2e /src/gpu
parentba5fb932a1b5666a861043735cfb055cc1b600c7 (diff)
Opt state takes a GP instead of a GeometryStage
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrDrawState.cpp42
-rw-r--r--src/gpu/GrDrawState.h16
-rw-r--r--src/gpu/GrDrawTarget.cpp2
-rw-r--r--src/gpu/GrOptDrawState.cpp14
-rw-r--r--src/gpu/GrOptDrawState.h9
-rw-r--r--src/gpu/GrProcessor.cpp17
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.h2
-rw-r--r--src/gpu/gl/GrGLGeometryProcessor.h2
-rw-r--r--src/gpu/gl/GrGLProcessor.h1
-rw-r--r--src/gpu/gl/GrGLProgram.cpp124
-rw-r--r--src/gpu/gl/GrGLProgram.h52
-rw-r--r--src/gpu/gl/GrGLProgramDesc.cpp149
-rw-r--r--src/gpu/gl/GrGLProgramDesc.h26
-rw-r--r--src/gpu/gl/GrGpuGL.h5
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp38
-rw-r--r--src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp13
-rw-r--r--src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h4
-rw-r--r--src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp28
-rw-r--r--src/gpu/gl/builders/GrGLNvprProgramBuilder.h6
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.cpp244
-rw-r--r--src/gpu/gl/builders/GrGLProgramBuilder.h132
-rw-r--r--src/gpu/gl/builders/GrGLVertexShaderBuilder.h2
22 files changed, 376 insertions, 552 deletions
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index 288fa12730..e1fa6da877 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -43,9 +43,7 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
if (this->hasGeometryProcessor()) {
if (!that.hasGeometryProcessor()) {
return false;
- } else if (!GrProcessorStage::AreCompatible(*this->getGeometryProcessor(),
- *that.getGeometryProcessor(),
- explicitLocalCoords)) {
+ } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
return false;
}
} else if (that.hasGeometryProcessor()) {
@@ -53,13 +51,13 @@ bool GrDrawState::isEqual(const GrDrawState& that) const {
}
for (int i = 0; i < this->numColorStages(); i++) {
- if (!GrProcessorStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
+ if (!GrFragmentStage::AreCompatible(this->getColorStage(i), that.getColorStage(i),
explicitLocalCoords)) {
return false;
}
}
for (int i = 0; i < this->numCoverageStages(); i++) {
- if (!GrProcessorStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
+ if (!GrFragmentStage::AreCompatible(this->getCoverageStage(i), that.getCoverageStage(i),
explicitLocalCoords)) {
return false;
}
@@ -116,9 +114,6 @@ GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr
SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
*this = state;
if (!preConcatMatrix.isIdentity()) {
- if (this->hasGeometryProcessor()) {
- fGeometryProcessor->localCoordChange(preConcatMatrix);
- }
for (int i = 0; i < this->numColorStages(); ++i) {
fColorStages[i].localCoordChange(preConcatMatrix);
}
@@ -147,7 +142,7 @@ GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
fCoverage = that.fCoverage;
fDrawFace = that.fDrawFace;
if (that.hasGeometryProcessor()) {
- fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*that.fGeometryProcessor.get())));
+ fGeometryProcessor.initAndRef(that.fGeometryProcessor);
} else {
fGeometryProcessor.reset(NULL);
}
@@ -202,9 +197,6 @@ bool GrDrawState::setIdentityViewMatrix() {
// sad trombone sound
return false;
}
- if (this->hasGeometryProcessor()) {
- fGeometryProcessor->localCoordChange(invVM);
- }
for (int s = 0; s < this->numColorStages(); ++s) {
fColorStages[s].localCoordChange(invVM);
}
@@ -265,9 +257,7 @@ bool GrDrawState::validateVertexAttribs() const {
}
if (this->hasGeometryProcessor()) {
- const GrGeometryStage& stage = *this->getGeometryProcessor();
- const GrGeometryProcessor* gp = stage.getProcessor();
- SkASSERT(gp);
+ const GrGeometryProcessor* gp = this->getGeometryProcessor();
// make sure that any attribute indices have the correct binding type, that the attrib
// type and effect's shader lang type are compatible, and that attributes shared by
// multiple effects use the same shader lang type.
@@ -410,8 +400,7 @@ bool GrDrawState::hasSolidCoverage() const {
// Run through the coverage stages and see if the coverage will be all ones at the end.
if (this->hasGeometryProcessor()) {
- const GrGeometryProcessor* gp = fGeometryProcessor->getProcessor();
- gp->computeInvariantOutput(&inout);
+ fGeometryProcessor->computeInvariantOutput(&inout);
}
for (int s = 0; s < this->numCoverageStages(); ++s) {
@@ -456,7 +445,7 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
if (SK_InvalidUniqueID == fOriginalGPID) {
fDrawState->fGeometryProcessor.reset(NULL);
} else {
- SkASSERT(fDrawState->getGeometryProcessor()->getProcessor()->getUniqueID() ==
+ SkASSERT(fDrawState->getGeometryProcessor()->getUniqueID() ==
fOriginalGPID);
fOriginalGPID = SK_InvalidUniqueID;
}
@@ -477,7 +466,7 @@ void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
if (NULL != ds) {
SkASSERT(SK_InvalidUniqueID == fOriginalGPID);
if (NULL != ds->getGeometryProcessor()) {
- fOriginalGPID = ds->getGeometryProcessor()->getProcessor()->getUniqueID();
+ fOriginalGPID = ds->getGeometryProcessor()->getUniqueID();
}
fColorEffectCnt = ds->numColorStages();
fCoverageEffectCnt = ds->numCoverageStages();
@@ -515,14 +504,9 @@ void GrDrawState::AutoViewMatrixRestore::restore() {
fDrawState->fViewMatrix = fViewMatrix;
SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
- numCoverageStages -= fHasGeometryProcessor ? 1 : 0;
SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
int i = 0;
- if (fHasGeometryProcessor) {
- SkASSERT(fDrawState->hasGeometryProcessor());
- fDrawState->fGeometryProcessor->restoreCoordChange(fSavedCoordChanges[i++]);
- }
for (int s = 0; s < fNumColorStages; ++s, ++i) {
fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
}
@@ -568,7 +552,6 @@ bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
if (0 == drawState->numTotalStages()) {
drawState->fViewMatrix.reset();
fDrawState = drawState;
- fHasGeometryProcessor = false;
fNumColorStages = 0;
fSavedCoordChanges.reset(0);
SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
@@ -590,13 +573,6 @@ void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& co
fSavedCoordChanges.reset(fDrawState->numTotalStages());
int i = 0;
- fHasGeometryProcessor = false;
- if (fDrawState->hasGeometryProcessor()) {
- fDrawState->fGeometryProcessor->saveCoordChange(&fSavedCoordChanges[i++]);
- fDrawState->fGeometryProcessor->localCoordChange(coordChangeMatrix);
- fHasGeometryProcessor = true;
- }
-
fNumColorStages = fDrawState->numColorStages();
for (int s = 0; s < fNumColorStages; ++s, ++i) {
fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]);
@@ -619,7 +595,7 @@ void GrDrawState::convertToPendingExec() {
fColorStages[i].convertToPendingExec();
}
if (fGeometryProcessor) {
- fGeometryProcessor->convertToPendingExec();
+ fGeometryProcessor.convertToPendingExec();
}
for (int i = 0; i < fCoverageStages.count(); ++i) {
fCoverageStages[i].convertToPendingExec();
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 03af7b532f..d58d8c64e7 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -221,7 +221,7 @@ public:
const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
SkASSERT(geometryProcessor);
SkASSERT(!this->hasGeometryProcessor());
- fGeometryProcessor.reset(new GrGeometryStage(geometryProcessor));
+ fGeometryProcessor.reset(SkRef(geometryProcessor));
this->invalidateOptState();
return geometryProcessor;
}
@@ -254,7 +254,7 @@ public:
}
bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
- const GrGeometryStage* getGeometryProcessor() const { return fGeometryProcessor.get(); }
+ const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
const GrFragmentStage& getColorStage(int idx) const { return fColorStages[idx]; }
const GrFragmentStage& getCoverageStage(int idx) const { return fCoverageStages[idx]; }
@@ -485,8 +485,7 @@ public:
GrDrawState* fDrawState;
SkMatrix fViewMatrix;
int fNumColorStages;
- bool fHasGeometryProcessor;
- SkAutoSTArray<8, GrProcessorStage::SavedCoordChange> fSavedCoordChanges;
+ SkAutoSTArray<8, GrFragmentStage::SavedCoordChange> fSavedCoordChanges;
};
/// @}
@@ -810,10 +809,11 @@ private:
GrBlendCoeff fSrcBlend;
GrBlendCoeff fDstBlend;
- typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
- SkAutoTDelete<GrGeometryStage> fGeometryProcessor;
- FragmentStageArray fColorStages;
- FragmentStageArray fCoverageStages;
+ typedef SkSTArray<4, GrFragmentStage> FragmentStageArray;
+ typedef GrProgramElementRef<const GrGeometryProcessor> ProgramGeometryProcessor;
+ ProgramGeometryProcessor fGeometryProcessor;
+ FragmentStageArray fColorStages;
+ FragmentStageArray fCoverageStages;
uint32_t fHints;
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 7265f4d23a..b144caf63e 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -391,7 +391,7 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
SkASSERT(drawState.getRenderTarget());
if (drawState.hasGeometryProcessor()) {
- const GrGeometryProcessor* gp = drawState.getGeometryProcessor()->getProcessor();
+ const GrGeometryProcessor* gp = drawState.getGeometryProcessor();
int numTextures = gp->numTextures();
for (int t = 0; t < numTextures; ++t) {
GrTexture* texture = gp->texture(t);
diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp
index b3d90f7310..7c8710f7d6 100644
--- a/src/gpu/GrOptDrawState.cpp
+++ b/src/gpu/GrOptDrawState.cpp
@@ -54,7 +54,7 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState,
// Copy GeometryProcesssor from DS or ODS
if (drawState.hasGeometryProcessor()) {
- fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*drawState.getGeometryProcessor())));
+ fGeometryProcessor.initAndRef(drawState.fGeometryProcessor);
} else {
fGeometryProcessor.reset(NULL);
}
@@ -305,8 +305,8 @@ void GrOptDrawState::getStageStats(const GrDrawState& ds, int firstColorStageIdx
get_stage_stats(stage, &fReadsDst, &fReadsFragPosition);
}
if (ds.hasGeometryProcessor()) {
- const GrGeometryStage& stage = *ds.getGeometryProcessor();
- fReadsFragPosition = fReadsFragPosition || stage.getProcessor()->willReadFragmentPosition();
+ const GrGeometryProcessor& gp = *ds.getGeometryProcessor();
+ fReadsFragPosition = fReadsFragPosition || gp.willReadFragmentPosition();
}
}
@@ -354,9 +354,7 @@ bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
if (this->hasGeometryProcessor()) {
if (!that.hasGeometryProcessor()) {
return false;
- } else if (!GrProcessorStage::AreCompatible(*this->getGeometryProcessor(),
- *that.getGeometryProcessor(),
- explicitLocalCoords)) {
+ } else if (!this->getGeometryProcessor()->isEqual(*that.getGeometryProcessor())) {
return false;
}
} else if (that.hasGeometryProcessor()) {
@@ -364,8 +362,8 @@ bool GrOptDrawState::isEqual(const GrOptDrawState& that) const {
}
for (int i = 0; i < this->numFragmentStages(); i++) {
- if (!GrProcessorStage::AreCompatible(this->getFragmentStage(i), that.getFragmentStage(i),
- explicitLocalCoords)) {
+ if (!GrFragmentStage::AreCompatible(this->getFragmentStage(i), that.getFragmentStage(i),
+ explicitLocalCoords)) {
return false;
}
}
diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h
index 1c439bbff1..f47913a41a 100644
--- a/src/gpu/GrOptDrawState.h
+++ b/src/gpu/GrOptDrawState.h
@@ -127,7 +127,7 @@ public:
}
bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
- const GrGeometryStage* getGeometryProcessor() const { return fGeometryProcessor.get(); }
+ const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
const GrFragmentStage& getColorStage(int idx) const {
SkASSERT(idx < this->numColorStages());
return fFragmentStages[idx];
@@ -441,11 +441,12 @@ private:
GrBlendCoeff fDstBlend;
typedef SkSTArray<8, GrFragmentStage> FragmentStageArray;
- SkAutoTDelete<GrGeometryStage> fGeometryProcessor;
- FragmentStageArray fFragmentStages;
+ typedef GrProgramElementRef<const GrGeometryProcessor> ProgramGeometryProcessor;
+ ProgramGeometryProcessor fGeometryProcessor;
+ FragmentStageArray fFragmentStages;
// This function is equivalent to the offset into fFragmentStages where coverage stages begin.
- int fNumColorStages;
+ int fNumColorStages;
// This is simply a different representation of info in fVertexAttribs and thus does
// not need to be compared in op==.
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 71dfaae912..1732e3a27a 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -103,11 +103,6 @@ const char* GrProcessor::name() const {
return this->getFactory().name();
}
-void GrProcessor::addCoordTransform(const GrCoordTransform* transform) {
- fCoordTransforms.push_back(transform);
- SkDEBUGCODE(transform->setInEffect();)
-}
-
void GrProcessor::addTextureAccess(const GrTextureAccess* access) {
fTextureAccesses.push_back(access);
this->addGpuResource(access->getProgramTexture());
@@ -123,10 +118,6 @@ void GrProcessor::operator delete(void* target) {
#ifdef SK_DEBUG
void GrProcessor::assertEquality(const GrProcessor& other) const {
- SkASSERT(this->numTransforms() == other.numTransforms());
- for (int i = 0; i < this->numTransforms(); ++i) {
- SkASSERT(this->coordTransform(i) == other.coordTransform(i));
- }
SkASSERT(this->numTextures() == other.numTextures());
for (int i = 0; i < this->numTextures(); ++i) {
SkASSERT(this->textureAccess(i) == other.textureAccess(i));
@@ -173,5 +164,11 @@ bool GrProcessor::InvariantOutput::validPreMulColor() const {
}
return true;
}
-#endif
+#endif // end DEBUG
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+void GrFragmentProcessor::addCoordTransform(const GrCoordTransform* transform) {
+ fCoordTransforms.push_back(transform);
+ SkDEBUGCODE(transform->setInEffect();)
+}
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index aa2c87482e..8c65dce506 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -10,7 +10,7 @@
#include "GrSingleTextureEffect.h"
-class GrProcessorStage;
+class GrFragmentStage;
class GrGLConfigConversionEffect;
/**
diff --git a/src/gpu/gl/GrGLGeometryProcessor.h b/src/gpu/gl/GrGLGeometryProcessor.h
index ce1c7c988a..e50f5987f2 100644
--- a/src/gpu/gl/GrGLGeometryProcessor.h
+++ b/src/gpu/gl/GrGLGeometryProcessor.h
@@ -10,6 +10,8 @@
#include "GrGLProcessor.h"
+class GrGLGPBuilder;
+
/**
* If a GL effect needs a GrGLFullShaderBuilder* object to emit vertex code, then it must inherit
* from this class. Since paths don't have vertices, this class is only meant to be used internally
diff --git a/src/gpu/gl/GrGLProcessor.h b/src/gpu/gl/GrGLProcessor.h
index 5f698325fb..04870779a3 100644
--- a/src/gpu/gl/GrGLProcessor.h
+++ b/src/gpu/gl/GrGLProcessor.h
@@ -114,6 +114,7 @@ public:
@param samplers Contains one entry for each GrTextureAccess of the GrProcessor. These
can be passed to the builder to emit texture reads in the generated
code.
+ TODO this should take a struct
*/
virtual void emitCode(GrGLFPBuilder* builder,
const GrFragmentProcessor& effect,
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index e0d4939323..2d9b569333 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -10,6 +10,7 @@
#include "GrAllocator.h"
#include "GrProcessor.h"
#include "GrCoordTransform.h"
+#include "GrGLGeometryProcessor.h"
#include "GrGLProcessor.h"
#include "GrGpuGL.h"
#include "GrGLPathRendering.h"
@@ -24,7 +25,7 @@
/**
* Retrieves the final matrix that a transform needs to apply to its source coords.
*/
-static SkMatrix get_transform_matrix(const GrProcessorStage& processorStage,
+static SkMatrix get_transform_matrix(const GrFragmentStage& processorStage,
bool useExplicitLocalCoords,
int transformIdx) {
const GrCoordTransform& coordTransform =
@@ -59,17 +60,15 @@ GrGLProgram::GrGLProgram(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
- GrGLInstalledProcessors* geometryProcessor,
- GrGLInstalledProcessors* colorProcessors,
- GrGLInstalledProcessors* coverageProcessors)
+ GrGLInstalledGeoProc* geometryProcessor,
+ GrGLInstalledFragProcs* fragmentProcessors)
: fColor(GrColor_ILLEGAL)
, fCoverage(GrColor_ILLEGAL)
, fDstCopyTexUnit(-1)
, fBuiltinUniformHandles(builtinUniforms)
, fProgramID(programID)
- , fGeometryProcessor(SkSafeRef(geometryProcessor))
- , fColorEffects(SkRef(colorProcessors))
- , fCoverageEffects(SkRef(coverageProcessors))
+ , fGeometryProcessor(geometryProcessor)
+ , fFragmentProcessors(SkRef(fragmentProcessors))
, fDesc(desc)
, fGpu(gpu)
, fProgramDataManager(gpu, uniforms) {
@@ -96,28 +95,24 @@ void GrGLProgram::initSamplerUniforms() {
if (fGeometryProcessor.get()) {
this->initSamplers(fGeometryProcessor.get(), &texUnitIdx);
}
- this->initSamplers(fColorEffects.get(), &texUnitIdx);
- this->initSamplers(fCoverageEffects.get(), &texUnitIdx);
+ 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) {
@@ -134,9 +129,6 @@ void GrGLProgram::bindTextures(const GrGLInstalledProcessors* ip,
void GrGLProgram::setData(const GrOptDrawState& optState,
GrGpu::DrawType drawType,
- const GrGeometryStage* geometryProcessor,
- const GrFragmentStage* colorStages[],
- const GrFragmentStage* coverageStages[],
const GrDeviceCoordTexture* dstCopy,
SharedGLState* sharedState) {
GrColor color = optState.getColor();
@@ -170,25 +162,34 @@ void GrGLProgram::setData(const GrOptDrawState& optState,
// we set the textures, and uniforms for installed processors in a generic way, but subclasses
// of GLProgram determine how to set coord transforms
if (fGeometryProcessor.get()) {
- SkASSERT(geometryProcessor);
- this->setData<GrGeometryStage>(&geometryProcessor, fGeometryProcessor.get());
+ SkASSERT(optState.hasGeometryProcessor());
+ const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
+ fGeometryProcessor->fGLProc->setData(fProgramDataManager, gp);
+ this->bindTextures(fGeometryProcessor, gp);
}
- this->setData<GrFragmentStage>(colorStages, fColorEffects.get());
- this->setData<GrFragmentStage>(coverageStages, fCoverageEffects.get());
+ this->setFragmentData(optState);
// Some of GrGLProgram subclasses need to update state here
this->didSetData(drawType);
}
-void GrGLProgram::setTransformData(const GrProcessorStage& processor,
- int effectIdx,
- GrGLInstalledProcessors* ip) {
- SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = ip->fTransforms[effectIdx];
+void GrGLProgram::setFragmentData(const GrOptDrawState& optState) {
+ int numProcessors = fFragmentProcessors->fProcs.count();
+ for (int e = 0; e < numProcessors; ++e) {
+ const GrFragmentStage& stage = optState.getFragmentStage(e);
+ const GrProcessor& processor = *stage.getProcessor();
+ fFragmentProcessors->fProcs[e]->fGLProc->setData(fProgramDataManager, processor);
+ this->setTransformData(stage, fFragmentProcessors->fProcs[e]);
+ this->bindTextures(fFragmentProcessors->fProcs[e], processor);
+ }
+}
+void GrGLProgram::setTransformData(const GrFragmentStage& processor, GrGLInstalledFragProc* ip) {
+ SkTArray<GrGLInstalledFragProc::Transform, true>& transforms = ip->fTransforms;
int numTransforms = transforms.count();
SkASSERT(numTransforms == processor.getProcessor()->numTransforms());
for (int t = 0; t < numTransforms; ++t) {
SkASSERT(transforms[t].fHandle.isValid());
- const SkMatrix& matrix = get_transform_matrix(processor, ip->fHasExplicitLocalCoords, t);
+ const SkMatrix& matrix = get_transform_matrix(processor, ip->fLocalCoordAttrib, t);
if (!transforms[t].fCurrentValue.cheapEqualTo(matrix)) {
fProgramDataManager.setSkMatrix(transforms[t].fHandle.convertToUniformHandle(), matrix);
transforms[t].fCurrentValue = matrix;
@@ -321,10 +322,8 @@ GrGLNvprProgramBase::GrGLNvprProgramBase(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
- GrGLInstalledProcessors* colorProcessors,
- GrGLInstalledProcessors* coverageProcessors)
- : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL, colorProcessors,
- coverageProcessors) {
+ GrGLInstalledFragProcs* fragmentProcessors)
+ : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, NULL, fragmentProcessors) {
}
void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawType,
@@ -343,11 +342,9 @@ GrGLNvprProgram::GrGLNvprProgram(GrGpuGL* gpu,
const BuiltinUniformHandles& builtinUniforms,
GrGLuint programID,
const UniformInfoArray& uniforms,
- GrGLInstalledProcessors* colorProcessors,
- GrGLInstalledProcessors* coverageProcessors,
+ GrGLInstalledFragProcs* fragmentProcessors,
const SeparableVaryingInfoArray& separableVaryings)
- : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, colorProcessors,
- coverageProcessors) {
+ : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fragmentProcessors) {
int count = separableVaryings.count();
fVaryings.push_back_n(count);
for (int i = 0; i < count; i++) {
@@ -365,15 +362,13 @@ void GrGLNvprProgram::didSetData(GrGpu::DrawType drawType) {
SkASSERT(GrGpu::IsPathRenderingDrawType(drawType));
}
-void GrGLNvprProgram::setTransformData(const GrProcessorStage& processor,
- int effectIdx,
- GrGLInstalledProcessors* ip) {
- SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = ip->fTransforms[effectIdx];
+void GrGLNvprProgram::setTransformData(const GrFragmentStage& proc, GrGLInstalledFragProc* ip) {
+ SkTArray<GrGLInstalledFragProc::Transform, true>& transforms = ip->fTransforms;
int numTransforms = transforms.count();
- SkASSERT(numTransforms == processor.getProcessor()->numTransforms());
+ SkASSERT(numTransforms == proc.getProcessor()->numTransforms());
for (int t = 0; t < numTransforms; ++t) {
SkASSERT(transforms[t].fHandle.isValid());
- const SkMatrix& transform = get_transform_matrix(processor, ip->fHasExplicitLocalCoords, t);
+ const SkMatrix& transform = get_transform_matrix(proc, false, t);
if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
continue;
}
@@ -392,15 +387,13 @@ void GrGLNvprProgram::setTransformData(const GrProcessorStage& processor,
//////////////////////////////////////////////////////////////////////////////////////
GrGLLegacyNvprProgram::GrGLLegacyNvprProgram(GrGpuGL* gpu,
- const GrGLProgramDesc& desc,
- const BuiltinUniformHandles& builtinUniforms,
- GrGLuint programID,
- const UniformInfoArray& uniforms,
- GrGLInstalledProcessors* colorProcessors,
- GrGLInstalledProcessors* coverageProcessors,
- int texCoordSetCnt)
- : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, colorProcessors,
- coverageProcessors)
+ const GrGLProgramDesc& desc,
+ const BuiltinUniformHandles& builtinUniforms,
+ GrGLuint programID,
+ const UniformInfoArray& uniforms,
+ GrGLInstalledFragProcs* fps,
+ int texCoordSetCnt)
+ : INHERITED(gpu, desc, builtinUniforms, programID, uniforms, fps)
, fTexCoordSetCnt(texCoordSetCnt) {
}
@@ -409,17 +402,16 @@ void GrGLLegacyNvprProgram::didSetData(GrGpu::DrawType drawType) {
fGpu->glPathRendering()->flushPathTexGenSettings(fTexCoordSetCnt);
}
-void GrGLLegacyNvprProgram::setTransformData(const GrProcessorStage& processorStage,
- int effectIdx,
- GrGLInstalledProcessors* ip) {
+void
+GrGLLegacyNvprProgram::setTransformData(const GrFragmentStage& proc, GrGLInstalledFragProc* ip) {
// We've hidden the texcoord index in the first entry of the transforms array for each effect
- int texCoordIndex = ip->fTransforms[effectIdx][0].fHandle.handle();
- int numTransforms = processorStage.getProcessor()->numTransforms();
+ int texCoordIndex = ip->fTransforms[0].fHandle.handle();
+ int numTransforms = proc.getProcessor()->numTransforms();
for (int t = 0; t < numTransforms; ++t) {
- const SkMatrix& transform = get_transform_matrix(processorStage, false, t);
+ const SkMatrix& transform = get_transform_matrix(proc, false, t);
GrGLPathRendering::PathTexGenComponents components =
GrGLPathRendering::kST_PathTexGenComponents;
- if (processorStage.isPerspectiveCoordTransform(t, false)) {
+ if (proc.isPerspectiveCoordTransform(t, false)) {
components = GrGLPathRendering::kSTR_PathTexGenComponents;
}
fGpu->glPathRendering()->enablePathTexGen(texCoordIndex++, components, transform);
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index fc441e5d76..e8aef35f1d 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -152,9 +152,6 @@ public:
*/
void setData(const GrOptDrawState&,
GrGpu::DrawType,
- const GrGeometryStage* geometryProcessor,
- const GrFragmentStage* colorStages[],
- const GrFragmentStage* coverageStages[],
const GrDeviceCoordTexture* dstCopy, // can be NULL
SharedGLState*);
@@ -167,13 +164,12 @@ protected:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
- GrGLInstalledProcessors* geometryProcessor,
- GrGLInstalledProcessors* colorProcessors,
- GrGLInstalledProcessors* coverageProcessors);
+ GrGLInstalledGeoProc* geometryProcessor,
+ GrGLInstalledFragProcs* fragmentProcessors);
// Sets the texture units for samplers.
void initSamplerUniforms();
- void initSamplers(GrGLInstalledProcessors* processors, int* texUnitIdx);
+ void initSamplers(GrGLInstalledProc*, int* texUnitIdx);
// Helper for setData(). Makes GL calls to specify the initial color when there is not
// per-vertex colors.
@@ -184,23 +180,9 @@ protected:
void setCoverage(const GrOptDrawState&, GrColor coverage, SharedGLState*);
// A templated helper to loop over effects, set the transforms(via subclass) and bind textures
- template <class ProcessorStage>
- void setData(const ProcessorStage* effectStages[],
- GrGLInstalledProcessors* installedProcessors) {
- int numEffects = installedProcessors->fGLProcessors.count();
- SkASSERT(numEffects == installedProcessors->fTransforms.count());
- SkASSERT(numEffects == installedProcessors->fSamplers.count());
- for (int e = 0; e < numEffects; ++e) {
- const GrProcessor& effect = *effectStages[e]->getProcessor();
- installedProcessors->fGLProcessors[e]->setData(fProgramDataManager, effect);
- this->setTransformData(*effectStages[e], e, installedProcessors);
- this->bindTextures(installedProcessors, effect, e);
- }
- }
- virtual void setTransformData(const GrProcessorStage& effectStage,
- int effectIdx,
- GrGLInstalledProcessors* pe);
- void bindTextures(const GrGLInstalledProcessors*, const GrProcessor&, int effectIdx);
+ void setFragmentData(const GrOptDrawState&);
+ virtual void setTransformData(const GrFragmentStage& effectStage, GrGLInstalledFragProc* pe);
+ void bindTextures(const GrGLInstalledProc*, const GrProcessor&);
/*
* Legacy NVPR needs a hook here to flush path tex gen settings.
@@ -221,9 +203,8 @@ protected:
GrGLuint fProgramID;
// the installed effects
- SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor;
- SkAutoTUnref<GrGLInstalledProcessors> fColorEffects;
- SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects;
+ SkAutoTDelete<GrGLInstalledGeoProc> fGeometryProcessor;
+ SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
GrGLProgramDesc fDesc;
GrGpuGL* fGpu;
@@ -248,8 +229,7 @@ protected:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
- GrGLInstalledProcessors* colorProcessors,
- GrGLInstalledProcessors* coverageProcessors);
+ GrGLInstalledFragProcs* fragmentProcessors);
virtual void onSetMatrixAndRenderTargetHeight(GrGpu::DrawType, const GrOptDrawState&);
typedef GrGLProgram INHERITED;
@@ -267,13 +247,10 @@ private:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
- GrGLInstalledProcessors* colorProcessors,
- GrGLInstalledProcessors* coverageProcessors,
+ GrGLInstalledFragProcs* fragmentProcessors,
const SeparableVaryingInfoArray& separableVaryings);
virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
- virtual void setTransformData(const GrProcessorStage&,
- int effectIdx,
- GrGLInstalledProcessors*) SK_OVERRIDE;
+ virtual void setTransformData(const GrFragmentStage&, GrGLInstalledFragProc*) SK_OVERRIDE;
struct Varying {
GrGLint fLocation;
@@ -298,13 +275,10 @@ private:
const BuiltinUniformHandles&,
GrGLuint programID,
const UniformInfoArray&,
- GrGLInstalledProcessors* colorProcessors,
- GrGLInstalledProcessors* coverageProcessors,
+ GrGLInstalledFragProcs* fragmentProcessors,
int texCoordSetCnt);
virtual void didSetData(GrGpu::DrawType) SK_OVERRIDE;
- virtual void setTransformData(const GrProcessorStage&,
- int effectIdx,
- GrGLInstalledProcessors*) SK_OVERRIDE;
+ virtual void setTransformData(const GrFragmentStage&, GrGLInstalledFragProc*) SK_OVERRIDE;
int fTexCoordSetCnt;
diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp
index 0c85c99a8a..224411e51c 100644
--- a/src/gpu/gl/GrGLProgramDesc.cpp
+++ b/src/gpu/gl/GrGLProgramDesc.cpp
@@ -60,10 +60,10 @@ static bool swizzle_requires_alpha_remapping(const GrGLCaps& caps,
return false;
}
-static uint32_t gen_attrib_key(const GrGeometryProcessor* effect) {
+static uint32_t gen_attrib_key(const GrGeometryProcessor& proc) {
uint32_t key = 0;
- const GrGeometryProcessor::VertexAttribArray& vars = effect->getVertexAttribs();
+ const GrGeometryProcessor::VertexAttribArray& vars = proc.getVertexAttribs();
int numAttributes = vars.count();
SkASSERT(numAttributes <= 2);
for (int a = 0; a < numAttributes; ++a) {
@@ -73,7 +73,7 @@ static uint32_t gen_attrib_key(const GrGeometryProcessor* effect) {
return key;
}
-static uint32_t gen_transform_key(const GrProcessorStage& effectStage,
+static uint32_t gen_transform_key(const GrFragmentStage& effectStage,
bool useExplicitLocalCoords) {
uint32_t totalKey = 0;
int numTransforms = effectStage.getProcessor()->numTransforms();
@@ -96,11 +96,11 @@ static uint32_t gen_transform_key(const GrProcessorStage& effectStage,
return totalKey;
}
-static uint32_t gen_texture_key(const GrProcessor* effect, const GrGLCaps& caps) {
+static uint32_t gen_texture_key(const GrProcessor& proc, const GrGLCaps& caps) {
uint32_t key = 0;
- int numTextures = effect->numTextures();
+ int numTextures = proc.numTextures();
for (int t = 0; t < numTextures; ++t) {
- const GrTextureAccess& access = effect->textureAccess(t);
+ const GrTextureAccess& access = proc.textureAccess(t);
uint32_t configComponentMask = GrPixelConfigComponentMask(access.getTexture()->config());
if (swizzle_requires_alpha_remapping(caps, configComponentMask, access.swizzleMask())) {
key |= 1 << t;
@@ -115,101 +115,61 @@ static uint32_t gen_texture_key(const GrProcessor* effect, const GrGLCaps& caps)
* in its key (e.g. the pixel format of textures used). So we create a meta-key for
* every effect using this function. It is also responsible for inserting the effect's class ID
* which must be different for every GrProcessor subclass. It can fail if an effect uses too many
- * textures, transforms, etc, for the space allotted in the meta-key.
+ * textures, transforms, etc, for the space allotted in the meta-key. NOTE, both FPs and GPs share
+ * this function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
*/
-
-static uint32_t* get_processor_meta_key(const GrProcessorStage& processorStage,
- bool useExplicitLocalCoords,
- const GrGLCaps& caps,
- GrProcessorKeyBuilder* b) {
-
- uint32_t textureKey = gen_texture_key(processorStage.getProcessor(), caps);
- uint32_t transformKey = gen_transform_key(processorStage,useExplicitLocalCoords);
- uint32_t classID = processorStage.getProcessor()->getFactory().effectClassID();
-
- // 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);
}
};
@@ -242,17 +202,9 @@ GrGLProgramDesc::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::Sta
bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
GrGpu::DrawType drawType,
- GrBlendCoeff srcCoeff,
- GrBlendCoeff dstCoeff,
GrGpuGL* gpu,
const GrDeviceCoordTexture* dstCopy,
- const GrGeometryStage** geometryProcessor,
- SkTArray<const GrFragmentStage*, true>* colorStages,
- SkTArray<const GrFragmentStage*, true>* coverageStages,
GrGLProgramDesc* desc) {
- colorStages->reset();
- coverageStages->reset();
-
bool inputColorIsUsed = optState.inputColorIsUsed();
bool inputCoverageIsUsed = optState.inputCoverageIsUsed();
@@ -274,29 +226,17 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
// We can only have one effect which touches the vertex shader
if (optState.hasGeometryProcessor()) {
- const GrGeometryStage& gpStage = *optState.getGeometryProcessor();
- if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(gpStage,
+ if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(*optState.getGeometryProcessor(),
gpu->glCaps(),
- requiresLocalCoordAttrib,
+ 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,
@@ -399,15 +339,8 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState,
header->fPrimaryOutputType = optState.getPrimaryOutputType();
header->fSecondaryOutputType = optState.getSecondaryOutputType();
- for (int s = 0; s < optState.numColorStages(); ++s) {
- colorStages->push_back(&optState.getColorStage(s));
- }
- for (int s = 0; s < optState.numCoverageStages(); ++s) {
- coverageStages->push_back(&optState.getCoverageStage(s));
- }
-
- header->fColorEffectCnt = colorStages->count();
- header->fCoverageEffectCnt = coverageStages->count();
+ header->fColorEffectCnt = optState.numColorStages();
+ header->fCoverageEffectCnt = optState.numCoverageStages();
desc->finalize();
return true;
}
diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h
index 9bf7553b61..4e1be5b2f9 100644
--- a/src/gpu/gl/GrGLProgramDesc.h
+++ b/src/gpu/gl/GrGLProgramDesc.h
@@ -43,13 +43,8 @@ public:
*/
static bool Build(const GrOptDrawState&,
GrGpu::DrawType,
- GrBlendCoeff srcCoeff,
- GrBlendCoeff dstCoeff,
GrGpuGL*,
- const GrDeviceCoordTexture* dstCopy,
- const GrGeometryStage** geometryProcessor,
- SkTArray<const GrFragmentStage*, true>* colorStages,
- SkTArray<const GrFragmentStage*, true>* coverageStages,
+ const GrDeviceCoordTexture*,
GrGLProgramDesc*);
bool hasGeometryProcessor() const {
@@ -160,26 +155,23 @@ private:
const KeyHeader& getHeader() const { return *this->atOffset<KeyHeader, kHeaderOffset>(); }
/** Used to provide effects' keys to their emitCode() function. */
- class EffectKeyProvider {
+ class ProcKeyProvider {
public:
- enum EffectType {
- kGeometryProcessor_EffectType,
- kColor_EffectType,
- kCoverage_EffectType,
+ enum ProcessorType {
+ kGeometry_ProcessorType,
+ kFragment_ProcessorType,
};
- EffectKeyProvider(const GrGLProgramDesc* desc, EffectType type) : fDesc(desc) {
+ ProcKeyProvider(const GrGLProgramDesc* desc, ProcessorType type)
+ : fDesc(desc), fBaseIndex(0) {
switch (type) {
- case kGeometryProcessor_EffectType:
+ case kGeometry_ProcessorType:
// there can be only one
fBaseIndex = 0;
break;
- case kColor_EffectType:
+ case kFragment_ProcessorType:
fBaseIndex = desc->hasGeometryProcessor() ? 1 : 0;
break;
- case kCoverage_EffectType:
- fBaseIndex = desc->numColorEffects() + (desc->hasGeometryProcessor() ? 1 : 0);
- break;
}
}
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 056f0935ec..24ab4ec14d 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -181,10 +181,7 @@ private:
void abandon();
GrGLProgram* getProgram(const GrOptDrawState&,
const GrGLProgramDesc&,
- DrawType,
- const GrGeometryStage* geometryProcessor,
- const GrFragmentStage* colorStages[],
- const GrFragmentStage* coverageStages[]);
+ DrawType);
private:
enum {
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 7dba5316a4..6a09ebf64e 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -93,10 +93,7 @@ int GrGpuGL::ProgramCache::search(const GrGLProgramDesc& desc) const {
GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState,
const GrGLProgramDesc& desc,
- DrawType type,
- const GrGeometryStage* geometryProcessor,
- const GrFragmentStage* colorStages[],
- const GrFragmentStage* coverageStages[]) {
+ DrawType type) {
#ifdef PROGRAM_CACHE_STATS
++fTotalRequests;
#endif
@@ -131,9 +128,7 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrOptDrawState& optState,
#ifdef PROGRAM_CACHE_STATS
++fCacheMisses;
#endif
- GrGLProgram* program = GrGLProgramBuilder::CreateProgram(optState, desc, type,
- geometryProcessor, colorStages,
- coverageStages, fGpu);
+ GrGLProgram* program = GrGLProgramBuilder::CreateProgram(optState, desc, type, fGpu);
if (NULL == program) {
return NULL;
}
@@ -237,30 +232,13 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
return false;
}
- const GrGeometryStage* geometryProcessor = NULL;
- SkSTArray<8, const GrFragmentStage*, true> colorStages;
- SkSTArray<8, const GrFragmentStage*, true> coverageStages;
GrGLProgramDesc desc;
- if (!GrGLProgramDesc::Build(*optState.get(),
- type,
- srcCoeff,
- dstCoeff,
- this,
- dstCopy,
- &geometryProcessor,
- &colorStages,
- &coverageStages,
- &desc)) {
+ if (!GrGLProgramDesc::Build(*optState.get(), type, this, dstCopy, &desc)) {
SkDEBUGFAIL("Failed to generate GL program descriptor");
return false;
}
- fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(),
- desc,
- type,
- geometryProcessor,
- colorStages.begin(),
- coverageStages.begin()));
+ fCurrentProgram.reset(fProgramCache->getProgram(*optState.get(), desc, type));
if (NULL == fCurrentProgram.get()) {
SkDEBUGFAIL("Failed to create program!");
return false;
@@ -276,13 +254,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC
this->flushBlend(*optState.get(), kDrawLines_DrawType == type, srcCoeff, dstCoeff);
- fCurrentProgram->setData(*optState.get(),
- type,
- geometryProcessor,
- colorStages.begin(),
- coverageStages.begin(),
- dstCopy,
- &fSharedGLProgramState);
+ fCurrentProgram->setData(*optState.get(), type, dstCopy, &fSharedGLProgramState);
}
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(optState->getRenderTarget());
diff --git a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp b/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp
index acb4af10be..1c1cb42122 100644
--- a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp
@@ -24,20 +24,17 @@ int GrGLLegacyNvprProgramBuilder::addTexCoordSets(int count) {
return firstFreeCoordSet;
}
-void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrProcessorStage& processorStage,
+void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrFragmentStage& processorStage,
GrGLProcessor::TransformedCoordsArray* outCoords,
- GrGLInstalledProcessors* installedProcessors) {
+ GrGLInstalledFragProc* ifp) {
int numTransforms = processorStage.getProcessor()->numTransforms();
int texCoordIndex = this->addTexCoordSets(numTransforms);
- SkTArray<GrGLInstalledProcessors::Transform, true>& transforms =
- installedProcessors->addTransforms();
-
// Use the first uniform location as the texcoord index. This may seem a bit hacky but it
// allows us to use one program effects object for all of our programs which really simplifies
// the code overall
- transforms.push_back_n(1);
- transforms[0].fHandle = GrGLInstalledProcessors::ShaderVarHandle(texCoordIndex);
+ ifp->fTransforms.push_back_n(1);
+ ifp->fTransforms[0].fHandle = GrGLInstalledFragProc::ShaderVarHandle(texCoordIndex);
SkString name;
for (int t = 0; t < numTransforms; ++t) {
@@ -51,5 +48,5 @@ void GrGLLegacyNvprProgramBuilder::emitTransforms(const GrProcessorStage& proces
GrGLProgram* GrGLLegacyNvprProgramBuilder::createProgram(GrGLuint programID) {
return SkNEW_ARGS(GrGLLegacyNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fColorEffects, fCoverageEffects, fTexCoordSetCnt));
+ fFragmentProcessors.get(), fTexCoordSetCnt));
}
diff --git a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h b/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h
index 496fbd8726..dabec081b4 100644
--- a/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h
@@ -18,9 +18,9 @@ public:
private:
int addTexCoordSets(int count);
- void emitTransforms(const GrProcessorStage&,
+ void emitTransforms(const GrFragmentStage&,
GrGLProcessor::TransformedCoordsArray* outCoords,
- GrGLInstalledProcessors*);
+ GrGLInstalledFragProc*);
int fTexCoordSetCnt;
diff --git a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
index e5eae9d884..a20b0d6b0d 100644
--- a/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp
@@ -18,15 +18,13 @@ GrGLNvprProgramBuilder::GrGLNvprProgramBuilder(GrGpuGL* gpu,
, fSeparableVaryingInfos(kVarsPerBlock) {
}
-void GrGLNvprProgramBuilder::emitTransforms(const GrProcessorStage& processorStage,
+void GrGLNvprProgramBuilder::emitTransforms(const GrFragmentStage& processorStage,
GrGLProcessor::TransformedCoordsArray* outCoords,
- GrGLInstalledProcessors* installedProcessors) {
- const GrProcessor* effect = processorStage.getProcessor();
+ GrGLInstalledFragProc* ifp) {
+ const GrFragmentProcessor* effect = processorStage.getProcessor();
int numTransforms = effect->numTransforms();
- SkTArray<GrGLInstalledProcessors::Transform, true>& transforms =
- installedProcessors->addTransforms();
- transforms.push_back_n(numTransforms);
+ ifp->fTransforms.push_back_n(numTransforms);
for (int t = 0; t < numTransforms; t++) {
GrSLType varyingType =
@@ -43,24 +41,24 @@ void GrGLNvprProgramBuilder::emitTransforms(const GrProcessorStage& processorSta
}
const char* vsVaryingName;
const char* fsVaryingName;
- transforms[t].fHandle = this->addSeparableVarying(varyingType, varyingName,
- &vsVaryingName, &fsVaryingName);
- transforms[t].fType = varyingType;
+ ifp->fTransforms[t].fHandle = this->addSeparableVarying(varyingType, varyingName,
+ &vsVaryingName, &fsVaryingName);
+ ifp->fTransforms[t].fType = varyingType;
SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
(SkString(fsVaryingName), varyingType));
}
}
-GrGLInstalledProcessors::ShaderVarHandle
+GrGLInstalledFragProc::ShaderVarHandle
GrGLNvprProgramBuilder::addSeparableVarying(GrSLType type,
- const char* name,
- const char** vsOutName,
- const char** fsInName) {
+ const char* name,
+ const char** vsOutName,
+ const char** fsInName) {
addVarying(type, name, vsOutName, fsInName);
SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back();
varying.fVariable = fFS.fInputs.back();
- return GrGLInstalledProcessors::ShaderVarHandle(fSeparableVaryingInfos.count() - 1);
+ return GrGLInstalledFragProc::ShaderVarHandle(fSeparableVaryingInfos.count() - 1);
}
void GrGLNvprProgramBuilder::resolveSeparableVaryings(GrGLuint programId) {
@@ -80,5 +78,5 @@ GrGLProgram* GrGLNvprProgramBuilder::createProgram(GrGLuint programID) {
// building
this->resolveSeparableVaryings(programID);
return SkNEW_ARGS(GrGLNvprProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fColorEffects, fCoverageEffects, fSeparableVaryingInfos));
+ fFragmentProcessors.get(), fSeparableVaryingInfos));
}
diff --git a/src/gpu/gl/builders/GrGLNvprProgramBuilder.h b/src/gpu/gl/builders/GrGLNvprProgramBuilder.h
index cb1337521d..4bf7e02414 100644
--- a/src/gpu/gl/builders/GrGLNvprProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLNvprProgramBuilder.h
@@ -28,11 +28,11 @@ public:
virtual GrGLProgram* createProgram(GrGLuint programID);
private:
- virtual void emitTransforms(const GrProcessorStage&,
+ virtual void emitTransforms(const GrFragmentStage&,
GrGLProcessor::TransformedCoordsArray* outCoords,
- GrGLInstalledProcessors*) SK_OVERRIDE;
+ GrGLInstalledFragProc*) SK_OVERRIDE;
- typedef GrGLInstalledProcessors::ShaderVarHandle ShaderVarHandle;
+ typedef GrGLInstalledFragProc::ShaderVarHandle ShaderVarHandle;
/**
* Add a separable varying input variable to the current program.
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index fbf78d7634..7af7e8c215 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -6,7 +6,6 @@
*/
#include "GrGLProgramBuilder.h"
-#include "gl/GrGLGeometryProcessor.h"
#include "gl/GrGLProgram.h"
#include "gl/GrGLSLPrettyPrint.h"
#include "gl/GrGLUniformHandle.h"
@@ -32,16 +31,13 @@ const int GrGLProgramBuilder::kVarsPerBlock = 8;
GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
const GrGLProgramDesc& desc,
GrGpu::DrawType drawType,
- const GrGeometryStage* geometryProcessor,
- const GrFragmentStage* colorStages[],
- const GrFragmentStage* coverageStages[],
GrGpuGL* gpu) {
// create a builder. This will be handed off to effects so they can use it to add
// uniforms, varyings, textures, etc
SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(desc,
optState,
drawType,
- SkToBool(geometryProcessor),
+ optState.hasGeometryProcessor(),
gpu));
GrGLProgramBuilder* pb = builder.get();
@@ -74,8 +70,7 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
}
}
- pb->createAndEmitProcessors(geometryProcessor, colorStages, coverageStages, &inputColor,
- &inputCoverage);
+ pb->emitAndInstallProcs(optState, &inputColor, &inputCoverage);
if (hasVertexShader) {
pb->fVS.transformSkiaToGLCoords();
@@ -116,13 +111,15 @@ GrGLProgramBuilder::CreateProgramBuilder(const GrGLProgramDesc& desc,
/////////////////////////////////////////////////////////////////////////////
-GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrOptDrawState& optState,
+GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
+ const GrOptDrawState& optState,
const GrGLProgramDesc& desc)
: fVS(this)
, fGS(this)
, fFS(this, desc)
, fOutOfStage(true)
, fStageIndex(-1)
+ , fGeometryProcessor(NULL)
, fOptState(optState)
, fDesc(desc)
, fGpu(gpu)
@@ -225,104 +222,106 @@ void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* input
}
}
-void GrGLProgramBuilder::createAndEmitProcessors(const GrGeometryStage* geometryProcessor,
- const GrFragmentStage* colorStages[],
- const GrFragmentStage* coverageStages[],
- GrGLSLExpr4* inputColor,
- GrGLSLExpr4* inputCoverage) {
- bool useLocalCoords = fVS.hasExplicitLocalCoords();
-
- EffectKeyProvider colorKeyProvider(&fDesc, EffectKeyProvider::kColor_EffectType);
- int numColorEffects = fDesc.numColorEffects();
- GrGLInstalledProcessors* ip = SkNEW_ARGS(GrGLInstalledProcessors, (numColorEffects,
- useLocalCoords));
- this->createAndEmitProcessors<GrFragmentStage>(colorStages, numColorEffects, colorKeyProvider,
- inputColor, ip);
- fColorEffects.reset(ip);
-
- if (geometryProcessor) {
- fVS.emitAttributes(*geometryProcessor->getProcessor());
- EffectKeyProvider gpKeyProvider(&fDesc, EffectKeyProvider::kGeometryProcessor_EffectType);
- ip = SkNEW_ARGS(GrGLInstalledProcessors, (1, useLocalCoords));
- this->createAndEmitProcessors<GrGeometryStage>(&geometryProcessor, 1, gpKeyProvider,
- inputCoverage, ip);
- fGeometryProcessor.reset(ip);
+void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState,
+ GrGLSLExpr4* inputColor,
+ GrGLSLExpr4* inputCoverage) {
+ fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
+ int numProcs = optState.numFragmentStages();
+ this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor);
+ if (optState.hasGeometryProcessor()) {
+ const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
+ fVS.emitAttributes(gp);
+ ProcKeyProvider keyProvider(&fDesc, ProcKeyProvider::kGeometry_ProcessorType);
+ GrGLSLExpr4 output;
+ this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &output);
+ *inputCoverage = output;
}
+ 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.reset(fp.getFactory().createGLInstance(fp));
+
+ SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures());
+ this->emitSamplers(fp, &samplers, ifp);
+
+ // Fragment processors can have coord transforms
+ SkSTArray<2, GrGLProcessor::TransformedCoords> coords(fp.numTransforms());
+ this->emitTransforms(fs, &coords, ifp);
+
+ ifp->fGLProc->emitCode(this, fp, key, outColor, inColor, coords, samplers);
+
+ // We have to check that effects and the code they emit are consistent, ie if an effect
+ // asks for dst color, then the emit code needs to follow suit
+ verify(fp);
+ fFragmentProcessors->fProcs.push_back(ifp);
+}
+
+void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
+ const GrProcessorKey& key,
+ const char* outColor,
+ const char* inColor) {
+ SkASSERT(!fGeometryProcessor);
+ fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
+
+ fGeometryProcessor->fGLProc.reset(gp.getFactory().createGLInstance(gp));
+
+ SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
+ this->emitSamplers(gp, &samplers, fGeometryProcessor);
+
+ SkSTArray<2, GrGLProcessor::TransformedCoords> coords;
+
+ // TODO remove coords from emit code signature, probably best to use a struct here so these
+ // updates are less painful
+ fGeometryProcessor->fGLProc->emitCode(this, gp, key, outColor, inColor, coords, samplers);
+
+ // We have to check that effects and the code they emit are consistent, ie if an effect
+ // asks for dst color, then the emit code needs to follow suit
+ verify(gp);
}
void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) {
@@ -334,19 +333,17 @@ void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor());
}
-void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
+void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
GrGLProcessor::TransformedCoordsArray* outCoords,
- GrGLInstalledProcessors* installedProcessors) {
- SkTArray<GrGLInstalledProcessors::Transform, true>& transforms =
- installedProcessors->addTransforms();
- const GrProcessor* effect = effectStage.getProcessor();
+ GrGLInstalledFragProc* ifp) {
+ const GrFragmentProcessor* effect = effectStage.getProcessor();
int numTransforms = effect->numTransforms();
- transforms.push_back_n(numTransforms);
+ ifp->fTransforms.push_back_n(numTransforms);
for (int t = 0; t < numTransforms; t++) {
const char* uniName = "StageMatrix";
GrSLType varyingType =
- effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalCoords()) ?
+ effectStage.isPerspectiveCoordTransform(t, fVS.hasLocalCoords()) ?
kVec3f_GrSLType :
kVec2f_GrSLType;
@@ -356,10 +353,10 @@ void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
suffixedUniName.appendf("_%i", t);
uniName = suffixedUniName.c_str();
}
- transforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
- kMat33f_GrSLType,
- uniName,
- &uniName).toShaderBuilderIndex();
+ ifp->fTransforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+ kMat33f_GrSLType,
+ uniName,
+ &uniName).toShaderBuilderIndex();
const char* varyingName = "MatrixCoord";
SkString suffixedVaryingName;
@@ -393,18 +390,17 @@ void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
GrGLProcessor::TextureSamplerArray* outSamplers,
- GrGLInstalledProcessors* installedProcessors) {
- SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = installedProcessors->addSamplers();
+ GrGLInstalledProc* ip) {
int numTextures = processor.numTextures();
- samplers.push_back_n(numTextures);
+ ip->fSamplers.push_back_n(numTextures);
SkString name;
for (int t = 0; t < numTextures; ++t) {
name.printf("Sampler%d", t);
- samplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
- kSampler2D_GrSLType,
- name.c_str());
+ ip->fSamplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kSampler2D_GrSLType,
+ name.c_str());
SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
- (samplers[t].fUniform, processor.textureAccess(t)));
+ (ip->fSamplers[t].fUniform, processor.textureAccess(t)));
}
}
@@ -506,14 +502,14 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
return SkNEW_ARGS(GrGLProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
- fGeometryProcessor, fColorEffects, fCoverageEffects));
+ fGeometryProcessor, fFragmentProcessors.get()));
}
-////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
-GrGLInstalledProcessors::~GrGLInstalledProcessors() {
- int numEffects = fGLProcessors.count();
- for (int e = 0; e < numEffects; ++e) {
- SkDELETE(fGLProcessors[e]);
+GrGLInstalledFragProcs::~GrGLInstalledFragProcs() {
+ int numProcs = fProcs.count();
+ for (int e = 0; e < numProcs; ++e) {
+ SkDELETE(fProcs[e]);
}
}
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h
index 6141058152..2afdd099f4 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h
@@ -13,8 +13,7 @@
#include "GrGLVertexShaderBuilder.h"
#include "../GrGLProgramDataManager.h"
#include "../GrGLUniformHandle.h"
-
-class GrGLInstalledProcessors;
+#include "../GrGLGeometryProcessor.h"
/*
* This is the base class for a series of interfaces. This base class *MUST* remain abstract with
@@ -98,6 +97,11 @@ public:
*/
};
+struct GrGLInstalledProc;
+struct GrGLInstalledGeoProc;
+struct GrGLInstalledFragProc;
+struct GrGLInstalledFragProcs;
+
/*
* Please note - no diamond problems because of virtual inheritance. Also, both base classes
* are pure virtual with no data members. This is the base class for program building.
@@ -118,9 +122,6 @@ public:
static GrGLProgram* CreateProgram(const GrOptDrawState&,
const GrGLProgramDesc&,
GrGpu::DrawType,
- const GrGeometryStage* inGeometryProcessor,
- const GrFragmentStage* inColorStages[],
- const GrFragmentStage* inCoverageStages[],
GrGpuGL* gpu);
virtual UniformHandle addUniform(uint32_t visibility,
@@ -150,11 +151,12 @@ public:
virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() SK_OVERRIDE { return &fFS; }
virtual GrGLVertexBuilder* getVertexShaderBuilder() SK_OVERRIDE { return &fVS; }
- virtual void addVarying(GrSLType type,
- const char* name,
- const char** vsOutName = NULL,
- const char** fsInName = NULL,
- GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision);
+ virtual void addVarying(
+ GrSLType type,
+ const char* name,
+ const char** vsOutName = NULL,
+ const char** fsInName = NULL,
+ GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) SK_OVERRIDE;
// Handles for program uniforms (other than per-effect uniforms)
struct BuiltinUniformHandles {
@@ -174,6 +176,10 @@ public:
};
protected:
+ typedef GrGLProgramDesc::ProcKeyProvider ProcKeyProvider;
+ typedef GrGLProgramDataManager::UniformInfo UniformInfo;
+ typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
+
static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&,
const GrOptDrawState&,
GrGpu::DrawType,
@@ -191,32 +197,40 @@ protected:
// generating stage code.
void nameVariable(SkString* out, char prefix, const char* name);
void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage);
- void createAndEmitProcessors(const GrGeometryStage* geometryProcessor,
- const GrFragmentStage* colorStages[],
- const GrFragmentStage* coverageStages[],
- GrGLSLExpr4* inputColor,
- GrGLSLExpr4* inputCoverage);
- template <class ProcessorStage>
- void createAndEmitProcessors(const ProcessorStage*[],
- int effectCnt,
- const GrGLProgramDesc::EffectKeyProvider&,
- GrGLSLExpr4* fsInOutColor,
- GrGLInstalledProcessors*);
+ void emitAndInstallProcs(const GrOptDrawState& optState,
+ GrGLSLExpr4* inputColor,
+ GrGLSLExpr4* inputCoverage);
+ void emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut);
+ template <class Proc>
+ void emitAndInstallProc(const Proc&,
+ int index,
+ const ProcKeyProvider,
+ const GrGLSLExpr4& input,
+ GrGLSLExpr4* output);
+
+ // these emit functions help to keep the createAndEmitProcessors template general
+ void emitAndInstallProc(const GrFragmentStage&,
+ const GrProcessorKey&,
+ const char* outColor,
+ const char* inColor);
+ void emitAndInstallProc(const GrGeometryProcessor&,
+ const GrProcessorKey&,
+ const char* outColor,
+ const char* inColor);
void verify(const GrGeometryProcessor&);
void verify(const GrFragmentProcessor&);
void emitSamplers(const GrProcessor&,
GrGLProcessor::TextureSamplerArray* outSamplers,
- GrGLInstalledProcessors*);
+ GrGLInstalledProc*);
// each specific program builder has a distinct transform and must override this function
- virtual void emitTransforms(const GrProcessorStage&,
+ virtual void emitTransforms(const GrFragmentStage&,
GrGLProcessor::TransformedCoordsArray* outCoords,
- GrGLInstalledProcessors*);
+ GrGLInstalledFragProc*);
GrGLProgram* finalize();
void bindUniformLocations(GrGLuint programID);
bool checkLinkStatus(GrGLuint programID);
void resolveUniformLocations(GrGLuint programID);
-
void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs);
void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs);
@@ -256,10 +270,6 @@ protected:
void enterStage() { fOutOfStage = false; }
int stageIndex() const { return fStageIndex; }
- typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider;
- typedef GrGLProgramDataManager::UniformInfo UniformInfo;
- typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray;
-
// number of each input/output type in a single allocation block, used by many builders
static const int kVarsPerBlock;
@@ -270,9 +280,8 @@ protected:
bool fOutOfStage;
int fStageIndex;
- SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor;
- SkAutoTUnref<GrGLInstalledProcessors> fColorEffects;
- SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects;
+ GrGLInstalledGeoProc* fGeometryProcessor;
+ SkAutoTUnref<GrGLInstalledFragProcs> fFragmentProcessors;
const GrOptDrawState& fOptState;
const GrGLProgramDesc& fDesc;
@@ -286,32 +295,26 @@ protected:
};
/**
- * This class encapsulates an array of GrGLProcessors and their supporting data (coord transforms
- * and textures). It is built by GrGLProgramBuilder, then used to manage the necessary GL
- * state and shader uniforms in GLPrograms. Its just Plain old data, and as such is entirely public
- *
- * TODO We really don't need this class to have an array of processors. It makes sense for it
- * to just have one, also break out the transforms
+ * The below structs represent processors installed in programs. All processors can have texture
+ * samplers, but only frag processors have coord transforms, hence the need for different structs
*/
-class GrGLInstalledProcessors : public SkRefCnt {
-public:
- GrGLInstalledProcessors(int reserveCount, bool hasExplicitLocalCoords = false)
- : fGLProcessors(reserveCount)
- , fSamplers(reserveCount)
- , fTransforms(reserveCount)
- , fHasExplicitLocalCoords(hasExplicitLocalCoords) {
- }
-
- 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 {
+ SkAutoTDelete<GrGLGeometryProcessor> fGLProc;
+};
+struct GrGLInstalledFragProc : public GrGLInstalledProc {
+ GrGLInstalledFragProc(bool useLocalCoords) : fGLProc(NULL), fLocalCoordAttrib(useLocalCoords) {}
class ShaderVarHandle {
public:
bool isValid() const { return fHandle > -1; }
@@ -334,19 +337,14 @@ public:
GrSLType fType;
};
- void addEffect(GrGLProcessor* effect) { fGLProcessors.push_back(effect); }
- SkTArray<Sampler, true>& addSamplers() { return fSamplers.push_back(); }
- SkTArray<Transform, true>& addTransforms() { return fTransforms.push_back(); }
-
- SkTArray<GrGLProcessor*> fGLProcessors;
- SkTArray<SkSTArray<4, Sampler, true> > fSamplers;
- SkTArray<SkSTArray<2, Transform, true> > fTransforms;
- bool fHasExplicitLocalCoords;
+ SkAutoTDelete<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 {
+ virtual ~GrGLInstalledFragProcs();
+ SkSTArray<8, GrGLInstalledFragProc*, true> fProcs;
};
#endif
diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
index 0b85b84dfb..6e1495a746 100644
--- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
+++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h
@@ -21,7 +21,7 @@ public:
/**
* Are explicit local coordinates provided as input to the vertex shader.
*/
- bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
+ bool hasLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
/** Returns a vertex attribute that represents the local coords in the VS. This may be the same
as positionAttribute() or it may not be. It depends upon whether the rendering code