diff options
Diffstat (limited to 'chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp')
-rw-r--r-- | chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp | 364 |
1 files changed, 240 insertions, 124 deletions
diff --git a/chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp b/chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp index 961cad798fc..4b2778c5030 100644 --- a/chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/chromium/third_party/skia/src/gpu/gl/GrGLShaderBuilder.cpp @@ -13,7 +13,7 @@ #include "GrGpuGL.h" #include "GrTexture.h" #include "SkRTConf.h" -#include "SkTrace.h" +#include "SkTraceEvent.h" #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) @@ -89,45 +89,52 @@ static const char kDstCopyColorName[] = "_dstColor"; /////////////////////////////////////////////////////////////////////////////// -GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, - GrGLUniformManager& uniformManager, - const GrGLProgramDesc& desc) - : fGpu(gpu) - , fUniformManager(uniformManager) - , fFSFeaturesAddedMask(0) - , fFSInputs(kVarsPerBlock) - , fFSOutputs(kMaxFSOutputs) - , fUniforms(kVarsPerBlock) - , fSetupFragPosition(false) - , fHasCustomColorOutput(false) - , fHasSecondaryOutput(false) - , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) { +bool GrGLShaderBuilder::GenProgram(GrGpuGL* gpu, + GrGLUniformManager* uman, + const GrGLProgramDesc& desc, + const GrEffectStage* inColorStages[], + const GrEffectStage* inCoverageStages[], + GenProgramOutput* output) { + SkAutoTDelete<GrGLShaderBuilder> builder; + if (desc.getHeader().fHasVertexCode ||!gpu->shouldUseFixedFunctionTexturing()) { + builder.reset(SkNEW_ARGS(GrGLFullShaderBuilder, (gpu, uman, desc))); + } else { + builder.reset(SkNEW_ARGS(GrGLFragmentOnlyShaderBuilder, (gpu, uman, desc))); + } + if (builder->genProgram(inColorStages, inCoverageStages)) { + *output = builder->getOutput(); + return true; + } + return false; +} - const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); +bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], + const GrEffectStage* coverageStages[]) { + const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); - // Emit code to read the dst copy textue if necessary. + /////////////////////////////////////////////////////////////////////////// + // emit code to read the dst copy texture, if necessary if (kNoDstRead_DstReadKey != header.fDstReadKey && GrGLCaps::kNone_FBFetchType == fGpu->glCaps().fbFetchType()) { 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", @@ -138,33 +145,41 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); append_texture_lookup(&fFSCode, fGpu, - this->getUniformCStr(fDstCopySamplerUniform), + dstCopySamplerName, "_dstTexCoord", configMask, "rgba"); this->fsCodeAppend(";\n\n"); } + /////////////////////////////////////////////////////////////////////////// + // get the initial color and coverage to feed into the first effect in each effect chain + + GrGLSLExpr4 inputColor; + GrGLSLExpr4 inputCoverage; + if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) { const char* name; - fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, - kVec4f_GrSLType, "Color", &name); - fInputColor = GrGLSLExpr4(name); + fOutput.fUniformHandles.fColorUni = + this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Color", + &name); + inputColor = GrGLSLExpr4(name); } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fColorInput) { - fInputColor = GrGLSLExpr4(1); + inputColor = GrGLSLExpr4(1); } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fColorInput) { - fInputColor = GrGLSLExpr4(0); + inputColor = GrGLSLExpr4(0); } if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) { const char* name; - fCoverageUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, - kVec4f_GrSLType, "Coverage", &name); - fInputCoverage = GrGLSLExpr4(name); + fOutput.fUniformHandles.fCoverageUni = + this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Coverage", + &name); + inputCoverage = GrGLSLExpr4(name); } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) { - fInputCoverage = GrGLSLExpr4(1); + inputCoverage = GrGLSLExpr4(1); } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fCoverageInput) { - fInputCoverage = GrGLSLExpr4(0); + inputCoverage = GrGLSLExpr4(0); } if (k110_GrGLSLGeneration != fGpu->glslGeneration()) { @@ -173,6 +188,81 @@ GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, declared_color_output_name()); fHasCustomColorOutput = true; } + + this->emitCodeBeforeEffects(&inputColor, &inputCoverage); + + /////////////////////////////////////////////////////////////////////////// + // emit the per-effect code for both color and coverage effects + + fOutput.fColorEffects.reset(this->createAndEmitEffects(colorStages, + this->desc().getEffectKeys(), + this->desc().numColorEffects(), + &inputColor)); + + fOutput.fCoverageEffects.reset(this->createAndEmitEffects(coverageStages, + this->desc().getEffectKeys() + this->desc().numColorEffects(), + this->desc().numCoverageEffects(), + &inputCoverage)); + + this->emitCodeAfterEffects(); + + /////////////////////////////////////////////////////////////////////////// + // write the secondary color output if necessary + if (GrGLProgramDesc::CoverageOutputUsesSecondaryOutput(header.fCoverageOutput)) { + const char* secondaryOutputName = this->enableSecondaryOutput(); + + // default coeff to ones for kCoverage_DualSrcOutput + GrGLSLExpr4 coeff(1); + if (GrGLProgramDesc::kSecondaryCoverageISA_CoverageOutput == header.fCoverageOutput) { + // Get (1-A) into coeff + coeff = GrGLSLExpr4::VectorCast(GrGLSLExpr1(1) - inputColor.a()); + } else if (GrGLProgramDesc::kSecondaryCoverageISC_CoverageOutput == + header.fCoverageOutput){ + // Get (1-RGBA) into coeff + coeff = GrGLSLExpr4(1) - inputColor; + } + // Get coeff * coverage into modulate and then write that to the dual source output. + this->fsCodeAppendf("\t%s = %s;\n", secondaryOutputName, (coeff * inputCoverage).c_str()); + } + + /////////////////////////////////////////////////////////////////////////// + // combine color and coverage as frag color + + // Get "color * coverage" into fragColor + GrGLSLExpr4 fragColor = inputColor * inputCoverage; + // Now tack on "+(1-coverage)dst onto the frag color if we were asked to do so. + if (GrGLProgramDesc::kCombineWithDst_CoverageOutput == header.fCoverageOutput) { + GrGLSLExpr4 dstCoeff = GrGLSLExpr4(1) - inputCoverage; + + GrGLSLExpr4 dstContribution = dstCoeff * GrGLSLExpr4(this->dstColor()); + + fragColor = fragColor + dstContribution; + } + this->fsCodeAppendf("\t%s = %s;\n", this->getColorOutputName(), fragColor.c_str()); + + if (!this->finish()) { + return false; + } + + return true; +} + +////////////////////////////////////////////////////////////////////////////// + +GrGLShaderBuilder::GrGLShaderBuilder(GrGpuGL* gpu, + GrGLUniformManager* uniformManager, + const GrGLProgramDesc& desc) + : fDesc(desc) + , fGpu(gpu) + , fUniformManager(SkRef(uniformManager)) + , fFSFeaturesAddedMask(0) + , fFSInputs(kVarsPerBlock) + , fFSOutputs(kMaxFSOutputs) + , fUniforms(kVarsPerBlock) + , fSetupFragPosition(false) + , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) + , fHasCustomColorOutput(false) + , fHasSecondaryOutput(false) { } bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) { @@ -181,13 +271,13 @@ bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) { if (!fGpu->glCaps().shaderDerivativeSupport()) { return false; } - if (kES_GrGLBinding == fGpu->glBinding()) { + if (kGLES_GrGLStandard == fGpu->glStandard()) { this->addFSFeature(1 << kStandardDerivatives_GLSLFeature, "GL_OES_standard_derivatives"); } return true; default: - GrCrash("Unexpected GLSLFeature requested."); + SkFAIL("Unexpected GLSLFeature requested."); return false; } } @@ -218,7 +308,7 @@ bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) { "GL_NV_shader_framebuffer_fetch"); return true; default: - GrCrash("Unexpected GLSLPrivateFeature requested."); + SkFAIL("Unexpected GLSLPrivateFeature requested."); return false; } } @@ -249,7 +339,7 @@ const char* GrGLShaderBuilder::dstColor() { if (fCodeStage.inStageCode()) { const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect(); if (!effect->willReadDstColor()) { - GrDebugCrash("GrGLEffect asked for dst color but its generating GrEffect " + SkDEBUGFAIL("GrGLEffect asked for dst color but its generating GrEffect " "did not request access."); return ""; } @@ -262,7 +352,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 ""; @@ -355,7 +445,7 @@ GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t vi BuilderUniform& uni = fUniforms.push_back(); UniformHandle h = GrGLUniformManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1); SkDEBUGCODE(UniformHandle h2 =) - fUniformManager.appendUniform(type, count); + fUniformManager->appendUniform(type, count); // We expect the uniform manager to initially have no uniforms and that all uniforms are added // by this function. Therefore, the handles should match. SkASSERT(h2 == h); @@ -399,19 +489,16 @@ const char* GrGLShaderBuilder::fragmentPosition() { if (fCodeStage.inStageCode()) { const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect(); if (!effect->willReadFragmentPosition()) { - GrDebugCrash("GrGLEffect asked for frag position but its generating GrEffect " + SkDEBUGFAIL("GrGLEffect asked for frag position but its generating GrEffect " "did not request access."); return ""; } } + // We only declare "gl_FragCoord" when we're in the case where we want to use layout qualifiers + // to reverse y. Otherwise it isn't necessary and whether the "in" qualifier appears in the + // declaration varies in earlier GLSL specs. So it is simpler to omit it. if (fTopLeftFragPosRead) { - if (!fSetupFragPosition) { - fFSInputs.push_back().set(kVec4f_GrSLType, - GrGLShaderVar::kIn_TypeModifier, - "gl_FragCoord", - GrGLShaderVar::kDefault_Precision); - fSetupFragPosition = true; - } + fSetupFragPosition = true; return "gl_FragCoord"; } else if (fGpu->glCaps().fragCoordConventionsSupport()) { if (!fSetupFragPosition) { @@ -430,19 +517,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; } } @@ -471,10 +556,10 @@ void GrGLShaderBuilder::fsEmitFunction(GrSLType returnType, namespace { inline void append_default_precision_qualifier(GrGLShaderVar::Precision p, - GrGLBinding binding, + GrGLStandard standard, SkString* str) { // Desktop GLSL has added precision qualifiers but they don't do anything. - if (kES_GrGLBinding == binding) { + if (kGLES_GrGLStandard == standard) { switch (p) { case GrGLShaderVar::kHigh_Precision: str->append("precision highp float;\n"); @@ -486,9 +571,9 @@ inline void append_default_precision_qualifier(GrGLShaderVar::Precision p, str->append("precision lowp float;\n"); break; case GrGLShaderVar::kDefault_Precision: - GrCrash("Default precision now allowed."); + SkFAIL("Default precision now allowed."); default: - GrCrash("Unknown precision value."); + SkFAIL("Unknown precision value."); } } } @@ -572,27 +657,26 @@ const char* GrGLShaderBuilder::enableSecondaryOutput() { return dual_source_output_name(); } - -bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) { - SK_TRACE_EVENT0("GrGLShaderBuilder::finish"); - - 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; } - if (!this->compileAndAttachShaders(programId)) { - GL_CALL(DeleteProgram(programId)); + SkTDArray<GrGLuint> shadersToDelete; + + if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) { + GL_CALL(DeleteProgram(fOutput.fProgramID)); return false; } - this->bindProgramLocations(programId); - if (fUniformManager.isUsingBindUniform()) { - fUniformManager.getUniformLocations(programId, fUniforms); + this->bindProgramLocations(fOutput.fProgramID); + if (fUniformManager->isUsingBindUniform()) { + 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(); @@ -601,46 +685,51 @@ 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); + if (!fUniformManager->isUsingBindUniform()) { + fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms); } - *outProgramId = programId; + + for (int i = 0; i < shadersToDelete.count(); ++i) { + GL_CALL(DeleteShader(shadersToDelete[i])); + } + return true; } -// Compiles a GL shader, attaches it to a program, and releases the shader's reference. -// (That way there's no need to hang on to the GL shader id and delete it later.) -static bool attach_shader(const GrGLContext& glCtx, - GrGLuint programId, - GrGLenum type, - const SkString& shaderSrc) { +// Compiles a GL shader and attaches it to a program. Returns the shader ID if +// successful, or 0 if not. +static GrGLuint attach_shader(const GrGLContext& glCtx, + GrGLuint programId, + GrGLenum type, + const SkString& shaderSrc) { const GrGLInterface* gli = glCtx.interface(); GrGLuint shaderId; GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); if (0 == shaderId) { - return false; + return 0; } const GrGLchar* sourceStr = shaderSrc.c_str(); @@ -649,7 +738,7 @@ static bool attach_shader(const GrGLContext& glCtx, GR_GL_CALL(gli, CompileShader(shaderId)); // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds. - bool checkCompiled = !glCtx.info().isChromium(); + bool checkCompiled = !glCtx.isChromium(); #ifdef SK_DEBUG checkCompiled = true; #endif @@ -672,7 +761,7 @@ static bool attach_shader(const GrGLContext& glCtx, } SkDEBUGFAIL("Shader compilation failed!"); GR_GL_CALL(gli, DeleteShader(shaderId)); - return false; + return 0; } } if (c_PrintShaders) { @@ -680,16 +769,20 @@ static bool attach_shader(const GrGLContext& glCtx, GrPrintf("\n"); } + // Attach the shader, but defer deletion until after we have linked the program. + // This works around a bug in the Android emulator's GLES2 wrapper which + // will immediately delete the shader object and free its memory even though it's + // attached to a program, which then causes glLinkProgram to fail. GR_GL_CALL(gli, AttachShader(programId, shaderId)); - GR_GL_CALL(gli, DeleteShader(shaderId)); - return true; + + return shaderId; } -bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { +bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const { SkString fragShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); fragShaderSrc.append(fFSExtensions); append_default_precision_qualifier(kDefaultFragmentPrecision, - fGpu->glBinding(), + fGpu->glStandard(), &fragShaderSrc); this->appendUniformDecls(kFragment_Visibility, &fragShaderSrc); this->appendDecls(fFSInputs, &fragShaderSrc); @@ -700,10 +793,14 @@ bool GrGLShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { fragShaderSrc.append("void main() {\n"); fragShaderSrc.append(fFSCode); fragShaderSrc.append("}\n"); - if (!attach_shader(fGpu->glContext(), programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc)) { + + GrGLuint fragShaderId = attach_shader(fGpu->glContext(), programId, GR_GL_FRAGMENT_SHADER, fragShaderSrc); + if (!fragShaderId) { return false; } + *shaderIds->append() = fragShaderId; + return true; } @@ -723,16 +820,19 @@ const GrGLContextInfo& GrGLShaderBuilder::ctxInfo() const { //////////////////////////////////////////////////////////////////////////////// GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, - GrGLUniformManager& uniformManager, + GrGLUniformManager* uniformManager, const GrGLProgramDesc& desc) : INHERITED(gpu, uniformManager, desc) - , fDesc(desc) , fVSAttrs(kVarsPerBlock) , fVSOutputs(kVarsPerBlock) , fGSInputs(kVarsPerBlock) , fGSOutputs(kVarsPerBlock) { +} + +void GrGLFullShaderBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, GrGLSLExpr4* coverage) { + const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); - const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); + fOutput.fHasVertexShader = true; fPositionVar = &fVSAttrs.push_back(); fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition"); @@ -746,11 +846,12 @@ 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); - this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n" - "\tgl_Position = vec4(pos3.xy, 0, pos3.z);\n", + // Transform the position into Skia's device coords. + this->vsCodeAppendf("\tvec3 pos3 = %s * vec3(%s, 1);\n", viewMName, fPositionVar->c_str()); // we output point size in the GS if present @@ -767,7 +868,7 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, const char *vsName, *fsName; this->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); this->vsCodeAppendf("\t%s = %s;\n", vsName, color_attribute_name()); - this->setInputColor(fsName); + *color = fsName; } if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { @@ -775,10 +876,22 @@ GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGpuGL* gpu, const char *vsName, *fsName; this->addVarying(kVec4f_GrSLType, "Coverage", &vsName, &fsName); this->vsCodeAppendf("\t%s = %s;\n", vsName, coverage_attribute_name()); - this->setInputCoverage(fsName); + *coverage = fsName; } } +void GrGLFullShaderBuilder::emitCodeAfterEffects() { + const char* rtAdjustName; + fOutput.fUniformHandles.fRTAdjustmentUni = + this->addUniform(GrGLShaderBuilder::kVertex_Visibility, kVec4f_GrSLType, "rtAdjustment", + &rtAdjustName); + + // Transform from Skia's device coords to GL's normalized device coords. + this->vsCodeAppendf( + "\tgl_Position = vec4(dot(pos3.xz, %s.xy), dot(pos3.yz, %s.zw), 0, pos3.z);\n", + rtAdjustName, rtAdjustName); +} + bool GrGLFullShaderBuilder::addAttribute(GrSLType type, const char* name) { for (int i = 0; i < fVSAttrs.count(); ++i) { const GrGLShaderVar& attr = fVSAttrs[i]; @@ -820,7 +933,7 @@ void GrGLFullShaderBuilder::addVarying(GrSLType type, // input to FS comes either from VS or GS const SkString* fsName; #if GR_GL_EXPERIMENTAL_GS - if (fDesc.getHeader().fExperimentalGS) { + if (this->desc().getHeader().fExperimentalGS) { // if we have a GS take each varying in as an array // and output as non-array. fGSInputs.push_back(); @@ -870,7 +983,8 @@ GrGLProgramEffects* GrGLFullShaderBuilder::createAndEmitEffects( return programEffectsBuilder.finish(); } -bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { +bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId, + SkTDArray<GrGLuint>* shaderIds) const { const GrGLContext& glCtx = this->gpu()->glContext(); SkString vertShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); this->appendUniformDecls(kVertex_Visibility, &vertShaderSrc); @@ -879,12 +993,14 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { vertShaderSrc.append("void main() {\n"); vertShaderSrc.append(fVSCode); vertShaderSrc.append("}\n"); - if (!attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER, vertShaderSrc)) { + GrGLuint vertShaderId = attach_shader(glCtx, programId, GR_GL_VERTEX_SHADER, vertShaderSrc); + if (!vertShaderId) { return false; } + *shaderIds->append() = vertShaderId; #if GR_GL_EXPERIMENTAL_GS - if (fDesc.getHeader().fExperimentalGS) { + if (this->desc().getHeader().fExperimentalGS) { SkASSERT(this->ctxInfo().glslGeneration() >= k150_GrGLSLGeneration); SkString geomShaderSrc(GrGetGLSLVersionDecl(this->ctxInfo())); geomShaderSrc.append("layout(triangles) in;\n" @@ -894,7 +1010,7 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { geomShaderSrc.append("void main() {\n"); geomShaderSrc.append("\tfor (int i = 0; i < 3; ++i) {\n" "\t\tgl_Position = gl_in[i].gl_Position;\n"); - if (fDesc.getHeader().fEmitsPointSize) { + if (this->desc().getHeader().fEmitsPointSize) { geomShaderSrc.append("\t\tgl_PointSize = 1.0;\n"); } SkASSERT(fGSInputs.count() == fGSOutputs.count()); @@ -907,19 +1023,21 @@ bool GrGLFullShaderBuilder::compileAndAttachShaders(GrGLuint programId) const { "\t}\n" "\tEndPrimitive();\n"); geomShaderSrc.append("}\n"); - if (!attach_shader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc)) { + GrGLuint geomShaderId = attach_shader(glCtx, programId, GR_GL_GEOMETRY_SHADER, geomShaderSrc); + if (!geomShaderId) { return false; } + *shaderIds->append() = geomShaderId; } #endif - return this->INHERITED::compileAndAttachShaders(programId); + return this->INHERITED::compileAndAttachShaders(programId, shaderIds); } void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { this->INHERITED::bindProgramLocations(programId); - const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); + const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); // Bind the attrib locations to same values for all shaders SkASSERT(-1 != header.fPositionAttributeIndex); @@ -951,22 +1069,19 @@ void GrGLFullShaderBuilder::bindProgramLocations(GrGLuint programId) const { //////////////////////////////////////////////////////////////////////////////// GrGLFragmentOnlyShaderBuilder::GrGLFragmentOnlyShaderBuilder(GrGpuGL* gpu, - GrGLUniformManager& uniformManager, + GrGLUniformManager* uniformManager, const GrGLProgramDesc& desc) - : INHERITED(gpu, uniformManager, desc) - , fNumTexCoordSets(0) { - + : INHERITED(gpu, uniformManager, desc) { SkASSERT(!desc.getHeader().fHasVertexCode); - SkASSERT(gpu->glCaps().fixedFunctionSupport()); SkASSERT(gpu->glCaps().pathRenderingSupport()); SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fColorInput); SkASSERT(GrGLProgramDesc::kAttribute_ColorInput != desc.getHeader().fCoverageInput); } 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; } @@ -976,11 +1091,12 @@ GrGLProgramEffects* GrGLFragmentOnlyShaderBuilder::createAndEmitEffects( int effectCnt, GrGLSLExpr4* inOutFSColor) { - GrGLTexGenProgramEffectsBuilder texGenEffectsBuilder(this, effectCnt); - this->INHERITED::createAndEmitEffects(&texGenEffectsBuilder, + GrGLPathTexGenProgramEffectsBuilder pathTexGenEffectsBuilder(this, + effectCnt); + this->INHERITED::createAndEmitEffects(&pathTexGenEffectsBuilder, effectStages, effectKeys, effectCnt, inOutFSColor); - return texGenEffectsBuilder.finish(); + return pathTexGenEffectsBuilder.finish(); } |