130ba436f04e61d4505fb854d5fc56079636e0788joshualitt/* 230ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Copyright 2014 Google Inc. 330ba436f04e61d4505fb854d5fc56079636e0788joshualitt * 430ba436f04e61d4505fb854d5fc56079636e0788joshualitt * Use of this source code is governed by a BSD-style license that can be 530ba436f04e61d4505fb854d5fc56079636e0788joshualitt * found in the LICENSE file. 630ba436f04e61d4505fb854d5fc56079636e0788joshualitt */ 730ba436f04e61d4505fb854d5fc56079636e0788joshualitt 830ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "GrGLShaderStringBuilder.h" 930ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "../GrGpuGL.h" 1030ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "gl/GrGLSLPrettyPrint.h" 1130ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "SkRTConf.h" 1230ba436f04e61d4505fb854d5fc56079636e0788joshualitt#include "SkTraceEvent.h" 1330ba436f04e61d4505fb854d5fc56079636e0788joshualitt 1430ba436f04e61d4505fb854d5fc56079636e0788joshualitt#define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X) 1530ba436f04e61d4505fb854d5fc56079636e0788joshualitt#define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X) 1630ba436f04e61d4505fb854d5fc56079636e0788joshualitt 1730ba436f04e61d4505fb854d5fc56079636e0788joshualittSK_CONF_DECLARE(bool, c_PrintShaders, "gpu.printShaders", false, 1830ba436f04e61d4505fb854d5fc56079636e0788joshualitt "Print the source code for all shaders generated."); 1930ba436f04e61d4505fb854d5fc56079636e0788joshualitt 2030ba436f04e61d4505fb854d5fc56079636e0788joshualittGrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, 2130ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLuint programId, 2230ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLenum type, 23754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips const SkString& shaderSrc, 24754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrContext::GPUStats* gpuStats) { 2530ba436f04e61d4505fb854d5fc56079636e0788joshualitt const GrGLInterface* gli = glCtx.interface(); 2630ba436f04e61d4505fb854d5fc56079636e0788joshualitt 27754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrGLuint shaderId; 28754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); 29754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips if (0 == shaderId) { 30754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips return 0; 31754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips } 3230ba436f04e61d4505fb854d5fc56079636e0788joshualitt 33754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips#ifdef SK_DEBUG 34754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, false); 35754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips const GrGLchar* sourceStr = prettySource.c_str(); 36754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrGLint sourceLength = static_cast<GrGLint>(prettySource.size()); 37754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips#else 38754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size()); 39754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips const GrGLchar* sourceStr = shaderSrc.c_str(); 40754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips#endif 41754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); 42754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips gpuStats->incShaderCompilations(); 43754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GR_GL_CALL(gli, CompileShader(shaderId)); 4430ba436f04e61d4505fb854d5fc56079636e0788joshualitt 45754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds. 46754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips bool checkCompiled = !glCtx.isChromium(); 47754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips#ifdef SK_DEBUG 48754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips checkCompiled = true; 49754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips#endif 50754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips if (checkCompiled) { 51754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrGLint compiled = GR_GL_INIT_ZERO; 52754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled)); 5330ba436f04e61d4505fb854d5fc56079636e0788joshualitt 54754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips if (!compiled) { 55754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrGLint infoLen = GR_GL_INIT_ZERO; 56754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen)); 57754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger 58754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips if (infoLen > 0) { 59754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips // retrieve length even though we don't need it to workaround bug in Chromium cmd 60754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips // buffer param validation. 61754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrGLsizei length = GR_GL_INIT_ZERO; 62754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, 63754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips &length, (char*)log.get())); 64754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str()); 65754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrPrintf("\n%s", log.get()); 66754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips } 67754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips SkDEBUGFAIL("Shader compilation failed!"); 68754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GR_GL_CALL(gli, DeleteShader(shaderId)); 69754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips return 0; 70754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips } 71754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips } 7230ba436f04e61d4505fb854d5fc56079636e0788joshualitt 73754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader", 74754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shaderSrc.c_str())); 75754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips if (c_PrintShaders) { 76754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrPrintf(GrGLSLPrettyPrint::PrettyPrintGLSL(shaderSrc, true).c_str()); 77754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GrPrintf("\n"); 78754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips } 7930ba436f04e61d4505fb854d5fc56079636e0788joshualitt 80754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips // Attach the shader, but defer deletion until after we have linked the program. 81754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips // This works around a bug in the Android emulator's GLES2 wrapper which 82754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips // will immediately delete the shader object and free its memory even though it's 83754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips // attached to a program, which then causes glLinkProgram to fail. 84754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips GR_GL_CALL(gli, AttachShader(programId, shaderId)); 8530ba436f04e61d4505fb854d5fc56079636e0788joshualitt 86754f4e98d94d7c9ed76cd128cf983f9323a1885brobertphillips return shaderId; 8730ba436f04e61d4505fb854d5fc56079636e0788joshualitt} 88