Slowdown in RectangleList::consolidate

I’m experiencing a great slowdown in RectangleList::consolidate, when number of rectangles in list is about 145 and more. Sometimes graphics output just hangs for about 1-2 seconds because of this function! How can I avoid it? I noticed some old topics on this problem (http://www.rawmaterialsoftware.com/viewtopic.php?f=4&t=389 and http://www.rawmaterialsoftware.com/viewtopic.php?f=2&t=660), where in the last thread it’s considered resolved, but looks like it still happens in the 1.50 version of Juce, which I’m using.

What’s the context for this? Is it your own code using it, or just the renderer on linux?

The context is graphics renderer in my app, that at some point draws many rectangle objects with excluding their areas via Graphics::excludeClipRegion() function. This function calls RectangleList::subtract() function then, which in its turn calls RectangleList::consolidate(). And I base on Windows.

Hmm - it shouldn’t need to call consolidate() at all on windows. Maybe I’ve accidentally added a call that uses it indirectly. Thanks, I’ll check that out…

So, do you mean that currently I can fix it by removing consolidate() call or by wrapping it under defines?

I’ve got a fix - will check it in shortly.

Hi Jules,

Do you have any updates? Is the fix already integrated?

Yes, it’s been in there since last week.

Hi Jules,

I recently moved to the latest Juce sources in order to integrate your fix, but was quite surprised then by significant slowdown of the overall graphics rendering. I checked the update log and found a commit for big rewrite of LowLevelGraphicsSoftwareRenderer class where you note, that it will temporarily make font rendering quite slow, until it gets reoptimized. This looks like possible reason of the slowdown, since I use font rendering a lot. So, is it still not optimized? How soon are you planning to optimize this? Could you advise any workaround to fix RectangleList::consolidate without integrating the latest Juce updates then?

I optimised the font rendering weeks (months?) ago, and the rectangle list consolidation was just a mistake I made in the new renderer, and was also sorted out weeks ago.

As mentioned elsewhere, if you’re using windows, a release build will draw 10x faster than debug, so please make sure you’re not comparing an old debug build with a new debug build - I think the old one had some pragmas in it to force optimisation even in a debug build.

Of course I aware of debug and release builds difference and here I’m talking about release builds only. With my old 1.50 sources, downloaded in archive, everything is fast enough, but with the latest updates rendering speed is really slower. Couldn’t there be some pitfalls in your graphics engine rework that could cause this slowdown? My rendering system is complex and rich enough thus very sensitive to any changes in graphics output system, I guess.

The only things I can think of that would be slower are vertical lines and integer-aligned rectangles (though the extra overhead would only be noticeable if you draw lots of very thin, tall ones). Fonts are a little bit slower because they’re rendered with better accuracy, but you must be absolutely hammering it if you’re seeing a big difference in your app!

Well, unfortunately it looks like my app rendering is hardly influenced by these things. It’s a sequencer with many many vertical lines possible on main editing area:

It renders a lot of various complex stuff on big area, including text (and amount of text sometimes can be very big). So, hmm, looks like I’m in trouble, right? The difference between my and latest Juce rendering is really significant. Some smooth things became jittering things now. I’d stay on my old Juce, but I couldn’t fix the problem of slowdown in RectangleList::consolidate then, since the fix, as far as I can see, is based on this rendering system rework, right? Is it possible to do the same fix on the old rendering code and how it will look like then?

Ah yes, that’ll be the vertical lines slowing you down. It’d be a lot quicker to draw if you use an tiled image to fill the repeating patterns (and the same would probably have been true in the old code too).

…and also, if you’re filling the area under your graph using vertical lines, that’d be much faster if you just render it as a path.

Okay, but do you mean that any complex drawing based on vertical lines should be now “worked-around” to prevent slowdown? I’m in doubt that it will be possible for all of them. How about drawing and quickly re-rendering a wave, for example?

short lines are probably not too hard, it’s the longer ones that you’d have to worry about.

I’d love to say I’ll optimise it, but I really can’t think of a way it could be done! What I might be able to offer would be a new graphics method that fills a RectangleList in one call, which would cut down the overhead involved in handling each line individually.

Hi Jules,

I did as you suggested - reworked grid rendering to use tiled images instead of vertical lines. Also I updated my Juce to obtain your latest graphics optimization. After that, my rendering became somewhat faster, but it’s still apparently slower than the old renderer and not so smooth. Then I played with UI some more and discovered an interesting thing - even small and simple animations/redrawings (VUs, sliders, etc.) also became a bit slower and less smooth in similar way. Looks like this is not actually a graphics speed issue, eh? Probably it’s timing/threading problem or something like that.

I’m now trying to figure out what became wrong with app timing and my question is - were there any changes in this area that may cause the problem? The brief description is now the following: the overall graphics rendering has lost its smoothness after transition to the latest Juce updates. It was really smooth and nice and it’s not really smooth and nice now. I can give examples, if they’re needed.

Are you doing a lot of clipping, e.g. lots of deeply nested components or many small components? The clipping will be a little slower now that it supports complex regions…

I of course use clipping and lots of components, but the resulting smoothness is absolutely independent on how much of them are rerendered simultaneously. Either a single small animation or ten small animations will show the same “unsmoothness”. They also don’t consume more CPU than previously.