Upstream version 10.39.225.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 "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) {}