aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar ethannicholas <ethannicholas@google.com>2016-09-12 08:50:13 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-09-12 08:50:13 -0700
commit9b0fe3d125f237d9884732a48414fa85fc71b4e3 (patch)
treebf5470aacb44419cc3f5df2eded4f170be5a532a /src/gpu
parentd99858ad46ca2c3b5c38061be8b006b25d24c6e0 (diff)
Turned on SkSL->GLSL compiler
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/gl/GrGLContext.cpp12
-rw-r--r--src/gpu/gl/GrGLContext.h17
-rw-r--r--src/gpu/gl/GrGLGpu.cpp44
-rw-r--r--src/gpu/gl/builders/GrGLShaderStringBuilder.cpp95
-rw-r--r--src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp2
-rw-r--r--src/gpu/glsl/GrGLSLShaderVar.h10
6 files changed, 131 insertions, 49 deletions
diff --git a/src/gpu/gl/GrGLContext.cpp b/src/gpu/gl/GrGLContext.cpp
index 9e70b472c5..93f14cfc67 100644
--- a/src/gpu/gl/GrGLContext.cpp
+++ b/src/gpu/gl/GrGLContext.cpp
@@ -7,6 +7,7 @@
#include "GrGLContext.h"
#include "GrGLGLSL.h"
+#include "SkSLCompiler.h"
////////////////////////////////////////////////////////////////////////////////
@@ -63,6 +64,17 @@ GrGLContext* GrGLContext::Create(const GrGLInterface* interface, const GrContext
return new GrGLContext(args);
}
+GrGLContext::~GrGLContext() {
+ delete fCompiler;
+}
+
+SkSL::Compiler* GrGLContext::compiler() {
+ if (!fCompiler) {
+ fCompiler = new SkSL::Compiler();
+ }
+ return fCompiler;
+}
+
GrGLContextInfo::GrGLContextInfo(const ConstructorArgs& args) {
fInterface.reset(SkRef(args.fInterface));
fGLVersion = args.fGLVersion;
diff --git a/src/gpu/gl/GrGLContext.h b/src/gpu/gl/GrGLContext.h
index 6016f6859a..8a56535887 100644
--- a/src/gpu/gl/GrGLContext.h
+++ b/src/gpu/gl/GrGLContext.h
@@ -15,6 +15,9 @@
#include "GrGLUtil.h"
struct GrContextOptions;
+namespace SkSL {
+ class Compiler;
+}
/**
* Encapsulates information about an OpenGL context including the OpenGL
@@ -39,6 +42,8 @@ public:
const GrGLExtensions& extensions() const { return fInterface->fExtensions; }
+ virtual ~GrGLContextInfo() {}
+
protected:
struct ConstructorArgs {
const GrGLInterface* fInterface;
@@ -64,7 +69,7 @@ protected:
};
/**
- * Extension of GrGLContextInfo that also provides access to GrGLInterface.
+ * Extension of GrGLContextInfo that also provides access to GrGLInterface and SkSL::Compiler.
*/
class GrGLContext : public GrGLContextInfo {
public:
@@ -76,8 +81,16 @@ public:
const GrGLInterface* interface() const { return fInterface; }
+ SkSL::Compiler* compiler();
+
+ ~GrGLContext() override;
+
private:
- GrGLContext(const ConstructorArgs& args) : INHERITED(args) {}
+ GrGLContext(const ConstructorArgs& args)
+ : INHERITED(args)
+ , fCompiler(nullptr) {}
+
+ SkSL::Compiler* fCompiler;
typedef GrGLContextInfo INHERITED;
};
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index e002d5101b..e37f8430fb 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -3775,20 +3775,11 @@ bool GrGLGpu::createCopyProgram(int progIdx) {
fshaderTxt.append(";");
uTexture.appendDecl(glslCaps, &fshaderTxt);
fshaderTxt.append(";");
- const char* fsOutName;
- if (glslCaps->mustDeclareFragmentShaderOutput()) {
- oFragColor.appendDecl(glslCaps, &fshaderTxt);
- fshaderTxt.append(";");
- fsOutName = oFragColor.c_str();
- } else {
- fsOutName = "gl_FragColor";
- }
fshaderTxt.appendf(
"// Copy Program FS\n"
"void main() {"
- " %s = %s(u_texture, v_texCoord);"
+ " sk_FragColor = %s(u_texture, v_texCoord);"
"}",
- fsOutName,
GrGLSLTexture2DFunctionName(kVec2f_GrSLType, kSamplerTypes[progIdx], this->glslGeneration())
);
@@ -3921,14 +3912,6 @@ bool GrGLGpu::createMipmapProgram(int progIdx) {
}
uTexture.appendDecl(glslCaps, &fshaderTxt);
fshaderTxt.append(";");
- const char* fsOutName;
- if (glslCaps->mustDeclareFragmentShaderOutput()) {
- oFragColor.appendDecl(glslCaps, &fshaderTxt);
- fshaderTxt.append(";");
- fsOutName = oFragColor.c_str();
- } else {
- fsOutName = "gl_FragColor";
- }
const char* sampleFunction = GrGLSLTexture2DFunctionName(kVec2f_GrSLType,
kTexture2DSampler_GrSLType,
this->glslGeneration());
@@ -3939,19 +3922,19 @@ bool GrGLGpu::createMipmapProgram(int progIdx) {
if (oddWidth && oddHeight) {
fshaderTxt.appendf(
- " %s = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1) + "
- " %s(u_texture, v_texCoord2) + %s(u_texture, v_texCoord3)) * 0.25;",
- fsOutName, sampleFunction, sampleFunction, sampleFunction, sampleFunction
+ " sk_FragColor = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1) + "
+ " %s(u_texture, v_texCoord2) + %s(u_texture, v_texCoord3)) * 0.25;",
+ sampleFunction, sampleFunction, sampleFunction, sampleFunction
);
} else if (oddWidth || oddHeight) {
fshaderTxt.appendf(
- " %s = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1)) * 0.5;",
- fsOutName, sampleFunction, sampleFunction
+ " sk_FragColor = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1)) * 0.5;",
+ sampleFunction, sampleFunction
);
} else {
fshaderTxt.appendf(
- " %s = %s(u_texture, v_texCoord0);",
- fsOutName, sampleFunction
+ " sk_FragColor = %s(u_texture, v_texCoord0);",
+ sampleFunction
);
}
@@ -4038,20 +4021,11 @@ bool GrGLGpu::createWireRectProgram() {
&fshaderTxt);
uColor.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
fshaderTxt.append(";");
- const char* fsOutName;
- if (this->glCaps().glslCaps()->mustDeclareFragmentShaderOutput()) {
- oFragColor.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
- fshaderTxt.append(";");
- fsOutName = oFragColor.c_str();
- } else {
- fsOutName = "gl_FragColor";
- }
fshaderTxt.appendf(
"// Write Rect Program FS\n"
"void main() {"
- " %s = %s;"
+ " sk_FragColor = %s;"
"}",
- fsOutName,
uColor.c_str()
);
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
index d2e49a5cfb..0282fbb8a9 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,32 @@ 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;
+ SkSL::GLCaps caps = skslcaps_for_context(glCtx);
+ SkASSERT(type == GR_GL_VERTEX_SHADER || type == GR_GL_FRAGMENT_SHADER);
+ SkDEBUGCODE(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);
diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
index 7763f86e42..f1c655c58c 100644
--- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
+++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp
@@ -321,7 +321,7 @@ void GrGLSLFragmentShaderBuilder::enableSecondaryOutput() {
}
const char* GrGLSLFragmentShaderBuilder::getPrimaryColorOutputName() const {
- return fHasCustomColorOutput ? DeclaredColorOutputName() : "gl_FragColor";
+ return fHasCustomColorOutput ? DeclaredColorOutputName() : "sk_FragColor";
}
void GrGLSLFragmentBuilder::declAppendf(const char* fmt, ...) {
diff --git a/src/gpu/glsl/GrGLSLShaderVar.h b/src/gpu/glsl/GrGLSLShaderVar.h
index 9d162ecaa4..35ac4bcb84 100644
--- a/src/gpu/glsl/GrGLSLShaderVar.h
+++ b/src/gpu/glsl/GrGLSLShaderVar.h
@@ -213,24 +213,20 @@ public:
private:
static const char* TypeModifierString(const GrGLSLCaps* glslCaps, TypeModifier t) {
- GrGLSLGeneration gen = glslCaps->generation();
switch (t) {
case kNone_TypeModifier:
return "";
+ case kAttribute_TypeModifier: // fall through
+ case kVaryingIn_TypeModifier: // fall through
case kIn_TypeModifier:
return "in";
case kInOut_TypeModifier:
return "inout";
+ case kVaryingOut_TypeModifier: // fall through
case kOut_TypeModifier:
return "out";
case kUniform_TypeModifier:
return "uniform";
- case kAttribute_TypeModifier:
- return k110_GrGLSLGeneration == gen ? "attribute" : "in";
- case kVaryingIn_TypeModifier:
- return k110_GrGLSLGeneration == gen ? "varying" : "in";
- case kVaryingOut_TypeModifier:
- return k110_GrGLSLGeneration == gen ? "varying" : "out";
default:
SkFAIL("Unknown shader variable type modifier.");
return ""; // suppress warning