• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 "src/gpu/ganesh/GrRenderTarget.h"
9 #include "src/gpu/ganesh/GrShaderCaps.h"
10 #include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
11 #include "src/gpu/ganesh/glsl/GrGLSLProgramBuilder.h"
12 #include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"
13 #include "src/gpu/ganesh/glsl/GrGLSLVarying.h"
14 
GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder * program)15 GrGLSLFragmentShaderBuilder::GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program)
16         : GrGLSLShaderBuilder(program) {}
17 
dstColor()18 const char* GrGLSLFragmentShaderBuilder::dstColor() {
19     SkDEBUGCODE(fHasReadDstColorThisStage_DebugOnly = true;)
20 
21     const GrShaderCaps* shaderCaps = fProgramBuilder->shaderCaps();
22     if (shaderCaps->fFBFetchSupport) {
23         this->addFeature(1 << kFramebufferFetch_GLSLPrivateFeature,
24                          shaderCaps->fFBFetchExtensionString);
25 
26         // Some versions of this extension string require declaring custom color output on ES 3.0+
27         const char* fbFetchColorName = "sk_LastFragColor";
28         if (shaderCaps->fFBFetchNeedsCustomOutput) {
29             fPrimaryColorIsInOut = true;
30             fbFetchColorName = DeclaredColorOutputName();
31             // Set the dstColor to an intermediate variable so we don't override it with the output
32             this->codeAppendf("half4 %s = %s;", kDstColorName, fbFetchColorName);
33         } else {
34             return fbFetchColorName;
35         }
36     }
37     return kDstColorName;
38 }
39 
enableAdvancedBlendEquationIfNeeded(skgpu::BlendEquation equation)40 void GrGLSLFragmentShaderBuilder::enableAdvancedBlendEquationIfNeeded(
41         skgpu::BlendEquation equation) {
42     SkASSERT(skgpu::BlendEquationIsAdvanced(equation));
43 
44     if (fProgramBuilder->shaderCaps()->mustEnableAdvBlendEqs()) {
45         this->addFeature(1 << kBlendEquationAdvanced_GLSLPrivateFeature,
46                          "GL_KHR_blend_equation_advanced");
47         this->addLayoutQualifier("blend_support_all_equations", kOut_InterfaceQualifier);
48     }
49 }
50 
enableSecondaryOutput()51 void GrGLSLFragmentShaderBuilder::enableSecondaryOutput() {
52     SkASSERT(!fHasSecondaryOutput);
53     fHasSecondaryOutput = true;
54     const GrShaderCaps& caps = *fProgramBuilder->shaderCaps();
55     if (const char* extension = caps.fSecondaryOutputExtensionString) {
56         this->addFeature(1 << kBlendFuncExtended_GLSLPrivateFeature, extension);
57     }
58 
59     // If the primary output is declared, we must declare also the secondary output
60     // and vice versa, since it is not allowed to use a built-in gl_FragColor and a custom
61     // output. The condition also co-incides with the condition in which GLSL ES 2.0
62     // requires the built-in gl_SecondaryFragColorEXT, whereas 3.0 requires a custom output.
63     if (caps.mustDeclareFragmentShaderOutput()) {
64         fOutputs.emplace_back(DeclaredSecondaryColorOutputName(), SkSLType::kHalf4,
65                               GrShaderVar::TypeModifier::Out);
66         fProgramBuilder->finalizeFragmentSecondaryColor(fOutputs.back());
67     }
68 }
69 
getPrimaryColorOutputName() const70 const char* GrGLSLFragmentShaderBuilder::getPrimaryColorOutputName() const {
71     return DeclaredColorOutputName();
72 }
73 
primaryColorOutputIsInOut() const74 bool GrGLSLFragmentShaderBuilder::primaryColorOutputIsInOut() const {
75     return fPrimaryColorIsInOut;
76 }
77 
getSecondaryColorOutputName() const78 const char* GrGLSLFragmentShaderBuilder::getSecondaryColorOutputName() const {
79     if (this->hasSecondaryOutput()) {
80         return (fProgramBuilder->shaderCaps()->mustDeclareFragmentShaderOutput())
81                 ? DeclaredSecondaryColorOutputName()
82                 : "sk_SecondaryFragColor";
83     }
84     return nullptr;
85 }
86 
getSurfaceOrigin() const87 GrSurfaceOrigin GrGLSLFragmentShaderBuilder::getSurfaceOrigin() const {
88     return fProgramBuilder->origin();
89 }
90 
onFinalize()91 void GrGLSLFragmentShaderBuilder::onFinalize() {
92     fProgramBuilder->varyingHandler()->getFragDecls(&this->inputs(), &this->outputs());
93 }
94