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 "../GrGpuGL.h" 10 #include "gl/GrGLSLPrettyPrint.h" 11 #include "SkRTConf.h" 12 #include "SkTraceEvent.h" 13 14 #define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X) 15 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X) 16 17 SK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, 18 "Print the source code for all shaders generated."); 19 20 GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, 21 GrGLuint programId, 22 GrGLenum type, 23 const SkString& shaderSrc, 24 GrContext::GPUStats* gpuStats) { 25 const GrGLInterface* gli = glCtx.interface(); 26 27 GrGLuint shaderId; 28 GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); 29 if (0 == shaderId) { 30 return 0; 31 } 32 33 #ifdef SK_DEBUG 34 SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, false); 35 const GrGLchar* sourceStr = prettySource.c_str(); 36 GrGLint sourceLength = static_cast<GrGLint>(prettySource.size()); 37 #else 38 GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size()); 39 const GrGLchar* sourceStr = shaderSrc.c_str(); 40 #endif 41 GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); 42 gpuStats->incShaderCompilations(); 43 GR_GL_CALL(gli, CompileShader(shaderId)); 44 45 // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds. 46 bool checkCompiled = !glCtx.isChromium(); 47 #ifdef SK_DEBUG 48 checkCompiled = true; 49 #endif 50 if (checkCompiled) { 51 GrGLint compiled = GR_GL_INIT_ZERO; 52 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled)); 53 54 if (!compiled) { 55 GrGLint infoLen = GR_GL_INIT_ZERO; 56 GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen)); 57 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 58 if (infoLen > 0) { 59 // retrieve length even though we don't need it to workaround bug in Chromium cmd 60 // buffer param validation. 61 GrGLsizei length = GR_GL_INIT_ZERO; 62 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, 63 &length, (char*)log.get())); 64 GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str()); 65 GrPrintf("\n%s", log.get()); 66 } 67 SkDEBUGFAIL("Shader compilation failed!"); 68 GR_GL_CALL(gli, DeleteShader(shaderId)); 69 return 0; 70 } 71 } 72 73 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader", 74 TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shaderSrc.c_str())); 75 if (c_PrintShaders) { 76 GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str()); 77 GrPrintf("\n"); 78 } 79 80 // Attach the shader, but defer deletion until after we have linked the program. 81 // This works around a bug in the Android emulator's GLES2 wrapper which 82 // will immediately delete the shader object and free its memory even though it's 83 // attached to a program, which then causes glLinkProgram to fail. 84 GR_GL_CALL(gli, AttachShader(programId, shaderId)); 85 86 return shaderId; 87 } 88