Home | History | Annotate | Download | only in builders
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "GrGLShaderBuilder.h"
      9 #include "GrGLFullProgramBuilder.h"
     10 #include "GrGLProgramBuilder.h"
     11 #include "../GrGpuGL.h"
     12 #include "../GrGLShaderVar.h"
     13 
     14 namespace {
     15 inline const char* sample_function_name(GrSLType type, GrGLSLGeneration glslGen) {
     16     if (kVec2f_GrSLType == type) {
     17         return glslGen >= k130_GrGLSLGeneration ? "texture" : "texture2D";
     18     } else {
     19         SkASSERT(kVec3f_GrSLType == type);
     20         return glslGen >= k130_GrGLSLGeneration ? "textureProj" : "texture2DProj";
     21     }
     22 }
     23 void append_texture_lookup(SkString* out,
     24                            GrGpuGL* gpu,
     25                            const char* samplerName,
     26                            const char* coordName,
     27                            uint32_t configComponentMask,
     28                            const char* swizzle,
     29                            GrSLType varyingType = kVec2f_GrSLType) {
     30     SkASSERT(coordName);
     31 
     32     out->appendf("%s(%s, %s)",
     33                  sample_function_name(varyingType, gpu->glslGeneration()),
     34                  samplerName,
     35                  coordName);
     36 
     37     char mangledSwizzle[5];
     38 
     39     // The swizzling occurs using texture params instead of shader-mangling if ARB_texture_swizzle
     40     // is available.
     41     if (!gpu->glCaps().textureSwizzleSupport() &&
     42         (kA_GrColorComponentFlag == configComponentMask)) {
     43         char alphaChar = gpu->glCaps().textureRedSupport() ? 'r' : 'a';
     44         int i;
     45         for (i = 0; '\0' != swizzle[i]; ++i) {
     46             mangledSwizzle[i] = alphaChar;
     47         }
     48         mangledSwizzle[i] ='\0';
     49         swizzle = mangledSwizzle;
     50     }
     51     // For shader prettiness we omit the swizzle rather than appending ".rgba".
     52     if (memcmp(swizzle, "rgba", 4)) {
     53         out->appendf(".%s", swizzle);
     54     }
     55 }
     56 static const int kVarsPerBlock = 8;
     57 }
     58 
     59 GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program)
     60     : fProgramBuilder(program)
     61     , fInputs(kVarsPerBlock)
     62     , fOutputs(kVarsPerBlock)
     63     , fFeaturesAddedMask(0) {
     64 }
     65 
     66 void GrGLShaderBuilder::declAppend(const GrGLShaderVar& var) {
     67     SkString tempDecl;
     68     var.appendDecl(fProgramBuilder->ctxInfo(), &tempDecl);
     69     this->codeAppendf("%s;", tempDecl.c_str());
     70 }
     71 
     72 void GrGLShaderBuilder::emitFunction(GrSLType returnType,
     73                                      const char* name,
     74                                      int argCnt,
     75                                      const GrGLShaderVar* args,
     76                                      const char* body,
     77                                      SkString* outName) {
     78     fFunctions.append(GrGLSLTypeString(returnType));
     79     fProgramBuilder->nameVariable(outName, '\0', name);
     80     fFunctions.appendf(" %s", outName->c_str());
     81     fFunctions.append("(");
     82     const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo();
     83     for (int i = 0; i < argCnt; ++i) {
     84         args[i].appendDecl(ctxInfo, &fFunctions);
     85         if (i < argCnt - 1) {
     86             fFunctions.append(", ");
     87         }
     88     }
     89     fFunctions.append(") {\n");
     90     fFunctions.append(body);
     91     fFunctions.append("}\n\n");
     92 }
     93 
     94 void GrGLShaderBuilder::appendTextureLookup(SkString* out,
     95                                             const TextureSampler& sampler,
     96                                             const char* coordName,
     97                                             GrSLType varyingType) const {
     98     append_texture_lookup(out,
     99                           fProgramBuilder->gpu(),
    100                           fProgramBuilder->getUniformCStr(sampler.fSamplerUniform),
    101                           coordName,
    102                           sampler.configComponentMask(),
    103                           sampler.swizzle(),
    104                           varyingType);
    105 }
    106 
    107 void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler,
    108                                             const char* coordName,
    109                                             GrSLType varyingType) {
    110     this->appendTextureLookup(&fCode, sampler, coordName, varyingType);
    111 }
    112 
    113 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation,
    114                                                        const TextureSampler& sampler,
    115                                                        const char* coordName,
    116                                                        GrSLType varyingType) {
    117     SkString lookup;
    118     this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
    119     this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str());
    120 }
    121 
    122 
    123 const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
    124     if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
    125         if (caps.textureRedSupport()) {
    126             static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED };
    127             return gRedSmear;
    128         } else {
    129             static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
    130                                                     GR_GL_ALPHA, GR_GL_ALPHA };
    131             return gAlphaSmear;
    132         }
    133     } else {
    134         static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA };
    135         return gStraight;
    136     }
    137 }
    138 
    139 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) {
    140     if (!(featureBit & fFeaturesAddedMask)) {
    141         fExtensions.appendf("#extension %s: require\n", extensionName);
    142             fFeaturesAddedMask |= featureBit;
    143     }
    144 }
    145 
    146 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName,
    147                                             const char* coordName,
    148                                             uint32_t configComponentMask,
    149                                             const char* swizzle) {
    150     append_texture_lookup(&fCode,
    151                           fProgramBuilder->gpu(),
    152                           samplerName,
    153                           coordName,
    154                           configComponentMask,
    155                           swizzle,
    156                           kVec2f_GrSLType);
    157 }
    158 
    159 ///////////////////////////////////////////////////////////////////////////////////////////////////
    160 GrGLFullShaderBuilder::GrGLFullShaderBuilder(GrGLFullProgramBuilder* program)
    161     : INHERITED(program)
    162     , fFullProgramBuilder(program) {}
    163