Does Skia have "compute shader" APIs like OpenGL?

488 views
Skip to first unread message

Qian Cheng

unread,
May 9, 2024, 9:15:53 AM5/9/24
to skia-discuss
Hi, guys! I'm a Skia beginner. 

To speed up the filter effect, I want to use a "compute shader" similar to the one in opengl to preprocess the image and hand the resulting image over to skia for further rendering.

Is there any APIs in Skia to use compute shader? If not, how can I do this? Can you give me some ideas or helpful information?

Thanks! :)

John Stiles

unread,
May 9, 2024, 9:18:59 AM5/9/24
to skia-d...@googlegroups.com
What kind of effects did you have in mind?

Skia has SkRuntimeEffect, which lets you define a fragment shader using a GLSL-like language. This isn't entirely equivalent to a compute shader but it can do a lot of the same things. 


--
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/001e6736-7d37-4beb-86d8-d4d7cb328cfen%40googlegroups.com.

Qian Cheng

unread,
May 10, 2024, 8:16:12 AM5/10/24
to skia-discuss
Thanks for your relpy!

Actually, I want to compute 2D prefix sum of an image (aka integral image). OpenGL SuperBible 6th  gives a parallel implementation to accelerate the 2D prefix sum by using compute shader.
Then, I can use this 2D prefix sum to make a variable-sized filter. 

What I really want to do is that compute 2D prefix sum on gpu for an image created by sksurface->makeImageSnapshot(), and use this 2d prefix sum to make a variable-sized filter. 

Following is the compute shader code in OpenGL:
屏幕截图 2024-05-10 090847.png

John Stiles

unread,
May 10, 2024, 9:39:52 AM5/10/24
to skia-d...@googlegroups.com
As mentioned above, Runtime Effects don't support compute. If you wanted to do a compute shader like this, you would need to do this directly via OpenGL.

(Internally, Skia does have some support for compute shaders in the newer Graphite backend, but it's not exposed via the public API at all, and it isn't supported in OpenGL.)

It sounds like you originally wanted to use a Skia filter but were encountering performance issues? Which filter did you try, and what was the performance problem? 

Qian Cheng

unread,
May 10, 2024, 1:39:03 PM5/10/24
to skia-discuss
Thanks for your reply again!
I'm using Skia to make a gradient-blur filter like this (blur radius gets bigger and bigger from left to right):
屏幕截图 2024-05-10 223748.png

The current solution is:
1. a base radius r0 (e.g. 60).
2. use skGradientShader::MakeLinear() to make a gradientShader which returns a linear gradient alpha-channel value.
3. each pixel i has a specific blur radius (equals to r0 * alpha_i), then do a sperate boxblur (one horizontal and one vertical) :
屏幕截图 2024-05-10 225738.png

Now, I want to keep the first and second step. And speed up the third step.
My idea is using 2D prefix sum (aka integra; image). Then, each pixel can be blurred by 4 times additions using 2D prefix sum, instead of looping in SKSL.

Is there any better idea to speed up the whole process?

John Stiles

unread,
May 10, 2024, 2:13:23 PM5/10/24
to skia-d...@googlegroups.com
One of our Skia power users has done a gradient-based blur using an approach much like yours and had good results, and the performance was good:
https://groups.google.com/g/skia-discuss/c/mL2iaiwulmc/m/suUjaDCgBAAJ

You might want to experiment with that version and see what's different. At a glance, I don't see anything too out of place with the shader you've shown here. It doesn't seem like it should need compute to run decently well. Their version is based on React Native, but it's using Skia (CanvasKit) under the hood so the runtime effects themselves are identical.

(BTW, a small thing I noticed from your code is that you've evaluated the gradient twice. This is probably not what you intended to do, but I also doubt it will be a huge performance issue unless your gradient is very complex.)

There is a lot of research on doing blurs efficiently; you can get the GPU to do a lot of the work by shrinking your input image and/or sampling between texels. Doing a box blur in compute probably isn't the ideal approach for performance anyway. You might want to read https://www.intel.com/content/www/us/en/developer/articles/technical/an-investigation-of-fast-real-time-gpu-based-image-blur-algorithms.html. Skia's Viewer test app also has a Kawase slide that implements a Kawase blur.


Reply all
Reply to author
Forward
0 new messages