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 <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2019-04-19 14:16:19 -04:00 committed by Skia Commit-Bot
parent 6350cb0f4b
commit cbc33b8e35
4 changed files with 46 additions and 6 deletions

View File

@ -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.
*/

View File

@ -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 {

View File

@ -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<SkSL::Program> 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<SkSL::Program> 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<SkSL::Program> 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);

View File

@ -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", &params.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();