diff options
Diffstat (limited to 'src/gpu/gl/builders/GrGLShaderBuilder.cpp')
-rw-r--r-- | src/gpu/gl/builders/GrGLShaderBuilder.cpp | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.cpp b/src/gpu/gl/builders/GrGLShaderBuilder.cpp new file mode 100644 index 0000000000..4dea142632 --- /dev/null +++ b/src/gpu/gl/builders/GrGLShaderBuilder.cpp @@ -0,0 +1,155 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrGLShaderBuilder.h" +#include "GrGLProgramBuilder.h" +#include "../GrGpuGL.h" +#include "../GrGLShaderVar.h" + +namespace { +inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) { + if (kVec2f_GrSLType == type) { + return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D"; + } else { + SkASSERT(kVec3f_GrSLType == type); + return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj"; + } +} +void append_texture_lookup(SkString* out, + GrGpuGL* gpu, + const char* samplerName, + const char* coordName, + uint32_t configComponentMask, + const char* swizzle, + GrSLType varyingType = kVec2f_GrSLType) { + SkASSERT(NULL != coordName); + + out->appendf("%s(%s, %s)", + sample_function_name(varyingType, gpu->glslGeneration()), + samplerName, + coordName); + + char mangledSwizzle[5]; + + // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle + // is available. + if (!gpu->glCaps().textureSwizzleSupport() && + (kA_GrColorComponentFlag == configComponentMask)) { + char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a'; + int i; + for (i = 0; '\0' != swizzle[i]; ++i) { + mangledSwizzle[i] = alphaChar; + } + mangledSwizzle[i] ='\0'; + swizzle = mangledSwizzle; + } + // For shader prettiness we omit the swizzle rather than appending ".rgba". + if (memcmp(swizzle, "rgba", 4)) { + out->appendf(".%s", swizzle); + } +} +static const int kVarsPerBlock = 8; +} + +GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program) + : fProgramBuilder(program) + , fInputs(kVarsPerBlock) + , fOutputs(kVarsPerBlock) + , fFeaturesAddedMask(0) { +} + +void GrGLShaderBuilder::emitFunction(GrSLType returnType, + const char* name, + int argCnt, + const GrGLShaderVar* args, + const char* body, + SkString* outName) { + fFunctions.append(GrGLSLTypeString(returnType)); + fProgramBuilder->nameVariable(outName, '\0', name); + fFunctions.appendf(" %s", outName->c_str()); + fFunctions.append("("); + const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo(); + for (int i = 0; i < argCnt; ++i) { + args[i].appendDecl(ctxInfo, &fFunctions); + if (i < argCnt - 1) { + fFunctions.append(", "); + } + } + fFunctions.append(") {\n"); + fFunctions.append(body); + fFunctions.append("}\n\n"); +} + +void GrGLShaderBuilder::appendTextureLookup(SkString* out, + const TextureSampler& sampler, + const char* coordName, + GrSLType varyingType) const { + append_texture_lookup(out, + fProgramBuilder->gpu(), + fProgramBuilder->getUniformCStr(sampler.samplerUniform()), + coordName, + sampler.configComponentMask(), + sampler.swizzle(), + varyingType); +} + +void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler, + const char* coordName, + GrSLType varyingType) { + this->appendTextureLookup(&fCode, sampler, coordName, varyingType); +} + +void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation, + const TextureSampler& sampler, + const char* coordName, + GrSLType varyingType) { + SkString lookup; + this->appendTextureLookup(&lookup, sampler, coordName, varyingType); + this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str()); +} + + +const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) { + if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) { + if (caps.textureRedSupport()) { + static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED }; + return gRedSmear; + } else { + static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA, + GR_GL_ALPHA, GR_GL_ALPHA }; + return gAlphaSmear; + } + } else { + static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA }; + return gStraight; + } +} + +void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) { + if (!(featureBit & fFeaturesAddedMask)) { + fExtensions.appendf("#extension %s: require\n", extensionName); + fFeaturesAddedMask |= featureBit; + } +} + +void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, + const char* coordName, + uint32_t configComponentMask, + const char* swizzle) { + append_texture_lookup(&fCode, + fProgramBuilder->gpu(), + samplerName, + coordName, + configComponentMask, + swizzle, + kVec2f_GrSLType); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGLFullProgramBuilder* program) + : INHERITED(program) + , fFullProgramBuilder(program) {} |