A JUCE paint background renderer

Hi everyone,

I wrote a little tool that I figured might be of use to others, so I made the repo public for anyone who’s interested.

This is a JUCE background rendering tool, which will take a paint call that’s taking too long for the message thread, renders it on a background thread and then displays the image with a delay… I realise that this is not an ideal solution to the problem it solves, but especially when prototyping complex paint routines it happens too often, that things get slow and clog up the message thread resulting in problems like resizing being sluggish and making the app overall unresponsive.

This background renderer solves that problem with a few simple lines and therefore enables you to keep coding on your paint routines instead of taking care of infrastructure. Obviously the rendering results will only be displayed with a delay (when the background thread is finished rendering), but it beats stopping what you’re doing to take care of technicalities imo :slight_smile:

Hope, this is of use for somebody. Have fun :slight_smile:

(Also thanks to @TillFly for providing a complex paint routine that will block the message thread if not used through the Background Renderer and to @daniel for giving me the right pointers to make this as easy to use as possible :slight_smile: )

3 Likes

hey @benediktadams – just curious if you shipped something like this into production – and how the results were for you? – seems like a nice idea but curious if dedicating threads to components could create issues?

Hey @jakemumu

I haven’t shipped this, no. This was a little project I did for a student of mine who was doing some very nice, yet intense rendering in the paint () callback and sliders controlling the rendering would get stuck, because the MessageThread was blocked by the rendering routine.

I don’t think there should be any issues honestly. Without taking a closer look I think thread safety is managed and it’s a really simple process, just rendering the paint call onto an image on the background thread and displaying that image in the paint () method once it’s ready.

So the content of your rendering might lag user input and to make this production ready i think at least some “Working” indicator is warrented while the background thread is preparing the image (like a spinning circle or something on top of the rendering), but in theory this should be good to go.

While this is a nice little tool, I would recommend to rather make sure all information is available at render time, everything is preprocessed if necessary so it can be iterated swiftly and that your loops don’t do too much (e.g. taking the clip rect into account).

Usually adding threads always comes with a synchronisation penalty and in this case even the memory overhead of the background image and the additional cost copyng the image on the screen (drawImageAt).

2 Likes

Yes, figuring out a way to just have all paint data available in time is definitely the right way to go :slight_smile:

Which is why I haven’t used this code anywhere in production :wink: It was only ever meant as an easy “hotfix”, to get too complex rendering calls going for people, who were just trying to learn and fool around with the paint () call.

For sure! Thanks for the input – I’ve created a modified version of it which takes DPI factor into account and have been playing with the ideas – on weaker M1s the OpenGL rendering isn’t helping much in JUCE although our graphics have no problem on Intels, was thinking about using this and turning off OpenGL on M1 since they’re both semi threaded approaches. This method isn’t good for animations w/ OpenGL cause there’s a lot of time transferring and caching images which are only drawn once in JUCE.

I’ll report some more findings back, it was an interesting idea though and I really like how to bound the scope of the paint routine! It’s also easy to set a flag to flip it on or off which is nice.