I’m happy to experiment but I’m not sure where that test would go…?
And hang on, isn’t that what is happening in CoreGraphicsContext::clipToRectangle() already? Though there is a worrying comment in there that suggests that clipping the CGContext to a rectangle doesn’t actually work…
if (lastClipRectIsValid)
{
// This is actually incorrect, because the actual clip region may be complex, and
// clipping its bounds to a rect may not be right... But, removing this shortcut
// doesn't actually fix anything because CoreGraphics also ignores complex regions
// when calculating the resultant clip bounds, and makes the same mistake!
lastClipRect = lastClipRect.getIntersection (r);
return ! lastClipRect.isEmpty();
}
It seems that CGContextGetClipBoundingBox() doesn’t return what we would expect it to. Even if there is no clip region (so nothing will be drawn) it will still return a clip bounding box for an area that due to some quirky internal implementation it incorrectly thinks might contain a visible area.
This must be causing a huge inefficiency in a lot of Juce apps… any largish GUI with frequently updating components will be redrawing most of the GUI each update. For example a media player app with a time code display at the top and a progress bar at the bottom will have it’s entire GUI redrawn each time both the timecode and progress slider update.
otristan’s multiple repaint solution isn’t so terrible - in my case it reduces my GUI’s CPU usage from around 18% to 9%, but there must be a more elegant solution?! Using the software renderer isn’t really an option either as I need good performance on iOS.
Oh well, I’d be very happy if someday someone found a way to do this properly, but until then I can live with the multiple repaint option…
I’ve been struggling with this issue as well and it’s quite frustrating (and I had posted a new thread about it, not realizing that this one existed). My GUI is exactly as you describe, graffiti – large, with many frequently updating components. On Windows it works great, but on OS X it really drains the CPU. It almost makes the app unusable, which is a real bummer as you can imagine!
One thing you might try is using Component::setBufferedToImage(true). Basically this renders any component into a bitmap, so that when paint() is called, it doesn’t have to do any re-rendering (if nothing has changed). It lowered my CPU usage a bit. Not as much as I would have liked though!
edit - One more thing, in my thread (see http://www.rawmaterialsoftware.com/viewtopic.php?f=4&t=8626), jules mentions a new class “CachedComponentImage”. I gather this is new since 1.53 (since it’s not in the release), so I haven’t tried it yet. Might be worth investigating.
Unless someone can persuade Apple to add a suitable function to CoreGraphics that would give us the clipping info we need, then I've no idea what else we could possibly do.