• 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 #include "src/gpu/ganesh/gl/builders/GrGLShaderStringBuilder.h"
8 
9 #include "include/gpu/ganesh/gl/GrGLFunctions.h"
10 #include "include/gpu/ganesh/gl/GrGLInterface.h"
11 #include "include/private/base/SkTo.h"
12 #include "src/base/SkAutoMalloc.h"
13 #include "src/core/SkTraceEvent.h"
14 #include "src/gpu/ganesh/gl/GrGLDefines.h"
15 #include "src/gpu/ganesh/gl/GrGLGpu.h"
16 #include "src/gpu/ganesh/gl/GrGLUtil.h"
17 #include "src/sksl/SkSLString.h"
18 
19 #include <cstdint>
20 
GrGLCompileAndAttachShader(const GrGLContext & glCtx,GrGLuint programId,GrGLenum type,const std::string & glsl,bool shaderWasCached,GrThreadSafePipelineBuilder::Stats * stats,GrContextOptions::ShaderErrorHandler * errorHandler)21 GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
22                                     GrGLuint programId,
23                                     GrGLenum type,
24                                     const std::string& glsl,
25                                     bool shaderWasCached,
26                                     GrThreadSafePipelineBuilder::Stats* stats,
27                                     GrContextOptions::ShaderErrorHandler* errorHandler) {
28     TRACE_EVENT0_ALWAYS("skia.shaders", "driver_compile_shader");
29     const GrGLInterface* gli = glCtx.glInterface();
30 
31     // Specify GLSL source to the driver.
32     GrGLuint shaderId;
33     GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
34     if (0 == shaderId) {
35         return 0;
36     }
37     const GrGLchar* source = glsl.c_str();
38     GrGLint sourceLength = SkToInt(glsl.size());
39     GR_GL_CALL(gli, ShaderSource(shaderId, 1, &source, &sourceLength));
40 
41     stats->incShaderCompilations();
42     GR_GL_CALL(gli, CompileShader(shaderId));
43 
44     {
45         ATRACE_ANDROID_FRAMEWORK("checkCompiled");
46         GrGLint compiled = GR_GL_INIT_ZERO;
47         GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));
48 
49         if (!compiled) {
50             GrGLint infoLen = GR_GL_INIT_ZERO;
51             GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen));
52             SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
53             if (infoLen > 0) {
54                 // retrieve length even though we don't need it to workaround bug in Chromium cmd
55                 // buffer param validation.
56                 GrGLsizei length = GR_GL_INIT_ZERO;
57                 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, &length, (char*)log.get()));
58             }
59             errorHandler->compileError(
60                     glsl.c_str(), infoLen > 0 ? (const char*)log.get() : "", shaderWasCached);
61             GR_GL_CALL(gli, DeleteShader(shaderId));
62             return 0;
63         }
64     }
65 
66     // Attach the shader, but defer deletion until after we have linked the program.
67     // This works around a bug in the Android emulator's GLES2 wrapper which
68     // will immediately delete the shader object and free its memory even though it's
69     // attached to a program, which then causes glLinkProgram to fail.
70     GR_GL_CALL(gli, AttachShader(programId, shaderId));
71     return shaderId;
72 }
73 
GrGLCheckLinkStatus(const GrGLGpu * gpu,GrGLuint programID,bool shaderWasCached,GrContextOptions::ShaderErrorHandler * errorHandler,const std::string * sksl[kGrShaderTypeCount],const std::string glsl[kGrShaderTypeCount])74 bool GrGLCheckLinkStatus(const GrGLGpu* gpu,
75                          GrGLuint programID,
76                          bool shaderWasCached,
77                          GrContextOptions::ShaderErrorHandler* errorHandler,
78                          const std::string* sksl[kGrShaderTypeCount],
79                          const std::string glsl[kGrShaderTypeCount]) {
80     const GrGLInterface* gli = gpu->glInterface();
81 
82     GrGLint linked = GR_GL_INIT_ZERO;
83     GR_GL_CALL(gli, GetProgramiv(programID, GR_GL_LINK_STATUS, &linked));
84     if (!linked && errorHandler) {
85         std::string allShaders;
86 #if defined(SK_DEBUG)
87         #define SKSL_FORMAT "// Vertex SKSL\n%s\n// Fragment SKSL\n%s\n"
88 #else
89         #define SKSL_FORMAT "%s\n%s\n"
90 #endif
91         if (sksl) {
92             SkSL::String::appendf(&allShaders, SKSL_FORMAT,
93                                                sksl[kVertex_GrShaderType]->c_str(),
94                                                sksl[kFragment_GrShaderType]->c_str());
95         }
96         if (glsl) {
97             SkSL::String::appendf(&allShaders, SKSL_FORMAT,
98                                                glsl[kVertex_GrShaderType].c_str(),
99                                                glsl[kFragment_GrShaderType].c_str());
100         }
101 #undef SKSL_FORMAT
102         GrGLint infoLen = GR_GL_INIT_ZERO;
103         GR_GL_CALL(gli, GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen));
104         SkAutoMalloc log(infoLen+1);
105         if (infoLen > 0) {
106             // retrieve length even though we don't need it to workaround
107             // bug in chrome cmd buffer param validation.
108             GrGLsizei length = GR_GL_INIT_ZERO;
109             GR_GL_CALL(gli, GetProgramInfoLog(programID, infoLen+1, &length, (char*)log.get()));
110         }
111         const char* errorMsg = (infoLen > 0) ? (const char*)log.get()
112                                              : "link failed but did not provide an info log";
113         errorHandler->compileError(allShaders.c_str(), errorMsg, shaderWasCached);
114     }
115     return SkToBool(linked);
116 }
117