C++11 override should now be supported by all of {bots,Chrome,Android,Mozilla}
[platform/upstream/libSkiaSharp.git] / 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
10 #include "gl/GrGLGeometryProcessor.h"
11 #include "gl/GrGLGpu.h"
12 #include "gl/GrGLPathProcessor.h"
13 #include "gl/GrGLProgram.h"
14 #include "gl/GrGLSLPrettyPrint.h"
15 #include "gl/GrGLUniformHandle.h"
16 #include "gl/GrGLXferProcessor.h"
17 #include "GrAutoLocaleSetter.h"
18 #include "GrCoordTransform.h"
19 #include "GrGLProgramBuilder.h"
20 #include "GrTexture.h"
21 #include "SkRTConf.h"
22 #include "SkTraceEvent.h"
23
24 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
25 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
26
27 ///////////////////////////////////////////////////////////////////////////////////////////////////
28
29 class GrGLNvprProgramBuilder : public GrGLProgramBuilder {
30 public:
31     GrGLNvprProgramBuilder(GrGLGpu* gpu, const DrawArgs& args)
32         : INHERITED(gpu, args) {}
33
34     GrGLProgram* createProgram(GrGLuint programID) override {
35         // this is just for nvpr es, which has separable varyings that are plugged in after
36         // building
37         GrGLPathProcessor* pathProc =
38                 static_cast<GrGLPathProcessor*>(fGeometryProcessor->fGLProc.get());
39         pathProc->resolveSeparableVaryings(fGpu, programID);
40         return SkNEW_ARGS(GrGLNvprProgram, (fGpu, this->desc(), fUniformHandles, programID,
41                                             fUniforms,
42                                             fGeometryProcessor,
43                                             fXferProcessor, fFragmentProcessors.get()));
44     }
45
46 private:
47     typedef GrGLProgramBuilder INHERITED;
48 };
49
50
51
52 //////////////////////////////////////////////////////////////////////////////
53
54 const int GrGLProgramBuilder::kVarsPerBlock = 8;
55
56 GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gpu) {
57     GrAutoLocaleSetter als("C");
58
59     // create a builder.  This will be handed off to effects so they can use it to add
60     // uniforms, varyings, textures, etc
61     SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(args, gpu));
62
63     GrGLProgramBuilder* pb = builder.get();
64
65     // TODO: Once all stages can handle taking a float or vec4 and correctly handling them we can
66     // seed correctly here
67     GrGLSLExpr4 inputColor;
68     GrGLSLExpr4 inputCoverage;
69
70     pb->emitAndInstallProcs(&inputColor, &inputCoverage);
71
72     return pb->finalize();
73 }
74
75 GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& args,
76                                                              GrGLGpu* gpu) {
77     if (args.fPrimitiveProcessor->isPathRendering()) {
78         SkASSERT(gpu->glCaps().pathRenderingSupport() &&
79                  !args.fPrimitiveProcessor->willUseGeoShader() &&
80                  args.fPrimitiveProcessor->numAttribs() == 0);
81         return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, args));
82     } else {
83         return SkNEW_ARGS(GrGLProgramBuilder, (gpu, args));
84     }
85 }
86
87 /////////////////////////////////////////////////////////////////////////////
88
89 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args)
90     : fVS(this)
91     , fGS(this)
92     , fFS(this, args.fDesc->header().fFragPosKey)
93     , fOutOfStage(true)
94     , fStageIndex(-1)
95     , fGeometryProcessor(NULL)
96     , fXferProcessor(NULL)
97     , fArgs(args)
98     , fGpu(gpu)
99     , fUniforms(kVarsPerBlock) {
100 }
101
102 void GrGLProgramBuilder::addVarying(const char* name,
103                                     GrGLVarying* varying,
104                                     GrSLPrecision fsPrecision) {
105     SkASSERT(varying);
106     if (varying->vsVarying()) {
107         fVS.addVarying(name, varying);
108     }
109     if (this->primitiveProcessor().willUseGeoShader()) {
110         fGS.addVarying(name, varying);
111     }
112     if (varying->fsVarying()) {
113         fFS.addVarying(varying, fsPrecision);
114     }
115 }
116
117 void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Attribute* input,
118                                                  const char* output) {
119     GrSLType type = GrVertexAttribTypeToSLType(input->fType);
120     GrGLVertToFrag v(type);
121     this->addVarying(input->fName, &v);
122     fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName);
123     fFS.codeAppendf("%s = %s;", output, v.fsIn());
124 }
125
126 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
127     if ('\0' == prefix) {
128         *out = name;
129     } else {
130         out->printf("%c%s", prefix, name);
131     }
132     if (!fOutOfStage) {
133         if (out->endsWith('_')) {
134             // Names containing "__" are reserved.
135             out->append("x");
136         }
137         out->appendf("_Stage%d", fStageIndex);
138     }
139 }
140
141 GrGLProgramDataManager::UniformHandle GrGLProgramBuilder::addUniformArray(
142                                                                 uint32_t visibility,
143                                                                 GrSLType type,
144                                                                 GrSLPrecision precision,
145                                                                 const char* name,
146                                                                 int count,
147                                                                 const char** outName) {
148     SkASSERT(name && strlen(name));
149     SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFragment_Visibility);
150     SkASSERT(0 == (~kVisibilityMask & visibility));
151     SkASSERT(0 != visibility);
152     SkASSERT(kDefault_GrSLPrecision == precision || GrSLTypeIsFloatType(type));
153
154     UniformInfo& uni = fUniforms.push_back();
155     uni.fVariable.setType(type);
156     uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
157     // TODO this is a bit hacky, lets think of a better way.  Basically we need to be able to use
158     // the uniform view matrix name in the GP, and the GP is immutable so it has to tell the PB
159     // exactly what name it wants to use for the uniform view matrix.  If we prefix anythings, then
160     // the names will mismatch.  I think the correct solution is to have all GPs which need the
161     // uniform view matrix, they should upload the view matrix in their setData along with regular
162     // uniforms.
163     char prefix = 'u';
164     if ('u' == name[0]) {
165         prefix = '\0';
166     }
167     this->nameVariable(uni.fVariable.accessName(), prefix, name);
168     uni.fVariable.setArrayCount(count);
169     uni.fVisibility = visibility;
170     uni.fVariable.setPrecision(precision);
171
172     if (outName) {
173         *outName = uni.fVariable.c_str();
174     }
175     return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fUniforms.count() - 1);
176 }
177
178 void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility,
179                                             SkString* out) const {
180     for (int i = 0; i < fUniforms.count(); ++i) {
181         if (fUniforms[i].fVisibility & visibility) {
182             fUniforms[i].fVariable.appendDecl(this->ctxInfo(), out);
183             out->append(";\n");
184         }
185     }
186 }
187
188 const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const {
189     return fGpu->ctxInfo();
190 }
191
192 void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) {
193     // First we loop over all of the installed processors and collect coord transforms.  These will
194     // be sent to the GrGLPrimitiveProcessor in its emitCode function
195     SkSTArray<8, GrGLProcessor::TransformedCoordsArray> outCoords;
196     for (int i = 0; i < this->pipeline().numFragmentStages(); i++) {
197         const GrFragmentProcessor* processor = this->pipeline().getFragmentStage(i).processor();
198         SkSTArray<2, const GrCoordTransform*, true>& procCoords = fCoordTransforms.push_back();
199         for (int t = 0; t < processor->numTransforms(); t++) {
200             procCoords.push_back(&processor->coordTransform(t));
201         }
202     }
203
204     const GrPrimitiveProcessor& primProc = this->primitiveProcessor();
205     this->emitAndInstallProc(primProc, inputColor, inputCoverage);
206
207     fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs));
208     int numProcs = this->pipeline().numFragmentStages();
209     this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentStages(), inputColor);
210     this->emitAndInstallFragProcs(this->pipeline().numColorFragmentStages(), numProcs,
211                                   inputCoverage);
212     this->emitAndInstallXferProc(*this->pipeline().getXferProcessor(), *inputColor, *inputCoverage);
213 }
214
215 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset,
216                                                  int numProcs,
217                                                  GrGLSLExpr4* inOut) {
218     for (int e = procOffset; e < numProcs; ++e) {
219         GrGLSLExpr4 output;
220         const GrPendingFragmentStage& stage = this->pipeline().getFragmentStage(e);
221         this->emitAndInstallProc(stage, e, *inOut, &output);
222         *inOut = output;
223     }
224 }
225
226 void GrGLProgramBuilder::nameExpression(GrGLSLExpr4* output, const char* baseName) {
227     // create var to hold stage result.  If we already have a valid output name, just use that
228     // otherwise create a new mangled one.  This name is only valid if we are reordering stages
229     // and have to tell stage exactly where to put its output.
230     SkString outName;
231     if (output->isValid()) {
232         outName = output->c_str();
233     } else {
234         this->nameVariable(&outName, '\0', baseName);
235     }
236     fFS.codeAppendf("vec4 %s;", outName.c_str());
237     *output = outName;
238 }
239
240 // TODO Processors cannot output zeros because an empty string is all 1s
241 // the fix is to allow effects to take the GrGLSLExpr4 directly
242 void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& proc,
243                                             int index,
244                                             const GrGLSLExpr4& input,
245                                             GrGLSLExpr4* output) {
246     // Program builders have a bit of state we need to clear with each effect
247     AutoStageAdvance adv(this);
248     this->nameExpression(output, "output");
249
250     // Enclose custom code in a block to avoid namespace conflicts
251     SkString openBrace;
252     openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name());
253     fFS.codeAppend(openBrace.c_str());
254
255     this->emitAndInstallProc(proc, index, output->c_str(), input.isOnes() ? NULL : input.c_str());
256
257     fFS.codeAppend("}");
258 }
259
260 void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& proc,
261                                             GrGLSLExpr4* outputColor,
262                                             GrGLSLExpr4* outputCoverage) {
263     // Program builders have a bit of state we need to clear with each effect
264     AutoStageAdvance adv(this);
265     this->nameExpression(outputColor, "outputColor");
266     this->nameExpression(outputCoverage, "outputCoverage");
267
268     // Enclose custom code in a block to avoid namespace conflicts
269     SkString openBrace;
270     openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name());
271     fFS.codeAppend(openBrace.c_str());
272
273     this->emitAndInstallProc(proc, outputColor->c_str(), outputCoverage->c_str());
274
275     fFS.codeAppend("}");
276 }
277
278 void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& fs,
279                                             int index,
280                                             const char* outColor,
281                                             const char* inColor) {
282     GrGLInstalledFragProc* ifp = SkNEW(GrGLInstalledFragProc);
283
284     const GrFragmentProcessor& fp = *fs.processor();
285     ifp->fGLProc.reset(fp.createGLInstance());
286
287     SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures());
288     this->emitSamplers(fp, &samplers, ifp);
289
290     ifp->fGLProc->emitCode(this, fp, outColor, inColor, fOutCoords[index], samplers);
291
292     // We have to check that effects and the code they emit are consistent, ie if an effect
293     // asks for dst color, then the emit code needs to follow suit
294     verify(fp);
295     fFragmentProcessors->fProcs.push_back(ifp);
296 }
297
298 void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& gp,
299                                             const char* outColor,
300                                             const char* outCoverage) {
301     SkASSERT(!fGeometryProcessor);
302     fGeometryProcessor = SkNEW(GrGLInstalledGeoProc);
303
304     const GrBatchTracker& bt = this->batchTracker();
305     fGeometryProcessor->fGLProc.reset(gp.createGLInstance(bt, fGpu->glCaps()));
306
307     SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures());
308     this->emitSamplers(gp, &samplers, fGeometryProcessor);
309
310     GrGLGeometryProcessor::EmitArgs args(this, gp, bt, outColor, outCoverage, samplers,
311                                          fCoordTransforms, &fOutCoords);
312     fGeometryProcessor->fGLProc->emitCode(args);
313
314     // We have to check that effects and the code they emit are consistent, ie if an effect
315     // asks for dst color, then the emit code needs to follow suit
316     verify(gp);
317 }
318
319 void GrGLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
320                                                 const GrGLSLExpr4& colorIn,
321                                                 const GrGLSLExpr4& coverageIn) {
322     // Program builders have a bit of state we need to clear with each effect
323     AutoStageAdvance adv(this);
324
325     SkASSERT(!fXferProcessor);
326     fXferProcessor = SkNEW(GrGLInstalledXferProc);
327
328     fXferProcessor->fGLProc.reset(xp.createGLInstance());
329
330     // Enable dual source secondary output if we have one
331     if (xp.hasSecondaryOutput()) {
332         fFS.enableSecondaryOutput();
333     }
334
335     // On any post 1.10 GLSL supporting GPU, we declare custom output
336     if (k110_GrGLSLGeneration != fFS.fProgramBuilder->gpu()->glslGeneration()) {
337         fFS.enableCustomOutput();
338     }
339
340     SkString openBrace;
341     openBrace.printf("{ // Xfer Processor: %s\n", xp.name());
342     fFS.codeAppend(openBrace.c_str());
343
344     SkSTArray<4, GrGLProcessor::TextureSampler> samplers(xp.numTextures());
345     this->emitSamplers(xp, &samplers, fXferProcessor);
346
347     GrGLXferProcessor::EmitArgs args(this, xp, colorIn.c_str(), coverageIn.c_str(),
348                                      fFS.getPrimaryColorOutputName(),
349                                      fFS.getSecondaryColorOutputName(), samplers);
350     fXferProcessor->fGLProc->emitCode(args);
351
352     // We have to check that effects and the code they emit are consistent, ie if an effect
353     // asks for dst color, then the emit code needs to follow suit
354     verify(xp);
355     fFS.codeAppend("}");
356 }
357
358 void GrGLProgramBuilder::verify(const GrPrimitiveProcessor& gp) {
359     SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition());
360 }
361
362 void GrGLProgramBuilder::verify(const GrXferProcessor& xp) {
363     SkASSERT(fFS.hasReadDstColor() == xp.willReadDstColor());
364 }
365
366 void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) {
367     SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition());
368 }
369
370 template <class Proc>
371 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor,
372                                       GrGLProcessor::TextureSamplerArray* outSamplers,
373                                       GrGLInstalledProc<Proc>* ip) {
374     int numTextures = processor.numTextures();
375     ip->fSamplers.push_back_n(numTextures);
376     SkString name;
377     for (int t = 0; t < numTextures; ++t) {
378         name.printf("Sampler%d", t);
379         ip->fSamplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility,
380                                                      kSampler2D_GrSLType, kDefault_GrSLPrecision,
381                                                      name.c_str());
382         SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler,
383                                (ip->fSamplers[t].fUniform, processor.textureAccess(t)));
384     }
385 }
386
387 GrGLProgram* GrGLProgramBuilder::finalize() {
388     // verify we can get a program id
389     GrGLuint programID;
390     GL_CALL_RET(programID, CreateProgram());
391     if (0 == programID) {
392         return NULL;
393     }
394
395     // compile shaders and bind attributes / uniforms
396     SkTDArray<GrGLuint> shadersToDelete;
397
398     // Legacy nvpr will not compile with a vertex shader, but newer nvpr requires a dummy vertex
399     // shader
400     bool useNvpr = primitiveProcessor().isPathRendering();
401     if (!(useNvpr && fGpu->glCaps().nvprSupport() == GrGLCaps::kLegacy_NvprSupport)) {
402         if (!fVS.compileAndAttachShaders(programID, &shadersToDelete)) {
403             this->cleanupProgram(programID, shadersToDelete);
404             return NULL;
405         }
406
407         // Non fixed function NVPR actually requires a vertex shader to compile
408         if (!useNvpr) {
409             fVS.bindVertexAttributes(programID);
410         }
411     }
412
413     if (!fFS.compileAndAttachShaders(programID, &shadersToDelete)) {
414         this->cleanupProgram(programID, shadersToDelete);
415         return NULL;
416     }
417
418     bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
419     if (usingBindUniform) {
420         this->bindUniformLocations(programID);
421     }
422     fFS.bindFragmentShaderLocations(programID);
423     GL_CALL(LinkProgram(programID));
424
425     // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
426     bool checkLinked = !fGpu->ctxInfo().isChromium();
427 #ifdef SK_DEBUG
428     checkLinked = true;
429 #endif
430     if (checkLinked) {
431         checkLinkStatus(programID);
432     }
433     if (!usingBindUniform) {
434         this->resolveUniformLocations(programID);
435     }
436
437     this->cleanupShaders(shadersToDelete);
438
439     return this->createProgram(programID);
440 }
441
442 void GrGLProgramBuilder::bindUniformLocations(GrGLuint programID) {
443     int count = fUniforms.count();
444     for (int i = 0; i < count; ++i) {
445         GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str()));
446         fUniforms[i].fLocation = i;
447     }
448 }
449
450 bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
451     GrGLint linked = GR_GL_INIT_ZERO;
452     GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
453     if (!linked) {
454         GrGLint infoLen = GR_GL_INIT_ZERO;
455         GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
456         SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
457         if (infoLen > 0) {
458             // retrieve length even though we don't need it to workaround
459             // bug in chrome cmd buffer param validation.
460             GrGLsizei length = GR_GL_INIT_ZERO;
461             GL_CALL(GetProgramInfoLog(programID,
462                                       infoLen+1,
463                                       &length,
464                                       (char*)log.get()));
465             SkDebugf("%s", (char*)log.get());
466         }
467         SkDEBUGFAIL("Error linking program");
468         GL_CALL(DeleteProgram(programID));
469         programID = 0;
470     }
471     return SkToBool(linked);
472 }
473
474 void GrGLProgramBuilder::resolveUniformLocations(GrGLuint programID) {
475     int count = fUniforms.count();
476     for (int i = 0; i < count; ++i) {
477         GrGLint location;
478         GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str()));
479         fUniforms[i].fLocation = location;
480     }
481 }
482
483 void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs) {
484     GL_CALL(DeleteProgram(programID));
485     cleanupShaders(shaderIDs);
486 }
487 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) {
488     for (int i = 0; i < shaderIDs.count(); ++i) {
489       GL_CALL(DeleteShader(shaderIDs[i]));
490     }
491 }
492
493 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) {
494     return SkNEW_ARGS(GrGLProgram, (fGpu, this->desc(), fUniformHandles, programID, fUniforms,
495                                     fGeometryProcessor, fXferProcessor, fFragmentProcessors.get()));
496 }
497
498 ///////////////////////////////////////////////////////////////////////////////////////////////////
499
500 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() {
501     int numProcs = fProcs.count();
502     for (int e = 0; e < numProcs; ++e) {
503         SkDELETE(fProcs[e]);
504     }
505 }