OpenGL Renderer: massive performance decrease in Juce V.2

Hello,

today (April 22. 2012) I updated to the latest commit and I noticed a massive performance decrease of the OpenGL Renderer compared to the commit from February 12. 2012.
When I compile the Juce Demo in Release mode using the Version from Feb. 12. and use the OpenGL Renderer to render “Paths - Linear gradient” set the size to maximum and animate all other properties, the render time is about 2 ms.
Now, when I do exactly the same test, using the latest Juce Version from April 22., the render time is about 35ms.

These results are 100% reproducable, so there must have been some changes between February and today that led to a massive loss of performance.

You can easily test this yourself by compiling the Juce Demo using the current Juce Version 2 and then resetting the Master to the commit from May 12 (make sure to not just reset the index but to use the actual files from this date) and compiling the demo again.
The differences of the render times and the performance are huge, when using the two different versions of the OpenGl Renderer!

EDIT:
Actually the commit that is responible for the performance loss is:

Revision: b338698e346d3cb14e33e568f838a7e8523bb544
Author: jules
Date: 15/03/2012 12:13:38
Message:
OpenGL: removed the fixed-function rendering code, replacing it with a simple software renderer that blits its results to the GL context. Removed the public OpenGLGraphicsContext class, replacing it with a createOpenGLGraphicsContext() function which returns an appropriate shader-based or software-based renderer object.

All versions before this commit show great performance. All newer commits suffer from the performance problem.

The problem occurs at least on Windows 7 64 bit; Juce Demo compiled in 32 bit Release mode; other platforms not yet tested.

Sounds like you’re using a graphics card without shader support?

I tested this on a MacBook Pro (running Win 7) with a GeForce 9600M GT that supports: Shading language version: 3.30 NVIDIA via Cg compiler
I really don’t know much about OpenGL hardware requirements, but I assume that this card should support shaders.

Anyways, even if the performance issue should be due to my hardware restrictions, would it be possible to add a fall back to the OpenGL Renderer version that was used before the mentioned commit, if shaders are not supported, because the performance was really great compared to the Software Renderer and to the OpenGL Renderer of the current version? So users without shader support could benefit from this, too.

But first of all we should make sure that this issue is actually related to the missing shader support.

Ok, well if your system has shaders, it shouldn’t be using the non-shader code path at all - maybe it’s failing to recognise the shader engine on your system for some reason?

Could you see what it does in the createOpenGLContext() function (in juce_opengl_OpenGLGraphicsContext.cpp)? That’s where it checks for shader availability, and it sounds like it should work on your machine (unless the windows drivers don’t provide that feature for some reason)

Will check that tomorrow and give you some feedback.
Nevertheless, what do you think about a fallback for users without shader support?

There is a fallback: the software renderer. The old fixed-function code that I removed was actually extremely slow compared the software renderer. I presume that when the old version was working fast, you were actually seeing the shader-based renderer working correctly, and not the old fixed-function pipeline.

Ok, I see.

I just had time for one quick test. When I debug the code in the function you mentioned:

if (target.context.areShadersAvailable()) return new ShaderContext (target);
it enters the line and returns a new ShaderContext. So I assume that shaders are detected.

I’m sorry, but I don’t have time for further investigations right now. I’m gonna make some more test tomorrow…
Thanks for now.

Weird… Well, I really don’t know what might have changed in that commit that would make a difference. Certainly the removal of the old fixed-function stuff will be irrelevant because you’d always have been running the shader code…

I feel obliged to mention that once the OpenGL Renderer is on, those times/frame become somewhat arbitrary. They probably just represent to time to issue all the OpenGL Commands, not the CPU time taken by the driver, and certainly not the time the GPU requires to actually do the work.

Bruce

I have a similar system so I thought it would be worth testing.

I have a MacBook with a GeForce 9400M and Windows 7 64-bit.
Updated to tip (April 22), compiled JuceDemo 32-bit Release mode.
Set Juce Demo to “Use OpenGL Renderer”, “Paths - Linear Gradient”, hit maximise button, animated all properties.

Software Renderer: 12ms - 26ms Render Time
OpenGL Renderer: 6ms - 15ms Render Time

Times vary due to scaling animation. When scale of path is small, I get the smaller time, when scale of path is huge, I get the larger time. I think this is expected behaviour. There is a larger area to paint and I think Juce is uploading a new edgetable every time it the scale of a path changes as the path always looks great and never pixelated.

Not sure why your superior MacBook Pro is seeing worse performance than my inferior MacBook.

OSX 10.7, MacBook Pro, GT 330M, 8GB RAM

Software: 4-12 ms
OpenGL 1.5-2.0 ms

There’s one weak point in the win32 implementation that I never managed to figure out - if you look at OpenGLGraphicsContext, line 1029, there’s a numQuads setting which defines how large the chunks of data are that get sent to the GPU. Making that number bigger makes a massive improvement in performance (at least several times faster, depending on what’s being drawn), but crashes on some graphics cards (including mine)! And looking through the GL API there didn’t seem to be any reliable way to ask the driver for a safe value to use for it. Not sure what people do in games, etc. to work around it, but any suggestions are welcome!

Here are some more infos:
For each version I tested I used the original juce code without any modifications.
Of course, the render times depend on the screen resolution and the size of the juce demo window. I tested this with 1440 x 900 and 2560 x 1440 with fullsize app window. The huge differences in render times appear with both resolutions but obviously the render times are lower, the lower the screen resolution, no matter which renderer or which version.

@jules:

This code didn’t change between the versions with good and bad performance.

@Bruce:

Well, the differences are like comparing a quadcore to an atari. The current version doesn’t even render smoothly but stuttering (the earlier version rendered perfectly and the software renderer is smooth, too, but takes longer).

[quote]OSX 10.7, MacBook Pro, GT 330M, 8GB RAM
Software: 4-12 ms
OpenGL 1.5-2.0 ms[/quote]
These results are similar to what I get with the version before 15/03/2012 on an almost identical system (except that I’m testing with windows/bootcamp), but way better than what I get with the current version. What is your screen resolution?

@sonic59

[quote]Software Renderer: 12ms - 26ms Render Time
OpenGL Renderer: 6ms - 15ms Render Time
Times vary due to scaling animation…[/quote]

It seems to me that your render times are not ok, too. Because with the old version, it takes not even 2ms at a resolution of 2560 x 1440 and fullscreen on my system. Could you please do a test without animating the size and set it to maximum and then post your render times and your screen resolution.
If it is much higher than 2 ms, you have the same performance issues that I have.

[quote]It seems to me that your render times are not ok, too. Because with the old version, it takes not even 2ms at a resolution of 2560 x 1440 and fullscreen on my system. Could you please do a test without animating the size and set it to maximum and then post your render times and your screen resolution.
If it is much higher than 2 ms, you have the same performance issues that I have.[/quote]

OpenGL Renderer.
Position, Rotation and Gradient animated. Size not animated.
Juce Demo Stats: "1880 x 922 - Render Time: 2.35ms"
My Screen Resolution: 1920x1200

Sounds good to me.
If I do the same with the latest version and a similar window size, my render times are about 18ms with OpenGL Renderer and stuttering display with the current version and about 1.4ms and smooth diplay with the version before March 15.
Any ideas???

If I had to guess, I’d point my finger at the graphic card drivers.
Are you using 10.7 and bootcamp? Latest bootcamp drivers?

I’m using bootcamp win 7 and the latest official nvidia drivers for this card (no problems with 3d applications and openGL so far).
But how does this explain that juce before March 15. showed excellent performance?

I’m currently doing tests with other platforms and machines. Hope I have the results ready this evening.

If you could put together the smallest self contained test program that illustrates the problem, I can float it past the guys in ##OpenGL on Freenode (or you could go there yourself).

I took a look and I see numQuads = 64 for Win32, while it is 8192 for other platforms. That doesn’t smell right!

Well, that code didn’t change between the versions with good and bad performance.
The old version that shows excellent performance uses the value of 64, too.

I’m currently in the middle of some test and will post my results later.
Thanks.

I’ve really no idea - although there were a lot of changes in that check-in, they were all just removal of code-paths that you wouldn’t have been using. Perhaps something to try would be to build the old version, but set JUCE_USE_OPENGL_FIXED_FUNCTION=0 to make sure it really was using the shaders.