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

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: more cleanup Created 6 years, 3 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
Index: src/gpu/gl/builders/GrGLProgramBuilder.cpp
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
index 909ac76d62f73a2bd096f6ab12b0a1551c1280e9..207bcd857181c23fd73cfd31f8beb89a43fae695 100644
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp
@@ -5,109 +5,155 @@
* 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 "GrGLProgramBuilder.h"
+#include "GrCoordTransform.h"
+#include "GrGLESNvprProgramBuilder.h"
+#include "GrGLNvprProgramBuilder.h"
+#include "GrGLSkiaProgramBuilder.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();
+const int GrGLProgramBuilder::kVarsPerBlock = 8;
+
+GrGLProgram* GrGLProgramBuilder::CreateProgram(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,
+ 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();
+ }
- fFS.emitCodeBeforeEffects();
+ // On any post 1.10 GLSL supporting GPU, we declare custom output
+ if (k110_GrGLSLGeneration != gpu->glslGeneration()) {
+ pb->fFS.enableCustomOutput();
+ }
- ///////////////////////////////////////////////////////////////////////////
// get the initial color and coverage to feed into the first effect in each effect chain
+ GrGLSLExpr4 inputColor, inputCoverage;
+ pb->setupUniformColorIfNeeded(header.fColorInput, "Color", &inputColor);
+ pb->setupUniformColorIfNeeded(header.fCoverageInput, "Coverage", &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->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->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
+ bool hasSecondaryOutput =
+ (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType);
+ if (hasSecondaryOutput) {
+ pb->enableSecondaryOutput(inputColor, inputCoverage);
}
- // Subclasses drive effect emitting
- this->createAndEmitEffects(geometryProcessor, colorStages, coverageStages, &inputColor,
- &inputCoverage);
+ pb->combineColorAndCoverage(inputColor, inputCoverage);
- fFS.emitCodeAfterEffects(inputColor, inputCoverage);
+ return pb->compileBindLinkCreate();
+}
- if (!this->finish()) {
- return false;
+GrGLProgramBuilder*
+GrGLProgramBuilder::CreateProgramBuilder(const GrGLProgramDesc& desc,
+ 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(GrGLNvprProgramBuilder, (gpu, desc));
+ } else if (GrGpu::IsPathRenderingDrawType(drawType)) {
+ SkASSERT(gpu->glCaps().pathRenderingSupport());
+ SkASSERT(gpu->glPathRendering()->texturingMode() ==
+ GrGLPathRendering::SeparableShaders_TexturingMode);
+ SkASSERT(!hasGeometryProcessor);
+ return SkNEW_ARGS(GrGLESNvprProgramBuilder, (gpu, desc));
+ } else {
+ return SkNEW_ARGS(GrGLSkiaProgramBuilder, (gpu, desc));
}
-
- return true;
}
-//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu,
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)
, 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);
}
}
@@ -142,13 +188,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) {
@@ -159,20 +198,127 @@ 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::setupUniformColorIfNeeded(const GrGLProgramDesc::ColorInput& colorInput,
+ const char* name,
+ GrGLSLExpr4* input) {
+ if (GrGLProgramDesc::kUniform_ColorInput == colorInput) {
+ const char* uniformName;
+ this->fUniformHandles.fColorUni =
+ this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
+ kVec4f_GrSLType,
+ name,
+ &uniformName);
+ *input = GrGLSLExpr4(uniformName);
+ } else if (GrGLProgramDesc::kAllOnes_ColorInput == colorInput) {
+ *input = GrGLSLExpr4(1);
+ }
+}
+
+void GrGLProgramBuilder::transformGLToSkiaCoords() {
+ const char* viewMName;
+ fUniformHandles.fViewMatrixUni = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+ kMat33f_GrSLType,
+ "ViewM",
+ &viewMName);
+
+ // Transform the position into Skia's device coords.
+ fVS.codeAppendf("vec3 pos3 = %s * vec3(%s, 1);", viewMName, fVS.positionAttribute().c_str());
+}
+
+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
+ this->reset();
+ 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());
+
+ glEffect->emitCode(this, processor, keyProvider.get(e), outColor.c_str(), 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("}");
+
+ inColor = outColor;
effectEmitted = true;
}
@@ -181,40 +327,20 @@ 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;
-
- this->emitEffect(effectStage, keyProvider.get(effectIndex), outColor->c_str(),
- inColor->isOnes() ? NULL : inColor->c_str(), fCodeStage.stageIndex());
+void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) {
+ SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition());
+}
- *inColor = *outColor;
+void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
+ SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition());
+ SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor());
}
-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) {
@@ -223,27 +349,93 @@ 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;
- }
+void GrGLProgramBuilder::transformSkiaToGLCoords() {
+ const char* rtAdjustName;
+ fUniformHandles.fRTAdjustmentUni = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
+ kVec4f_GrSLType,
+ "rtAdjustment",
+ &rtAdjustName);
- SkTDArray<GrGLuint> shadersToDelete;
+ // Transform from Skia's device coords to GL's normalized device coords.
+ fVS.codeAppendf("gl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);",
+ rtAdjustName, rtAdjustName);
+}
+
+void GrGLProgramBuilder::enableSecondaryOutput(const GrGLSLExpr4& inputColor,
+ const GrGLSLExpr4& inputCoverage) {
+ fFS.enableSecondaryOutput();
+ const char* secondaryOutputName = fFS.getSecondaryColorOutputName();
+ GrGLSLExpr4 coeff(1);
+ switch (this->header().fSecondaryOutputType) {
+ case GrOptDrawState::kCoverage_SecondaryOutputType:
+ break;
+ case GrOptDrawState::kCoverageISA_SecondaryOutputType:
+ // Get (1-A) into coeff
+ coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a());
+ break;
+ case GrOptDrawState::kCoverageISC_SecondaryOutputType:
+ // Get (1-RGBA) into coeff
+ coeff = GrGLSLExpr4(1) - inputColor;
+ break;
+ default:
+ SkFAIL("Unexpected Secondary Output");
+ }
+ // Get coeff * coverage into modulate and then write that to the dual source output.
+ fFS.codeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str());
+}
- if (!this->compileAndAttachShaders(fProgramID, &shadersToDelete)) {
- GL_CALL(DeleteProgram(fProgramID));
- return false;
+void GrGLProgramBuilder::combineColorAndCoverage(const GrGLSLExpr4& inputColor,
+ const GrGLSLExpr4& inputCoverage) {
+ GrGLSLExpr4 fragColor = inputColor * inputCoverage;
+ switch (this->header().fPrimaryOutputType) {
+ case GrOptDrawState::kModulate_PrimaryOutputType:
+ break;
+ case GrOptDrawState::kCombineWithDst_PrimaryOutputType:
+ {
+ // Tack on "+(1-coverage)dst onto the frag color.
+ GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage;
+ GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(fFS.dstColor());
+ fragColor = fragColor + dstContribution;
+ }
+ break;
+ default:
+ SkFAIL("Unknown Primary Output");
}
+ fFS.codeAppendf("\t%s = %s;\n", fFS.getPrimaryColorOutputName(), fragColor.c_str());
+}
- this->bindProgramLocations(fProgramID);
- GL_CALL(LinkProgram(fProgramID));
+GrGLProgram* GrGLProgramBuilder::compileBindLinkCreate() {
+ // 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 (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) {
+ this->cleanupProgram(programID, shadersToDelete);
+ return NULL;
+ }
+ 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();
@@ -251,80 +443,77 @@ 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;
-}
+ // Finally, this is just for nvpr es, which has separable varyings that are plugged in after
+ // building
+ this->resolveSeparableVaryings(programID);
-bool GrGLProgramBuilder::compileAndAttachShaders(GrGLuint programId,
- SkTDArray<GrGLuint>* shaderIds) const {
- return fFS.compileAndAttachShaders(programId, shaderIds);
-}
+ this->cleanupShaders(shadersToDelete);
-void GrGLProgramBuilder::bindProgramLocations(GrGLuint programId) {
- fFS.bindProgramLocations(programId);
+ return this->createProgram(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]));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+GrGLInstalledProcessors::~GrGLInstalledProcessors() {
+ int numEffects = fGLProcessors.count();
+ for (int e = 0; e < numEffects; ++e) {
+ SkDELETE(fGLProcessors[e]);
+ }
}

Powered by Google App Engine
This is Rietveld 408576698