| 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;
|
| }
|
|
|
|
|