Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Unified Diff: src/gpu/gl/builders/GrGLProgramBuilder.cpp

Issue 611653002: Cleanup of shader building system (Closed) Base URL: https://skia.googlesource.com/skia.git@solo_gp
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/gl/builders/GrGLProgramBuilder.h ('k') | src/gpu/gl/builders/GrGLShaderBuilder.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/gl/builders/GrGLProgramBuilder.cpp
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index de08ec4ad06502b45a9ffb2a5794c4e0a745c839..fbf78d763464a3b0175fff9d60474c5db0beaa7f 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -5,110 +5,151 @@
* found in the LICENSE file.
*/
+#include "GrGLProgramBuilder.h"
+#include "gl/GrGLGeometryProcessor.h"
#include "gl/GrGLProgram.h"
#include "gl/GrGLSLPrettyPrint.h"
#include "gl/GrGLUniformHandle.h"
-#include "GrCoordTransform.h"
#include "../GrGpuGL.h"
-#include "GrGLFragmentShaderBuilder.h"
+#include "GrCoordTransform.h"
+#include "GrGLLegacyNvprProgramBuilder.h"
+#include "GrGLNvprProgramBuilder.h"
#include "GrGLProgramBuilder.h"
#include "GrTexture.h"
-#include "GrGLVertexShaderBuilder.h"
#include "SkRTConf.h"
#include "SkTraceEvent.h"
-namespace {
#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
-// number of each input/output type in a single allocation block
-static const int kVarsPerBlock = 8;
-
// ES2 FS only guarantees mediump and lowp support
static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-bool GrGLProgramBuilder::genProgram(const GrGeometryStage* geometryProcessor,
- const GrFragmentStage* colorStages[],
- const GrFragmentStage* coverageStages[]) {
- const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader();
+//////////////////////////////////////////////////////////////////////////////
- fFS.emitCodeBeforeEffects();
+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),
+ gpu));
+
+ GrGLProgramBuilder* pb = builder.get();
+ const GrGLProgramDesc::KeyHeader& header = pb->header();
+
+ // emit code to read the dst copy texture, if necessary
+ if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey
+ && !gpu->glCaps().fbFetchSupport()) {
+ pb->fFS.emitCodeToReadDstTexture();
+ }
- ///////////////////////////////////////////////////////////////////////////
// get the initial color and coverage to feed into the first effect in each effect chain
+ GrGLSLExpr4 inputColor, inputCoverage;
+ pb->setupUniformColorAndCoverageIfNeeded(&inputColor, &inputCoverage);
+
+ // if we have a vertex shader(we don't only if we are using NVPR or NVPR ES), then we may have
+ // to setup a few more things like builtin vertex attributes
+ bool hasVertexShader = !header.fUseFragShaderOnly;
+ if (hasVertexShader) {
+ pb->fVS.setupLocalCoords();
+ pb->fVS.transformGLToSkiaCoords();
+ if (header.fEmitsPointSize) {
+ pb->fVS.codeAppend("gl_PointSize = 1.0;");
+ }
+ if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) {
+ pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor);
+ }
+ if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
+ pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage);
+ }
+ }
- GrGLSLExpr4 inputColor;
- GrGLSLExpr4 inputCoverage;
+ pb->createAndEmitProcessors(geometryProcessor, colorStages, coverageStages, &inputColor,
+ &inputCoverage);
- if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
- const char* name;
- fUniformHandles.fColorUni =
- this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
- kVec4f_GrSLType,
- "Color",
- &name);
- inputColor = GrGLSLExpr4(name);
- } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fColorInput) {
- inputColor = GrGLSLExpr4(1);
+ if (hasVertexShader) {
+ pb->fVS.transformSkiaToGLCoords();
}
- if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
- const char* name;
- fUniformHandles.fCoverageUni =
- this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
- kVec4f_GrSLType,
- "Coverage",
- &name);
- inputCoverage = GrGLSLExpr4(name);
- } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) {
- inputCoverage = GrGLSLExpr4(1);
+ // write the secondary color output if necessary
+ if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
+ pb->fFS.enableSecondaryOutput(inputColor, inputCoverage);
}
- // Subclasses drive effect emitting
- this->createAndEmitEffects(geometryProcessor, colorStages, coverageStages, &inputColor,
- &inputCoverage);
+ pb->fFS.combineColorAndCoverage(inputColor, inputCoverage);
- fFS.emitCodeAfterEffects(inputColor, inputCoverage);
+ return pb->finalize();
+}
- if (!this->finish()) {
- return false;
+GrGLProgramBuilder*
+GrGLProgramBuilder::CreateProgramBuilder(const GrGLProgramDesc& desc,
+ const GrOptDrawState& optState,
+ GrGpu::DrawType drawType,
+ bool hasGeometryProcessor,
+ GrGpuGL* gpu) {
+ if (desc.getHeader().fUseFragShaderOnly) {
+ SkASSERT(gpu->glCaps().pathRenderingSupport());
+ SkASSERT(gpu->glPathRendering()->texturingMode() ==
+ GrGLPathRendering::FixedFunction_TexturingMode);
+ SkASSERT(!hasGeometryProcessor);
+ return SkNEW_ARGS(GrGLLegacyNvprProgramBuilder, (gpu, optState, desc));
+ } else if (GrGpu::IsPathRenderingDrawType(drawType)) {
+ SkASSERT(gpu->glCaps().pathRenderingSupport());
+ SkASSERT(gpu->glPathRendering()->texturingMode() ==
+ GrGLPathRendering::SeparableShaders_TexturingMode);
+ SkASSERT(!hasGeometryProcessor);
+ return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState, desc));
+ } else {
+ return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState, desc));
}
-
- return true;
}
-//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrOptDrawState& optState,
const GrGLProgramDesc& desc)
- : fEffectEmitter(NULL)
- , fFragOnly(SkToBool(desc.getHeader().fUseFragShaderOnly))
- , fTexCoordSetCnt(0)
- , fProgramID(0)
+ : fVS(this)
+ , fGS(this)
, fFS(this, desc)
- , fSeparableVaryingInfos(kVarsPerBlock)
- , fGrProcessorEmitter(this)
+ , fOutOfStage(true)
+ , fStageIndex(-1)
, fOptState(optState)
, fDesc(desc)
, fGpu(gpu)
, fUniforms(kVarsPerBlock) {
}
+void GrGLProgramBuilder::addVarying(GrSLType type,
+ const char* name,
+ const char** vsOutName,
+ const char** fsInName,
+ GrGLShaderVar::Precision fsPrecision) {
+ SkString* fsInputName = fVS.addVarying(type, name, vsOutName);
+ fFS.addVarying(type, fsInputName->c_str(), fsInName, fsPrecision);
+}
+
void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
if ('\0' == prefix) {
*out = name;
} else {
out->printf("%c%s", prefix, name);
}
- if (fCodeStage.inStageCode()) {
+ if (!fOutOfStage) {
if (out->endsWith('_')) {
// Names containing "__" are reserved.
out->append("x");
}
- out->appendf("_Stage%d", fCodeStage.stageIndex());
+ out->appendf("_Stage%d", fStageIndex);
}
}
@@ -143,13 +184,6 @@ GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32
return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1);
}
-void GrGLProgramBuilder::appendDecls(const VarArray& vars, SkString* out) const {
- for (int i = 0; i < vars.count(); ++i) {
- vars[i].appendDecl(this->ctxInfo(), out);
- out->append(";\n");
- }
-}
-
void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility,
SkString* out) const {
for (int i = 0; i < fUniforms.count(); ++i) {
@@ -160,20 +194,129 @@ void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility,
}
}
-void GrGLProgramBuilder::createAndEmitEffects(const GrFragmentStage* effectStages[],
- int effectCnt,
- const GrGLProgramDesc::EffectKeyProvider& keyProvider,
- GrGLSLExpr4* fsInOutColor) {
+const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
+ return fGpu->ctxInfo();
+}
+
+void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor,
+ GrGLSLExpr4* inputCoverage) {
+ const GrGLProgramDesc::KeyHeader& header = this->header();
+ if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) {
+ const char* name;
+ fUniformHandles.fColorUni =
+ this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kVec4f_GrSLType,
+ "Color",
+ &name);
+ *inputColor = GrGLSLExpr4(name);
+ } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fColorInput) {
+ *inputColor = GrGLSLExpr4(1);
+ }
+ if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
+ const char* name;
+ fUniformHandles.fCoverageUni =
+ this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kVec4f_GrSLType,
+ "Coverage",
+ &name);
+ *inputCoverage = GrGLSLExpr4(name);
+ } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) {
+ *inputCoverage = GrGLSLExpr4(1);
+ }
+}
+
+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);
+ }
+
+ 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);
+}
+
+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) {
- fGrProcessorEmitter.set(effectStages[e]->getFragmentProcessor());
- fEffectEmitter = &fGrProcessorEmitter;
- // calls into the subclass to emit the actual effect into the program effect object
- this->emitEffect(*effectStages[e], e, keyProvider, &inColor, &outColor);
+ // 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;
+ }
+
+ // 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;
}
@@ -182,40 +325,77 @@ void GrGLProgramBuilder::createAndEmitEffects(const GrFragmentStage* effectStage
}
}
-void GrGLProgramBuilder::emitEffect(const GrProcessorStage& effectStage,
- int effectIndex,
- const GrGLProgramDesc::EffectKeyProvider& keyProvider,
- GrGLSLExpr4* inColor,
- GrGLSLExpr4* outColor) {
- SkASSERT(effectStage.getProcessor());
- CodeStage::AutoStageRestore csar(&fCodeStage, &effectStage);
-
- 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("\tvec4 %s = %s;\n", inColorName.c_str(), inColor->c_str());
- *inColor = inColorName;
- }
-
- // create var to hold stage result
- SkString outColorName;
- this->nameVariable(&outColorName, '\0', "output");
- fFS.codeAppendf("\tvec4 %s;\n", outColorName.c_str());
- *outColor = outColorName;
+void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) {
+ SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition());
+}
- this->emitEffect(effectStage, keyProvider.get(effectIndex), outColor->c_str(),
- inColor->isOnes() ? NULL : inColor->c_str(), fCodeStage.stageIndex());
+void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
+ SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition());
+ SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor());
+}
- *inColor = *outColor;
+void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage,
+ GrGLProcessor::TransformedCoordsArray* outCoords,
+ GrGLInstalledProcessors* installedProcessors) {
+ SkTArray<GrGLInstalledProcessors::Transform, true>& transforms =
+ installedProcessors->addTransforms();
+ const GrProcessor* effect = effectStage.getProcessor();
+ int numTransforms = effect->numTransforms();
+ transforms.push_back_n(numTransforms);
+
+ for (int t = 0; t < numTransforms; t++) {
+ const char* uniName = "StageMatrix";
+ GrSLType varyingType =
+ effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalCoords()) ?
+ kVec3f_GrSLType :
+ kVec2f_GrSLType;
+
+ SkString suffixedUniName;
+ if (0 != t) {
+ suffixedUniName.append(uniName);
+ suffixedUniName.appendf("_%i", t);
+ uniName = suffixedUniName.c_str();
+ }
+ transforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+ kMat33f_GrSLType,
+ uniName,
+ &uniName).toShaderBuilderIndex();
+
+ const char* varyingName = "MatrixCoord";
+ SkString suffixedVaryingName;
+ if (0 != t) {
+ suffixedVaryingName.append(varyingName);
+ suffixedVaryingName.appendf("_%i", t);
+ varyingName = suffixedVaryingName.c_str();
+ }
+ const char* vsVaryingName;
+ const char* fsVaryingName;
+ this->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryingName);
+
+ const GrGLShaderVar& coords =
+ kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
+ fVS.positionAttribute() :
+ fVS.localCoordsAttribute();
+
+ // varying = matrix * coords (logically)
+ SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
+ if (kVec2f_GrSLType == varyingType) {
+ fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
+ vsVaryingName, uniName, coords.c_str());
+ } else {
+ fVS.codeAppendf("%s = %s * vec3(%s, 1);",
+ vsVaryingName, uniName, coords.c_str());
+ }
+ SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
+ (SkString(fsVaryingName), varyingType));
+ }
}
-void GrGLProgramBuilder::emitSamplers(const GrProcessor& effect,
- GrGLProcessor::TextureSamplerArray* outSamplers) {
- SkTArray<GrGLProgramEffects::Sampler, true>& samplers =
- this->getProgramEffects()->addSamplers();
- int numTextures = effect.numTextures();
+void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
+ GrGLProcessor::TextureSamplerArray* outSamplers,
+ GrGLInstalledProcessors* installedProcessors) {
+ SkTArray<GrGLInstalledProcessors::Sampler, true>& samplers = installedProcessors->addSamplers();
+ int numTextures = processor.numTextures();
samplers.push_back_n(numTextures);
SkString name;
for (int t = 0; t < numTextures; ++t) {
@@ -224,27 +404,37 @@ void GrGLProgramBuilder::emitSamplers(const GrProcessor& effect,
kSampler2D_GrSLType,
name.c_str());
SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
- (samplers[t].fUniform, effect.textureAccess(t)));
+ (samplers[t].fUniform, processor.textureAccess(t)));
}
}
-bool GrGLProgramBuilder::finish() {
- SkASSERT(0 == fProgramID);
- GL_CALL_RET(fProgramID, CreateProgram());
- if (!fProgramID) {
- return false;
+GrGLProgram* GrGLProgramBuilder::finalize() {
+ // verify we can get a program id
+ GrGLuint programID;
+ GL_CALL_RET(programID, CreateProgram());
+ if (0 == programID) {
+ return NULL;
}
+ // compile shaders and bind attributes / uniforms
SkTDArray<GrGLuint> shadersToDelete;
-
- if (!this->compileAndAttachShaders(fProgramID, &shadersToDelete)) {
- GL_CALL(DeleteProgram(fProgramID));
- return false;
+ if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) {
+ this->cleanupProgram(programID, shadersToDelete);
+ return NULL;
}
-
- this->bindProgramLocations(fProgramID);
-
- GL_CALL(LinkProgram(fProgramID));
+ if (!this->header().fUseFragShaderOnly) {
+ if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) {
+ this->cleanupProgram(programID, shadersToDelete);
+ return NULL;
+ }
+ fVS.bindVertexAttributes(programID);
+ }
+ bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
+ if (usingBindUniform) {
+ this->bindUniformLocations(programID);
+ }
+ fFS.bindFragmentShaderLocations(programID);
+ GL_CALL(LinkProgram(programID));
// Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
bool checkLinked = !fGpu->ctxInfo().isChromium();
@@ -252,80 +442,78 @@ bool GrGLProgramBuilder::finish() {
checkLinked = true;
#endif
if (checkLinked) {
- GrGLint linked = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramiv(fProgramID, GR_GL_LINK_STATUS, &linked));
- if (!linked) {
- GrGLint infoLen = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramiv(fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
- SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
- if (infoLen > 0) {
- // retrieve length even though we don't need it to workaround
- // bug in chrome cmd buffer param validation.
- GrGLsizei length = GR_GL_INIT_ZERO;
- GL_CALL(GetProgramInfoLog(fProgramID,
- infoLen+1,
- &length,
- (char*)log.get()));
- GrPrintf((char*)log.get());
- }
- SkDEBUGFAIL("Error linking program");
- GL_CALL(DeleteProgram(fProgramID));
- fProgramID = 0;
- return false;
- }
+ checkLinkStatus(programID);
}
-
- this->resolveProgramLocations(fProgramID);
-
- for (int i = 0; i < shadersToDelete.count(); ++i) {
- GL_CALL(DeleteShader(shadersToDelete[i]));
+ if (!usingBindUniform) {
+ this->resolveUniformLocations(programID);
}
- return true;
-}
+ this->cleanupShaders(shadersToDelete);
-bool GrGLProgramBuilder::compileAndAttachShaders(GrGLuint programId,
- SkTDArray<GrGLuint>* shaderIds) const {
- return fFS.compileAndAttachShaders(programId, shaderIds);
+ return this->createProgram(programID);
}
-void GrGLProgramBuilder::bindProgramLocations(GrGLuint programId) {
- fFS.bindProgramLocations(programId);
-
- // skbug.com/2056
- bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
- if (usingBindUniform) {
- int count = fUniforms.count();
- for (int i = 0; i < count; ++i) {
- GL_CALL(BindUniformLocation(programId, i, fUniforms[i].fVariable.c_str()));
- fUniforms[i].fLocation = i;
- }
+void GrGLProgramBuilder::bindUniformLocations(GrGLuint programID) {
+ int count = fUniforms.count();
+ for (int i = 0; i < count; ++i) {
+ GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str()));
+ fUniforms[i].fLocation = i;
}
}
-void GrGLProgramBuilder::resolveProgramLocations(GrGLuint programId) {
- bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
- if (!usingBindUniform) {
- int count = fUniforms.count();
- for (int i = 0; i < count; ++i) {
- GrGLint location;
- GL_CALL_RET(location,
- GetUniformLocation(programId, fUniforms[i].fVariable.c_str()));
- fUniforms[i].fLocation = location;
+bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
+ GrGLint linked = GR_GL_INIT_ZERO;
+ GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
+ if (!linked) {
+ GrGLint infoLen = GR_GL_INIT_ZERO;
+ GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
+ SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
+ if (infoLen > 0) {
+ // retrieve length even though we don't need it to workaround
+ // bug in chrome cmd buffer param validation.
+ GrGLsizei length = GR_GL_INIT_ZERO;
+ GL_CALL(GetProgramInfoLog(programID,
+ infoLen+1,
+ &length,
+ (char*)log.get()));
+ GrPrintf((char*)log.get());
}
+ SkDEBUGFAIL("Error linking program");
+ GL_CALL(DeleteProgram(programID));
+ programID = 0;
}
+ return SkToBool(linked);
+}
- int count = fSeparableVaryingInfos.count();
+void GrGLProgramBuilder::resolveUniformLocations(GrGLuint programID) {
+ int count = fUniforms.count();
for (int i = 0; i < count; ++i) {
GrGLint location;
- GL_CALL_RET(location,
- GetProgramResourceLocation(programId,
- GR_GL_FRAGMENT_INPUT,
- fSeparableVaryingInfos[i].fVariable.c_str()));
- fSeparableVaryingInfos[i].fLocation = location;
+ GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str()));
+ fUniforms[i].fLocation = location;
}
}
-const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
- return fGpu->ctxInfo();
+void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs) {
+ GL_CALL(DeleteProgram(programID));
+ cleanupShaders(shaderIDs);
+}
+void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
+ for (int i = 0; i < shaderIDs.count(); ++i) {
+ GL_CALL(DeleteShader(shaderIDs[i]));
+ }
+}
+
+GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
+ return SkNEW_ARGS(GrGLProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
+ fGeometryProcessor, fColorEffects, fCoverageEffects));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrGLInstalledProcessors::~GrGLInstalledProcessors() {
+ int numEffects = fGLProcessors.count();
+ for (int e = 0; e < numEffects; ++e) {
+ SkDELETE(fGLProcessors[e]);
+ }
}
« no previous file with comments | « src/gpu/gl/builders/GrGLProgramBuilder.h ('k') | src/gpu/gl/builders/GrGLShaderBuilder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698