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 "GrGLProgramBuilder.h" | 10 #include "GrGLShaderStringBuilder.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() {"; |
63 } | 73 } |
64 | 74 |
65 void GrGLShaderBuilder::declAppend(const GrGLShaderVar& var) { | 75 void GrGLShaderBuilder::declAppend(const GrGLShaderVar& var) { |
66 SkString tempDecl; | 76 SkString tempDecl; |
67 var.appendDecl(fProgramBuilder->ctxInfo(), &tempDecl); | 77 var.appendDecl(fProgramBuilder->ctxInfo(), &tempDecl); |
68 this->codeAppendf("%s;", tempDecl.c_str()); | 78 this->codeAppendf("%s;", tempDecl.c_str()); |
69 } | 79 } |
70 | 80 |
71 void GrGLShaderBuilder::emitFunction(GrSLType returnType, | 81 void GrGLShaderBuilder::emitFunction(GrSLType returnType, |
72 const char* name, | 82 const char* name, |
73 int argCnt, | 83 int argCnt, |
74 const GrGLShaderVar* args, | 84 const GrGLShaderVar* args, |
75 const char* body, | 85 const char* body, |
76 SkString* outName) { | 86 SkString* outName) { |
77 fFunctions.append(GrGLSLTypeString(returnType)); | 87 this->functions().append(GrGLSLTypeString(returnType)); |
78 fProgramBuilder->nameVariable(outName, '\0', name); | 88 fProgramBuilder->nameVariable(outName, '\0', name); |
79 fFunctions.appendf(" %s", outName->c_str()); | 89 this->functions().appendf(" %s", outName->c_str()); |
80 fFunctions.append("("); | 90 this->functions().append("("); |
81 const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo(); | 91 const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo(); |
82 for (int i = 0; i < argCnt; ++i) { | 92 for (int i = 0; i < argCnt; ++i) { |
83 args[i].appendDecl(ctxInfo, &fFunctions); | 93 args[i].appendDecl(ctxInfo, &this->functions()); |
84 if (i < argCnt - 1) { | 94 if (i < argCnt - 1) { |
85 fFunctions.append(", "); | 95 this->functions().append(", "); |
86 } | 96 } |
87 } | 97 } |
88 fFunctions.append(") {\n"); | 98 this->functions().append(") {\n"); |
89 fFunctions.append(body); | 99 this->functions().append(body); |
90 fFunctions.append("}\n\n"); | 100 this->functions().append("}\n\n"); |
91 } | 101 } |
92 | 102 |
93 void GrGLShaderBuilder::appendTextureLookup(SkString* out, | 103 void GrGLShaderBuilder::appendTextureLookup(SkString* out, |
94 const TextureSampler& sampler, | 104 const TextureSampler& sampler, |
95 const char* coordName, | 105 const char* coordName, |
96 GrSLType varyingType) const { | 106 GrSLType varyingType) const { |
97 append_texture_lookup(out, | 107 append_texture_lookup(out, |
98 fProgramBuilder->gpu(), | 108 fProgramBuilder->gpu(), |
99 fProgramBuilder->getUniformCStr(sampler.fSamplerUnifor
m), | 109 fProgramBuilder->getUniformCStr(sampler.fSamplerUnifor
m), |
100 coordName, | 110 coordName, |
101 sampler.configComponentMask(), | 111 sampler.configComponentMask(), |
102 sampler.swizzle(), | 112 sampler.swizzle(), |
103 varyingType); | 113 varyingType); |
104 } | 114 } |
105 | 115 |
106 void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler, | 116 void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler, |
107 const char* coordName, | 117 const char* coordName, |
108 GrSLType varyingType) { | 118 GrSLType varyingType) { |
109 this->appendTextureLookup(&fCode, sampler, coordName, varyingType); | 119 this->appendTextureLookup(&this->code(), sampler, coordName, varyingType); |
110 } | 120 } |
111 | 121 |
112 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, | 122 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, |
113 const TextureSampler& sam
pler, | 123 const TextureSampler& sam
pler, |
114 const char* coordName, | 124 const char* coordName, |
115 GrSLType varyingType) { | 125 GrSLType varyingType) { |
116 SkString lookup; | 126 SkString lookup; |
117 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); | 127 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); |
118 this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); | 128 this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); |
119 } | 129 } |
(...skipping 10 matching lines...) Expand all Loading... |
130 return gAlphaSmear; | 140 return gAlphaSmear; |
131 } | 141 } |
132 } else { | 142 } else { |
133 static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE
, GR_GL_ALPHA }; | 143 static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE
, GR_GL_ALPHA }; |
134 return gStraight; | 144 return gStraight; |
135 } | 145 } |
136 } | 146 } |
137 | 147 |
138 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionNam
e) { | 148 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionNam
e) { |
139 if (!(featureBit & fFeaturesAddedMask)) { | 149 if (!(featureBit & fFeaturesAddedMask)) { |
140 fExtensions.appendf("#extension %s: require\n", extensionName); | 150 this->extensions().appendf("#extension %s: require\n", extensionName); |
141 fFeaturesAddedMask |= featureBit; | 151 fFeaturesAddedMask |= featureBit; |
142 } | 152 } |
143 } | 153 } |
144 | 154 |
145 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { | 155 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { |
146 for (int i = 0; i < vars.count(); ++i) { | 156 for (int i = 0; i < vars.count(); ++i) { |
147 vars[i].appendDecl(fProgramBuilder->ctxInfo(), out); | 157 vars[i].appendDecl(fProgramBuilder->ctxInfo(), out); |
148 out->append(";\n"); | 158 out->append(";\n"); |
149 } | 159 } |
150 } | 160 } |
151 | 161 |
152 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, | 162 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, |
153 const char* coordName, | 163 const char* coordName, |
154 uint32_t configComponentMask, | 164 uint32_t configComponentMask, |
155 const char* swizzle) { | 165 const char* swizzle) { |
156 append_texture_lookup(&fCode, | 166 append_texture_lookup(&this->code(), |
157 fProgramBuilder->gpu(), | 167 fProgramBuilder->gpu(), |
158 samplerName, | 168 samplerName, |
159 coordName, | 169 coordName, |
160 configComponentMask, | 170 configComponentMask, |
161 swizzle, | 171 swizzle, |
162 kVec2f_GrSLType); | 172 kVec2f_GrSLType); |
163 } | 173 } |
| 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] = (int)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 |