| 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 |