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