• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "src/gpu/gl/builders/GrGLProgramBuilder.h"
9 
10 #include "include/gpu/GrDirectContext.h"
11 #include "src/core/SkATrace.h"
12 #include "src/core/SkAutoMalloc.h"
13 #include "src/core/SkReadBuffer.h"
14 #include "src/core/SkTraceEvent.h"
15 #include "src/core/SkWriteBuffer.h"
16 #include "src/gpu/GrAutoLocaleSetter.h"
17 #include "src/gpu/GrDirectContextPriv.h"
18 #include "src/gpu/GrPersistentCacheUtils.h"
19 #include "src/gpu/GrProgramDesc.h"
20 #include "src/gpu/GrShaderCaps.h"
21 #include "src/gpu/GrShaderUtils.h"
22 #include "src/gpu/GrSwizzle.h"
23 #include "src/gpu/gl/GrGLGpu.h"
24 #include "src/gpu/gl/GrGLProgram.h"
25 #include "src/gpu/gl/builders/GrGLProgramBuilder.h"
26 
27 #include <memory>
28 #include "src/gpu/gl/builders/GrGLShaderStringBuilder.h"
29 #include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
30 #include "src/gpu/glsl/GrGLSLGeometryProcessor.h"
31 #include "src/gpu/glsl/GrGLSLProgramDataManager.h"
32 #include "src/gpu/glsl/GrGLSLXferProcessor.h"
33 
34 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
35 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
36 
cleanup_shaders(GrGLGpu * gpu,const SkTDArray<GrGLuint> & shaderIDs)37 static void cleanup_shaders(GrGLGpu* gpu, const SkTDArray<GrGLuint>& shaderIDs) {
38     for (int i = 0; i < shaderIDs.count(); ++i) {
39         GR_GL_CALL(gpu->glInterface(), DeleteShader(shaderIDs[i]));
40     }
41 }
42 
cleanup_program(GrGLGpu * gpu,GrGLuint programID,const SkTDArray<GrGLuint> & shaderIDs)43 static void cleanup_program(GrGLGpu* gpu, GrGLuint programID,
44                             const SkTDArray<GrGLuint>& shaderIDs) {
45     GR_GL_CALL(gpu->glInterface(), DeleteProgram(programID));
46     cleanup_shaders(gpu, shaderIDs);
47 }
48 
CreateProgram(GrDirectContext * dContext,const GrProgramDesc & desc,const GrProgramInfo & programInfo,const GrGLPrecompiledProgram * precompiledProgram)49 sk_sp<GrGLProgram> GrGLProgramBuilder::CreateProgram(
50                                                GrDirectContext* dContext,
51                                                const GrProgramDesc& desc,
52                                                const GrProgramInfo& programInfo,
53                                                const GrGLPrecompiledProgram* precompiledProgram) {
54     TRACE_EVENT0_ALWAYS("skia.shaders", "shader_compile");
55     GrAutoLocaleSetter als("C");
56 
57     GrGLGpu* glGpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
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     GrGLProgramBuilder builder(glGpu, desc, programInfo);
62 
63     auto persistentCache = dContext->priv().getPersistentCache();
64     if (persistentCache && !precompiledProgram) {
65         sk_sp<SkData> key = SkData::MakeWithoutCopy(desc.asKey(), desc.keyLength());
66         builder.fCached = persistentCache->load(*key);
67         // the eventual end goal is to completely skip emitAndInstallProcs on a cache hit, but it's
68         // doing necessary setup in addition to generating the SkSL code. Currently we are only able
69         // to skip the SkSL->GLSL step on a cache hit.
70     }
71     if (!builder.emitAndInstallProcs()) {
72         return nullptr;
73     }
74     return builder.finalize(precompiledProgram);
75 }
76 
77 /////////////////////////////////////////////////////////////////////////////
78 
GrGLProgramBuilder(GrGLGpu * gpu,const GrProgramDesc & desc,const GrProgramInfo & programInfo)79 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu,
80                                        const GrProgramDesc& desc,
81                                        const GrProgramInfo& programInfo)
82         : INHERITED(desc, programInfo)
83         , fGpu(gpu)
84         , fVaryingHandler(this)
85         , fUniformHandler(this)
86         , fVertexAttributeCnt(0)
87         , fInstanceAttributeCnt(0)
88         , fVertexStride(0)
89         , fInstanceStride(0) {}
90 
caps() const91 const GrCaps* GrGLProgramBuilder::caps() const {
92     return fGpu->caps();
93 }
94 
shaderCompiler() const95 SkSL::Compiler* GrGLProgramBuilder::shaderCompiler() const {
96     return fGpu->shaderCompiler();
97 }
98 
compileAndAttachShaders(const SkSL::String & glsl,GrGLuint programId,GrGLenum type,SkTDArray<GrGLuint> * shaderIds,GrContextOptions::ShaderErrorHandler * errHandler)99 bool GrGLProgramBuilder::compileAndAttachShaders(const SkSL::String& glsl,
100                                                  GrGLuint programId,
101                                                  GrGLenum type,
102                                                  SkTDArray<GrGLuint>* shaderIds,
103                                                  GrContextOptions::ShaderErrorHandler* errHandler) {
104     GrGLGpu* gpu = this->gpu();
105     GrGLuint shaderId = GrGLCompileAndAttachShader(gpu->glContext(),
106                                                    programId,
107                                                    type,
108                                                    glsl,
109                                                    gpu->pipelineBuilder()->stats(),
110                                                    errHandler);
111     if (!shaderId) {
112         return false;
113     }
114 
115     *shaderIds->append() = shaderId;
116     return true;
117 }
118 
computeCountsAndStrides(GrGLuint programID,const GrGeometryProcessor & geomProc,bool bindAttribLocations)119 void GrGLProgramBuilder::computeCountsAndStrides(GrGLuint programID,
120                                                  const GrGeometryProcessor& geomProc,
121                                                  bool bindAttribLocations) {
122     fVertexAttributeCnt = geomProc.numVertexAttributes();
123     fInstanceAttributeCnt = geomProc.numInstanceAttributes();
124     fAttributes = std::make_unique<GrGLProgram::Attribute[]>(
125             fVertexAttributeCnt + fInstanceAttributeCnt);
126     auto addAttr = [&](int i, const auto& a, size_t* stride) {
127         fAttributes[i].fCPUType = a.cpuType();
128         fAttributes[i].fGPUType = a.gpuType();
129         fAttributes[i].fOffset = *stride;
130         *stride += a.sizeAlign4();
131         fAttributes[i].fLocation = i;
132         if (bindAttribLocations) {
133             GL_CALL(BindAttribLocation(programID, i, a.name()));
134         }
135     };
136     fVertexStride = 0;
137     int i = 0;
138     for (const auto& attr : geomProc.vertexAttributes()) {
139         addAttr(i++, attr, &fVertexStride);
140     }
141     SkASSERT(fVertexStride == geomProc.vertexStride());
142     fInstanceStride = 0;
143     for (const auto& attr : geomProc.instanceAttributes()) {
144         addAttr(i++, attr, &fInstanceStride);
145     }
146     SkASSERT(fInstanceStride == geomProc.instanceStride());
147 }
148 
addInputVars(const SkSL::Program::Inputs & inputs)149 void GrGLProgramBuilder::addInputVars(const SkSL::Program::Inputs& inputs) {
150     if (inputs.fRTHeight) {
151         this->addRTHeightUniform(SKSL_RTHEIGHT_NAME);
152     }
153 }
154 
155 static constexpr SkFourByteTag kSKSL_Tag = SkSetFourByteTag('S', 'K', 'S', 'L');
156 static constexpr SkFourByteTag kGLSL_Tag = SkSetFourByteTag('G', 'L', 'S', 'L');
157 static constexpr SkFourByteTag kGLPB_Tag = SkSetFourByteTag('G', 'L', 'P', 'B');
158 
storeShaderInCache(const SkSL::Program::Inputs & inputs,GrGLuint programID,const SkSL::String shaders[],bool isSkSL,SkSL::Program::Settings * settings)159 void GrGLProgramBuilder::storeShaderInCache(const SkSL::Program::Inputs& inputs, GrGLuint programID,
160                                             const SkSL::String shaders[], bool isSkSL,
161                                             SkSL::Program::Settings* settings) {
162     if (!this->gpu()->getContext()->priv().getPersistentCache()) {
163         return;
164     }
165     sk_sp<SkData> key = SkData::MakeWithoutCopy(this->desc().asKey(), this->desc().keyLength());
166     SkString description = GrProgramDesc::Describe(fProgramInfo, *fGpu->caps());
167     if (fGpu->glCaps().programBinarySupport()) {
168         // binary cache
169         GrGLsizei length = 0;
170         GL_CALL(GetProgramiv(programID, GL_PROGRAM_BINARY_LENGTH, &length));
171         if (length > 0) {
172             SkBinaryWriteBuffer writer;
173             writer.writeInt(GrPersistentCacheUtils::GetCurrentVersion());
174             writer.writeUInt(kGLPB_Tag);
175 
176             writer.writePad32(&inputs, sizeof(inputs));
177 
178             SkAutoSMalloc<2048> binary(length);
179             GrGLenum binaryFormat;
180             GL_CALL(GetProgramBinary(programID, length, &length, &binaryFormat, binary.get()));
181 
182             writer.writeUInt(binaryFormat);
183             writer.writeInt(length);
184             writer.writePad32(binary.get(), length);
185 
186             auto data = writer.snapshotAsData();
187             this->gpu()->getContext()->priv().getPersistentCache()->store(*key, *data, description);
188         }
189     } else {
190         // source cache, plus metadata to allow for a complete precompile
191         GrPersistentCacheUtils::ShaderMetadata meta;
192         meta.fSettings = settings;
193         meta.fHasCustomColorOutput = fFS.hasCustomColorOutput();
194         meta.fHasSecondaryColorOutput = fFS.hasSecondaryOutput();
195         for (const auto& attr : this->geometryProcessor().vertexAttributes()) {
196             meta.fAttributeNames.emplace_back(attr.name());
197         }
198         for (const auto& attr : this->geometryProcessor().instanceAttributes()) {
199             meta.fAttributeNames.emplace_back(attr.name());
200         }
201 
202         auto data = GrPersistentCacheUtils::PackCachedShaders(isSkSL ? kSKSL_Tag : kGLSL_Tag,
203                                                               shaders, &inputs, 1, &meta);
204         this->gpu()->getContext()->priv().getPersistentCache()->store(*key, *data, description);
205     }
206 }
207 
finalize(const GrGLPrecompiledProgram * precompiledProgram)208 sk_sp<GrGLProgram> GrGLProgramBuilder::finalize(const GrGLPrecompiledProgram* precompiledProgram) {
209     TRACE_EVENT0("skia.shaders", TRACE_FUNC);
210 
211     // verify we can get a program id
212     GrGLuint programID;
213     if (precompiledProgram) {
214         programID = precompiledProgram->fProgramID;
215     } else {
216         GL_CALL_RET(programID, CreateProgram());
217     }
218     if (0 == programID) {
219         return nullptr;
220     }
221 
222     if (this->gpu()->glCaps().programBinarySupport() &&
223         this->gpu()->glCaps().programParameterSupport() &&
224         this->gpu()->getContext()->priv().getPersistentCache() &&
225         !precompiledProgram) {
226         GL_CALL(ProgramParameteri(programID, GR_GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GR_GL_TRUE));
227     }
228 
229     this->finalizeShaders();
230 
231     // compile shaders and bind attributes / uniforms
232     auto errorHandler = this->gpu()->getContext()->priv().getShaderErrorHandler();
233     const GrGeometryProcessor& geomProc = this->geometryProcessor();
234     SkSL::Program::Settings settings;
235     settings.fFlipY = this->origin() != kTopLeft_GrSurfaceOrigin;
236     settings.fSharpenTextures =
237                     this->gpu()->getContext()->priv().options().fSharpenMipmappedTextures;
238     settings.fFragColorIsInOut = this->fragColorIsInOut();
239 
240     SkSL::Program::Inputs inputs;
241     SkTDArray<GrGLuint> shadersToDelete;
242 
243     bool checkLinked = !fGpu->glCaps().skipErrorChecks();
244 
245     bool cached = fCached.get() != nullptr;
246     bool usedProgramBinaries = false;
247     SkSL::String glsl[kGrShaderTypeCount];
248     SkSL::String* sksl[kGrShaderTypeCount] = {
249         &fVS.fCompilerString,
250         &fGS.fCompilerString,
251         &fFS.fCompilerString,
252     };
253     SkSL::String cached_sksl[kGrShaderTypeCount];
254     if (precompiledProgram) {
255         // This is very similar to when we get program binaries. We even set that flag, as it's
256         // used to prevent other compile work later, and to force re-querying uniform locations.
257         this->addInputVars(precompiledProgram->fInputs);
258         this->computeCountsAndStrides(programID, geomProc, false);
259         usedProgramBinaries = true;
260     } else if (cached) {
261         TRACE_EVENT0_ALWAYS("skia.shaders", "cache_hit");
262         SkReadBuffer reader(fCached->data(), fCached->size());
263         SkFourByteTag shaderType = GrPersistentCacheUtils::GetType(&reader);
264 
265         switch (shaderType) {
266             case kGLPB_Tag: {
267                 // Program binary cache hit. We may opt not to use this if we don't trust program
268                 // binaries on this driver
269                 if (!fGpu->glCaps().programBinarySupport()) {
270                     cached = false;
271                     break;
272                 }
273                 reader.readPad32(&inputs, sizeof(inputs));
274                 GrGLenum binaryFormat = reader.readUInt();
275                 GrGLsizei length      = reader.readInt();
276                 const void* binary = reader.skip(length);
277                 if (!reader.isValid()) {
278                     break;
279                 }
280                 this->gpu()->clearErrorsAndCheckForOOM();
281                 GR_GL_CALL_NOERRCHECK(this->gpu()->glInterface(),
282                                       ProgramBinary(programID, binaryFormat,
283                                                     const_cast<void*>(binary), length));
284                 if (this->gpu()->getErrorAndCheckForOOM() == GR_GL_NO_ERROR) {
285                     if (checkLinked) {
286                         cached = this->checkLinkStatus(programID, errorHandler, nullptr, nullptr);
287                     }
288                     if (cached) {
289                         this->addInputVars(inputs);
290                         this->computeCountsAndStrides(programID, geomProc, false);
291                     }
292                 } else {
293                     cached = false;
294                 }
295                 usedProgramBinaries = cached;
296                 break;
297             }
298 
299             case kGLSL_Tag:
300                 // Source cache hit, we don't need to compile the SkSL->GLSL
301                 GrPersistentCacheUtils::UnpackCachedShaders(&reader, glsl, &inputs, 1);
302                 break;
303 
304             case kSKSL_Tag:
305                 // SkSL cache hit, this should only happen in tools overriding the generated SkSL
306                 if (GrPersistentCacheUtils::UnpackCachedShaders(&reader, cached_sksl, &inputs, 1)) {
307                     for (int i = 0; i < kGrShaderTypeCount; ++i) {
308                         sksl[i] = &cached_sksl[i];
309                     }
310                 }
311                 break;
312 
313             default:
314                 // We got something invalid, so pretend it wasn't there
315                 reader.validate(false);
316                 break;
317         }
318         if (!reader.isValid()) {
319             cached = false;
320         }
321     }
322     if (!usedProgramBinaries) {
323         TRACE_EVENT0_ALWAYS("skia.shaders", "cache_miss");
324         // Either a cache miss, or we got something other than binaries from the cache
325 
326         /*
327            Fragment Shader
328         */
329         if (glsl[kFragment_GrShaderType].empty()) {
330             // Don't have cached GLSL, need to compile SkSL->GLSL
331             if (fFS.fForceHighPrecision) {
332                 settings.fForceHighPrecision = true;
333             }
334             std::unique_ptr<SkSL::Program> fs = GrSkSLtoGLSL(this->gpu(),
335                                                              SkSL::ProgramKind::kFragment,
336                                                              *sksl[kFragment_GrShaderType],
337                                                              settings,
338                                                              &glsl[kFragment_GrShaderType],
339                                                              errorHandler);
340             if (!fs) {
341                 cleanup_program(fGpu, programID, shadersToDelete);
342                 return nullptr;
343             }
344             inputs = fs->fInputs;
345         }
346 
347         this->addInputVars(inputs);
348         if (!this->compileAndAttachShaders(glsl[kFragment_GrShaderType], programID,
349                                            GR_GL_FRAGMENT_SHADER, &shadersToDelete, errorHandler)) {
350             cleanup_program(fGpu, programID, shadersToDelete);
351             return nullptr;
352         }
353 
354         /*
355            Vertex Shader
356         */
357         if (glsl[kVertex_GrShaderType].empty()) {
358             // Don't have cached GLSL, need to compile SkSL->GLSL
359             std::unique_ptr<SkSL::Program> vs = GrSkSLtoGLSL(this->gpu(),
360                                                              SkSL::ProgramKind::kVertex,
361                                                              *sksl[kVertex_GrShaderType],
362                                                              settings,
363                                                              &glsl[kVertex_GrShaderType],
364                                                              errorHandler);
365             if (!vs) {
366                 cleanup_program(fGpu, programID, shadersToDelete);
367                 return nullptr;
368             }
369         }
370         if (!this->compileAndAttachShaders(glsl[kVertex_GrShaderType], programID,
371                                            GR_GL_VERTEX_SHADER, &shadersToDelete, errorHandler)) {
372             cleanup_program(fGpu, programID, shadersToDelete);
373             return nullptr;
374         }
375 
376         // This also binds vertex attribute locations.
377         this->computeCountsAndStrides(programID, geomProc, true);
378 
379         /*
380            Tessellation Shaders
381         */
382         if (fProgramInfo.geomProc().willUseTessellationShaders()) {
383             // Tessellation shaders are not currently supported by SkSL. So here, we temporarily
384             // generate GLSL strings directly using back door methods on GrGeometryProcessor, and
385             // pass those raw strings on to the driver.
386             SkString versionAndExtensionDecls;
387             versionAndExtensionDecls.appendf("%s\n", this->shaderCaps()->versionDeclString());
388             if (const char* extensionString = this->shaderCaps()->tessellationExtensionString()) {
389                 versionAndExtensionDecls.appendf("#extension %s : require\n", extensionString);
390             }
391 
392             SkString tessControlShader = fGeometryProcessor->getTessControlShaderGLSL(
393                     geomProc, versionAndExtensionDecls.c_str(), fUniformHandler,
394                     *this->shaderCaps());
395             if (!this->compileAndAttachShaders(tessControlShader.c_str(), programID,
396                                                GR_GL_TESS_CONTROL_SHADER, &shadersToDelete,
397                                                errorHandler)) {
398                 cleanup_program(fGpu, programID, shadersToDelete);
399                 return nullptr;
400             }
401 
402             SkString tessEvaluationShader = fGeometryProcessor->getTessEvaluationShaderGLSL(
403                     geomProc, versionAndExtensionDecls.c_str(), fUniformHandler,
404                     *this->shaderCaps());
405             if (!this->compileAndAttachShaders(tessEvaluationShader.c_str(), programID,
406                                                GR_GL_TESS_EVALUATION_SHADER, &shadersToDelete,
407                                                errorHandler)) {
408                 cleanup_program(fGpu, programID, shadersToDelete);
409                 return nullptr;
410             }
411         }
412 
413         /*
414            Geometry Shader
415         */
416         if (geomProc.willUseGeoShader()) {
417             if (glsl[kGeometry_GrShaderType].empty()) {
418                 // Don't have cached GLSL, need to compile SkSL->GLSL
419                 std::unique_ptr<SkSL::Program> gs;
420                 gs = GrSkSLtoGLSL(this->gpu(),
421                                   SkSL::ProgramKind::kGeometry,
422                                   *sksl[kGeometry_GrShaderType],
423                                   settings,
424                                   &glsl[kGeometry_GrShaderType],
425                                   errorHandler);
426                 if (!gs) {
427                     cleanup_program(fGpu, programID, shadersToDelete);
428                     return nullptr;
429                 }
430             }
431             if (!this->compileAndAttachShaders(glsl[kGeometry_GrShaderType], programID,
432                                                GR_GL_GEOMETRY_SHADER, &shadersToDelete,
433                                                errorHandler)) {
434                 cleanup_program(fGpu, programID, shadersToDelete);
435                 return nullptr;
436             }
437         }
438         this->bindProgramResourceLocations(programID);
439 
440         {
441             TRACE_EVENT0_ALWAYS("skia.shaders", "driver_link_program");
442             GL_CALL(LinkProgram(programID));
443             if (checkLinked) {
444                 if (!this->checkLinkStatus(programID, errorHandler, sksl, glsl)) {
445                     cleanup_program(fGpu, programID, shadersToDelete);
446                     return nullptr;
447                 }
448             }
449         }
450     }
451     this->resolveProgramResourceLocations(programID, usedProgramBinaries);
452 
453     cleanup_shaders(fGpu, shadersToDelete);
454 
455     // We temporarily can't cache tessellation shaders while using back door GLSL.
456     //
457     // We also can't cache SkSL or GLSL if we were given a precompiled program, but there's not
458     // much point in doing so.
459     if (!cached && !geomProc.willUseTessellationShaders() && !precompiledProgram) {
460         // FIXME: Remove the check for tessellation shaders in the above 'if' once the back door
461         // GLSL mechanism is removed.
462         (void)&GrGLSLGeometryProcessor::getTessControlShaderGLSL;
463         bool isSkSL = false;
464         if (fGpu->getContext()->priv().options().fShaderCacheStrategy ==
465                 GrContextOptions::ShaderCacheStrategy::kSkSL) {
466             for (int i = 0; i < kGrShaderTypeCount; ++i) {
467                 glsl[i] = GrShaderUtils::PrettyPrint(*sksl[i]);
468             }
469             isSkSL = true;
470         }
471         this->storeShaderInCache(inputs, programID, glsl, isSkSL, &settings);
472     }
473     return this->createProgram(programID);
474 }
475 
bindProgramResourceLocations(GrGLuint programID)476 void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) {
477     fUniformHandler.bindUniformLocations(programID, fGpu->glCaps());
478 
479     const GrGLCaps& caps = this->gpu()->glCaps();
480     if (fFS.hasCustomColorOutput() && caps.bindFragDataLocationSupport()) {
481         GL_CALL(BindFragDataLocation(programID, 0,
482                                      GrGLSLFragmentShaderBuilder::DeclaredColorOutputName()));
483     }
484     if (fFS.hasSecondaryOutput() && caps.shaderCaps()->mustDeclareFragmentShaderOutput()) {
485         GL_CALL(BindFragDataLocationIndexed(programID, 0, 1,
486                                   GrGLSLFragmentShaderBuilder::DeclaredSecondaryColorOutputName()));
487     }
488 }
489 
checkLinkStatus(GrGLuint programID,GrContextOptions::ShaderErrorHandler * errorHandler,SkSL::String * sksl[],const SkSL::String glsl[])490 bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID,
491                                          GrContextOptions::ShaderErrorHandler* errorHandler,
492                                          SkSL::String* sksl[], const SkSL::String glsl[]) {
493     GrGLint linked = GR_GL_INIT_ZERO;
494     GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
495     if (!linked) {
496         SkSL::String allShaders;
497         if (sksl) {
498             allShaders.appendf("// Vertex SKSL\n%s\n", sksl[kVertex_GrShaderType]->c_str());
499             if (!sksl[kGeometry_GrShaderType]->empty()) {
500                 allShaders.appendf("// Geometry SKSL\n%s\n", sksl[kGeometry_GrShaderType]->c_str());
501             }
502             allShaders.appendf("// Fragment SKSL\n%s\n", sksl[kFragment_GrShaderType]->c_str());
503         }
504         if (glsl) {
505             allShaders.appendf("// Vertex GLSL\n%s\n", glsl[kVertex_GrShaderType].c_str());
506             if (!glsl[kGeometry_GrShaderType].empty()) {
507                 allShaders.appendf("// Geometry GLSL\n%s\n", glsl[kGeometry_GrShaderType].c_str());
508             }
509             allShaders.appendf("// Fragment GLSL\n%s\n", glsl[kFragment_GrShaderType].c_str());
510         }
511         GrGLint infoLen = GR_GL_INIT_ZERO;
512         GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
513         SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
514         if (infoLen > 0) {
515             // retrieve length even though we don't need it to workaround
516             // bug in chrome cmd buffer param validation.
517             GrGLsizei length = GR_GL_INIT_ZERO;
518             GL_CALL(GetProgramInfoLog(programID, infoLen+1, &length, (char*)log.get()));
519         }
520         errorHandler->compileError(allShaders.c_str(), infoLen > 0 ? (const char*)log.get() : "");
521     }
522     return SkToBool(linked);
523 }
524 
resolveProgramResourceLocations(GrGLuint programID,bool force)525 void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID, bool force) {
526     fUniformHandler.getUniformLocations(programID, fGpu->glCaps(), force);
527 }
528 
createProgram(GrGLuint programID)529 sk_sp<GrGLProgram> GrGLProgramBuilder::createProgram(GrGLuint programID) {
530     return GrGLProgram::Make(fGpu,
531                              fUniformHandles,
532                              programID,
533                              fUniformHandler.fUniforms,
534                              fUniformHandler.fSamplers,
535                              std::move(fGeometryProcessor),
536                              std::move(fXferProcessor),
537                              std::move(fFPImpls),
538                              std::move(fAttributes),
539                              fVertexAttributeCnt,
540                              fInstanceAttributeCnt,
541                              fVertexStride,
542                              fInstanceStride);
543 }
544 
PrecompileProgram(GrDirectContext * dContext,GrGLPrecompiledProgram * precompiledProgram,const SkData & cachedData)545 bool GrGLProgramBuilder::PrecompileProgram(GrDirectContext* dContext,
546                                            GrGLPrecompiledProgram* precompiledProgram,
547                                            const SkData& cachedData) {
548     SkReadBuffer reader(cachedData.data(), cachedData.size());
549     SkFourByteTag shaderType = GrPersistentCacheUtils::GetType(&reader);
550     if (shaderType != kSKSL_Tag) {
551         // TODO: Support GLSL, and maybe even program binaries, too?
552         return false;
553     }
554 
555     GrGLGpu* glGpu = static_cast<GrGLGpu*>(dContext->priv().getGpu());
556 
557     const GrGLInterface* gl = glGpu->glInterface();
558     auto errorHandler = dContext->priv().getShaderErrorHandler();
559 
560     SkSL::Program::Settings settings;
561     settings.fSharpenTextures = dContext->priv().options().fSharpenMipmappedTextures;
562     GrPersistentCacheUtils::ShaderMetadata meta;
563     meta.fSettings = &settings;
564 
565     SkSL::String shaders[kGrShaderTypeCount];
566     SkSL::Program::Inputs inputs;
567     if (!GrPersistentCacheUtils::UnpackCachedShaders(&reader, shaders, &inputs, 1, &meta)) {
568         return false;
569     }
570 
571     GrGLuint programID;
572     GR_GL_CALL_RET(gl, programID, CreateProgram());
573     if (0 == programID) {
574         return false;
575     }
576 
577     SkTDArray<GrGLuint> shadersToDelete;
578 
579     auto compileShader = [&](SkSL::ProgramKind kind, const SkSL::String& sksl, GrGLenum type) {
580         SkSL::String glsl;
581         auto program = GrSkSLtoGLSL(glGpu, kind, sksl, settings, &glsl, errorHandler);
582         if (!program) {
583             return false;
584         }
585 
586         if (GrGLuint shaderID = GrGLCompileAndAttachShader(glGpu->glContext(), programID, type,
587                                                            glsl, glGpu->pipelineBuilder()->stats(),
588                                                            errorHandler)) {
589             shadersToDelete.push_back(shaderID);
590             return true;
591         } else {
592             return false;
593         }
594     };
595 
596     if (!compileShader(SkSL::ProgramKind::kFragment,
597                        shaders[kFragment_GrShaderType],
598                        GR_GL_FRAGMENT_SHADER) ||
599         !compileShader(SkSL::ProgramKind::kVertex,
600                        shaders[kVertex_GrShaderType],
601                        GR_GL_VERTEX_SHADER) ||
602         (!shaders[kGeometry_GrShaderType].empty() &&
603          !compileShader(SkSL::ProgramKind::kGeometry,
604                        shaders[kGeometry_GrShaderType],
605                        GR_GL_GEOMETRY_SHADER))) {
606         cleanup_program(glGpu, programID, shadersToDelete);
607         return false;
608     }
609 
610     for (int i = 0; i < meta.fAttributeNames.count(); ++i) {
611         GR_GL_CALL(glGpu->glInterface(), BindAttribLocation(programID, i,
612                                                           meta.fAttributeNames[i].c_str()));
613     }
614 
615     const GrGLCaps& caps = glGpu->glCaps();
616     if (meta.fHasCustomColorOutput && caps.bindFragDataLocationSupport()) {
617         GR_GL_CALL(glGpu->glInterface(),
618                    BindFragDataLocation(programID, 0,
619                                         GrGLSLFragmentShaderBuilder::DeclaredColorOutputName()));
620     }
621     if (meta.fHasSecondaryColorOutput && caps.shaderCaps()->mustDeclareFragmentShaderOutput()) {
622         GR_GL_CALL(glGpu->glInterface(),
623                    BindFragDataLocationIndexed(programID, 0, 1,
624                                GrGLSLFragmentShaderBuilder::DeclaredSecondaryColorOutputName()));
625     }
626 
627     GR_GL_CALL(glGpu->glInterface(), LinkProgram(programID));
628     GrGLint linked = GR_GL_INIT_ZERO;
629     GR_GL_CALL(glGpu->glInterface(), GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
630     if (!linked) {
631         cleanup_program(glGpu, programID, shadersToDelete);
632         return false;
633     }
634 
635     cleanup_shaders(glGpu, shadersToDelete);
636 
637     precompiledProgram->fProgramID = programID;
638     precompiledProgram->fInputs = inputs;
639     return true;
640 }
641