Painting individual dirty rectangles on Windows/Mac (JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS?)


#1

Hi,

I’ve got a situation that should be pretty familiar on these forums. I have a large GUI and several small controls, e.g. blinking LEDs, in various corners. As a result, I’ve getting paint() calls with very large clipping bounds, because the little paint rectangles are being consolidated into one paint() command.

I’ve been trying to research this on the forums. For macOS, I’ve found a mention of a “JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS” macro that seemingly breaks the paint command into several paint commands with small rectangles. My code is running on Windows, and I’d like to know:

  1. Is there a similar Windows #define I can use to solve this problem in a Windows app?

  2. Is the best way to add this feature under Extra Preprocessor Definitions in the Jucer, or is there a more elegant way to enable this feature?

This could really help improve our app’s graphics performance a lot! Particularly if there’s a Windows solution.

Thanks,
Dan


#2

I added this to juce_win32_Windowing.cpp:

#if RENDER_WITH_MULTIPLE_PAINT_CALLS
                    for (auto& i : contextClip)
                    {
                        std::unique_ptr<LowLevelGraphicsContext> context(component.getLookAndFeel()
                                                                           .createGraphicsContext(offscreenImage, Point<int>(-x, -y), i));
                        handlePaint(*context);
                    }
#else
                    std::unique_ptr<LowLevelGraphicsContext> context (component.getLookAndFeel()
                                                                        .createGraphicsContext (offscreenImage, Point<int> (-x, -y), contextClip));
                    handlePaint (*context);
#endif

I have to say, it sped up my application significantly. Any chance something like this could get added to the Juce code?

Dan


#3

I also have this issue. I’d like this addition. Thanks Dan (=


#4

It’s really not obvious where your performance improvement is coming from. Everything apart from CoreGraphics should already avoid drawing in the intermediate areas. Could you provide an example project where this happens?


#5

T0m,

I’m sure our issue does not apply to everyone’s design, which is why a preprocessor flag might be most helpful. In our case, we have an Image overlay over the entire window that shows user-modifiable connections between various parts of the application. Since there can be dozens or even hundreds of connections, we paint this overlay as a single Image, and not as a bunch of Components, but even if we used Components, many of the connections can cross the entire interface. The problem is that small changes in the interface beneath the overlay can cause the entire overlay to draw, over and over and over, which is very slow and is nearly always unnecessary. Breaking the paint commands into individual rectangles causes only those components and the overlay above those components to redraw, which is infinitely faster.

Again, I’m sure this isn’t a problem for everyone’s design, but it seriously affects our design.

Thanks,
Dan