Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / builders / GrGLShaderBuilder.cpp
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 "GrGLProgramBuilder.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 }
57
58 GrGLShaderBuilder::GrGLShaderBuilder(GrGLProgramBuilder* program)
59     : fProgramBuilder(program)
60     , fInputs(GrGLProgramBuilder::kVarsPerBlock)
61     , fOutputs(GrGLProgramBuilder::kVarsPerBlock)
62     , fFeaturesAddedMask(0) {
63 }
64
65 void GrGLShaderBuilder::declAppend(const GrGLShaderVar& var) {
66     SkString tempDecl;
67     var.appendDecl(fProgramBuilder->ctxInfo(), &tempDecl);
68     this->codeAppendf("%s;", tempDecl.c_str());
69 }
70
71 void GrGLShaderBuilder::emitFunction(GrSLType returnType,
72                                      const char* name,
73                                      int argCnt,
74                                      const GrGLShaderVar* args,
75                                      const char* body,
76                                      SkString* outName) {
77     fFunctions.append(GrGLSLTypeString(returnType));
78     fProgramBuilder->nameVariable(outName, '\0', name);
79     fFunctions.appendf(" %s", outName->c_str());
80     fFunctions.append("(");
81     const GrGLContextInfo& ctxInfo = fProgramBuilder->gpu()->ctxInfo();
82     for (int i = 0; i < argCnt; ++i) {
83         args[i].appendDecl(ctxInfo, &fFunctions);
84         if (i < argCnt - 1) {
85             fFunctions.append(", ");
86         }
87     }
88     fFunctions.append(") {\n");
89     fFunctions.append(body);
90     fFunctions.append("}\n\n");
91 }
92
93 void GrGLShaderBuilder::appendTextureLookup(SkString* out,
94                                             const TextureSampler& sampler,
95                                             const char* coordName,
96                                             GrSLType varyingType) const {
97     append_texture_lookup(out,
98                           fProgramBuilder->gpu(),
99                           fProgramBuilder->getUniformCStr(sampler.fSamplerUniform),
100                           coordName,
101                           sampler.configComponentMask(),
102                           sampler.swizzle(),
103                           varyingType);
104 }
105
106 void GrGLShaderBuilder::appendTextureLookup(const TextureSampler& sampler,
107                                             const char* coordName,
108                                             GrSLType varyingType) {
109     this->appendTextureLookup(&fCode, sampler, coordName, varyingType);
110 }
111
112 void GrGLShaderBuilder::appendTextureLookupAndModulate(const char* modulation,
113                                                        const TextureSampler& sampler,
114                                                        const char* coordName,
115                                                        GrSLType varyingType) {
116     SkString lookup;
117     this->appendTextureLookup(&lookup, sampler, coordName, varyingType);
118     this->codeAppend((GrGLSLExpr4(modulation) * GrGLSLExpr4(lookup)).c_str());
119 }
120
121
122 const GrGLenum* GrGLShaderBuilder::GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps) {
123     if (caps.textureSwizzleSupport() && GrPixelConfigIsAlphaOnly(config)) {
124         if (caps.textureRedSupport()) {
125             static const GrGLenum gRedSmear[] = { GR_GL_RED, GR_GL_RED, GR_GL_RED, GR_GL_RED };
126             return gRedSmear;
127         } else {
128             static const GrGLenum gAlphaSmear[] = { GR_GL_ALPHA, GR_GL_ALPHA,
129                                                     GR_GL_ALPHA, GR_GL_ALPHA };
130             return gAlphaSmear;
131         }
132     } else {
133         static const GrGLenum gStraight[] = { GR_GL_RED, GR_GL_GREEN, GR_GL_BLUE, GR_GL_ALPHA };
134         return gStraight;
135     }
136 }
137
138 void GrGLShaderBuilder::addFeature(uint32_t featureBit, const char* extensionName) {
139     if (!(featureBit & fFeaturesAddedMask)) {
140         fExtensions.appendf("#extension %s: require\n", extensionName);
141             fFeaturesAddedMask |= featureBit;
142     }
143 }
144
145 void GrGLShaderBuilder::appendDecls(const VarArray& vars, SkString* out) const {
146     for (int i = 0; i < vars.count(); ++i) {
147         vars[i].appendDecl(fProgramBuilder->ctxInfo(), out);
148         out->append(";\n");
149     }
150 }
151
152 void GrGLShaderBuilder::appendTextureLookup(const char* samplerName,
153                                             const char* coordName,
154                                             uint32_t configComponentMask,
155                                             const char* swizzle) {
156     append_texture_lookup(&fCode,
157                           fProgramBuilder->gpu(),
158                           samplerName,
159                           coordName,
160                           configComponentMask,
161                           swizzle,
162                           kVec2f_GrSLType);
163 }