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); |