• Home
  • History
  • Annotate
  • 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 "GrGLShaderBuilder.h"
9 #include "GrGLFullProgramBuilder.h"
10 #include "GrGLProgramBuilder.h"
11 #include "../GrGpuGL.h"
12 #include "../GrGLShaderVar.h"
13 
14 namespace {
sample_function_name(GrSLType type,GrGLSLGeneration glslGen)15 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) {
16     if (kVec2f_GrSLType == type) {
17         return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D";
18     } else {
19         SkASSERT(kVec3f_GrSLType == type);
20         return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj";
21     }
22 }
append_texture_lookup(SkString * out,GrGpuGL * gpu,const char * samplerName,const char * coordName,uint32_t configComponentMask,const char * swizzle,GrSLType varyingType=kVec2f_GrSLType)23 void append_texture_lookup(SkString* out,
24                            GrGpuGL* gpu,
25                            const char* samplerName,
26                            const char* coordName,
27                            uint32_t configComponentMask,
28                            const char* swizzle,
29                            GrSLType varyingType = kVec2f_GrSLType) {
30     SkASSERT(coordName);
31 
32     out->appendf("%s(%s, %s)",
33                  sample_function_name(varyingType, gpu->glslGeneration()),
34                  samplerName,
35                  coordName);
36 
37     char mangledSwizzle[5];
38 
39     // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle
40     // is available.
41     if (!gpu->glCaps().textureSwizzleSupport() &&
42         (kA_GrColorComponentFlag == configComponentMask)) {
43         char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a';
44         int i;
45         for (i = 0; '\0' != swizzle[i]; ++i) {
46             mangledSwizzle[i] = alphaChar;
47         }
48         mangledSwizzle[i] ='\0';
49         swizzle = mangledSwizzle;
50     }
51     // For shader prettiness we omit the swizzle rather than appending ".rgba".
52     if (memcmp(swizzle, "rgba", 4)) {
53         out->appendf(".%s", swizzle);
54     }
55 }
56 static const int kVarsPerBlock = 8;
57 }
58 
GrGLShaderBuilder(GrGLProgramBuilder * program)59 GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program)
60     : fProgramBuilder(program)
61     , fInputs(kVarsPerBlock)
62     , fOutputs(kVarsPerBlock)
63     , fFeaturesAddedMask(0) {
64 }
65 
declAppend(const GrGLShaderVar & var)66 void GrGLShaderBuilder::declAppend(const GrGLShaderVar& var) {
67     SkString tempDecl;
68     var.appendDecl(fProgramBuilder->ctxInfo(), &tempDecl);
69     this->codeAppendf("%s;", tempDecl.c_str());
70 }
71 
emitFunction(GrSLType returnType,const char * name,int argCnt,const GrGLShaderVar * args,const char * body,SkString * outName)72 void GrGLShaderBuilder::emitFunction(GrSLType returnType,
73                                      const char* name,
74                                      int argCnt,
75                                      const GrGLShaderVar* args,
76                                      const char* body,
77                                      SkString* outName) {
78     fFunctions.append(GrGLSLTypeString(returnType));
79     fProgramBuilder->nameVariable(outName, '\0', name);
80     fFunctions.appendf(" %s", outName->c_str());
81     fFunctions.append("(");
82     const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo();
83     for (int i = 0; i < argCnt; ++i) {
84         args[i].appendDecl(ctxInfo, &fFunctions);
85         if (i < argCnt - 1) {
86             fFunctions.append(", ");
87         }
88     }
89     fFunctions.append(") {\n");
90     fFunctions.append(body);
91     fFunctions.append("}\n\n");
92 }
93 
appendTextureLookup(SkString * out,const TextureSampler & sampler,const char * coordName,GrSLType varyingType) const94 void GrGLShaderBuilder::appendTextureLookup(SkString* out,
95                                             const TextureSampler& sampler,
96                                             const char* coordName,
97                                             GrSLType varyingType) const {
98     append_texture_lookup(out,
99                           fProgramBuilder->gpu(),
100                           fProgramBuilder->getUniformCStr(sampler.fSamplerUniform),
101                           coordName,
102                           sampler.configComponentMask(),
103                           sampler.swizzle(),
104                           varyingType);
105 }
106 
appendTextureLookup(const TextureSampler & sampler,const char * coordName,GrSLType varyingType)107 void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler,
108                                             const char* coordName,
109                                             GrSLType varyingType) {
110     this->appendTextureLookup(&fCode, sampler, coordName, varyingType);
111 }
112 
appendTextureLookupAndModulate(const char * modulation,const TextureSampler & sampler,const char * coordName,GrSLType varyingType)113 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation,
114                                                        const TextureSampler& sampler,
115                                                        const char* coordName,
116                                                        GrSLType varyingType) {
117     SkString lookup;
118     this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
119     this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str());
120 }
121 
122 
GetTexParamSwizzle(GrPixelConfig config,const GrGLCaps & caps)123 const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
124     if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
125         if (caps.textureRedSupport()) {
126             static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED };
127             return gRedSmear;
128         } else {
129             static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
130                                                     GR_GL_ALPHA, GR_GL_ALPHA };
131             return gAlphaSmear;
132         }
133     } else {
134         static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA };
135         return gStraight;
136     }
137 }
138 
addFeature(uint32_t featureBit,const char * extensionName)139 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) {
140     if (!(featureBit & fFeaturesAddedMask)) {
141         fExtensions.appendf("#extension %s: require\n", extensionName);
142             fFeaturesAddedMask |= featureBit;
143     }
144 }
145 
appendTextureLookup(const char * samplerName,const char * coordName,uint32_t configComponentMask,const char * swizzle)146 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName,
147                                             const char* coordName,
148                                             uint32_t configComponentMask,
149                                             const char* swizzle) {
150     append_texture_lookup(&fCode,
151                           fProgramBuilder->gpu(),
152                           samplerName,
153                           coordName,
154                           configComponentMask,
155                           swizzle,
156                           kVec2f_GrSLType);
157 }
158 
159 ///////////////////////////////////////////////////////////////////////////////////////////////////
GrGLFullShaderBuilder(GrGLFullProgramBuilder * program)160 GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGLFullProgramBuilder* program)
161     : INHERITED(program)
162     , fFullProgramBuilder(program) {}
163