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>
This commit is contained in:
John Stiles 2020-06-24 12:13:31 -04:00 committed by Skia Commit-Bot
parent 8ee607cbc1
commit 38b7d2f223
3 changed files with 56 additions and 20 deletions

View File

@ -68,6 +68,10 @@ public:
void deleteTestingOnlyBackendRenderTarget(const GrBackendRenderTarget&) override;
void testingOnly_flushGpuAndSync() override;
void resetShaderCacheForTesting() const override {
fResourceProvider.resetShaderCacheForTesting();
}
#endif
void copySurfaceAsResolve(GrSurface* dst, GrSurface* src);

View File

@ -41,6 +41,10 @@ public:
// Destroy any cached resources. To be called before releasing the MtlDevice.
void destroyResources();
#if GR_TEST_UTILS
void resetShaderCacheForTesting() const { fPipelineStateCache->release(); }
#endif
private:
#ifdef SK_DEBUG
#define GR_PIPELINE_STATE_CACHE_STATS

View File

@ -1693,6 +1693,35 @@ static bool ImGui_DragQuad(SkPoint* pts) {
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 @@ void Viewer::drawImGui() {
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,