Graphics::drawImage performance


#1

We are building a plugin using the JUCE framework (mac only for now).  We have two GUI controls that are constantly updated (A VU meter and a curve display).

We initialise a timer in the PluginEditor (which is a Timer object) constructor

startTimer(50);

In the PluginEditor::timerCallback() function we call setValue of our Components.  This means that the Graphics::drawImageAt is called every 50ms for our two components.

When we use the Instruments Time Profiler, we notice that Graphics::drawImageAt is consuming a substantial amount of CPU.  It results in a call of Graphics::drawImageTransformed, resulting in CoreGraphicsContext::drawImage.

I've included a snippet from the Time Profiler, which shows that the application takes 33 percent of its time (which includes dsp of the plugin etc.) drawing images.

From the code it looks like a choice has been made that a transform can be applied at all times. However, we are using an image exclusively for offscreen rendering, which does not require the ability to transform. We miss the ability to draw (a part of) an image whithout an AffineTransform, which we suppose to be much more efficient.

Any suggestions?

Gilles


#2

Don't be misled by the affine transform - the way these things work is that the code that does the low-level rendering will be optimised for cases where the transform is an identity or integer translation. Unless you're shifting it by a sub-pixel amount then it should render optimally fast.

But continuously blasting images to the screen is going to be slow when the images are memory-based, because of the bandwidth involved. The GL renderer is much better at caching images on the GPU than the CoreGraphics one.


#3

I am having similar problems while programming skinned image-based sliders and animated VU meters. The drawImage() and drawImageAt() just seem to slow. Could you give me some hints on how to implement GL rendering for this purpose? Do I have to derive all my animated components from OpenGLContext and use attachTo(*this) ? This would mean I will have multiple GlContexts running simlutaneously in my main window though..Is that really the way to go? Thanks for any advice!


#4

(Yuck.. Image-based sliders - a pet hate of mine!)

But if for some reason you really can't use vector graphics, then moving to GL is easy - any normal image will be cached on the GPU when you use it, so should draw very fast. No need to use frame buffers explicitly.


#5

Thanks for your reply! He..he.. can't help needing them.. so I just need to change the rendering engine for the application main window using setRenderingEngine()? No OpenGLContext needed?


#6

Yes, just change the rendering engine. You do need a context for that (see the demo example of how to do it), but don't need to change any image code.


#7

I studied the demo juce app. So I derived my main GUI window from OpenGLRenderer, added a OpenGLContext instance and added following code to the constructor of the main GUI window:

            // change rendering engine to OpenGL

            openGLContext.setComponentPaintingEnabled(true);

            openGLContext.attachTo(*this);

            openGLContext.setContinuousRepainting(true);

            openGLContext.setRenderer(this);

 

however this does not seem to do the trick and my window displays mostly random rubbish.. What am I missing? Thanks!


#8

just adding a member OpenGlContext mOpenGLContext

and do 

mOpenGLContext.attachTo(*this);

should be enough AFAIK