Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / builders / GrGLProgramBuilder.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 "GrGLProgramBuilder.h"
9 #include "gl/GrGLProgram.h"
10 #include "gl/GrGLSLPrettyPrint.h"
11 #include "gl/GrGLUniformHandle.h"
12 #include "../GrGpuGL.h"
13 #include "GrCoordTransform.h"
14 #include "GrGLLegacyNvprProgramBuilder.h"
15 #include "GrGLNvprProgramBuilder.h"
16 #include "GrGLProgramBuilder.h"
17 #include "GrTexture.h"
18 #include "SkRTConf.h"
19 #include "SkTraceEvent.h"
20
21 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
22 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
23
24 // ES2 FS only guarantees mediump and lowp support
25 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar::kMedium_Precision;
26
27 //////////////////////////////////////////////////////////////////////////////
28
29 const int GrGLProgramBuilder::kVarsPerBlock = 8;
30
31 GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState,
32                                                GrGpu::DrawType drawType,
33                                                GrGpuGL* gpu) {
34     // create a builder.  This will be handed off to effects so they can use it to add
35     // uniforms, varyings, textures, etc
36     SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(optState,
37                                                                    drawType,
38                                                                    optState.hasGeometryProcessor(),
39                                                                    gpu));
40
41     GrGLProgramBuilder* pb = builder.get();
42     const GrGLProgramDescBuilder::GLKeyHeader& header = GrGLProgramDescBuilder::GetHeader(pb->desc());
43
44     // emit code to read the dst copy texture, if necessary
45     if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey
46             && !gpu->glCaps().fbFetchSupport()) {
47         pb->fFS.emitCodeToReadDstTexture();
48     }
49
50     // get the initial color and coverage to feed into the first effect in each effect chain
51     GrGLSLExpr4 inputColor;
52     GrGLSLExpr1 inputCoverage;
53     pb->setupUniformColorAndCoverageIfNeeded(&inputColor,  &inputCoverage);
54
55     // if we have a vertex shader(we don't only if we are using NVPR or NVPR ES), then we may have
56     // to setup a few more things like builtin vertex attributes
57     bool hasVertexShader = !(header.fUseNvpr &&
58                              gpu->glPathRendering()->texturingMode() ==
59                              GrGLPathRendering::FixedFunction_TexturingMode);
60     if (hasVertexShader) {
61         pb->fVS.setupLocalCoords();
62         pb->fVS.transformGLToSkiaCoords();
63         if (header.fEmitsPointSize) {
64             pb->fVS.codeAppend("gl_PointSize = 1.0;");
65         }
66         if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) {
67             pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor);
68         }
69         if (GrProgramDesc::kAttribute_ColorInput == header.fCoverageInput) {
70             pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage);
71         }
72     }
73
74     // TODO: Once all stages can handle taking a float or vec4 and correctly handling them we can
75     // remove this cast to a vec4.
76     GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage);
77
78     pb->emitAndInstallProcs(optState, &inputColor, &inputCoverageVec4);
79
80     if (hasVertexShader) {
81         pb->fVS.transformSkiaToGLCoords();
82     }
83
84     // write the secondary color output if necessary
85     if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType) {
86         pb->fFS.enableSecondaryOutput(inputColor, inputCoverageVec4);
87     }
88
89     pb->fFS.combineColorAndCoverage(inputColor, inputCoverageVec4);
90
91     return pb->finalize();
92 }
93
94 GrGLProgramBuilder*
95 GrGLProgramBuilder::CreateProgramBuilder(const GrOptDrawState& optState,
96                                          GrGpu::DrawType drawType,
97                                          bool hasGeometryProcessor,
98                                          GrGpuGL* gpu) {
99     const GrProgramDesc& desc = optState.programDesc();
100     if (GrGLProgramDescBuilder::GetHeader(desc).fUseNvpr) {
101         SkASSERT(gpu->glCaps().pathRenderingSupport());
102         SkASSERT(GrProgramDesc::kAttribute_ColorInput != desc.header().fColorInput);
103         SkASSERT(GrProgramDesc::kAttribute_ColorInput != desc.header().fCoverageInput);
104         SkASSERT(!hasGeometryProcessor);
105         if (gpu->glPathRendering()->texturingMode() ==
106             GrGLPathRendering::FixedFunction_TexturingMode) {
107             return SkNEW_ARGS(GrGLLegacyNvprProgramBuilder, (gpu, optState));
108         } else {
109             return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, optState));
110         }
111     } else {
112         return SkNEW_ARGS(GrGLProgramBuilder, (gpu, optState));
113     }
114 }
115
116 /////////////////////////////////////////////////////////////////////////////
117
118 GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrOptDrawState& optState)
119     : fVS(this)
120     , fGS(this)
121     , fFS(this, optState.programDesc().header().fFragPosKey)
122     , fOutOfStage(true)
123     , fStageIndex(-1)
124     , fGeometryProcessor(NULL)
125     , fOptState(optState)
126     , fDesc(optState.programDesc())
127     , fGpu(gpu)
128     , fUniforms(kVarsPerBlock) {
129 }
130
131 void GrGLProgramBuilder::addVarying(const char* name,
132                                     GrGLVarying* varying,
133                                     GrGLShaderVar::Precision fsPrecision) {
134     SkASSERT(varying);
135     if (varying->vsVarying()) {
136         fVS.addVarying(name, varying);
137     }
138     if (fOptState.hasGeometryProcessor() && fOptState.getGeometryProcessor()->willUseGeoShader()) {
139         fGS.addVarying(name, varying);
140     }
141     if (varying->fsVarying()) {
142         fFS.addVarying(varying, fsPrecision);
143     }
144 }
145
146 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
147     if ('\0' == prefix) {
148         *out = name;
149     } else {
150         out->printf("%c%s", prefix, name);
151     }
152     if (!fOutOfStage) {
153         if (out->endsWith('_')) {
154             // Names containing "__" are reserved.
155             out->append("x");
156         }
157         out->appendf("_Stage%d", fStageIndex);
158     }
159 }
160
161 GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(uint32_t visibility,
162                                                                           GrSLType type,
163                                                                           const char* name,
164                                                                           int count,
165                                                                           const char** outName) {
166     SkASSERT(name && strlen(name));
167     SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFragment_Visibility);
168     SkASSERT(0 == (~kVisibilityMask & visibility));
169     SkASSERT(0 != visibility);
170
171     UniformInfo& uni = fUniforms.push_back();
172     uni.fVariable.setType(type);
173     uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
174     this->nameVariable(uni.fVariable.accessName(), 'u', name);
175     uni.fVariable.setArrayCount(count);
176     uni.fVisibility = visibility;
177
178     // If it is visible in both the VS and FS, the precision must match.
179     // We declare a default FS precision, but not a default VS. So set the var
180     // to use the default FS precision.
181     if ((kVertex_Visibility | kFragment_Visibility) == visibility) {
182         // the fragment and vertex precisions must match
183         uni.fVariable.setPrecision(kDefaultFragmentPrecision);
184     }
185
186     if (outName) {
187         *outName = uni.fVariable.c_str();
188     }
189     return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1);
190 }
191
192 void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility,
193                                             SkString* out) const {
194     for (int i = 0; i < fUniforms.count(); ++i) {
195         if (fUniforms[i].fVisibility & visibility) {
196             fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out);
197             out->append(";\n");
198         }
199     }
200 }
201
202 const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
203     return fGpu->ctxInfo();
204 }
205
206 void GrGLProgramBuilder::setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor,
207                                                               GrGLSLExpr1* inputCoverage) {
208     const GrProgramDesc::KeyHeader& header = this->header();
209     if (GrProgramDesc::kUniform_ColorInput == header.fColorInput) {
210         const char* name;
211         fUniformHandles.fColorUni =
212             this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
213                              kVec4f_GrSLType,
214                              "Color",
215                              &name);
216         *inputColor = GrGLSLExpr4(name);
217     } else if (GrProgramDesc::kAllOnes_ColorInput == header.fColorInput) {
218         *inputColor = GrGLSLExpr4(1);
219     }
220     if (GrProgramDesc::kUniform_ColorInput == header.fCoverageInput) {
221         const char* name;
222         fUniformHandles.fCoverageUni =
223             this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
224                              kFloat_GrSLType,
225                              "Coverage",
226                              &name);
227         *inputCoverage = GrGLSLExpr1(name);
228     } else if (GrProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) {
229         *inputCoverage = GrGLSLExpr1(1);
230     }
231 }
232
233 void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState,
234                                              GrGLSLExpr4* inputColor,
235                                              GrGLSLExpr4* inputCoverage) {
236     fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
237     int numProcs = optState.numFragmentStages();
238     this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor);
239     if (optState.hasGeometryProcessor()) {
240         const GrGeometryProcessor& gp = *optState.getGeometryProcessor();
241         fVS.emitAttributes(gp);
242         ProcKeyProvider keyProvider(&fDesc,
243                                     ProcKeyProvider::kGeometry_ProcessorType,
244                                     GrGLProgramDescBuilder::kProcessorKeyOffsetsAndLengthOffset);
245         GrGLSLExpr4 output;
246         this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *inputCoverage, &output);
247         *inputCoverage = output;
248     }
249     this->emitAndInstallFragProcs(optState.numColorStages(), numProcs,  inputCoverage);
250 }
251
252 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, GrGLSLExpr4* inOut) {
253     ProcKeyProvider keyProvider(&fDesc,
254                                 ProcKeyProvider::kFragment_ProcessorType,
255                                 GrGLProgramDescBuilder::kProcessorKeyOffsetsAndLengthOffset);
256     for (int e = procOffset; e < numProcs; ++e) {
257         GrGLSLExpr4 output;
258         const GrFragmentStage& stage = fOptState.getFragmentStage(e);
259         this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut, &output);
260         *inOut = output;
261     }
262 }
263
264 // TODO Processors cannot output zeros because an empty string is all 1s
265 // the fix is to allow effects to take the GrGLSLExpr4 directly
266 template <class Proc>
267 void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc,
268                                             int index,
269                                             const ProcKeyProvider& keyProvider,
270                                             const GrGLSLExpr4& input,
271                                             GrGLSLExpr4* output) {
272     // Program builders have a bit of state we need to clear with each effect
273     AutoStageAdvance adv(this);
274
275     // create var to hold stage result
276     SkString outColorName;
277     this->nameVariable(&outColorName, '\0', "output");
278     fFS.codeAppendf("vec4 %s;", outColorName.c_str());
279     *output = outColorName;
280
281     // Enclose custom code in a block to avoid namespace conflicts
282     SkString openBrace;
283     openBrace.printf("{ // Stage %d\n", fStageIndex);
284     fFS.codeAppend(openBrace.c_str());
285
286     this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(),
287                              input.isOnes() ? NULL : input.c_str());
288
289     fFS.codeAppend("}");
290 }
291
292 void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentStage& fs,
293                                             const GrProcessorKey& key,
294                                             const char* outColor,
295                                             const char* inColor) {
296     GrGLInstalledFragProc* ifp = SkNEW_ARGS(GrGLInstalledFragProc, (fVS.hasLocalCoords()));
297
298     const GrFragmentProcessor& fp = *fs.getProcessor();
299     ifp->fGLProc.reset(fp.getFactory().createGLInstance(fp));
300
301     SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures());
302     this->emitSamplers(fp, &samplers, ifp);
303
304     // Fragment processors can have coord transforms
305     SkSTArray<2, GrGLProcessor::TransformedCoords> coords(fp.numTransforms());
306     this->emitTransforms(fs, &coords, ifp);
307
308     ifp->fGLProc->emitCode(this, fp, key, outColor, inColor, coords, samplers);
309
310     // We have to check that effects and the code they emit are consistent, ie if an effect
311     // asks for dst color, then the emit code needs to follow suit
312     verify(fp);
313     fFragmentProcessors->fProcs.push_back(ifp);
314 }
315
316 void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp,
317                                             const GrProcessorKey& key,
318                                             const char* outColor,
319                                             const char* inColor) {
320     SkASSERT(!fGeometryProcessor);
321     fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
322
323     fGeometryProcessor->fGLProc.reset(gp.getFactory().createGLInstance(gp));
324
325     SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
326     this->emitSamplers(gp, &samplers, fGeometryProcessor);
327
328     GrGLGeometryProcessor::EmitArgs args(this, gp, key, outColor, inColor, samplers);
329     fGeometryProcessor->fGLProc->emitCode(args);
330
331     // We have to check that effects and the code they emit are consistent, ie if an effect
332     // asks for dst color, then the emit code needs to follow suit
333     verify(gp);
334 }
335
336 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) {
337     SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition());
338 }
339
340 void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
341     SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition());
342     SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor());
343 }
344
345 void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage,
346                                         GrGLProcessor::TransformedCoordsArray* outCoords,
347                                         GrGLInstalledFragProc* ifp) {
348     const GrFragmentProcessor* effect = effectStage.getProcessor();
349     int numTransforms = effect->numTransforms();
350     ifp->fTransforms.push_back_n(numTransforms);
351
352     for (int t = 0; t < numTransforms; t++) {
353         const char* uniName = "StageMatrix";
354         GrSLType varyingType =
355                 effectStage.isPerspectiveCoordTransform(t, fVS.hasLocalCoords()) ?
356                         kVec3f_GrSLType :
357                         kVec2f_GrSLType;
358
359         SkString suffixedUniName;
360         if (0 != t) {
361             suffixedUniName.append(uniName);
362             suffixedUniName.appendf("_%i", t);
363             uniName = suffixedUniName.c_str();
364         }
365         ifp->fTransforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Visibility,
366                                                        kMat33f_GrSLType,
367                                                        uniName,
368                                                        &uniName).toShaderBuilderIndex();
369
370         const char* varyingName = "MatrixCoord";
371         SkString suffixedVaryingName;
372         if (0 != t) {
373             suffixedVaryingName.append(varyingName);
374             suffixedVaryingName.appendf("_%i", t);
375             varyingName = suffixedVaryingName.c_str();
376         }
377         GrGLVertToFrag v(varyingType);
378         this->addVarying(varyingName, &v);
379
380         const GrGLShaderVar& coords =
381                 kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords() ?
382                                           fVS.positionAttribute() :
383                                           fVS.localCoordsAttribute();
384
385         // varying = matrix * coords (logically)
386         SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingType);
387         if (kVec2f_GrSLType == varyingType) {
388             fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;",
389                             v.vsOut(), uniName, coords.c_str());
390         } else {
391             fVS.codeAppendf("%s = %s * vec3(%s, 1);",
392                             v.vsOut(), uniName, coords.c_str());
393         }
394         SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords,
395                                (SkString(v.fsIn()), varyingType));
396     }
397 }
398
399 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
400                                       GrGLProcessor::TextureSamplerArray* outSamplers,
401                                       GrGLInstalledProc* ip) {
402     int numTextures = processor.numTextures();
403     ip->fSamplers.push_back_n(numTextures);
404     SkString name;
405     for (int t = 0; t < numTextures; ++t) {
406         name.printf("Sampler%d", t);
407         ip->fSamplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
408                                                      kSampler2D_GrSLType,
409                                                      name.c_str());
410         SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
411                                (ip->fSamplers[t].fUniform, processor.textureAccess(t)));
412     }
413 }
414
415 GrGLProgram* GrGLProgramBuilder::finalize() {
416     // verify we can get a program id
417     GrGLuint programID;
418     GL_CALL_RET(programID, CreateProgram());
419     if (0 == programID) {
420         return NULL;
421     }
422
423     // compile shaders and bind attributes / uniforms
424     SkTDArray<GrGLuint> shadersToDelete;
425     if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) {
426         this->cleanupProgram(programID, shadersToDelete);
427         return NULL;
428     }
429     if (!(GrGLProgramDescBuilder::GetHeader(fDesc).fUseNvpr &&
430           fGpu->glPathRendering()->texturingMode() ==
431           GrGLPathRendering::FixedFunction_TexturingMode)) {
432         if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) {
433             this->cleanupProgram(programID, shadersToDelete);
434             return NULL;
435         }
436         fVS.bindVertexAttributes(programID);
437     }
438     bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
439     if (usingBindUniform) {
440         this->bindUniformLocations(programID);
441     }
442     fFS.bindFragmentShaderLocations(programID);
443     GL_CALL(LinkProgram(programID));
444
445     // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
446     bool checkLinked = !fGpu->ctxInfo().isChromium();
447 #ifdef SK_DEBUG
448     checkLinked = true;
449 #endif
450     if (checkLinked) {
451         checkLinkStatus(programID);
452     }
453     if (!usingBindUniform) {
454         this->resolveUniformLocations(programID);
455     }
456
457     this->cleanupShaders(shadersToDelete);
458
459     return this->createProgram(programID);
460 }
461
462 void GrGLProgramBuilder::bindUniformLocations(GrGLuint programID) {
463     int count = fUniforms.count();
464     for (int i = 0; i < count; ++i) {
465         GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str()));
466         fUniforms[i].fLocation = i;
467     }
468 }
469
470 bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
471     GrGLint linked = GR_GL_INIT_ZERO;
472     GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
473     if (!linked) {
474         GrGLint infoLen = GR_GL_INIT_ZERO;
475         GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
476         SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
477         if (infoLen > 0) {
478             // retrieve length even though we don't need it to workaround
479             // bug in chrome cmd buffer param validation.
480             GrGLsizei length = GR_GL_INIT_ZERO;
481             GL_CALL(GetProgramInfoLog(programID,
482                                       infoLen+1,
483                                       &length,
484                                       (char*)log.get()));
485             SkDebugf((char*)log.get());
486         }
487         SkDEBUGFAIL("Error linking program");
488         GL_CALL(DeleteProgram(programID));
489         programID = 0;
490     }
491     return SkToBool(linked);
492 }
493
494 void GrGLProgramBuilder::resolveUniformLocations(GrGLuint programID) {
495     int count = fUniforms.count();
496     for (int i = 0; i < count; ++i) {
497         GrGLint location;
498         GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str()));
499         fUniforms[i].fLocation = location;
500     }
501 }
502
503 void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs) {
504     GL_CALL(DeleteProgram(programID));
505     cleanupShaders(shaderIDs);
506 }
507 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
508     for (int i = 0; i < shaderIDs.count(); ++i) {
509       GL_CALL(DeleteShader(shaderIDs[i]));
510     }
511 }
512
513 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
514     return SkNEW_ARGS(GrGLProgram, (fGpu, fDesc, fUniformHandles, programID, fUniforms,
515                                     fGeometryProcessor, fFragmentProcessors.get()));
516 }
517
518 ///////////////////////////////////////////////////////////////////////////////////////////////////
519
520 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() {
521     int numProcs = fProcs.count();
522     for (int e = 0; e < numProcs; ++e) {
523         SkDELETE(fProcs[e]);
524     }
525 }