Your input is needed


#1

Hi All,

I draw a 5 point amplifier envelope onto a bitmap (just as a shaded old style LCD background) using
4 quatrilaterals and some small circles arround its points to pick up and move the points
by mouse.

[attachment=0]env.JPG[/attachment]

That works pretty well but I noticed quiet a huge CPU usage when points get moved,
either by mouse or by incoming Midi data. I am talking about up to 20% CPU usage in release mode
for a 10cm x 4cm component which is too much from my point of you?!
I’ve searched the forum for performance optimization and all of those optimizations are helpful but
don’t get performance down dramatically.

I am drawing onto an opaque component using the below code:

[code]void JK_Envelope::paint (Graphics& g)
{
_bufferedImage = Image (Image::RGB, getWidth(), getHeight(), Image::NativeImage);

Graphics imG (_bufferedImage);

imG.drawImageAt(backgroundPic, 0, 0);

Path env;

for (int i = 0; i < envPoints.size() - 2; i = i + 2)
	env.addQuadrilateral(envPoints[i + 1]->getX(),
						 envPoints[i + 1]->getY(),
						 envPoints[i + 0]->getX(),
						 envPoints[i + 0]->getY(),
						 envPoints[i + 2]->getX(),
						 envPoints[i + 2]->getY(),
						 envPoints[i + 3]->getX(),
						 envPoints[i + 3]->getY());

imG.setColour($findColour($LookAndFeel->EN_Colour));
imG.fillPath(env);

for (int i = 1; i < envPoints.size(); i = i + 2)
{
	imG.setTiledImageFill(backgroundPic, 0, 0, 1.0f);
	imG.fillRoundedRectangle(envPoints[i]->getX() - 5.0f,
						   envPoints[i]->getY() - 5.0f,
						   10.0f, 10.0f, 5.0f);

	imG.setColour($findColour($LookAndFeel->EN_Colour));
	imG.drawRoundedRectangle(envPoints[i]->getX() - 5.0f,
						   envPoints[i]->getY() - 5.0f,
						   10.0f, 10.0f, 5.0f, 1.0f);
}

g.drawImageAt (_bufferedImage, 0, 0);

}[/code]

If I now attach a Listener to each point then the CPU usage gets up to 30% when points are moving.

So I guess I can do some more optimizations to my envelope code to get a decent usage but
here I need some ideas. I noticed that broadcaster/listener always have an impact to performance which
might be one reason why Jules has changed UI update code in the demo plugin from Broadcaster/Listener to
timer. So what else could I do instead?
There is another UI code in my plugin that need some optimization but may I can pull out information for that
from your input…

i am also open for a easier way to draw such an envelope :slight_smile:

Thank you!
Joerg


#2

I don’t understand why you’ve gone to all the trouble of creating an image, drawing into it, and then drawing it to the component. Why not just draw to the component directly?


#3

Drawing into memory instead onto a graphics device directly should speed up things I thought
and its the same as setBufferedToImage(true), isn’t it?


#4

Good grief, no! You’ve written a whole heap of complicated code which will just make everything much slower!

The only reason you’d ever want to use an offscreen image is if you’re rendering something that doesn’t change, so you can cache the image and use it many times. If you re-build the entire image in every paint() method, you’re just hugely increasing the amount of work that gets done, for no benefit whatsoever! (Not to mention that paint() may only be repainting a tiny section of your image, so re-rendering the entire thing each time is a massive waste of effort!)


#5

Hmm…it might be a waste of effort to use the offscreen image but I’ve been hammering on juce Graphics class and its pretty fast. Looking at your code, I see no reason why your function should be slow. There must be something else causing the slowdown. Maybe you have a transform somewhere and the image is getting interpolated? Are you stretching the LCD background image to fit the client window?

I mean seriously…you’re filling a Path, drawing a few control points, and then doing a drawImage(), Juce is more than capable of doing that quickly even considering that you don’t need the extra off-screen image.


#6

I investigated a bit more and found the culprit, I think.
At first, drawing into an offscreen image had a big impact in speed
and to reduce flickering when I wrote my stuff in a Windows only, C based
language. So I thought it could also affect my juce code but following to
Jules explanation, it doesn’t make sense here. That’s fine and understandable
for me…

What I found out was that the system I use for coding had an outdated
graphics card driver installed or lets put it this way, I run XP on my note book
which was designed to run at least Vista so I had to hack the nVidia driver
to get it installed cause nVidia didn’t support XP anymore for that particular
chip. Anyway, running juce on a different note book did increase the performance so
now I have a CPU usage between 5 - 8% which is fine I guess.

I my first post I mentioned some other outstanding parts of the code to optimize
but even there is a big performance increase. But I have no expieriences
in terms of graphic performance so it would help if you could tell me if
a CPU usage between 10 - 15% average while scrolling a listbox is decent or not.
The listbox has to draw the same background (LCD style), filling a path etc.
All of my background pictures has been streched to the right size while creating
so no stretching is involved while drawing.

Are those numbers okay?

Thank you for your help!