Chromium Code Reviews| Index: src/gpu/gl/builders/GrGLShaderStringBuilder.cpp |
| diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp |
| index d2e49a5cfb0b5716b988aa4d3aaec1d4a5451050..2f1860aa5017d6933cb13a07afe56e49263e70f3 100644 |
| --- a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp |
| +++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp |
| @@ -9,6 +9,8 @@ |
| #include "gl/GrGLGpu.h" |
| #include "gl/GrGLSLPrettyPrint.h" |
| #include "SkTraceEvent.h" |
| +#include "SkSLCompiler.h" |
| +#include "ir/SkSLProgram.h" |
| #define GL_CALL(X) GR_GL_CALL(gpu->glInterface(), X) |
| #define GL_CALL_RET(R, X) GR_GL_CALL_RET(gpu->glInterface(), R, X) |
| @@ -18,6 +20,74 @@ static const bool c_PrintShaders{false}; |
| static void print_shader_source(const char** strings, int* lengths, int count); |
| +static SkSL::GLCaps skslcaps_for_context(const GrGLContext& context) { |
| + GrGLStandard standard = context.standard(); |
| + const GrGLCaps* caps = context.caps(); |
| + const GrGLSLCaps* glslCaps = caps->glslCaps(); |
| + SkSL::GLCaps result; |
| + switch (standard) { |
| + case kGL_GrGLStandard: |
| + result.fStandard = SkSL::GLCaps::kGL_Standard; |
| + break; |
| + case kGLES_GrGLStandard: |
| + result.fStandard = SkSL::GLCaps::kGLES_Standard; |
| + break; |
| + default: |
| + SkASSERT(false); |
| + result.fStandard = SkSL::GLCaps::kGL_Standard; |
| + } |
| + |
| + switch (glslCaps->generation()) { |
| + case k110_GrGLSLGeneration: |
| + if (kGLES_GrGLStandard == standard) { |
| + // ES2's shader language is based on GLSL 1.20 but is version 1.00 of the ES |
| + // language |
| + result.fVersion = 100; |
| + } else { |
| + SkASSERT(kGL_GrGLStandard == standard); |
| + result.fVersion = 110; |
| + } |
| + break; |
| + case k130_GrGLSLGeneration: |
| + SkASSERT(kGL_GrGLStandard == standard); |
| + result.fVersion = 130; |
| + break; |
| + case k140_GrGLSLGeneration: |
| + SkASSERT(kGL_GrGLStandard == standard); |
| + result.fVersion = 140; |
| + break; |
| + case k150_GrGLSLGeneration: |
| + SkASSERT(kGL_GrGLStandard == standard); |
| + result.fVersion = 150; |
| + break; |
| + case k330_GrGLSLGeneration: |
| + if (kGLES_GrGLStandard == standard) { |
| + result.fVersion = 300; |
| + } else { |
| + SkASSERT(kGL_GrGLStandard == standard); |
| + result.fVersion = 330; |
| + } |
| + break; |
| + case k400_GrGLSLGeneration: |
| + SkASSERT(kGL_GrGLStandard == standard); |
| + result.fVersion = 400; |
| + break; |
| + case k310es_GrGLSLGeneration: |
| + SkASSERT(kGLES_GrGLStandard == standard); |
| + result.fVersion = 310; |
| + break; |
| + case k320es_GrGLSLGeneration: |
| + SkASSERT(kGLES_GrGLStandard == standard); |
| + result.fVersion = 320; |
| + break; |
| + } |
| + result.fIsCoreProfile = caps->isCoreProfile(); |
| + result.fUsesPrecisionModifiers = glslCaps->usesPrecisionModifiers(); |
| + result.fMustDeclareFragmentShaderOutput = glslCaps->mustDeclareFragmentShaderOutput(); |
| + result.fCanUseMinAndAbsTogether = glslCaps->canUseMinAndAbsTogether(); |
| + return result; |
| +} |
| + |
| GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, |
| GrGLuint programId, |
| GrGLenum type, |
| @@ -33,15 +103,31 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx, |
| return 0; |
| } |
| + std::string sksl; |
| #ifdef SK_DEBUG |
| SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, false); |
| - const GrGLchar* sourceStr = prettySource.c_str(); |
| - GrGLint sourceLength = static_cast<GrGLint>(prettySource.size()); |
| - GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength)); |
| + sksl = std::string(prettySource.c_str()); |
| #else |
| - GR_GL_CALL(gli, ShaderSource(shaderId, count, strings, lengths)); |
| + for (int i = 0; i < count; i++) { |
| + sksl.append(strings[i], lengths[i]); |
| + } |
| #endif |
| + std::string glsl; |
| + // creating Compiler is expensive, and we are single-threaded anyway, so just reuse a static one |
| + static SkSL::Compiler compiler; |
|
bsalomon
2016/09/08 19:51:37
We only allow a single GrContext to be used on one
ethannicholas
2016/09/09 16:34:54
I moved the compiler instance into GrGLContext to
bsalomon
2016/09/12 13:48:57
I don't have a problem with including SkSLCompiler
ethannicholas
2016/09/12 14:53:26
error: invalid application of ‘sizeof’ to incomple
|
| + SkSL::GLCaps caps = skslcaps_for_context(glCtx); |
| + SkASSERT(type == GR_GL_VERTEX_SHADER || type == GR_GL_FRAGMENT_SHADER); |
| + bool result = compiler.toGLSL(type == GR_GL_VERTEX_SHADER ? SkSL::Program::kVertex_Kind |
| + : SkSL::Program::kFragment_Kind, |
| + std::string(sksl.c_str()), |
| + caps, |
| + &glsl); |
| + SkASSERTF(result, "SkSL errors:\n%s", compiler.errorText().c_str()); |
| + const char* glslChars = glsl.c_str(); |
| + GrGLint glslLength = (GrGLint) glsl.length(); |
| + GR_GL_CALL(gli, ShaderSource(shaderId, 1, &glslChars, &glslLength)); |
| + |
| // If tracing is enabled in chrome then we pretty print |
| bool traceShader; |
| TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), &traceShader); |