Asynchronous ShaderJobs are Murderers

A warning of a bug in Flash's handling of asynchronous ShaderJobs.

Really I should post this after a nice tutorial explaining all about ShaderJob and custom shaders and PixelBender.  But having spent today finding the bug I feel I should post it.

A Rapid Introduction

A ShaderJob allows you to apply a shader to an image (or a 'shader' to a set of data, which is mechanically very similar.)  The nice thing about ShaderJobs is they can be run asynchronously.  This means I can start off a ShaderJob to do a fancy lighting effect, and whilst it's doing that my program can carry on executing and working on AI or whatever.  This is thanks to the ShaderJob executing in its own threads separate from the single thread that all the rest of an Actionscript program executes in.  The performance increase from finally being able to use something close to multithreading (what the shader can actually do is cruelly limited) is significant.

And the Problem

Sadly, it all breaks if you try to run multiple ShaderJobs simultaneously.  Ideally, they should be able to just all run at once - that's kind of the point of multiple threads.  Instead the documentation claims that they're kept in a queue and executed one after the other.  Which is a shame, but isn't actually the problem!

Instead of being kept in a queue, additional ShaderJobs just silently vanish.  Start a ShaderJob to blur an image of a circle, then start a ShaderJob to blur an image of a square.  If the ShaderJob for the circle is set to be asynchronous then the ShaderJob for the square will never execute.  No errors are produced; it just silently fails.

The 'neat' thing is that so long as an asynchronous ShaderJob is running in the background, any further ShaderJobs started (whether synchronous or not) will be silently destroyed.  It is possible to avoid this by tracking when an asynchronous ShaderJob completes and not allowing the creation of new ShaderJobs until then.  But if the execution of significant parts of your program has to wait for an asynchronous process to finish then it rather defeats the purpose of it being asynchronous.

I managed to find a report of the issue on Adobe's forums from a year ago, although they didn't seem to discover the full range of the  asynchronous ShaderJob's murderous intentions.

In Summary

Only run a ShaderJob asynchronously if you are certain that no other ShaderJobs will be started until it has finished executing.

Post a Comment

Your email is never published nor shared.

Powered by WP Hashcash