androidshaderandroid-wallpaper

Android WallpaperService.Engine with RuntimeShader


I've recently discovered the RuntimeShader in Android, and hoo boy is it nice to be able to add shaders without all the overhead. I've been tinkering with WallpaperService and thought it would be an easy way to start using shaders there. However, I get an exception IllegalArgumentException: Software rendering doesn't support RuntimeShader.

The error is getting thrown by BaseCanvas when performing canvas.drawPaint(Paint) with a Paint object that has it's shader set to an instance of RuntimeShader`.

This error is thrown even if in my WallpaperService.Engine all I do is a simple fixed color shader:


override fun onSurfaceChanged(
            holder: SurfaceHolder?, format: Int,
            w: Int, h: Int
        ) {
            super.onSurfaceChanged(holder, format, w, h)

            val fixedColorShader = RuntimeShader(
            """
                half4 main(float2 fragCoord) {
                            return half4(1,0,0,1);
                }
            """)
            val paintShader = Paint()
            paintShader.shader = fixedColorShader

            val canvas = holder?.lockCanvas()
            canvas?.drawPaint(paintShader)
            holder?.unlockCanvasAndPost(canvas)
        }

I'm guessing this is an unfortunate limitation of RuntimeShader, but could this be an issue with the specific device I'm using?

I'm still going to ask if anyone knows how to use a RuntimeShader in a WallpaperService, and if not, if anyone knows why this limitation exists?


Solution

  • Use canvas = holder.lockHardwareCanvas(); instead holder.lockCanvas();