Index: src/gpu/gl/GrGLShaderBuilder.cpp |
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp |
index 79cb52fc8abc67763a07a9ee468397c9a6669be7..93364e164015e2dbdd39e29c9bd9f3c132ab7d4c 100644 |
--- a/src/gpu/gl/GrGLShaderBuilder.cpp |
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp |
@@ -95,34 +95,27 @@ bool GrGLShaderBuilder::GenProgram(GrGpuGL* gpu, |
const GrEffectStage* inColorStages[], |
const GrEffectStage* inCoverageStages[], |
GenProgramOutput* output) { |
+ SkAutoTDelete<GrGLShaderBuilder> builder; |
if (desc.getHeader().fHasVertexCode ||!gpu->shouldUseFixedFunctionTexturing()) { |
- GrGLFullShaderBuilder fullBuilder(gpu, uman, desc); |
- if (fullBuilder.genProgram(inColorStages, inCoverageStages, output)) { |
- output->fHasVS = true; |
- output->fUniformHandles.fViewMatrixUni = fullBuilder.getViewMatrixUniform(); |
- output->fUniformHandles.fRTAdjustmentUni = fullBuilder.getRTAdjustmentVecUniform(); |
- return true; |
- } |
+ builder.reset(SkNEW_ARGS(GrGLFullShaderBuilder, (gpu, uman, desc))); |
} else { |
- GrGLFragmentOnlyShaderBuilder fragmentOnlyBuilder(gpu, uman, desc); |
- if (fragmentOnlyBuilder.genProgram(inColorStages, inCoverageStages, output)) { |
- output->fHasVS = false; |
- output->fNumTexCoordSets = fragmentOnlyBuilder.getNumTexCoordSets(); |
- return true; |
- } |
+ builder.reset(SkNEW_ARGS(GrGLFragmentOnlyShaderBuilder, (gpu, uman, desc))); |
+ } |
+ if (builder->genProgram(inColorStages, inCoverageStages)) { |
+ *output = builder->getOutput(); |
+ return true; |
} |
return false; |
} |
bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], |
- const GrEffectStage* coverageStages[], |
- GenProgramOutput* output) { |
+ const GrEffectStage* coverageStages[]) { |
const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); |
// incoming color to current stage being processed. |
GrGLSLExpr4 inColor = this->getInputColor(); |
- output->fColorEffects = |
+ fOutput.fColorEffects = |
this->createAndEmitEffects(colorStages, |
this->desc().getEffectKeys(), |
this->desc().numColorEffects(), |
@@ -132,7 +125,7 @@ bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], |
// compute the partial coverage |
GrGLSLExpr4 inCoverage = this->getInputCoverage(); |
- output->fCoverageEffects = |
+ fOutput.fCoverageEffects = |
this->createAndEmitEffects(coverageStages, |
this->desc().getEffectKeys() + this->desc().numColorEffects(), |
this->desc().numCoverageEffects(), |
@@ -170,17 +163,10 @@ bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], |
} |
this->fsCodeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str()); |
- if (!this->finish(&output->fProgramID)) { |
+ if (!this->finish()) { |
return false; |
} |
- output->fUniformHandles.fRTHeightUni = fRTHeightUniform; |
- output->fUniformHandles.fColorUni = fColorUniform; |
- output->fUniformHandles.fCoverageUni = fCoverageUniform; |
- output->fUniformHandles.fDstCopyTopLeftUni = fDstCopyTopLeftUniform; |
- output->fUniformHandles.fDstCopyScaleUni = fDstCopyScaleUniform; |
- output->fUniformHandles.fDstCopySamplerUni = fDstCopySamplerUniform; |
- |
return true; |
} |
@@ -197,9 +183,9 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, |
, fFSOutputs(kMaxFSOutputs) |
, fUniforms(kVarsPerBlock) |
, fSetupFragPosition(false) |
+ , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) |
, fHasCustomColorOutput(false) |
- , fHasSecondaryOutput(false) |
- , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) { |
+ , fHasSecondaryOutput(false) { |
const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); |
@@ -209,23 +195,22 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, |
bool topDown = SkToBool(kTopLeftOrigin_DstReadKeyBit & header.fDstReadKey); |
const char* dstCopyTopLeftName; |
const char* dstCopyCoordScaleName; |
+ const char* dstCopySamplerName; |
uint32_t configMask; |
if (SkToBool(kUseAlphaConfig_DstReadKeyBit & header.fDstReadKey)) { |
configMask = kA_GrColorComponentFlag; |
} else { |
configMask = kRGBA_GrColorComponentFlags; |
} |
- fDstCopySamplerUniform = this->addUniform(kFragment_Visibility, |
- kSampler2D_GrSLType, |
- "DstCopySampler"); |
- fDstCopyTopLeftUniform = this->addUniform(kFragment_Visibility, |
- kVec2f_GrSLType, |
- "DstCopyUpperLeft", |
- &dstCopyTopLeftName); |
- fDstCopyScaleUniform = this->addUniform(kFragment_Visibility, |
- kVec2f_GrSLType, |
- "DstCopyCoordScale", |
- &dstCopyCoordScaleName); |
+ fOutput.fUniformHandles.fDstCopySamplerUni = |
+ this->addUniform(kFragment_Visibility, kSampler2D_GrSLType, "DstCopySampler", |
+ &dstCopySamplerName); |
+ fOutput.fUniformHandles.fDstCopyTopLeftUni = |
+ this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyUpperLeft", |
+ &dstCopyTopLeftName); |
+ fOutput.fUniformHandles.fDstCopyScaleUni = |
+ this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyCoordScale", |
+ &dstCopyCoordScaleName); |
const char* fragPos = this->fragmentPosition(); |
this->fsCodeAppend("\t// Read color from copy of the destination.\n"); |
this->fsCodeAppendf("\tvec2 _dstTexCoord = (%s.xy - %s) * %s;\n", |
@@ -236,7 +221,7 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, |
this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); |
append_texture_lookup(&fFSCode, |
fGpu, |
- this->getUniformCStr(fDstCopySamplerUniform), |
+ dstCopySamplerName, |
"_dstTexCoord", |
configMask, |
"rgba"); |
@@ -245,8 +230,9 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, |
if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) { |
const char* name; |
- fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
- kVec4f_GrSLType, "Color", &name); |
+ fOutput.fUniformHandles.fColorUni = |
+ this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Color", |
+ &name); |
fInputColor = GrGLSLExpr4(name); |
} else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fColorInput) { |
fInputColor = GrGLSLExpr4(1); |
@@ -256,8 +242,9 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, |
if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) { |
const char* name; |
- fCoverageUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
- kVec4f_GrSLType, "Coverage", &name); |
+ fOutput.fUniformHandles.fCoverageUni = |
+ this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Coverage", |
+ &name); |
fInputCoverage = GrGLSLExpr4(name); |
} else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) { |
fInputCoverage = GrGLSLExpr4(1); |
@@ -360,7 +347,7 @@ const char* GrGLShaderBuilder::dstColor() { |
} else if (GrGLCaps::kNV_FBFetchType == fetchType) { |
SkAssertResult(this->enablePrivateFeature(kNVShaderFramebufferFetch_GLSLPrivateFeature)); |
return kFBFetchColorName; |
- } else if (fDstCopySamplerUniform.isValid()) { |
+ } else if (fOutput.fUniformHandles.fDstCopySamplerUni.isValid()) { |
return kDstCopyColorName; |
} else { |
return ""; |
@@ -525,19 +512,17 @@ const char* GrGLShaderBuilder::fragmentPosition() { |
// temporarily change the stage index because we're inserting non-stage code. |
CodeStage::AutoStageRestore csar(&fCodeStage, NULL); |
- SkASSERT(!fRTHeightUniform.isValid()); |
+ SkASSERT(!fOutput.fUniformHandles.fRTHeightUni.isValid()); |
const char* rtHeightName; |
- fRTHeightUniform = this->addUniform(kFragment_Visibility, |
- kFloat_GrSLType, |
- "RTHeight", |
- &rtHeightName); |
+ fOutput.fUniformHandles.fRTHeightUni = |
+ this->addUniform(kFragment_Visibility, kFloat_GrSLType, "RTHeight", &rtHeightName); |
this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, gl_FragCoord.zw);\n", |
kCoordName, rtHeightName); |
fSetupFragPosition = true; |
} |
- SkASSERT(fRTHeightUniform.isValid()); |
+ SkASSERT(fOutput.fUniformHandles.fRTHeightUni.isValid()); |
return kCoordName; |
} |
} |
@@ -667,26 +652,26 @@ const char* GrGLShaderBuilder::enableSecondaryOutput() { |
return dual_source_output_name(); |
} |
-bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) { |
- GrGLuint programId = 0; |
- GL_CALL_RET(programId, CreateProgram()); |
- if (!programId) { |
+bool GrGLShaderBuilder::finish() { |
+ SkASSERT(0 == fOutput.fProgramID); |
+ GL_CALL_RET(fOutput.fProgramID, CreateProgram()); |
+ if (!fOutput.fProgramID) { |
return false; |
} |
SkTDArray<GrGLuint> shadersToDelete; |
- if (!this->compileAndAttachShaders(programId, &shadersToDelete)) { |
- GL_CALL(DeleteProgram(programId)); |
+ if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) { |
+ GL_CALL(DeleteProgram(fOutput.fProgramID)); |
return false; |
} |
- this->bindProgramLocations(programId); |
+ this->bindProgramLocations(fOutput.fProgramID); |
if (fUniformManager->isUsingBindUniform()) { |
- fUniformManager->getUniformLocations(programId, fUniforms); |
+ fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms); |
} |
- GL_CALL(LinkProgram(programId)); |
+ GL_CALL(LinkProgram(fOutput.fProgramID)); |
// Calling GetProgramiv is expensive in Chromium. Assume success in release builds. |
bool checkLinked = !fGpu->ctxInfo().isChromium(); |
@@ -695,36 +680,36 @@ bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) { |
#endif |
if (checkLinked) { |
GrGLint linked = GR_GL_INIT_ZERO; |
- GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked)); |
+ GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_LINK_STATUS, &linked)); |
if (!linked) { |
GrGLint infoLen = GR_GL_INIT_ZERO; |
- GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen)); |
+ GL_CALL(GetProgramiv(fOutput.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(programId, |
+ GL_CALL(GetProgramInfoLog(fOutput.fProgramID, |
infoLen+1, |
&length, |
(char*)log.get())); |
GrPrintf((char*)log.get()); |
} |
SkDEBUGFAIL("Error linking program"); |
- GL_CALL(DeleteProgram(programId)); |
+ GL_CALL(DeleteProgram(fOutput.fProgramID)); |
+ fOutput.fProgramID = 0; |
return false; |
} |
} |
if (!fUniformManager->isUsingBindUniform()) { |
- fUniformManager->getUniformLocations(programId, fUniforms); |
+ fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms); |
} |
for (int i = 0; i < shadersToDelete.count(); ++i) { |
GL_CALL(DeleteShader(shadersToDelete[i])); |
} |
- *outProgramId = programId; |
return true; |
} |
@@ -840,6 +825,8 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, |
const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); |
+ fOutput.fHasVertexShader = true; |
+ |
fPositionVar = &fVSAttrs.push_back(); |
fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition"); |
if (-1 != header.fLocalCoordAttributeIndex) { |
@@ -852,11 +839,13 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, |
} |
const char* viewMName; |
- fViewMatrixUniform = this->addUniform(GrGLShaderBuilder::kVertex_Visibility, |
- kMat33f_GrSLType, "ViewM", &viewMName); |
+ fOutput.fUniformHandles.fViewMatrixUni = |
+ this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kMat33f_GrSLType, "ViewM", |
+ &viewMName); |
const char* rtAdjustName; |
- fRTAdustmentVecUniform = this->addUniform(GrGLShaderBuilder::kVertex_Visibility, |
- kVec4f_GrSLType, "rtAdjustment", &rtAdjustName); |
+ fOutput.fUniformHandles.fRTAdjustmentUni = |
+ this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kVec4f_GrSLType, "rtAdjustment", |
+ &rtAdjustName); |
// Transform the position into Skia's device coords. |
this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n", |
@@ -1072,8 +1061,7 @@ void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { |
GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, |
GrGLUniformManager* uniformManager, |
const GrGLProgramDesc& desc) |
- : INHERITED(gpu, uniformManager, desc) |
- , fNumTexCoordSets(0) { |
+ : INHERITED(gpu, uniformManager, desc) { |
SkASSERT(!desc.getHeader().fHasVertexCode); |
SkASSERT(gpu->glCaps().pathRenderingSupport()); |
@@ -1082,9 +1070,9 @@ GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, |
} |
int GrGLFragmentOnlyShaderBuilder::addTexCoordSets(int count) { |
- int firstFreeCoordSet = fNumTexCoordSets; |
- fNumTexCoordSets += count; |
- SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fNumTexCoordSets); |
+ int firstFreeCoordSet = fOutput.fTexCoordSetCnt; |
+ fOutput.fTexCoordSetCnt += count; |
+ SkASSERT(gpu()->glCaps().maxFixedFunctionTextureCoords() >= fOutput.fTexCoordSetCnt); |
return firstFreeCoordSet; |
} |