Use SkCanvas layer contents as input to SkShader

178 views
Skip to first unread message

Keiwan Donyagard

unread,
Jan 14, 2022, 6:06:01 AM1/14/22
to skia-discuss
Hi!

Is it possible to somehow pass the contents of a saved SkCanvas layer as an input into an SkShader when the shader is applied during the call to SkCanvas::restore?

As far as I can tell, an image filter created using SkImageFilters::Shader assumes that the shader produces its output without further shader inputs but we would like to apply a series of custom shaders to content that was dynamically rendered into a canvas layer as if it were an image.

The only way to do this that I'm currently seeing is to use a secondary canvas, draw into that, call SkSurface::makeImageShapshot and use that as the input to the shader graph in the main canvas. For the sake of performance, we would like to avoid this overhead if possible.

Thank you!
- Keiwan

Brian Osman

unread,
Jan 14, 2022, 8:40:26 AM1/14/22
to skia-d...@googlegroups.com
Hi!
There is a newer API that should help with this: SkImageFilters::RuntimeShader. It works similarly to SkImageFilters::Shader, but was designed for use with custom SkSL shaders (SkRuntimeEffect). One side effect of how it's built is that any `uniform shader` variables in your SkSL can be dynamically bound to image filter inputs. There's a bit to unpack, but two different tests in this file show how it works:

Two things that might be useful to notice: Binding one of the named inputs to nullptr will cause that `uniform shader` to be the "default" contents of the image filter evaluation - in your case, that would be the layer contents during the restore process. Secondly, if the shaders you want to apply to the content already exist (as builtin shaders), you can pretty easily make a pass-through SkSL shader that just forwards the content:

  uniform shader child;
  vec4 main(vec2 coord) { return child.eval(coord); }

Of course, if you were already planning to apply a custom SkSL shader for your processing, you can just write that code in the SkSL you supply (as is being done in the examples I linked).

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/2c5a6929-ebfa-4a0e-8bf1-6a5c3fd55a7en%40googlegroups.com.

Keiwan Donyagard

unread,
Jan 17, 2022, 8:19:50 AM1/17/22
to skia-discuss
Perfect, thanks!
Reply all
Reply to author
Forward
0 new messages