diff options
author | joshualitt <joshualitt@chromium.org> | 2014-10-10 09:56:55 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-10 09:56:55 -0700 |
commit | 71856d520461ae025a0332aa0ce9735a096d9baf (patch) | |
tree | b8cbbecf6a8ef31ffde8f7fb2be543d95587e7ad /src/gpu | |
parent | 5324978a88677ac6b758324321816427814e7793 (diff) |
Opt state takes a GP instead of a GeometryStage
BUG=skia:
Review URL: https://codereview.chromium.org/637003003
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrDrawState.cpp | 42 | ||||
-rw-r--r-- | src/gpu/GrDrawState.h | 16 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrOptDrawState.cpp | 14 | ||||
-rw-r--r-- | src/gpu/GrOptDrawState.h | 9 | ||||
-rw-r--r-- | src/gpu/GrProcessor.cpp | 17 | ||||
-rw-r--r-- | src/gpu/effects/GrConfigConversionEffect.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProcessor.h | 1 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 124 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 52 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.cpp | 149 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramDesc.h | 26 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 5 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 38 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.cpp | 13 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLLegacyNvprProgramBuilder.h | 4 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLNvprProgramBuilder.cpp | 28 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLNvprProgramBuilder.h | 6 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 243 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.h | 131 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLVertexShaderBuilder.h | 2 |
21 files changed, 373 insertions, 551 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/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..2216fb1c5a 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, ip->fLocalCoordAttrib, 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..687c2fd4c9 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -32,16 +32,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 +71,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 +112,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 +223,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 = 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) { @@ -334,19 +334,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 +354,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 +391,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 +503,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]->fGLProc); } } diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index 6141058152..a8293545b2 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -14,8 +14,6 @@ #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. @@ -98,6 +96,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 +121,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 +150,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 +175,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 +196,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 +269,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 +279,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 +294,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 { + GrGLGeometryProcessor* fGLProc; +}; +struct GrGLInstalledFragProc : public GrGLInstalledProc { + GrGLInstalledFragProc(bool useLocalCoords) : fGLProc(NULL), fLocalCoordAttrib(useLocalCoords) {} class ShaderVarHandle { public: bool isValid() const { return fHandle > -1; } @@ -334,19 +336,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; + 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 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 |