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 "GrGLShaderStringBuilder.h" 9 #include "GrSKSLPrettyPrint.h" 10 #include "SkAutoMalloc.h" 11 #include "SkSLCompiler.h" 12 #include "SkSLGLSLCodeGenerator.h" 13 #include "SkTraceEvent.h" 14 #include "gl/GrGLGpu.h" 15 #include "ir/SkSLProgram.h" 16 17 #define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X) 18 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X) 19 20 // Print the source code for all shaders generated. 21 static const bool c_PrintShaders{false}; 22 23 static void print_source_lines_with_numbers(const char* source, 24 std::function<void(const char*)> println) { 25 SkTArray<SkString> lines; 26 SkStrSplit(source, "\n", kStrict_SkStrSplitMode, &lines); 27 for (int i = 0; i < lines.count(); ++i) { 28 SkString& line = lines[i]; 29 line.prependf("%4i\t", i + 1); 30 println(line.c_str()); 31 } 32 } 33 34 // Prints shaders one line at the time. This ensures they don't get truncated by the adb log. 35 static void print_shaders_line_by_line(const char** skslStrings, int* lengths, 36 int count, const SkSL::String& glsl, 37 std::function<void(const char*)> println = [](const char* ln) { 38 SkDebugf("%s\n", ln); 39 }) { 40 SkString sksl = GrSKSLPrettyPrint::PrettyPrint(skslStrings, lengths, count, false); 41 println("SKSL:"); 42 print_source_lines_with_numbers(sksl.c_str(), println); 43 if (!glsl.isEmpty()) { 44 println("GLSL:"); 45 print_source_lines_with_numbers(glsl.c_str(), println); 46 } 47 } 48 49 std::unique_ptr<SkSL::Program> translate_to_glsl(const GrGLContext& context, GrGLenum type, 50 const char** skslStrings, int* lengths, int count, 51 const SkSL::Program::Settings& settings, 52 SkSL::String* glsl) { 53 SkString sksl; 54 #ifdef SK_DEBUG 55 sksl = GrSKSLPrettyPrint::PrettyPrint(skslStrings, lengths, count, false); 56 #else 57 for (int i = 0; i < count; i++) { 58 sksl.append(skslStrings[i], lengths[i]); 59 } 60 #endif 61 SkSL::Compiler* compiler = context.compiler(); 62 std::unique_ptr<SkSL::Program> program; 63 SkSL::Program::Kind programKind; 64 switch (type) { 65 case GR_GL_VERTEX_SHADER: programKind = SkSL::Program::kVertex_Kind; break; 66 case GR_GL_FRAGMENT_SHADER: programKind = SkSL::Program::kFragment_Kind; break; 67 case GR_GL_GEOMETRY_SHADER: programKind = SkSL::Program::kGeometry_Kind; break; 68 } 69 program = compiler->convertProgram(programKind, sksl, settings); 70 if (!program || !compiler->toGLSL(*program, glsl)) { 71 SkDebugf("SKSL compilation error\n----------------------\n"); 72 print_shaders_line_by_line(skslStrings, lengths, count, *glsl); 73 SkDebugf("\nErrors:\n%s\n", compiler->errorText().c_str()); 74 SkDEBUGFAIL("SKSL compilation failed!\n"); 75 return nullptr; 76 } 77 return program; 78 } 79 80 GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, 81 GrGLuint programId, 82 GrGLenum type, 83 const char** skslStrings, 84 int* lengths, 85 int count, 86 GrGpu::Stats* stats, 87 const SkSL::Program::Settings& settings, 88 SkSL::Program::Inputs* outInputs) { 89 const GrGLInterface* gli = glCtx.interface(); 90 91 SkSL::String glsl; 92 auto program = translate_to_glsl(glCtx, type, skslStrings, lengths, count, settings, &glsl); 93 if (!program) { 94 return 0; 95 } 96 97 // Specify GLSL source to the driver. 98 GrGLuint shaderId; 99 GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); 100 if (0 == shaderId) { 101 return 0; 102 } 103 const char* glslChars = glsl.c_str(); 104 GrGLint glslLength = (GrGLint) glsl.size(); 105 GR_GL_CALL(gli, ShaderSource(shaderId, 1, &glslChars, &glslLength)); 106 107 // Trace event for shader preceding driver compilation 108 bool traceShader; 109 TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), &traceShader); 110 if (traceShader) { 111 SkString shaderDebugString; 112 print_shaders_line_by_line(skslStrings, lengths, count, glsl, [&](const char* ln) { 113 shaderDebugString.append(ln); 114 shaderDebugString.append("\n"); 115 }); 116 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader", 117 TRACE_EVENT_SCOPE_THREAD, "shader", 118 TRACE_STR_COPY(shaderDebugString.c_str())); 119 } 120 121 stats->incShaderCompilations(); 122 GR_GL_CALL(gli, CompileShader(shaderId)); 123 124 // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds. 125 bool checkCompiled = kChromium_GrGLDriver != glCtx.driver(); 126 #ifdef SK_DEBUG 127 checkCompiled = true; 128 #endif 129 if (checkCompiled) { 130 GrGLint compiled = GR_GL_INIT_ZERO; 131 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled)); 132 133 if (!compiled) { 134 SkDebugf("GLSL compilation error\n----------------------\n"); 135 print_shaders_line_by_line(skslStrings, lengths, count, glsl); 136 GrGLint infoLen = GR_GL_INIT_ZERO; 137 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen)); 138 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 139 if (infoLen > 0) { 140 // retrieve length even though we don't need it to workaround bug in Chromium cmd 141 // buffer param validation. 142 GrGLsizei length = GR_GL_INIT_ZERO; 143 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, &length, (char*)log.get())); 144 SkDebugf("Errors:\n%s\n", (const char*) log.get()); 145 } 146 SkDEBUGFAIL("GLSL compilation failed!"); 147 GR_GL_CALL(gli, DeleteShader(shaderId)); 148 return 0; 149 } 150 } 151 152 if (c_PrintShaders) { 153 const char* typeName = "Unknown"; 154 switch (type) { 155 case GR_GL_VERTEX_SHADER: typeName = "Vertex"; break; 156 case GR_GL_GEOMETRY_SHADER: typeName = "Geometry"; break; 157 case GR_GL_FRAGMENT_SHADER: typeName = "Fragment"; break; 158 } 159 SkDebugf("---- %s shader ----------------------------------------------------\n", typeName); 160 print_shaders_line_by_line(skslStrings, lengths, count, glsl); 161 } 162 163 // Attach the shader, but defer deletion until after we have linked the program. 164 // This works around a bug in the Android emulator's GLES2 wrapper which 165 // will immediately delete the shader object and free its memory even though it's 166 // attached to a program, which then causes glLinkProgram to fail. 167 GR_GL_CALL(gli, AttachShader(programId, shaderId)); 168 *outInputs = program->fInputs; 169 return shaderId; 170 } 171 172 void GrGLPrintShader(const GrGLContext& context, GrGLenum type, const char** skslStrings, 173 int* lengths, int count, const SkSL::Program::Settings& settings) { 174 SkSL::String glsl; 175 if (translate_to_glsl(context, type, skslStrings, lengths, count, settings, &glsl)) { 176 print_shaders_line_by_line(skslStrings, lengths, count, glsl); 177 } 178 } 179