• 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/GrRenderTarget.h"
9 #include "src/gpu/GrShaderCaps.h"
10 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
11 #include "src/gpu/glsl/GrGLSLProgramBuilder.h"
12 #include "src/gpu/glsl/GrGLSLUniformHandler.h"
13 #include "src/gpu/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->fbFetchSupport()) {
23         this->addFeature(1 << kFramebufferFetch_GLSLPrivateFeature,
24                          shaderCaps->fbFetchExtensionString());
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->fbFetchNeedsCustomOutput()) {
29             this->enableCustomOutput();
30             fCustomColorOutput->setTypeModifier(GrShaderVar::TypeModifier::InOut);
31             fbFetchColorName = DeclaredColorOutputName();
32             // Set the dstColor to an intermediate variable so we don't override it with the output
33             this->codeAppendf("half4 %s = %s;", kDstColorName, fbFetchColorName);
34         } else {
35             return fbFetchColorName;
36         }
37     }
38     return kDstColorName;
39 }
40 
enableAdvancedBlendEquationIfNeeded(GrBlendEquation equation)41 void GrGLSLFragmentShaderBuilder::enableAdvancedBlendEquationIfNeeded(GrBlendEquation equation) {
42     SkASSERT(GrBlendEquationIsAdvanced(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 
enableCustomOutput()51 void GrGLSLFragmentShaderBuilder::enableCustomOutput() {
52     if (!fCustomColorOutput) {
53         fCustomColorOutput = &fOutputs.emplace_back(DeclaredColorOutputName(), kHalf4_GrSLType,
54                                                     GrShaderVar::TypeModifier::Out);
55         fProgramBuilder->finalizeFragmentOutputColor(fOutputs.back());
56     }
57 }
58 
enableSecondaryOutput()59 void GrGLSLFragmentShaderBuilder::enableSecondaryOutput() {
60     SkASSERT(!fHasSecondaryOutput);
61     fHasSecondaryOutput = true;
62     const GrShaderCaps& caps = *fProgramBuilder->shaderCaps();
63     if (const char* extension = caps.secondaryOutputExtensionString()) {
64         this->addFeature(1 << kBlendFuncExtended_GLSLPrivateFeature, extension);
65     }
66 
67     // If the primary output is declared, we must declare also the secondary output
68     // and vice versa, since it is not allowed to use a built-in gl_FragColor and a custom
69     // output. The condition also co-incides with the condition in which GLSL ES 2.0
70     // requires the built-in gl_SecondaryFragColorEXT, whereas 3.0 requires a custom output.
71     if (caps.mustDeclareFragmentShaderOutput()) {
72         fOutputs.emplace_back(DeclaredSecondaryColorOutputName(), kHalf4_GrSLType,
73                               GrShaderVar::TypeModifier::Out);
74         fProgramBuilder->finalizeFragmentSecondaryColor(fOutputs.back());
75     }
76 }
77 
getPrimaryColorOutputName() const78 const char* GrGLSLFragmentShaderBuilder::getPrimaryColorOutputName() const {
79     return DeclaredColorOutputName();
80 }
81 
primaryColorOutputIsInOut() const82 bool GrGLSLFragmentShaderBuilder::primaryColorOutputIsInOut() const {
83     return fCustomColorOutput &&
84            fCustomColorOutput->getTypeModifier() == GrShaderVar::TypeModifier::InOut;
85 }
86 
getSecondaryColorOutputName() const87 const char* GrGLSLFragmentShaderBuilder::getSecondaryColorOutputName() const {
88     if (this->hasSecondaryOutput()) {
89         return (fProgramBuilder->shaderCaps()->mustDeclareFragmentShaderOutput())
90                 ? DeclaredSecondaryColorOutputName()
91                 : "sk_SecondaryFragColor";
92     }
93     return nullptr;
94 }
95 
getSurfaceOrigin() const96 GrSurfaceOrigin GrGLSLFragmentShaderBuilder::getSurfaceOrigin() const {
97     return fProgramBuilder->origin();
98 }
99 
onFinalize()100 void GrGLSLFragmentShaderBuilder::onFinalize() {
101     fProgramBuilder->varyingHandler()->getFragDecls(&this->inputs(), &this->outputs());
102 }
103