OpenGL and high CPU usage


#1

I'm working on a plugin that uses two components that use OpenGL for rendering. Each is derived from OpenGLRenderer and they have their own OpenGLContext.

When I look at the CPU usage in Instruments I see:


Running Time    Self (ms)        Symbol Name
7187.0ms   47.5%    0.0                   juce::MessageManagerLock::MessageManagerLock(juce::Thread*)

Running Time    Self (ms)        Symbol Name
5401.0ms   35.7%    0.0                   juce::MessageManagerLock::MessageManagerLock(juce::Thread*)

My plugin is spending 83.2% of it's CPU time trying to grab the message manager lock from within OpenGLContext::CachedImage::renderFrame()

Should I be sharing a context between the two compnents? What is the correct way to work around this? I'm using an older version of Juce, I haven't upgrade to 4 yet.


OpenGL Demo uses full CPU on Windows
#2

If you don't attach them to components then they should run freely on their own threads without needing the lock.

But something I need to do (and is very near the top of my list) is to add a new system for GL where it allows a background thread to render multiple GL windows into background frame-buffers, and then afterwards composite them into the component hierarchy. That'll allow GL components to be embedded amongst none-GL ones and will also avoid this need to lock the MM while they're being drawn.


#3

This would be awesome. +1!


#4

Just curious: why would you want to mix OpenGl and non-OpenGl components? Isnt it faster to render everything in OpenGl?


#5

Yes, but I think the limiting factor is text (if I've interpreted the code paths correctly): JUCE uses the native glyph APIs for rendering text.

That is, unless JUCE gets set up with ICU, Freetype and Harfbuzz (or creates its own rendition of these 3 libraries, which would be insane to do).


#6

It's probably not the best design, and it's been a pain, getting colors to match between the OpenGL rendering and the CoreGraphics rendering etc. I'm not a 3d programmer, so another developer did the 3d components and I thought I'd be able to just drop them in.


#7

If you don't attach them to components then they should run freely on their own threads without needing the lock.

I don't understand this, if I don't attach them, then how do I draw the component?

The new GL system would be very useful for me. I have a horrible hack where the opengl components search for any siblings that overlap, render them to image, and then draw that image via opengl. So the overlapping part is drawn twice. Horrible.


#8

I implemented automatic caching of the image textures generated by the drawText functions (well, wrapped the drawText functions in my own ones that did this, so they could be used exactly the same, but internally, if you're drawing the same text as in a previous frame, it doesn't have to do anything besides tell opengl where to place the texture on the screen), because even without the locking-issues that you're having, re-drawing text every frame (which is typically the same) is unneccessary and can get expensive.

One could even go further, and have the drawText internally render+cache all the symbols in some big texture(s) (in whichever fonts+size [and colors unless one got clever with the coloring]) - this is the kind of I did when doing mobile games where the performance was more critical. A little harder to make totally automatic+transparent (i.e. it needs some idea of the range of your alphabetal requirements - you could be chinese for example - in advance, or has to cache each letter individually as used).