As mentioned above QuartzDebug is probably the best way to see what is actually being drawn to the screen, this should allow you to see the coalesced rectangle, and give you some idea of the components that are likely being repainted. I’ve never found the JUCE paint debugging tools to be overly helpful and normally misleading. The is all based on my experience, and it has been a while since I’ve had to do this.
One thing I recommend doing is making sure every component has one of two jobs. Either, it has child components, or, it draws. In other words only leaf node components should implement the paint
method.
For example avoid components that draw a background and have child components. Instead create a separate background component that is a sibling to the other child components.
Once you’ve done this, for all components that don’t change often and the drawing is more expensive than drawing an image, call setBufferedToImage (True)
on them.
Note, If you call setBufferedToImage (True)
on a component that does need to repaint often (say a meter), it may make things worse. This is because the image will need to be redrawn and then drawn to the screen, making it more expensive than just drawing it straight to the screen.
However, if something doesn’t change often (like a background), but it is constantly being redrawn (due to a coalesced rectangle), then setBufferedToImage (True)
will mean most of the time it can just redraw the image, thus avoiding calls to the components paint
method, as this only needs to be called to repaint the image.
Unfortunately if a child component has to repaint, even if the parent is set to buffer to an image, its image will always be redrawn before being painted to screen. This is unintuitive and it means calling setBufferedToImage (true)
can actually make things worse! I can’t remember the exact reasoning why it behaves this way, but this is the reason I say only allow leaf node components to draw. Essentially if you stick to this rule it will be easier to make optimisations using setBufferedToImage
.
Other optimisations that may help.
-
Always call
setOpaque (true)
for components that have no transparency. IME this is quite rare, but if it’s true for you it could prevent some paint methods being called. -
Call
setPaintingIsUnclipped (true)
on all components that don’t draw outside their bounds. IME this can (and should) apply to almost all components. If you have a lot of components this could at least reduce the cost of repainting.