Add support for magenta highlights on shader mouseover in Metal.
Change-Id: Ia449e2cfd8b1153e7ab1cd7ad1916550aecf55ef
Bug: skia:10428
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/298744
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index ec69093..45d4fbd 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -1693,6 +1693,35 @@
return dc.fDragging;
}
+static SkSL::String build_sksl_highlight_shader() {
+ return SkSL::String("out half4 sk_FragColor;\n"
+ "void main() { sk_FragColor = half4(1, 0, 1, 0.5); }");
+}
+
+static SkSL::String build_metal_highlight_shader(const SkSL::String& inShader) {
+ // Metal fragment shaders need a lot of non-trivial boilerplate that we don't want to recompute
+ // here. So keep all shader code, but right before `return *_out;`, swap out the sk_FragColor.
+ size_t pos = inShader.rfind("return *_out;\n");
+ if (pos == std::string::npos) {
+ return inShader;
+ }
+
+ SkSL::String replacementShader = inShader;
+ replacementShader.insert(pos, "_out->sk_FragColor = float4(1.0, 0.0, 1.0, 0.5); ");
+ return replacementShader;
+}
+
+static SkSL::String build_glsl_highlight_shader(const GrShaderCaps& shaderCaps) {
+ const char* versionDecl = shaderCaps.versionDeclString();
+ SkSL::String highlight = versionDecl ? versionDecl : "";
+ if (shaderCaps.usesPrecisionModifiers()) {
+ highlight.append("precision mediump float;\n");
+ }
+ highlight.appendf("out vec4 sk_FragColor;\n"
+ "void main() { sk_FragColor = vec4(1, 0, 1, 0.5); }");
+ return highlight;
+}
+
void Viewer::drawImGui() {
// Support drawing the ImGui demo window. Superfluous, but gives a good idea of what's possible
if (fShowImGuiTestWindow) {
@@ -2292,30 +2321,29 @@
doSave = false;
}
if (doSave) {
- // The hovered item (if any) gets a special shader to make it identifiable
- auto shaderCaps = ctx->priv().caps()->shaderCaps();
-
- SkSL::String highlight;
- if (!sksl) {
- const char* versionDecl = shaderCaps->versionDeclString();
- highlight = versionDecl ? versionDecl : "";
- if (shaderCaps->usesPrecisionModifiers()) {
- highlight.append("precision mediump float;\n");
- }
- }
- const char* f4Type = sksl ? "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();
for (auto& entry : fCachedShaders) {
SkSL::String backup = entry.fShader[kFragment_GrShaderType];
- if (entry.fHovered &&
- (entry.fShaderType == SkSetFourByteTag('S', 'K', 'S', 'L') ||
- entry.fShaderType == SkSetFourByteTag('G', 'L', 'S', 'L'))) {
- entry.fShader[kFragment_GrShaderType] = highlight;
+ if (entry.fHovered) {
+ // The hovered item (if any) gets a special shader to make it
+ // identifiable.
+ SkSL::String& fragShader = entry.fShader[kFragment_GrShaderType];
+ switch (entry.fShaderType) {
+ case SkSetFourByteTag('S', 'K', 'S', 'L'): {
+ fragShader = build_sksl_highlight_shader();
+ break;
+ }
+ case SkSetFourByteTag('G', 'L', 'S', 'L'): {
+ fragShader = build_glsl_highlight_shader(
+ *ctx->priv().caps()->shaderCaps());
+ break;
+ }
+ case SkSetFourByteTag('M', 'S', 'L', ' '): {
+ fragShader = build_metal_highlight_shader(fragShader);
+ break;
+ }
+ }
}
auto data = GrPersistentCacheUtils::PackCachedShaders(entry.fShaderType,