1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #include "glsl/GrGLSLProgramBuilder.h" 9 10 #include "GrCaps.h" 11 #include "GrPipeline.h" 12 #include "GrRenderTarget.h" 13 #include "GrShaderCaps.h" 14 #include "GrTexturePriv.h" 15 #include "glsl/GrGLSLFragmentProcessor.h" 16 #include "glsl/GrGLSLGeometryProcessor.h" 17 #include "glsl/GrGLSLVarying.h" 18 #include "glsl/GrGLSLXferProcessor.h" 19 #include "SkSLCompiler.h" 20 21 const int GrGLSLProgramBuilder::kVarsPerBlock = 8; 22 23 GrGLSLProgramBuilder::GrGLSLProgramBuilder(GrRenderTarget* renderTarget, GrSurfaceOrigin origin, 24 const GrPrimitiveProcessor& primProc, 25 const GrTextureProxy* const primProcProxies[], 26 const GrPipeline& pipeline, 27 GrProgramDesc* desc) 28 : fVS(this) 29 , fGS(this) 30 , fFS(this) 31 , fStageIndex(-1) 32 , fRenderTarget(renderTarget) 33 , fOrigin(origin) 34 , fPipeline(pipeline) 35 , fPrimProc(primProc) 36 , fPrimProcProxies(primProcProxies) 37 , fDesc(desc) 38 , fGeometryProcessor(nullptr) 39 , fXferProcessor(nullptr) 40 , fNumFragmentSamplers(0) {} 41 42 void GrGLSLProgramBuilder::addFeature(GrShaderFlags shaders, 43 uint32_t featureBit, 44 const char* extensionName) { 45 if (shaders & kVertex_GrShaderFlag) { 46 fVS.addFeature(featureBit, extensionName); 47 } 48 if (shaders & kGeometry_GrShaderFlag) { 49 SkASSERT(this->primitiveProcessor().willUseGeoShader()); 50 fGS.addFeature(featureBit, extensionName); 51 } 52 if (shaders & kFragment_GrShaderFlag) { 53 fFS.addFeature(featureBit, extensionName); 54 } 55 } 56 57 bool GrGLSLProgramBuilder::emitAndInstallProcs() { 58 // First we loop over all of the installed processors and collect coord transforms. These will 59 // be sent to the GrGLSLPrimitiveProcessor in its emitCode function 60 SkString inputColor; 61 SkString inputCoverage; 62 this->emitAndInstallPrimProc(&inputColor, &inputCoverage); 63 this->emitAndInstallFragProcs(&inputColor, &inputCoverage); 64 this->emitAndInstallXferProc(inputColor, inputCoverage); 65 this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput()); 66 67 return this->checkSamplerCounts(); 68 } 69 70 void GrGLSLProgramBuilder::emitAndInstallPrimProc(SkString* outputColor, 71 SkString* outputCoverage) { 72 const GrPrimitiveProcessor& proc = this->primitiveProcessor(); 73 const GrTextureProxy* const* primProcProxies = this->primProcProxies(); 74 75 // Program builders have a bit of state we need to clear with each effect 76 AutoStageAdvance adv(this); 77 this->nameExpression(outputColor, "outputColor"); 78 this->nameExpression(outputCoverage, "outputCoverage"); 79 80 SkASSERT(!fUniformHandles.fRTAdjustmentUni.isValid()); 81 GrShaderFlags rtAdjustVisibility; 82 if (proc.willUseGeoShader()) { 83 rtAdjustVisibility = kGeometry_GrShaderFlag; 84 } else { 85 rtAdjustVisibility = kVertex_GrShaderFlag; 86 } 87 fUniformHandles.fRTAdjustmentUni = this->uniformHandler()->addUniform( 88 rtAdjustVisibility, 89 kFloat4_GrSLType, 90 SkSL::Compiler::RTADJUST_NAME); 91 const char* rtAdjustName = 92 this->uniformHandler()->getUniformCStr(fUniformHandles.fRTAdjustmentUni); 93 94 // Enclose custom code in a block to avoid namespace conflicts 95 SkString openBrace; 96 openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name()); 97 fFS.codeAppend(openBrace.c_str()); 98 fVS.codeAppendf("// Primitive Processor %s\n", proc.name()); 99 100 SkASSERT(!fGeometryProcessor); 101 fGeometryProcessor.reset(proc.createGLSLInstance(*this->shaderCaps())); 102 103 SkAutoSTMalloc<4, SamplerHandle> texSamplers(proc.numTextureSamplers()); 104 for (int i = 0; i < proc.numTextureSamplers(); ++i) { 105 SkString name; 106 name.printf("TextureSampler_%d", i); 107 const auto& sampler = proc.textureSampler(i); 108 const GrTexture* texture = primProcProxies[i]->peekTexture(); 109 SkASSERT(sampler.textureType() == texture->texturePriv().textureType()); 110 SkASSERT(sampler.config() == texture->config()); 111 texSamplers[i] = this->emitSampler(texture, 112 sampler.samplerState(), 113 name.c_str()); 114 } 115 116 GrGLSLPrimitiveProcessor::FPCoordTransformHandler transformHandler(fPipeline, 117 &fTransformedCoordVars); 118 GrGLSLGeometryProcessor::EmitArgs args(&fVS, 119 proc.willUseGeoShader() ? &fGS : nullptr, 120 &fFS, 121 this->varyingHandler(), 122 this->uniformHandler(), 123 this->shaderCaps(), 124 proc, 125 outputColor->c_str(), 126 outputCoverage->c_str(), 127 rtAdjustName, 128 texSamplers.get(), 129 &transformHandler); 130 fGeometryProcessor->emitCode(args); 131 132 // We have to check that effects and the code they emit are consistent, ie if an effect 133 // asks for dst color, then the emit code needs to follow suit 134 SkDEBUGCODE(verify(proc);) 135 136 fFS.codeAppend("}"); 137 } 138 139 void GrGLSLProgramBuilder::emitAndInstallFragProcs(SkString* color, SkString* coverage) { 140 int transformedCoordVarsIdx = 0; 141 SkString** inOut = &color; 142 SkSTArray<8, std::unique_ptr<GrGLSLFragmentProcessor>> glslFragmentProcessors; 143 for (int i = 0; i < this->pipeline().numFragmentProcessors(); ++i) { 144 if (i == this->pipeline().numColorFragmentProcessors()) { 145 inOut = &coverage; 146 } 147 SkString output; 148 const GrFragmentProcessor& fp = this->pipeline().getFragmentProcessor(i); 149 output = this->emitAndInstallFragProc(fp, i, transformedCoordVarsIdx, **inOut, output, 150 &glslFragmentProcessors); 151 GrFragmentProcessor::Iter iter(&fp); 152 while (const GrFragmentProcessor* fp = iter.next()) { 153 transformedCoordVarsIdx += fp->numCoordTransforms(); 154 } 155 **inOut = output; 156 } 157 fFragmentProcessorCnt = glslFragmentProcessors.count(); 158 fFragmentProcessors.reset(new std::unique_ptr<GrGLSLFragmentProcessor>[fFragmentProcessorCnt]); 159 for (int i = 0; i < fFragmentProcessorCnt; ++i) { 160 fFragmentProcessors[i] = std::move(glslFragmentProcessors[i]); 161 } 162 } 163 164 // TODO Processors cannot output zeros because an empty string is all 1s 165 // the fix is to allow effects to take the SkString directly 166 SkString GrGLSLProgramBuilder::emitAndInstallFragProc( 167 const GrFragmentProcessor& fp, 168 int index, 169 int transformedCoordVarsIdx, 170 const SkString& input, 171 SkString output, 172 SkTArray<std::unique_ptr<GrGLSLFragmentProcessor>>* glslFragmentProcessors) { 173 SkASSERT(input.size()); 174 // Program builders have a bit of state we need to clear with each effect 175 AutoStageAdvance adv(this); 176 this->nameExpression(&output, "output"); 177 178 // Enclose custom code in a block to avoid namespace conflicts 179 SkString openBrace; 180 openBrace.printf("{ // Stage %d, %s\n", fStageIndex, fp.name()); 181 fFS.codeAppend(openBrace.c_str()); 182 183 GrGLSLFragmentProcessor* fragProc = fp.createGLSLInstance(); 184 185 SkSTArray<4, SamplerHandle> texSamplers; 186 GrFragmentProcessor::Iter fpIter(&fp); 187 int samplerIdx = 0; 188 while (const auto* subFP = fpIter.next()) { 189 for (int i = 0; i < subFP->numTextureSamplers(); ++i) { 190 SkString name; 191 name.printf("TextureSampler_%d", samplerIdx++); 192 const auto& sampler = subFP->textureSampler(i); 193 texSamplers.emplace_back(this->emitSampler(sampler.peekTexture(), 194 sampler.samplerState(), 195 name.c_str())); 196 } 197 } 198 199 const GrShaderVar* coordVars = fTransformedCoordVars.begin() + transformedCoordVarsIdx; 200 GrGLSLFragmentProcessor::TransformedCoordVars coords(&fp, coordVars); 201 GrGLSLFragmentProcessor::TextureSamplers textureSamplers(&fp, texSamplers.begin()); 202 GrGLSLFragmentProcessor::EmitArgs args(&fFS, 203 this->uniformHandler(), 204 this->shaderCaps(), 205 fp, 206 output.c_str(), 207 input.c_str(), 208 coords, 209 textureSamplers); 210 211 fragProc->emitCode(args); 212 213 // We have to check that effects and the code they emit are consistent, ie if an effect 214 // asks for dst color, then the emit code needs to follow suit 215 SkDEBUGCODE(verify(fp);) 216 glslFragmentProcessors->emplace_back(fragProc); 217 218 fFS.codeAppend("}"); 219 return output; 220 } 221 222 void GrGLSLProgramBuilder::emitAndInstallXferProc(const SkString& colorIn, 223 const SkString& coverageIn) { 224 // Program builders have a bit of state we need to clear with each effect 225 AutoStageAdvance adv(this); 226 227 SkASSERT(!fXferProcessor); 228 const GrXferProcessor& xp = fPipeline.getXferProcessor(); 229 fXferProcessor.reset(xp.createGLSLInstance()); 230 231 // Enable dual source secondary output if we have one 232 if (xp.hasSecondaryOutput()) { 233 fFS.enableSecondaryOutput(); 234 } 235 236 if (this->shaderCaps()->mustDeclareFragmentShaderOutput()) { 237 fFS.enableCustomOutput(); 238 } 239 240 SkString openBrace; 241 openBrace.printf("{ // Xfer Processor: %s\n", xp.name()); 242 fFS.codeAppend(openBrace.c_str()); 243 244 SamplerHandle dstTextureSamplerHandle; 245 GrSurfaceOrigin dstTextureOrigin = kTopLeft_GrSurfaceOrigin; 246 247 if (GrTexture* dstTexture = fPipeline.peekDstTexture()) { 248 // GrProcessor::TextureSampler sampler(dstTexture); 249 SkString name("DstTextureSampler"); 250 dstTextureSamplerHandle = 251 this->emitSampler(dstTexture, GrSamplerState(), "DstTextureSampler"); 252 dstTextureOrigin = fPipeline.dstTextureProxy()->origin(); 253 SkASSERT(dstTexture->texturePriv().textureType() != GrTextureType::kExternal); 254 } 255 256 SkString finalInColor; 257 if (colorIn.size()) { 258 if (this->desc()->header().fClampBlendInput) { 259 finalInColor.printf("saturate(%s)", colorIn.c_str()); 260 } else { 261 finalInColor = colorIn; 262 } 263 } else { 264 finalInColor = "float4(1)"; 265 } 266 267 GrGLSLXferProcessor::EmitArgs args(&fFS, 268 this->uniformHandler(), 269 this->shaderCaps(), 270 xp, 271 finalInColor.c_str(), 272 coverageIn.size() ? coverageIn.c_str() : "float4(1)", 273 fFS.getPrimaryColorOutputName(), 274 fFS.getSecondaryColorOutputName(), 275 dstTextureSamplerHandle, 276 dstTextureOrigin); 277 fXferProcessor->emitCode(args); 278 279 // We have to check that effects and the code they emit are consistent, ie if an effect 280 // asks for dst color, then the emit code needs to follow suit 281 SkDEBUGCODE(verify(xp);) 282 fFS.codeAppend("}"); 283 } 284 285 GrGLSLProgramBuilder::SamplerHandle GrGLSLProgramBuilder::emitSampler(const GrTexture* texture, 286 const GrSamplerState& state, 287 const char* name) { 288 ++fNumFragmentSamplers; 289 return this->uniformHandler()->addSampler(texture, state, name, this->shaderCaps()); 290 } 291 292 void GrGLSLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) { 293 // Swizzle the fragment shader outputs if necessary. 294 GrSwizzle swizzle; 295 swizzle.setFromKey(this->desc()->header().fOutputSwizzle); 296 if (swizzle != GrSwizzle::RGBA()) { 297 fFS.codeAppendf("%s = %s.%s;", fFS.getPrimaryColorOutputName(), 298 fFS.getPrimaryColorOutputName(), 299 swizzle.c_str()); 300 if (hasSecondaryOutput) { 301 fFS.codeAppendf("%s = %s.%s;", fFS.getSecondaryColorOutputName(), 302 fFS.getSecondaryColorOutputName(), 303 swizzle.c_str()); 304 } 305 } 306 } 307 308 bool GrGLSLProgramBuilder::checkSamplerCounts() { 309 const GrShaderCaps& shaderCaps = *this->shaderCaps(); 310 if (fNumFragmentSamplers > shaderCaps.maxFragmentSamplers()) { 311 GrCapsDebugf(this->caps(), "Program would use too many fragment samplers\n"); 312 return false; 313 } 314 return true; 315 } 316 317 #ifdef SK_DEBUG 318 void GrGLSLProgramBuilder::verify(const GrPrimitiveProcessor& gp) { 319 SkASSERT(!fFS.fHasReadDstColorThisStage_DebugOnly); 320 SkASSERT(fFS.fUsedProcessorFeaturesThisStage_DebugOnly == gp.requestedFeatures()); 321 } 322 323 void GrGLSLProgramBuilder::verify(const GrFragmentProcessor& fp) { 324 SkASSERT(!fFS.fHasReadDstColorThisStage_DebugOnly); 325 SkASSERT(fFS.fUsedProcessorFeaturesThisStage_DebugOnly == fp.requestedFeatures()); 326 } 327 328 void GrGLSLProgramBuilder::verify(const GrXferProcessor& xp) { 329 SkASSERT(xp.willReadDstColor() == fFS.fHasReadDstColorThisStage_DebugOnly); 330 SkASSERT(fFS.fUsedProcessorFeaturesThisStage_DebugOnly == xp.requestedFeatures()); 331 } 332 #endif 333 334 void GrGLSLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name, bool mangle) { 335 if ('\0' == prefix) { 336 *out = name; 337 } else { 338 out->printf("%c%s", prefix, name); 339 } 340 if (mangle) { 341 if (out->endsWith('_')) { 342 // Names containing "__" are reserved. 343 out->append("x"); 344 } 345 out->appendf("_Stage%d%s", fStageIndex, fFS.getMangleString().c_str()); 346 } 347 } 348 349 void GrGLSLProgramBuilder::nameExpression(SkString* output, const char* baseName) { 350 // create var to hold stage result. If we already have a valid output name, just use that 351 // otherwise create a new mangled one. This name is only valid if we are reordering stages 352 // and have to tell stage exactly where to put its output. 353 SkString outName; 354 if (output->size()) { 355 outName = output->c_str(); 356 } else { 357 this->nameVariable(&outName, '\0', baseName); 358 } 359 fFS.codeAppendf("half4 %s;", outName.c_str()); 360 *output = outName; 361 } 362 363 void GrGLSLProgramBuilder::appendUniformDecls(GrShaderFlags visibility, SkString* out) const { 364 this->uniformHandler()->appendUniformDecls(visibility, out); 365 } 366 367 void GrGLSLProgramBuilder::addRTWidthUniform(const char* name) { 368 SkASSERT(!fUniformHandles.fRTWidthUni.isValid()); 369 GrGLSLUniformHandler* uniformHandler = this->uniformHandler(); 370 fUniformHandles.fRTWidthUni = 371 uniformHandler->internalAddUniformArray(kFragment_GrShaderFlag, kHalf_GrSLType, name, 372 false, 0, nullptr); 373 } 374 375 void GrGLSLProgramBuilder::addRTHeightUniform(const char* name) { 376 SkASSERT(!fUniformHandles.fRTHeightUni.isValid()); 377 GrGLSLUniformHandler* uniformHandler = this->uniformHandler(); 378 fUniformHandles.fRTHeightUni = 379 uniformHandler->internalAddUniformArray(kFragment_GrShaderFlag, kHalf_GrSLType, name, 380 false, 0, nullptr); 381 } 382 383 void GrGLSLProgramBuilder::finalizeShaders() { 384 this->varyingHandler()->finalize(); 385 fVS.finalize(kVertex_GrShaderFlag); 386 if (this->primitiveProcessor().willUseGeoShader()) { 387 SkASSERT(this->shaderCaps()->geometryShaderSupport()); 388 fGS.finalize(kGeometry_GrShaderFlag); 389 } 390 fFS.finalize(kFragment_GrShaderFlag); 391 } 392