void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, const char* coordName, uint32_t configComponentMask, const char* swizzle) { append_texture_lookup(&fCode, fProgramBuilder->gpu(), samplerName, coordName, configComponentMask, swizzle, kVec2f_GrSLType); }
void GrGLShaderBuilder::appendTextureLookup(SkString* out, const GrGLShaderBuilder::TextureSampler& sampler, const char* coordName, GrSLType varyingType) const { append_texture_lookup(out, fGpu, this->getUniformCStr(sampler.samplerUniform()), coordName, sampler.configComponentMask(), sampler.swizzle(), varyingType); }
bool GrGLShaderBuilder::genProgram(const GrEffectStage* colorStages[], const GrEffectStage* coverageStages[]) { const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); /////////////////////////////////////////////////////////////////////////// // emit code to read the dst copy texture, if necessary if (kNoDstRead_DstReadKey != header.fDstReadKey && !fGpu->glCaps().fbFetchSupport()) { 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; } fUniformHandles.fDstCopySamplerUni = this->addUniform(kFragment_Visibility, kSampler2D_GrSLType, "DstCopySampler", &dstCopySamplerName); fUniformHandles.fDstCopyTopLeftUni = this->addUniform(kFragment_Visibility, kVec2f_GrSLType, "DstCopyUpperLeft", &dstCopyTopLeftName); 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", fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); if (!topDown) { this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); } this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); append_texture_lookup(&fFSCode, fGpu, 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; fUniformHandles.fColorUni = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Color", &name); inputColor = GrGLSLExpr4(name); } if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) { const char* name; fUniformHandles.fCoverageUni = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Coverage", &name); inputCoverage = GrGLSLExpr4(name); } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) { inputCoverage = GrGLSLExpr4(1); } if (k110_GrGLSLGeneration != fGpu->glslGeneration()) { fFSOutputs.push_back().set(kVec4f_GrSLType, GrGLShaderVar::kOut_TypeModifier, declared_color_output_name()); fHasCustomColorOutput = true; } this->emitCodeBeforeEffects(&inputColor, &inputCoverage); /////////////////////////////////////////////////////////////////////////// // emit the per-effect code for both color and coverage effects GrGLProgramDesc::EffectKeyProvider colorKeyProvider( &this->desc(), GrGLProgramDesc::EffectKeyProvider::kColor_EffectType); fColorEffects.reset(this->createAndEmitEffects(colorStages, this->desc().numColorEffects(), colorKeyProvider, &inputColor)); GrGLProgramDesc::EffectKeyProvider coverageKeyProvider( &this->desc(), GrGLProgramDesc::EffectKeyProvider::kCoverage_EffectType); fCoverageEffects.reset(this->createAndEmitEffects(coverageStages, this->desc().numCoverageEffects(), coverageKeyProvider, &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) : fGpu(gpu) , fUniformManager(uniformManager) , fFSFeaturesAddedMask(0) , fFSInputs(kVarsPerBlock) , fFSOutputs(kMaxFSOutputs) , fUniforms(kVarsPerBlock) , fSetupFragPosition(false) , fHasCustomColorOutput(false) , fHasSecondaryOutput(false) , fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) { const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); // Emit code to read the dst copy textue 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; 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); 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", fragPos, dstCopyTopLeftName, dstCopyCoordScaleName); if (!topDown) { this->fsCodeAppend("\t_dstTexCoord.y = 1.0 - _dstTexCoord.y;\n"); } this->fsCodeAppendf("\tvec4 %s = ", kDstCopyColorName); append_texture_lookup(&fFSCode, fGpu, this->getUniformCStr(fDstCopySamplerUniform), "_dstTexCoord", configMask, "rgba"); this->fsCodeAppend(";\n\n"); } if (GrGLProgramDesc::kUniform_ColorInput == header.fColorInput) { const char* name; fColorUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Color", &name); fInputColor = GrGLSLExpr4(name); } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fColorInput) { fInputColor = GrGLSLExpr4(1); } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fColorInput) { fInputColor = GrGLSLExpr4(0); } if (GrGLProgramDesc::kUniform_ColorInput == header.fCoverageInput) { const char* name; fCoverageUniform = this->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "Coverage", &name); fInputCoverage = GrGLSLExpr4(name); } else if (GrGLProgramDesc::kSolidWhite_ColorInput == header.fCoverageInput) { fInputCoverage = GrGLSLExpr4(1); } else if (GrGLProgramDesc::kTransBlack_ColorInput == header.fCoverageInput) { fInputCoverage = GrGLSLExpr4(0); } if (k110_GrGLSLGeneration != fGpu->glslGeneration()) { fFSOutputs.push_back().set(kVec4f_GrSLType, GrGLShaderVar::kOut_TypeModifier, declared_color_output_name()); fHasCustomColorOutput = true; } }