| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2014 Google Inc. | 2  * Copyright 2014 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include "GrGLShaderStringBuilder.h" | 8 #include "GrGLShaderStringBuilder.h" | 
| 9 #include "gl/GrGLGpu.h" | 9 #include "gl/GrGLGpu.h" | 
| 10 #include "gl/GrGLSLPrettyPrint.h" | 10 #include "gl/GrGLSLPrettyPrint.h" | 
| 11 #include "SkTraceEvent.h" | 11 #include "SkTraceEvent.h" | 
|  | 12 #include "SkSLCompiler.h" | 
|  | 13 #include "SkSLGLSLCodeGenerator.h" | 
|  | 14 #include "ir/SkSLProgram.h" | 
| 12 | 15 | 
| 13 #define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X) | 16 #define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X) | 
| 14 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X) | 17 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X) | 
| 15 | 18 | 
| 16 // Print the source code for all shaders generated. | 19 // Print the source code for all shaders generated. | 
| 17 static const bool c_PrintShaders{false}; | 20 static const bool c_PrintShaders{false}; | 
| 18 | 21 | 
| 19 static void print_shader_source(const char** strings, int* lengths, int count); | 22 static void print_shader_source(const char** strings, int* lengths, int count); | 
| 20 | 23 | 
|  | 24 SkSL::GLCaps GrGLSkSLCapsForContext(const GrGLContext& context) { | 
|  | 25     GrGLStandard standard = context.standard(); | 
|  | 26     const GrGLCaps* caps = context.caps(); | 
|  | 27     const GrGLSLCaps* glslCaps = caps->glslCaps(); | 
|  | 28     SkSL::GLCaps result; | 
|  | 29     switch (standard) { | 
|  | 30         case kGL_GrGLStandard: | 
|  | 31             result.fStandard = SkSL::GLCaps::kGL_Standard; | 
|  | 32             break; | 
|  | 33         case kGLES_GrGLStandard: | 
|  | 34             result.fStandard = SkSL::GLCaps::kGLES_Standard; | 
|  | 35             break; | 
|  | 36         default: | 
|  | 37             SkASSERT(false); | 
|  | 38             result.fStandard = SkSL::GLCaps::kGL_Standard; | 
|  | 39     } | 
|  | 40 | 
|  | 41     switch (glslCaps->generation()) { | 
|  | 42         case k110_GrGLSLGeneration: | 
|  | 43             if (kGLES_GrGLStandard == standard) { | 
|  | 44                 // ES2's shader language is based on GLSL 1.20 but is version 1.
     00 of the ES | 
|  | 45                 // language | 
|  | 46                 result.fVersion = 100; | 
|  | 47             } else { | 
|  | 48                 SkASSERT(kGL_GrGLStandard == standard); | 
|  | 49                 result.fVersion = 110; | 
|  | 50             } | 
|  | 51             break; | 
|  | 52         case k130_GrGLSLGeneration: | 
|  | 53             SkASSERT(kGL_GrGLStandard == standard); | 
|  | 54             result.fVersion = 130; | 
|  | 55             break; | 
|  | 56         case k140_GrGLSLGeneration: | 
|  | 57             SkASSERT(kGL_GrGLStandard == standard); | 
|  | 58             result.fVersion = 140; | 
|  | 59             break; | 
|  | 60         case k150_GrGLSLGeneration: | 
|  | 61             SkASSERT(kGL_GrGLStandard == standard); | 
|  | 62             result.fVersion = 150; | 
|  | 63             break; | 
|  | 64         case k330_GrGLSLGeneration: | 
|  | 65             if (kGLES_GrGLStandard == standard) { | 
|  | 66                 result.fVersion = 300; | 
|  | 67             } else { | 
|  | 68                 SkASSERT(kGL_GrGLStandard == standard); | 
|  | 69                 result.fVersion = 330; | 
|  | 70             } | 
|  | 71             break; | 
|  | 72         case k400_GrGLSLGeneration: | 
|  | 73             SkASSERT(kGL_GrGLStandard == standard); | 
|  | 74             result.fVersion = 400; | 
|  | 75             break; | 
|  | 76         case k310es_GrGLSLGeneration: | 
|  | 77             SkASSERT(kGLES_GrGLStandard == standard); | 
|  | 78             result.fVersion = 310; | 
|  | 79             break; | 
|  | 80         case k320es_GrGLSLGeneration: | 
|  | 81             SkASSERT(kGLES_GrGLStandard == standard); | 
|  | 82             result.fVersion = 320; | 
|  | 83             break; | 
|  | 84     } | 
|  | 85     result.fIsCoreProfile = caps->isCoreProfile(); | 
|  | 86     result.fUsesPrecisionModifiers = glslCaps->usesPrecisionModifiers(); | 
|  | 87     result.fMustDeclareFragmentShaderOutput = glslCaps->mustDeclareFragmentShade
     rOutput(); | 
|  | 88     result.fCanUseMinAndAbsTogether = glslCaps->canUseMinAndAbsTogether(); | 
|  | 89     return result; | 
|  | 90 } | 
|  | 91 | 
|  | 92 static void dump_string(std::string s) { | 
|  | 93     // on Android, SkDebugf only displays the first 1K characters of output, whi
     ch results in | 
|  | 94     // incomplete shader source code. Print each line individually to avoid this
      problem. | 
|  | 95     size_t index = 0; | 
|  | 96     for (;;) { | 
|  | 97         size_t next = s.find("\n", index); | 
|  | 98         if (next == std::string::npos) { | 
|  | 99             SkDebugf("%s", s.substr(index).c_str()); | 
|  | 100             break; | 
|  | 101         } else { | 
|  | 102             SkDebugf("%s", s.substr(index, next - index + 1).c_str()); | 
|  | 103             index = next + 1; | 
|  | 104         } | 
|  | 105     } | 
|  | 106 } | 
|  | 107 | 
| 21 GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, | 108 GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, | 
| 22                                     GrGLuint programId, | 109                                     GrGLuint programId, | 
| 23                                     GrGLenum type, | 110                                     GrGLenum type, | 
| 24                                     const char** strings, | 111                                     const char** strings, | 
| 25                                     int* lengths, | 112                                     int* lengths, | 
| 26                                     int count, | 113                                     int count, | 
| 27                                     GrGpu::Stats* stats) { | 114                                     GrGpu::Stats* stats) { | 
| 28     const GrGLInterface* gli = glCtx.interface(); | 115     const GrGLInterface* gli = glCtx.interface(); | 
| 29 | 116 | 
| 30     GrGLuint shaderId; | 117     GrGLuint shaderId; | 
| 31     GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); | 118     GR_GL_CALL_RET(gli, shaderId, CreateShader(type)); | 
| 32     if (0 == shaderId) { | 119     if (0 == shaderId) { | 
| 33         return 0; | 120         return 0; | 
| 34     } | 121     } | 
| 35 | 122 | 
|  | 123     std::string sksl; | 
| 36 #ifdef SK_DEBUG | 124 #ifdef SK_DEBUG | 
| 37     SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths,
      count, false); | 125     SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths,
      count, false); | 
| 38     const GrGLchar* sourceStr = prettySource.c_str(); | 126     sksl = std::string(prettySource.c_str()); | 
| 39     GrGLint sourceLength = static_cast<GrGLint>(prettySource.size()); |  | 
| 40     GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); |  | 
| 41 #else | 127 #else | 
| 42     GR_GL_CALL(gli, ShaderSource(shaderId, count, strings, lengths)); | 128     for (int i = 0; i < count; i++) { | 
|  | 129         sksl.append(strings[i], lengths[i]); | 
|  | 130     } | 
| 43 #endif | 131 #endif | 
| 44 | 132 | 
|  | 133     std::string glsl; | 
|  | 134     SkSL::Compiler& compiler = *glCtx.compiler(); | 
|  | 135     SkSL::GLCaps caps = GrGLSkSLCapsForContext(glCtx); | 
|  | 136     SkASSERT(type == GR_GL_VERTEX_SHADER || type == GR_GL_FRAGMENT_SHADER); | 
|  | 137     SkDEBUGCODE(bool result = )compiler.toGLSL(type == GR_GL_VERTEX_SHADER | 
|  | 138                                                                     ? SkSL::Prog
     ram::kVertex_Kind | 
|  | 139                                                                     : SkSL::Prog
     ram::kFragment_Kind, | 
|  | 140                                                std::string(sksl.c_str()), | 
|  | 141                                                caps, | 
|  | 142                                                &glsl); | 
|  | 143 #ifdef SK_DEBUG | 
|  | 144     if (!result) { | 
|  | 145         SkDebugf("SKSL compilation error\n----------------------\n"); | 
|  | 146         SkDebugf("SKSL:\n"); | 
|  | 147         dump_string(sksl); | 
|  | 148         SkDebugf("\nErrors:\n%s\n", compiler.errorText().c_str()); | 
|  | 149         SkDEBUGFAIL("SKSL compilation failed!\n"); | 
|  | 150     } | 
|  | 151 #endif | 
|  | 152 | 
|  | 153     const char* glslChars = glsl.c_str(); | 
|  | 154     GrGLint glslLength = (GrGLint) glsl.length(); | 
|  | 155     GR_GL_CALL(gli, ShaderSource(shaderId, 1, &glslChars, &glslLength)); | 
|  | 156 | 
| 45     // If tracing is enabled in chrome then we pretty print | 157     // If tracing is enabled in chrome then we pretty print | 
| 46     bool traceShader; | 158     bool traceShader; | 
| 47     TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), &t
     raceShader); | 159     TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), &t
     raceShader); | 
| 48     if (traceShader) { | 160     if (traceShader) { | 
| 49         SkString shader = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, c
     ount, false); | 161         SkString shader = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, c
     ount, false); | 
| 50         TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::G
     LShader", | 162         TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::G
     LShader", | 
| 51                              TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(
     shader.c_str())); | 163                              TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(
     shader.c_str())); | 
| 52     } | 164     } | 
| 53 | 165 | 
| 54     stats->incShaderCompilations(); | 166     stats->incShaderCompilations(); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 65 | 177 | 
| 66         if (!compiled) { | 178         if (!compiled) { | 
| 67             GrGLint infoLen = GR_GL_INIT_ZERO; | 179             GrGLint infoLen = GR_GL_INIT_ZERO; | 
| 68             GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLe
     n)); | 180             GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLe
     n)); | 
| 69             SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugg
     er | 181             SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugg
     er | 
| 70             if (infoLen > 0) { | 182             if (infoLen > 0) { | 
| 71                 // retrieve length even though we don't need it to workaround bu
     g in Chromium cmd | 183                 // retrieve length even though we don't need it to workaround bu
     g in Chromium cmd | 
| 72                 // buffer param validation. | 184                 // buffer param validation. | 
| 73                 GrGLsizei length = GR_GL_INIT_ZERO; | 185                 GrGLsizei length = GR_GL_INIT_ZERO; | 
| 74                 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, &length, (
     char*)log.get())); | 186                 GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1, &length, (
     char*)log.get())); | 
| 75                 print_shader_source(strings, lengths, count); | 187                 SkDebugf("GLSL compilation error\n----------------------\n"); | 
| 76                 SkDebugf("\n%s", (const char*)log.get()); | 188                 SkDebugf("SKSL:\n"); | 
|  | 189                 dump_string(sksl); | 
|  | 190                 SkDebugf("GLSL:\n"); | 
|  | 191                 dump_string(glsl); | 
|  | 192                 SkDebugf("Errors:\n%s\n", (const char*) log.get()); | 
| 77             } | 193             } | 
| 78             SkDEBUGFAIL("Shader compilation failed!"); | 194             SkDEBUGFAIL("GLSL compilation failed!"); | 
| 79             GR_GL_CALL(gli, DeleteShader(shaderId)); | 195             GR_GL_CALL(gli, DeleteShader(shaderId)); | 
| 80             return 0; | 196             return 0; | 
| 81         } | 197         } | 
| 82     } | 198     } | 
| 83 | 199 | 
| 84     if (c_PrintShaders) { | 200     if (c_PrintShaders) { | 
| 85         print_shader_source(strings, lengths, count); | 201         print_shader_source(strings, lengths, count); | 
| 86     } | 202     } | 
| 87 | 203 | 
| 88     // Attach the shader, but defer deletion until after we have linked the prog
     ram. | 204     // Attach the shader, but defer deletion until after we have linked the prog
     ram. | 
| 89     // This works around a bug in the Android emulator's GLES2 wrapper which | 205     // This works around a bug in the Android emulator's GLES2 wrapper which | 
| 90     // will immediately delete the shader object and free its memory even though
      it's | 206     // will immediately delete the shader object and free its memory even though
      it's | 
| 91     // attached to a program, which then causes glLinkProgram to fail. | 207     // attached to a program, which then causes glLinkProgram to fail. | 
| 92     GR_GL_CALL(gli, AttachShader(programId, shaderId)); | 208     GR_GL_CALL(gli, AttachShader(programId, shaderId)); | 
| 93 | 209 | 
| 94     return shaderId; | 210     return shaderId; | 
| 95 } | 211 } | 
| 96 | 212 | 
| 97 static void print_shader_source(const char** strings, int* lengths, int count) { | 213 static void print_shader_source(const char** strings, int* lengths, int count) { | 
| 98     const SkString& pretty = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths
     , count, true); | 214     const SkString& pretty = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths
     , count, true); | 
| 99     SkTArray<SkString> lines; | 215     SkTArray<SkString> lines; | 
| 100     SkStrSplit(pretty.c_str(), "\n", &lines); | 216     SkStrSplit(pretty.c_str(), "\n", &lines); | 
| 101     for (const SkString& line : lines) { | 217     for (const SkString& line : lines) { | 
| 102         // Print the shader one line at the time so it doesn't get truncated by 
     the adb log. | 218         // Print the shader one line at the time so it doesn't get truncated by 
     the adb log. | 
| 103         SkDebugf("%s\n", line.c_str()); | 219         SkDebugf("%s\n", line.c_str()); | 
| 104     } | 220     } | 
| 105 } | 221 } | 
| OLD | NEW | 
|---|