# GUI Drawing Efficiency

**URL:** <https://forum.juce.com/t/gui-drawing-efficiency/15429>\
**Category:** Audio Plugins\
**Created:** [August 29, 2015, 1:38pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429 "2015-08-29T13:38:09Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![LukeM](https://avatars.discourse-cdn.com/v4/letter/l/f04885/32.png) [@LukeM](https://forum.juce.com/u/LukeM)\
**Post date:** [August 29, 2015, 1:38pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/1 "2015-08-29T13:38:09Z")

</div>

Hi Jules and team,

I have been noticing recently that my GUIs with meters or graphs (i.e. which have sections which are redrawing regularly) have a very obvious effect on the host drawing. One instance is usually fine, two is passable, but any more than this severally lags the host’s own drawing. I suspect this behaviour is due to all of the drawing been handled by the same message thread which just gets overwhelmed with the amount of drawing required.

Comparing to plug-ins written using VST GUI it is clearly not an issue for them, which is slightly concerning. Are there any improvements to this upcoming in JUCE 4 or planned for the future? I’m aware that using OpenGL will certainly help the matter, but from what I can see there isn’t a way to use an OpenGL Graphics context to pass down through the paint methods.

Any improvements in this area would be really appreciated!

Cheers,

Luke.

---

<div class="post-metadata">

**Author:** ![xeneize](https://avatars.discourse-cdn.com/v4/letter/x/ce7236/32.png) [@xeneize](https://forum.juce.com/u/xeneize)\
**Post date:** [August 30, 2015, 2:25am UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/2 "2015-08-30T02:25:23Z")

</div>

mmmh, I've the same issue on mac, I've tried coreimage, juceimage and&nbsp;opengl but the CPU load still high, you can noticed lags on sliders and vumeter (drawImage with filmstrip)&nbsp;if you open the gui of several plugin instances at the same time.

I've removed timers and listeners from AudioProcessorEditor but the problem persisted. I've set JUCE\_ENABLE\_REPAINT to check if there is a unwanted repaint.&nbsp;So I don't think is a drawimage problem or any repaint.

&nbsp;

&nbsp;

&nbsp;

&nbsp;&nbsp;

&nbsp;

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [August 30, 2015, 7:55am UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/3 "2015-08-30T07:55:12Z")

</div>

> Comparing to plug-ins written using VST GUI it is clearly not an issue for them, which is slightly concerning.

It's painful when we see people post things like this - it creates unfair FUD around juce's drawing code! There are plenty of juce-based metering apps out there that perform very well, but you can't just approach something like this naively and expect the framework to magically make your code run fast - getting good&nbsp;graphics performance&nbsp;requires some careful work&nbsp;on any framework.

The juce rendering engines are very fast - at least as fast as anything you'll get in VSTGUI or other frameworks.

> Are there any improvements to this upcoming in JUCE 4 or planned for the future?

Interesting question!

- The CoreGraphics renderer: Impossible to improve it, because it's&nbsp;obviously bottlenecked by the performance of CoreGraphics itself.

- The software renderer: Can't be improved, because although its compositing code could probably have a few more percentage-points squeezed out of it, on modern devices it's entirely bottlenecked by the huge memory bandwidth required to get high-res bitmaps onto the screen. CPU-based rendering is simply&nbsp;not a feasible option for retina-size displays now.

- The openGL renderer: This is already very fast, but it's&nbsp;bottleneck is in the time taken to rasterise paths, which isn't a task&nbsp;that can be moved onto the GPU, so there's not really anything else we can do to make this faster.

But.... New post-openGL frameworks are appearing like Metal and Vulkan, and we'll be able to write some crazily-fast rendering engines for these APIs. We're looking forward to working on that, it'll be a fun programming challenge!

But to answer your problem - just like for&nbsp;any performance-related problem the answer is always:

PROFILE YOUR APP!

There's really no point in asking for help until you understand where your CPU is being used, and the results are almost always surprising.

> I’m aware that using OpenGL will certainly help the matter, but from what I can see there isn’t a way to use an OpenGL Graphics context to pass down through the paint methods.

If you're drawing bitmap images, the&nbsp;GL renderer&nbsp;will be faster by a ridiculous amount.&nbsp;Have a look at the demo app to see how you can enable GL-based rendering - it's only about 4 lines of code and a bit of messing-about to do so. (We're going to add some helper functionality soon to make it a one-line change to enable it)

&nbsp;

&nbsp;

---

<div class="post-metadata">

**Author:** ![jimc](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jimc/32/16067_2.png) [@jimc](https://forum.juce.com/u/jimc)\
**Post date:** [August 30, 2015, 10:19am UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/4 "2015-08-30T10:19:15Z")

</div>

Jules - that was a good list of bullet points. &nbsp;But you say:&nbsp;

> - The openGL renderer: This is already very fast, but its&nbsp;bottleneck is in the time taken to rasterise paths, which isn't a task&nbsp;that can be moved onto the GPU.

From my playing with OpenGL, I thought rasterising stuff was a mainstream activity for it. &nbsp;Taking a series of positions and sorts&nbsp;out all the pixel shit.&nbsp;

Which bit are you referring to ?&nbsp;

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [August 30, 2015, 10:32am UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/5 "2015-08-30T10:32:00Z")

</div>

In order to draw a bezier path, it needs to be broken into triangles somehow for GL to process. The solution I opted for was to use the same scanline rasterisation algorithm as the software renderer uses, so that it's effectively building the shape out of one-pixel-high rectangles. This gives the exact same anti-aliasing as the software renderer gets, but is faster because it doesn't need to do any compositing.

The alternative way to do it is&nbsp;to triangulate the path, but that's really not much easiler in terms of algorithmic complexity, and although it's fewer triangles for the GPU to handle, it means that the only way to&nbsp;anti-alias is relies on the GPU multi-sampling, which isn't available (or very good) on all devices.

But in either method the bottleneck is the CPU flattening beziers into something the GPU can process..&nbsp;Ideally, we'd like to just throw the raw bezier data at the GPU and let it handle it while the CPU does something else, but GLSL isn't built for that kind of task. It can be done with openCL, but that's not available on all devices..&nbsp;The next-gen APIs will be better though - AFAICT&nbsp;Metal/Vulkan are a bit more openCL-like, so we should be able to build a really great renderer on there.

---

<div class="post-metadata">

**Author:** ![jimc](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jimc/32/16067_2.png) [@jimc](https://forum.juce.com/u/jimc)\
**Post date:** [August 30, 2015, 10:48am UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/6 "2015-08-30T10:48:08Z")

</div>

Ah .... :)

---

<div class="post-metadata">

**Author:** ![OBO](https://avatars.discourse-cdn.com/v4/letter/o/ba8739/32.png) [@OBO](https://forum.juce.com/u/OBO)\
**Post date:** [August 30, 2015, 7:49pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/7 "2015-08-30T19:49:46Z")

</div>

Afaict, NanoVG does this portably and might work out&nbsp;as a&nbsp;GL render backend.&nbsp;

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [August 30, 2015, 8:05pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/8 "2015-08-30T20:05:38Z")

</div>

AFAIK it doesn't anti-alias like JUCE does. And it will have&nbsp;the same bottleneck I described above - i.e. the path flattening or tesselating&nbsp;must be done on the CPU. _All_ openGL 2D renderers will have this issue - it's unlikely that any other library&nbsp;could be significantly faster than JUCE, because GL just isn't built for it.

---

<div class="post-metadata">

**Author:** ![OBO](https://avatars.discourse-cdn.com/v4/letter/o/ba8739/32.png) [@OBO](https://forum.juce.com/u/OBO)\
**Post date:** [August 31, 2015, 7:24am UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/9 "2015-08-31T07:24:18Z")

</div>

Yes, i see, thanks for clarifications.  
I hope to find time to hack together a NanoVG render backend just to see what it looks and performs like with an existing juce application.

---

<div class="post-metadata">

**Author:** ![xeneize](https://avatars.discourse-cdn.com/v4/letter/x/ce7236/32.png) [@xeneize](https://forum.juce.com/u/xeneize)\
**Post date:** [August 31, 2015, 6:36pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/10 "2015-08-31T18:36:27Z")

</div>

Hi Jules,&nbsp;

The drawing is not the problem, I can draw/repaint images very efficiently using coreimage and juce native.

I've created a test plugin with 250 sliders with listeners, and&nbsp;runs very smooth without lags.  
Then another plugin with 5 sliders, but this time I've created 30 instances in reaper,&nbsp;when I start to open their guis, sliders starts to lag, if you open all instances gui, the lag is very noticeable.

so I don't&nbsp;think it's a problem with the paint components, for me, the render engine is fast

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [August 31, 2015, 7:00pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/11 "2015-08-31T19:00:00Z")

</div>

Well it's presumably the host or OS repaint schedule adding some kind of overhead.

But like I've said hundreds of times before on this forum: The only way to investigate this kind of thing is to&nbsp;USE A PROFILER to measure what's actually happening!

---

<div class="post-metadata">

**Author:** ![xeneize](https://avatars.discourse-cdn.com/v4/letter/x/ce7236/32.png) [@xeneize](https://forum.juce.com/u/xeneize)\
**Post date:** [August 31, 2015, 8:07pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/12 "2015-08-31T20:07:29Z")

</div>

Thanks Jules,&nbsp;

I'll see if I can identify where the bottleneck is,&nbsp;I've never used a profiler yet, &nbsp;when I have some time I will look at this.

---

<div class="post-metadata">

**Author:** ![lalala](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/lalala/32/8577_2.png) [@lalala](https://forum.juce.com/u/lalala)\
**Post date:** [August 31, 2015, 8:18pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/13 "2015-08-31T20:18:28Z")

</div>

as you said you tested in reaper, perhaps that could be related :&nbsp;http://forum.cockos.com/showthread.php?t=165227

---

<div class="post-metadata">

**Author:** ![xeneize](https://avatars.discourse-cdn.com/v4/letter/x/ce7236/32.png) [@xeneize](https://forum.juce.com/u/xeneize)\
**Post date:** [August 31, 2015, 9:02pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/14 "2015-08-31T21:02:51Z")

</div>

Yes,&nbsp;

I noticed that reaper vst2 plugin gui gets continuously&nbsp;repainted a rectangle on the bottom part of the gui,&nbsp;

I've done the same test with vst3 (30 gui instances) and all run smoothly... I've tested too a plugin with a big VU meter (bitmap based) and run all smooth with 30 gui instances opened.

So, isn't a juce problem...&nbsp;

---

<div class="post-metadata">

**Author:** ![xeneize](https://avatars.discourse-cdn.com/v4/letter/x/ce7236/32.png) [@xeneize](https://forum.juce.com/u/xeneize)\
**Post date:** [August 31, 2015, 11:50pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/15 "2015-08-31T23:50:41Z")

</div>

Juce Plugin Host process from "activity Monitor" %CPU, &nbsp;10 plugin instances (with gui opened):

VST2: 30.1% CPU

VST3: 6% CPU&nbsp;

Macbook pro mid 2014, i5, 8gb ram, ssd disk, osx 10.9.&nbsp;

Base sdk 10.10, comp 10.7, release build with fastest optimizations, coreimage.

&nbsp;

Sorry, for now I will not profile because I don't know how yet, but when I get some free time, I will investigate it

---

<div class="post-metadata">

**Author:** ![xeneize](https://avatars.discourse-cdn.com/v4/letter/x/ce7236/32.png) [@xeneize](https://forum.juce.com/u/xeneize)\
**Post date:** [September 1, 2015, 4:20am UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/16 "2015-09-01T04:20:00Z")

</div>

~~I think I found the problem,&nbsp;~~

~~on VST 2.4 AudioProcessor::createEditor()&nbsp;gets called twice when you open the plugin gui.~~

~~You can reproduce it in Juce Demo Plugin:&nbsp;AudioProcessorEditor\* JuceDemoPluginAudioProcessor::createEditor();~~

Edit: apparently this is normal,&nbsp;&nbsp;http://www.juce.com/forum/topic/plugineditor-ctor

&nbsp;

---

<div class="post-metadata">

**Author:** ![jimc](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jimc/32/16067_2.png) [@jimc](https://forum.juce.com/u/jimc)\
**Post date:** [September 1, 2015, 8:09am UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/17 "2015-09-01T08:09:01Z")

</div>

Profilers are super-awesome. &nbsp;Click, run, ohhhhhh ....:)

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [September 1, 2015, 8:12am UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/18 "2015-09-01T08:12:57Z")

</div>

Yes - there's really no point in spending time looking at a performance problem unless&nbsp;you&nbsp;profile&nbsp;it. Looking at the numbers in Activity Monitor won't tell you much.

---

<div class="post-metadata">

**Author:** ![asimilon](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/asimilon/32/4235_2.png) [@asimilon](https://forum.juce.com/u/asimilon)\
**Post date:** [June 20, 2018, 5:59pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/19 "2018-06-20T17:59:24Z")

</div>

> [@jules](#):
>
> If you’re drawing bitmap images, the GL renderer will be faster by a ridiculous amount. Have a look at the demo app to see how you can enable GL-based rendering - it’s only about 4 lines of code and a bit of messing-about to do so. (We’re going to add some helper functionality soon to make it a one-line change to enable it)

Does this still hold true?

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [June 20, 2018, 6:00pm UTC](https://forum.juce.com/t/gui-drawing-efficiency/15429/20 "2018-06-20T18:00:30Z")

</div>

Yeah, pretty much.

[Next page](https://forum.juce.com/t/gui-drawing-efficiency/15429.md?page=2)
