OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "GrGLShaderBuilder.h" | 8 #include "GrGLShaderBuilder.h" |
9 #include "GrGLProgramBuilder.h" | 9 #include "GrGLProgramBuilder.h" |
10 #include "GrGLShaderStringBuilder.h" | 10 #include "GrGLProgramBuilder.h" |
11 #include "../GrGLGpu.h" | 11 #include "../GrGLGpu.h" |
12 #include "../GrGLShaderVar.h" | 12 #include "../GrGLShaderVar.h" |
13 | 13 |
14 namespace { | 14 namespace { |
15 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen)
{ | 15 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen)
{ |
16 if (kVec2f_GrSLType == type) { | 16 if (kVec2f_GrSLType == type) { |
17 return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; | 17 return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; |
18 } else { | 18 } else { |
19 SkASSERT(kVec3f_GrSLType == type); | 19 SkASSERT(kVec3f_GrSLType == type); |
20 return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj
"; | 20 return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj
"; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 if (memcmp(swizzle, "rgba", 4)) { | 52 if (memcmp(swizzle, "rgba", 4)) { |
53 out->appendf(".%s", swizzle); | 53 out->appendf(".%s", swizzle); |
54 } | 54 } |
55 } | 55 } |
56 } | 56 } |
57 | 57 |
58 GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program) | 58 GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program) |
59 : fProgramBuilder(program) | 59 : fProgramBuilder(program) |
60 , fInputs(GrGLProgramBuilder::kVarsPerBlock) | 60 , fInputs(GrGLProgramBuilder::kVarsPerBlock) |
61 , fOutputs(GrGLProgramBuilder::kVarsPerBlock) | 61 , fOutputs(GrGLProgramBuilder::kVarsPerBlock) |
62 , fFeaturesAddedMask(0) | 62 , fFeaturesAddedMask(0) { |
63 , fCodeIndex(kCode) | |
64 , fFinalized(false) { | |
65 // We push back some dummy pointers which will later become our header | |
66 for (int i = 0; i <= kCode; i++) { | |
67 fShaderStrings.push_back(); | |
68 fCompilerStrings.push_back(NULL); | |
69 fCompilerStringLengths.push_back(0); | |
70 } | |
71 | |
72 this->main() = "void main() {"; | |
73 } | 63 } |
74 | 64 |
75 void GrGLShaderBuilder::declAppend(const GrGLShaderVar& var) { | 65 void GrGLShaderBuilder::declAppend(const GrGLShaderVar& var) { |
76 SkString tempDecl; | 66 SkString tempDecl; |
77 var.appendDecl(fProgramBuilder->ctxInfo(), &tempDecl); | 67 var.appendDecl(fProgramBuilder->ctxInfo(), &tempDecl); |
78 this->codeAppendf("%s;", tempDecl.c_str()); | 68 this->codeAppendf("%s;", tempDecl.c_str()); |
79 } | 69 } |
80 | 70 |
81 void GrGLShaderBuilder::emitFunction(GrSLType returnType, | 71 void GrGLShaderBuilder::emitFunction(GrSLType returnType, |
82 const char* name, | 72 const char* name, |
83 int argCnt, | 73 int argCnt, |
84 const GrGLShaderVar* args, | 74 const GrGLShaderVar* args, |
85 const char* body, | 75 const char* body, |
86 SkString* outName) { | 76 SkString* outName) { |
87 this->functions().append(GrGLSLTypeString(returnType)); | 77 fFunctions.append(GrGLSLTypeString(returnType)); |
88 fProgramBuilder->nameVariable(outName, '\0', name); | 78 fProgramBuilder->nameVariable(outName, '\0', name); |
89 this->functions().appendf(" %s", outName->c_str()); | 79 fFunctions.appendf(" %s", outName->c_str()); |
90 this->functions().append("("); | 80 fFunctions.append("("); |
91 const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo(); | 81 const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo(); |
92 for (int i = 0; i < argCnt; ++i) { | 82 for (int i = 0; i < argCnt; ++i) { |
93 args[i].appendDecl(ctxInfo, &this->functions()); | 83 args[i].appendDecl(ctxInfo, &fFunctions); |
94 if (i < argCnt - 1) { | 84 if (i < argCnt - 1) { |
95 this->functions().append(", "); | 85 fFunctions.append(", "); |
96 } | 86 } |
97 } | 87 } |
98 this->functions().append(") {\n"); | 88 fFunctions.append(") {\n"); |
99 this->functions().append(body); | 89 fFunctions.append(body); |
100 this->functions().append("}\n\n"); | 90 fFunctions.append("}\n\n"); |
101 } | 91 } |
102 | 92 |
103 void GrGLShaderBuilder::appendTextureLookup(SkString* out, | 93 void GrGLShaderBuilder::appendTextureLookup(SkString* out, |
104 const TextureSampler& sampler, | 94 const TextureSampler& sampler, |
105 const char* coordName, | 95 const char* coordName, |
106 GrSLType varyingType) const { | 96 GrSLType varyingType) const { |
107 append_texture_lookup(out, | 97 append_texture_lookup(out, |
108 fProgramBuilder->gpu(), | 98 fProgramBuilder->gpu(), |
109 fProgramBuilder->getUniformCStr(sampler.fSamplerUnifor
m), | 99 fProgramBuilder->getUniformCStr(sampler.fSamplerUnifor
m), |
110 coordName, | 100 coordName, |
111 sampler.configComponentMask(), | 101 sampler.configComponentMask(), |
112 sampler.swizzle(), | 102 sampler.swizzle(), |
113 varyingType); | 103 varyingType); |
114 } | 104 } |
115 | 105 |
116 void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler, | 106 void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler, |
117 const char* coordName, | 107 const char* coordName, |
118 GrSLType varyingType) { | 108 GrSLType varyingType) { |
119 this->appendTextureLookup(&this->code(), sampler, coordName, varyingType); | 109 this->appendTextureLookup(&fCode, sampler, coordName, varyingType); |
120 } | 110 } |
121 | 111 |
122 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, | 112 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, |
123 const TextureSampler& sam
pler, | 113 const TextureSampler& sam
pler, |
124 const char* coordName, | 114 const char* coordName, |
125 GrSLType varyingType) { | 115 GrSLType varyingType) { |
126 SkString lookup; | 116 SkString lookup; |
127 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); | 117 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); |
128 this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); | 118 this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); |
129 } | 119 } |
(...skipping 10 matching lines...) Expand all Loading... |
140 return gAlphaSmear; | 130 return gAlphaSmear; |
141 } | 131 } |
142 } else { | 132 } else { |
143 static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE
, GR_GL_ALPHA }; | 133 static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE
, GR_GL_ALPHA }; |
144 return gStraight; | 134 return gStraight; |
145 } | 135 } |
146 } | 136 } |
147 | 137 |
148 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionNam
e) { | 138 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionNam
e) { |
149 if (!(featureBit & fFeaturesAddedMask)) { | 139 if (!(featureBit & fFeaturesAddedMask)) { |
150 this->extensions().appendf("#extension %s: require\n", extensionName); | 140 fExtensions.appendf("#extension %s: require\n", extensionName); |
151 fFeaturesAddedMask |= featureBit; | 141 fFeaturesAddedMask |= featureBit; |
152 } | 142 } |
153 } | 143 } |
154 | 144 |
155 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { | 145 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { |
156 for (int i = 0; i < vars.count(); ++i) { | 146 for (int i = 0; i < vars.count(); ++i) { |
157 vars[i].appendDecl(fProgramBuilder->ctxInfo(), out); | 147 vars[i].appendDecl(fProgramBuilder->ctxInfo(), out); |
158 out->append(";\n"); | 148 out->append(";\n"); |
159 } | 149 } |
160 } | 150 } |
161 | 151 |
162 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, | 152 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, |
163 const char* coordName, | 153 const char* coordName, |
164 uint32_t configComponentMask, | 154 uint32_t configComponentMask, |
165 const char* swizzle) { | 155 const char* swizzle) { |
166 append_texture_lookup(&this->code(), | 156 append_texture_lookup(&fCode, |
167 fProgramBuilder->gpu(), | 157 fProgramBuilder->gpu(), |
168 samplerName, | 158 samplerName, |
169 coordName, | 159 coordName, |
170 configComponentMask, | 160 configComponentMask, |
171 swizzle, | 161 swizzle, |
172 kVec2f_GrSLType); | 162 kVec2f_GrSLType); |
173 } | 163 } |
174 | |
175 bool | |
176 GrGLShaderBuilder::finalize(GrGLuint programId, GrGLenum type, SkTDArray<GrGLuin
t>* shaderIds) { | |
177 SkASSERT(!fFinalized); | |
178 // append the 'footer' to code | |
179 this->code().append("}"); | |
180 | |
181 for (int i = 0; i <= fCodeIndex; i++) { | |
182 fCompilerStrings[i] = fShaderStrings[i].c_str(); | |
183 fCompilerStringLengths[i] = fShaderStrings[i].size(); | |
184 } | |
185 | |
186 GrGLGpu* gpu = fProgramBuilder->gpu(); | |
187 GrGLuint shaderId = GrGLCompileAndAttachShader(gpu->glContext(), | |
188 programId, | |
189 type, | |
190 fCompilerStrings.begin(), | |
191 fCompilerStringLengths.begin(
), | |
192 fCompilerStrings.count(), | |
193 gpu->stats()); | |
194 | |
195 fFinalized = true; | |
196 | |
197 if (!shaderId) { | |
198 return false; | |
199 } | |
200 | |
201 *shaderIds->append() = shaderId; | |
202 | |
203 return true; | |
204 } | |
OLD | NEW |