From cbc33b8e35748803782ca89ffadd6306adc6e350 Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Fri, 19 Apr 2019 14:16:19 -0400 Subject: [PATCH] Add SkSL viewing/editing to viewer Still only works with the GL backend. For other backends, need to add similar logic to the shader caching, and some extra checks in Viewer to force the SkSL flag on. But in GL, this lets you toggle the checkbox and see the SkSL / GLSL at will (and edit in either form). Change-Id: I6d392113aa9cbcbd6e64589b849de70d0ac3beeb Reviewed-on: https://skia-review.googlesource.com/c/skia/+/209165 Reviewed-by: Brian Salomon Commit-Queue: Brian Osman --- include/gpu/GrContextOptions.h | 5 ++++ src/gpu/gl/GrGLCaps.cpp | 5 ++++ src/gpu/gl/builders/GrGLProgramBuilder.cpp | 29 +++++++++++++++++++--- tools/viewer/Viewer.cpp | 13 +++++++--- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/include/gpu/GrContextOptions.h b/include/gpu/GrContextOptions.h index 3bfe6f383e..9a87718cb4 100644 --- a/include/gpu/GrContextOptions.h +++ b/include/gpu/GrContextOptions.h @@ -216,6 +216,11 @@ struct SK_API GrContextOptions { */ bool fWireframeMode = false; + /** + * Similar to fDisallowGLSLBinaryCaching. If set to true, SkSL shader strings will be cached. + */ + bool fCacheSKSL = false; + /** * Include or exclude specific GPU path renderers. */ diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 8e9952a2a7..4e044233bf 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -3009,6 +3009,11 @@ void GrGLCaps::onApplyOptionsOverrides(const GrContextOptions& options) { if (options.fDisallowGLSLBinaryCaching) { fProgramBinarySupport = false; } +#if GR_TEST_UTILS + if (options.fCacheSKSL) { + fProgramBinarySupport = false; + } +#endif } bool GrGLCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const { diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index 40968b1f85..885e363d83 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -15,6 +15,7 @@ #include "GrPersistentCacheUtils.h" #include "GrProgramDesc.h" #include "GrShaderCaps.h" +#include "GrSKSLPrettyPrint.h" #include "GrSwizzle.h" #include "SkAutoMalloc.h" #include "SkATrace.h" @@ -216,6 +217,14 @@ GrGLProgram* GrGLProgramBuilder::finalize() { #endif bool cached = fCached.get() != nullptr; SkSL::String glsl[kGrShaderTypeCount]; + SkSL::String* sksl[kGrShaderTypeCount] = { + &fVS.fCompilerString, + &fGS.fCompilerString, + &fFS.fCompilerString, + }; +#if GR_TEST_UTILS + SkSL::String cached_sksl[kGrShaderTypeCount]; +#endif if (cached) { if (fGpu->glCaps().programBinarySupport()) { // binary cache hit, just hand the binary to GL @@ -239,6 +248,13 @@ GrGLProgram* GrGLProgramBuilder::finalize() { } else { cached = false; } +#if GR_TEST_UTILS + } else if (fGpu->getContext()->priv().options().fCacheSKSL) { + GrPersistentCacheUtils::UnpackCachedGLSL(fCached.get(), &inputs, cached_sksl); + for (int i = 0; i < kGrShaderTypeCount; ++i) { + sksl[i] = &cached_sksl[i]; + } +#endif } else { // source cache hit, we don't need to compile the SkSL->GLSL GrPersistentCacheUtils::UnpackCachedGLSL(fCached.get(), &inputs, glsl); @@ -253,7 +269,7 @@ GrGLProgram* GrGLProgramBuilder::finalize() { } std::unique_ptr fs = GrSkSLtoGLSL(gpu()->glContext(), GR_GL_FRAGMENT_SHADER, - fFS.fCompilerString, + *sksl[kFragment_GrShaderType], settings, &glsl[kFragment_GrShaderType]); if (!fs) { @@ -279,7 +295,7 @@ GrGLProgram* GrGLProgramBuilder::finalize() { // Don't have cached GLSL, need to compile SkSL->GLSL std::unique_ptr vs = GrSkSLtoGLSL(gpu()->glContext(), GR_GL_VERTEX_SHADER, - fVS.fCompilerString, + *sksl[kVertex_GrShaderType], settings, &glsl[kVertex_GrShaderType]); if (!vs) { @@ -307,7 +323,7 @@ GrGLProgram* GrGLProgramBuilder::finalize() { std::unique_ptr gs; gs = GrSkSLtoGLSL(gpu()->glContext(), GR_GL_GEOMETRY_SHADER, - fGS.fCompilerString, + *sksl[kGeometry_GrShaderType], settings, &glsl[kGeometry_GrShaderType]); if (!gs) { @@ -354,6 +370,13 @@ GrGLProgram* GrGLProgramBuilder::finalize() { this->cleanupShaders(shadersToDelete); if (!cached) { +#if GR_TEST_UTILS + if (fGpu->getContext()->priv().options().fCacheSKSL) { + for (int i = 0; i < kGrShaderTypeCount; ++i) { + glsl[i] = GrSKSLPrettyPrint::PrettyPrint(*sksl[i]); + } + } +#endif this->storeShaderInCache(inputs, programID, glsl); } return this->createProgram(programID); diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 3e20c0f7cd..c2a359584d 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -1977,7 +1977,12 @@ void Viewer::drawImGui() { // Defer actually doing the load/save logic so that we can trigger a save when we // start or finish hovering on a tree node in the list below: bool doLoad = ImGui::Button("Load"); ImGui::SameLine(); - bool doSave = ImGui::Button("Save"); + bool doSave = ImGui::Button("Save"); ImGui::SameLine(); + if (ImGui::Checkbox("SkSL", ¶ms.fGrContextOptions.fCacheSKSL)) { + paramsChanged = true; + doLoad = true; + fDeferredActions.push_back([=]() { fPersistentCache.reset(); }); + } ImGui::BeginChild("##ScrollingRegion"); for (auto& entry : fCachedGLSL) { @@ -2008,8 +2013,10 @@ void Viewer::drawImGui() { if (doSave) { // The hovered item (if any) gets a special shader to make it identifiable SkSL::String highlight = ctx->priv().caps()->shaderCaps()->versionDeclString(); - highlight.append("out vec4 sk_FragColor;\n" - "void main() { sk_FragColor = vec4(1, 0, 1, 0.5); }"); + const char* f4Type = params.fGrContextOptions.fCacheSKSL ? "half4" : "vec4"; + highlight.appendf("out %s sk_FragColor;\n" + "void main() { sk_FragColor = %s(1, 0, 1, 0.5); }", + f4Type, f4Type); fPersistentCache.reset(); fWindow->getGrContext()->priv().getGpu()->resetShaderCacheForTesting();