We have a very complex UI in a standalone app, originally built with j6 and recently upgraded to j8. The UI is a mainComponent with many layers deep of nested components.
At some point in the past we had landed on setting JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS to ON.
We had also used a specific combination of setPaintingIsUnclipped() and setOpaque() on different components. IIRC there were big performance improvements with some of these choices in very heavy layouts, and some of these gains were contrary to the suggestions in the comments in the juce code.
What we are now seeing with a couple of our beta testers is that most of the UI is displaying black till some other object enters the view, or the window is clicked. Another tester sees the components but they are painting extremely infrequently (seconds) such that it feels like the app is very sluggish. We can’t repro the issue in-house.
Interestingly, turning off JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS seems to have fixed the issue for one user, who even reports the app feels snappier now.
Even more interestingly, in his example video linked below, there is one Component in our UI which seems immune to the issue (triple panel thing at bottom). That Component happens to inherit from juce::OpenGLRenderer, but also displays some things (like its BG colour & the logo in the middle) using normal juce painting code when no GL work needs to be done (as is the case in the video).
So can anyone guess what’s happening here?
It seems like RENDER_WITH_MULTIPLE_PAINT_CALLS is often cited on these forums as a fix for all manner of ills, so we’re obviously concerned about how disabling it would affect different OSes and hardware, and all the testing we’ll have to do by changing it.
From JUCE 7 I would only recommend using JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS in the specific case where macOS or iOS is erroneously marking more area than necessary as needing to redraw. In that specific case then enabling this flag allows your software to do less drawing, but the raw drawing speed is much slower. If this would be a benefit to you is highly dependent on your specific GUI.
We’re currently working on changing how setPaintingIsUnclipped and setOpaque work to make them both much more intuitive and effective.
Thanks.
Sounds like it’s worth turning off. But does the bizarre rendering issue in the video ring any bells for you? If we need to turn it back on for any reason (or anyone else does) this issue will occur for some users.
It’s important to note that setOpaque (true) and setPaintingIsUnclipped (true) interact in a way that is not immediately obvious. setOpaque (true) effectively works based on clipping the graphics context where-as setPaintingIsUnclipped (true), as the name suggests, does not clip the graphics context. Therefore these two settings can work against each other. As Tom says we are working internally to improve that.
It would be difficult to dive into all the details here but if you were able to come back and say that removing all the calls to setOpaque() and setPaintingIsUnclipped() prevents the issue described above that would be an extremely helpful data point for us. setOpaque() seems the most likely candidate just because it’s job is to prevent drawing components.
Another thought based on the mention of OpenGL, is it could be OpenGL related. In the past on products I’ve worked on we made sure to have some kind of switch (maybe hidden in a config file) that allows users to switch off all OpenGL rendering and contexts. This was generally more important on Windows because of the various state of drivers, but importantly it allowed us to isolate the issue, and normally allowed the customer to continue what they are doing for now. Something like that might be worth a try as another useful data point?
killing openGL would mean killing a section of the view entirely, but that certainly is a good idea to test.
And I will try with all those setOpaque() and setPaintingIsUnclipped() removed as well.
It’s just really hard to test things because we cannot reproduce it in-house and are reliant on the dwindling patience of our beta testers.
FTR, the very deliberate setting of setPaintingIsUnclipped() and setOpaque() were a result of lots of trial and error with very large timelines (thousands of clips, text etc), zooming and scrolling and feeling the performance changes. Sounds like now is a good time to re-assess.
I completely understand. Maybe you could have all three as settings in a config file that is read when the app is booted up? that way you’re not making several builds and beta testers can relatively easily toggle settings on and off. You could probably use something like the PropertiesFile class if you haven’t already got a config file you could use.