Paint(), fillRoundedRectangle() - heavy performance issues

Hello,

I’m making something like a Piano Roll, which should be able to show (and resize) around 500-1000 rectangles without heavy performance problems. I did them components, however I read that you shouldn’t use too many components on screen simultaneously. (By the way, it was a mess to place them in the right order, since some of them must stay on front and others behind, and this changes dynamically). It was easier to avoid components and paint rectangles in the right order: first, the ones behind and then the ones that are in front.

However, the performance obtained painting the rectangles instead of using components was really bad, and I was looking for the reason. The biggest problem i’ve found is in the paint() function, where fillRoundedRectangle() takes from 2 to 8 times more to execute, depending on the size of the rectangle. I think in both cases the time cost might be equal.

What should I do here? Why does the same function have so different results? Is there any optimization in Component that I should use?

Thanks to all,

Below it is given the code of the two cases:

The Rectangles as Component code:

[code]class RectangleBase: public Component
{
public:
RectangleBase();
~RectangleBase();

// Juce
virtual void paint(Graphics& g);
};

void RectangleBase::paint(Graphics& g)
{
static PerformanceCounter pt(“paint componente”);
g.setColour(Colours::blue);

pt.start();
g.fillRoundedRectangle(m_areaVisible, 1.0f);
pt.stop();

}[/code]

The big Component with all rectangles drawn inside:

[code]class eLayer: public Component
{
public:
// Juce
virtual void paint(Graphics& g);
};

void eLayer::paint(Graphics& g)
{
static PerformanceCounter performCount(“big component”);

     for (uint16 i=0; i<rectangles.size(); ++i)
     {
        // ... some functions ...

        const Rectangle<int32> area(x, y, w, h);
        const Rectangle<float> areaFix = area.toFloat();

        g.setColour(Colours::blue);

        performCount.start();
        g.fillRoundedRectangle(areaFix, 1.0f);
        performCount.stop();

     }

}[/code]

And the performance…

Performance count for “big component” - average over 100 run(s) = 352 microsecs, total = 0.03525 seconds
Performance count for “paint component” - average over 100 run(s) = 162 microsecs, total = 0.01622 seconds
Performance count for “big component” - average over 100 run(s) = 293 microsecs, total = 0.02935 seconds
Performance count for “paint component” - average over 100 run(s) = 88 microsecs, total = 0.00885 seconds
Performance count for “big component” - average over 100 run(s) = 264 microsecs, total = 0.02647 seconds
Performance count for “paint component” - average over 100 run(s) = 90 microsecs, total = 0.00903 seconds
Performance count for “big component” - average over 100 run(s) = 277 microsecs, total = 0.02777 seconds
Performance count for “paint component” - average over 100 run(s) = 90 microsecs, total = 0.00910 seconds
Performance count for “big component” - average over 100 run(s) = 283 microsecs, total = 0.02834 seconds
Performance count for “paint component” - average over 100 run(s) = 86 microsecs, total = 0.00860 seconds

You need to use a proper profiling tool - there’s no other way to get a real picture of where the time is being spent.

And a good tip if you have many components is to learn about Component::setPaintingIsUnclipped()

Thank you, I tried with vtune and almost managed to solve it. Isn’t PerformanceCounter class a reliable class for measuring CPU times?

Which solution did you end up using? Many components?

It’s fine, but can’t debug a complex system like that with only one number. You need to see the real hotspots, which may not be where you expect to find them.

I did a new proyect to test again the differences. It was a very simple proyect: several rectangles as components and several rectangles painted (the same number). The result was pretty similar.

So this, and some time with v-tune and release mode, gave me the idea to go for the new solution, paint the rectangles in the grid instead using components.