Chromium Code Reviews| 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 "gl/builders/GrGLProgramBuilder.h" |
| 10 #include "GrGLShaderStringBuilder.h" | |
| 11 #include "gl/GrGLCaps.h" | |
| 12 #include "gl/GrGLContext.h" | |
| 13 #include "gl/GrGLGpu.h" | |
| 14 #include "glsl/GrGLSLCaps.h" | 10 #include "glsl/GrGLSLCaps.h" |
| 15 #include "glsl/GrGLSLShaderVar.h" | 11 #include "glsl/GrGLSLShaderVar.h" |
| 16 #include "glsl/GrGLSLTextureSampler.h" | 12 #include "glsl/GrGLSLTextureSampler.h" |
| 17 | 13 |
| 18 namespace { | 14 namespace { |
| 19 void append_texture_lookup(SkString* out, | 15 void append_texture_lookup(SkString* out, |
| 20 GrGLGpu* gpu, | 16 const GrGLSLCaps* glslCaps, |
| 21 const char* samplerName, | 17 const char* samplerName, |
| 22 const char* coordName, | 18 const char* coordName, |
| 23 uint32_t configComponentMask, | 19 uint32_t configComponentMask, |
| 24 const char* swizzle, | 20 const char* swizzle, |
| 25 GrSLType varyingType = kVec2f_GrSLType) { | 21 GrSLType varyingType = kVec2f_GrSLType) { |
| 26 SkASSERT(coordName); | 22 SkASSERT(coordName); |
| 27 | 23 |
| 28 out->appendf("%s(%s, %s)", | 24 out->appendf("%s(%s, %s)", |
| 29 GrGLSLTexture2DFunctionName(varyingType, gpu->glslGeneration()) , | 25 GrGLSLTexture2DFunctionName(varyingType, glslCaps->generation() ), |
| 30 samplerName, | 26 samplerName, |
| 31 coordName); | 27 coordName); |
| 32 | 28 |
| 33 char mangledSwizzle[5]; | 29 char mangledSwizzle[5]; |
| 34 | 30 |
| 35 // The swizzling occurs using texture params instead of shader-mangling if A RB_texture_swizzle | 31 // The swizzling occurs using texture params instead of shader-mangling if A RB_texture_swizzle |
| 36 // is available. | 32 // is available. |
| 37 if (!gpu->glCaps().textureSwizzleSupport() && | 33 if (!glslCaps->textureSwizzleSupport() && |
| 38 (kA_GrColorComponentFlag == configComponentMask)) { | 34 (kA_GrColorComponentFlag == configComponentMask)) { |
| 39 char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a'; | 35 char alphaChar = glslCaps->textureRedSupport() ? 'r' : 'a'; |
| 40 int i; | 36 int i; |
| 41 for (i = 0; '\0' != swizzle[i]; ++i) { | 37 for (i = 0; '\0' != swizzle[i]; ++i) { |
| 42 mangledSwizzle[i] = alphaChar; | 38 mangledSwizzle[i] = alphaChar; |
| 43 } | 39 } |
| 44 mangledSwizzle[i] ='\0'; | 40 mangledSwizzle[i] ='\0'; |
| 45 swizzle = mangledSwizzle; | 41 swizzle = mangledSwizzle; |
| 46 } | 42 } |
| 47 // For shader prettiness we omit the swizzle rather than appending ".rgba". | 43 // For shader prettiness we omit the swizzle rather than appending ".rgba". |
| 48 if (memcmp(swizzle, "rgba", 4)) { | 44 if (memcmp(swizzle, "rgba", 4)) { |
| 49 out->appendf(".%s", swizzle); | 45 out->appendf(".%s", swizzle); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 93 this->functions().append(") {\n"); | 89 this->functions().append(") {\n"); |
| 94 this->functions().append(body); | 90 this->functions().append(body); |
| 95 this->functions().append("}\n\n"); | 91 this->functions().append("}\n\n"); |
| 96 } | 92 } |
| 97 | 93 |
| 98 void GrGLShaderBuilder::appendTextureLookup(SkString* out, | 94 void GrGLShaderBuilder::appendTextureLookup(SkString* out, |
| 99 const GrGLSLTextureSampler& sampler, | 95 const GrGLSLTextureSampler& sampler, |
| 100 const char* coordName, | 96 const char* coordName, |
| 101 GrSLType varyingType) const { | 97 GrSLType varyingType) const { |
| 102 append_texture_lookup(out, | 98 append_texture_lookup(out, |
| 103 fProgramBuilder->gpu(), | 99 fProgramBuilder->glslCaps(), |
| 104 fProgramBuilder->getUniformCStr(sampler.fSamplerUnifor m), | 100 fProgramBuilder->getUniformCStr(sampler.fSamplerUnifor m), |
| 105 coordName, | 101 coordName, |
| 106 sampler.configComponentMask(), | 102 sampler.configComponentMask(), |
| 107 sampler.swizzle(), | 103 sampler.swizzle(), |
| 108 varyingType); | 104 varyingType); |
| 109 } | 105 } |
| 110 | 106 |
| 111 void GrGLShaderBuilder::appendTextureLookup(const GrGLSLTextureSampler& sampler, | 107 void GrGLShaderBuilder::appendTextureLookup(const GrGLSLTextureSampler& sampler, |
| 112 const char* coordName, | 108 const char* coordName, |
| 113 GrSLType varyingType) { | 109 GrSLType varyingType) { |
| 114 this->appendTextureLookup(&this->code(), sampler, coordName, varyingType); | 110 this->appendTextureLookup(&this->code(), sampler, coordName, varyingType); |
| 115 } | 111 } |
| 116 | 112 |
| 117 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, | 113 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, |
| 118 const GrGLSLTextureSample r& sampler, | 114 const GrGLSLTextureSample r& sampler, |
| 119 const char* coordName, | 115 const char* coordName, |
| 120 GrSLType varyingType) { | 116 GrSLType varyingType) { |
| 121 SkString lookup; | 117 SkString lookup; |
| 122 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); | 118 this->appendTextureLookup(&lookup, sampler, coordName, varyingType); |
| 123 this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); | 119 this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); |
| 124 } | 120 } |
| 125 | 121 |
| 126 | |
| 127 const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, cons t GrGLCaps& caps) { | |
| 128 if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) { | |
| 129 if (caps.textureRedSupport()) { | |
| 130 static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RE D, GR_GL_RED }; | |
| 131 return gRedSmear; | |
| 132 } else { | |
| 133 static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA, | |
| 134 GR_GL_ALPHA, GR_GL_ALPHA }; | |
| 135 return gAlphaSmear; | |
| 136 } | |
| 137 } else { | |
| 138 static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE , GR_GL_ALPHA }; | |
| 139 return gStraight; | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionNam e) { | 122 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionNam e) { |
| 144 if (!(featureBit & fFeaturesAddedMask)) { | 123 if (!(featureBit & fFeaturesAddedMask)) { |
| 145 this->extensions().appendf("#extension %s: require\n", extensionName); | 124 this->extensions().appendf("#extension %s: require\n", extensionName); |
| 146 fFeaturesAddedMask |= featureBit; | 125 fFeaturesAddedMask |= featureBit; |
| 147 } | 126 } |
| 148 } | 127 } |
| 149 | 128 |
| 150 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { | 129 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const { |
| 151 for (int i = 0; i < vars.count(); ++i) { | 130 for (int i = 0; i < vars.count(); ++i) { |
| 152 vars[i].appendDecl(fProgramBuilder->glslCaps(), out); | 131 vars[i].appendDecl(fProgramBuilder->glslCaps(), out); |
| 153 out->append(";\n"); | 132 out->append(";\n"); |
| 154 } | 133 } |
| 155 } | 134 } |
| 156 | 135 |
| 157 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, | 136 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, |
| 158 const char* coordName, | 137 const char* coordName, |
| 159 uint32_t configComponentMask, | 138 uint32_t configComponentMask, |
| 160 const char* swizzle) { | 139 const char* swizzle) { |
| 161 append_texture_lookup(&this->code(), | 140 append_texture_lookup(&this->code(), |
| 162 fProgramBuilder->gpu(), | 141 fProgramBuilder->glslCaps(), |
| 163 samplerName, | 142 samplerName, |
| 164 coordName, | 143 coordName, |
| 165 configComponentMask, | 144 configComponentMask, |
| 166 swizzle, | 145 swizzle, |
| 167 kVec2f_GrSLType); | 146 kVec2f_GrSLType); |
| 168 } | 147 } |
| 169 | 148 |
| 170 void GrGLShaderBuilder::addLayoutQualifier(const char* param, InterfaceQualifier interface) { | 149 void GrGLShaderBuilder::addLayoutQualifier(const char* param, InterfaceQualifier interface) { |
| 171 SkASSERT(fProgramBuilder->gpu()->glslGeneration() >= k330_GrGLSLGeneration | | | 150 SkASSERT(fProgramBuilder->glslCaps()->generation() >= k330_GrGLSLGeneration || |
| 172 fProgramBuilder->gpu()->glCaps().glslCaps()->mustEnableAdvBlendEqs( )); | 151 fProgramBuilder->glslCaps()->mustEnableAdvBlendEqs()); |
| 173 fLayoutParams[interface].push_back() = param; | 152 fLayoutParams[interface].push_back() = param; |
| 174 } | 153 } |
| 175 | 154 |
| 176 void GrGLShaderBuilder::compileAndAppendLayoutQualifiers() { | 155 void GrGLShaderBuilder::compileAndAppendLayoutQualifiers() { |
| 177 static const char* interfaceQualifierNames[] = { | 156 static const char* interfaceQualifierNames[] = { |
| 178 "out" | 157 "out" |
| 179 }; | 158 }; |
| 180 | 159 |
| 181 for (int interface = 0; interface <= kLastInterfaceQualifier; ++interface) { | 160 for (int interface = 0; interface <= kLastInterfaceQualifier; ++interface) { |
| 182 const SkTArray<SkString>& params = fLayoutParams[interface]; | 161 const SkTArray<SkString>& params = fLayoutParams[interface]; |
| 183 if (params.empty()) { | 162 if (params.empty()) { |
| 184 continue; | 163 continue; |
| 185 } | 164 } |
| 186 this->layoutQualifiers().appendf("layout(%s", params[0].c_str()); | 165 this->layoutQualifiers().appendf("layout(%s", params[0].c_str()); |
| 187 for (int i = 1; i < params.count(); ++i) { | 166 for (int i = 1; i < params.count(); ++i) { |
| 188 this->layoutQualifiers().appendf(", %s", params[i].c_str()); | 167 this->layoutQualifiers().appendf(", %s", params[i].c_str()); |
| 189 } | 168 } |
| 190 this->layoutQualifiers().appendf(") %s;\n", interfaceQualifierNames[inte rface]); | 169 this->layoutQualifiers().appendf(") %s;\n", interfaceQualifierNames[inte rface]); |
| 191 } | 170 } |
| 192 | 171 |
| 193 GR_STATIC_ASSERT(0 == GrGLShaderBuilder::kOut_InterfaceQualifier); | 172 GR_STATIC_ASSERT(0 == GrGLShaderBuilder::kOut_InterfaceQualifier); |
| 194 GR_STATIC_ASSERT(SK_ARRAY_COUNT(interfaceQualifierNames) == kLastInterfaceQu alifier + 1); | 173 GR_STATIC_ASSERT(SK_ARRAY_COUNT(interfaceQualifierNames) == kLastInterfaceQu alifier + 1); |
| 195 } | 174 } |
| 196 | 175 |
| 197 bool | 176 void GrGLShaderBuilder::finalize(uint32_t visibility) { |
| 198 GrGLShaderBuilder::finalize(GrGLuint programId, GrGLenum type, SkTDArray<GrGLuin t>* shaderIds) { | |
| 199 SkASSERT(!fFinalized); | 177 SkASSERT(!fFinalized); |
| 178 this->versionDecl() = fProgramBuilder->glslCaps()->versionDeclString(); | |
| 179 this->compileAndAppendLayoutQualifiers(); | |
|
robertphillips
2015/10/30 16:39:46
\n somewhere ?
egdaniel
2015/10/30 18:24:20
Done.
| |
| 180 fProgramBuilder->appendUniformDecls((GrGLProgramBuilder::ShaderVisibility) v isibility, &this->uniforms()); | |
| 181 this->appendDecls(fInputs, &this->inputs()); | |
|
robertphillips
2015/10/30 16:39:46
can this be on one line ?
egdaniel
2015/10/30 18:24:20
sadly no, 101 chars
| |
| 182 SkASSERT(k110_GrGLSLGeneration != fProgramBuilder->glslCaps()->generation() || | |
| 183 fOutputs.empty()); | |
| 184 this->appendDecls(fOutputs, &this->outputs()); | |
| 185 this->onFinalize(); | |
| 200 // append the 'footer' to code | 186 // append the 'footer' to code |
| 201 this->code().append("}"); | 187 this->code().append("}"); |
| 202 | 188 |
| 203 for (int i = 0; i <= fCodeIndex; i++) { | 189 for (int i = 0; i <= fCodeIndex; i++) { |
| 204 fCompilerStrings[i] = fShaderStrings[i].c_str(); | 190 fCompilerStrings[i] = fShaderStrings[i].c_str(); |
| 205 fCompilerStringLengths[i] = (int)fShaderStrings[i].size(); | 191 fCompilerStringLengths[i] = (int)fShaderStrings[i].size(); |
| 206 } | 192 } |
| 207 | 193 |
| 208 GrGLGpu* gpu = fProgramBuilder->gpu(); | 194 fFinalized = true; |
| 209 GrGLuint shaderId = GrGLCompileAndAttachShader(gpu->glContext(), | 195 } |
| 210 programId, | |
| 211 type, | |
| 212 fCompilerStrings.begin(), | |
| 213 fCompilerStringLengths.begin( ), | |
| 214 fCompilerStrings.count(), | |
| 215 gpu->stats()); | |
| 216 | 196 |
| 217 fFinalized = true; | |
| 218 | |
| 219 if (!shaderId) { | |
| 220 return false; | |
| 221 } | |
| 222 | |
| 223 *shaderIds->append() = shaderId; | |
| 224 | |
| 225 return true; | |
| 226 } | |
| OLD | NEW |