I am trying to compile some of my projects with the latest Juce 8.0.6 and applied some changes to try using the software renderer, so wherever an image is created or loaded, it is done using the SoftwareImageType(), and I have removed all calls to setBufferedToImage() in components that used it.
Still, an application that, compiled using Juce 7.0.12, used barely 1% of my CPU when in idle, now takes 10% of CPU and around 18~20% of GPU power. Something that used to take around 5~6% of CPU, now jumps to 45~60% of CPU power and 50% of GPU.
All fonts and all images have a sort of totally unwanted and blurry “anti-aliasing” effect, even if I draw a straight line of just one pixel, if I look at it with the Windows magnifier (and its own antialiasing option turned off), it appears with fading edges.
And I’m working on a new computer, CPU is i9 14900K with 32 GB of DDR5 @ 7200 MHz, GPU is NVIDIA RTX4060.
I have read many posts on this forum of people reporting a drop in performance with JUCE 8 and what I see is a total indifference shown by the JUCE personnel who won’t listen to their users. If a solid solution is not offered that totally turns off this forced Direct2D nonsense and gives the user the ability to CHOOSE whether to use it or not, I could as well decide to stop paying for my montly subscription, that I’m paying since 2018.
I’m sorry that you feel this way, and I realise it must be frustrating. We are currently in the process of tracking down the performance issues you’ve raised in order to find a long-term solution. In my opinion the team has demonstrated commitment to try to track any issues raised regarding the Direct2D renderer and resolve them as promptly as possible.
We appreciate the suggestion to disable Direct2D as a potential solution but at this moment in time we don’t believe that would be the best long-term solution. Instead we would first like to concentrate on improving the Direct2D renderer so that performance isn’t an issue for you or ideally anyone!
It’s worth adding that most users are experiencing improvements, many very significant. It’s also worth highlighting that on what is predominately a support forum there understandably tends to be a selection bias towards negative feedback and issues. However, that isn’t to dismiss the issues you’re facing. We accept that despite our best efforts, with changes this large, unfortunately there is likely to be a minority of users that still experience issues.
We value the feedback users such as yourself are able to provide in order to help track these issues down and resolve them so everybody (including yourself) can benefit from the advantages they offer.
If you have more details regarding the areas of code that are causing bottlenecks for you specifically, or problematic code examples, beyond what you may have already shared elsewhere in the forum, that may be helpful for the team to track down the problems you’re facing and resolve them faster.
In regards to a blurry “anti-aliasing” effect, some comparative screenshots may be helpful for us to understand the issue. I’m not as familiar with the Direct2D work as others in the team, but some questions that jump out to me immediately…
Are you using a particular scaling factor for any of your monitors?
Are these images that contain fonts, lines etc. or are you drawing directly to the graphics context?
Is the font a bitmap font?
Can you reproduce the same issues in the DemoRunner?
How does the font in question render in other applications in Windows (for example a web browser)?
This is how the two versions appear when I use the Windows magnifier. Left: app compiled with JUCE 8.0.6, right compiled with JUCE 7.0.12.
I wasn’t able to take a screenshot with the magnifier, so I took a photo at the screen, but you can clearly see that the magnifier itself is not softening the edges (see the mouse cursor), but everything painted on the left clip appears blurry.
The screen resolution is FHD with 100% zoom, no scaling applied. Images used on my UI are both PNG read from the resources, and Image() objects that I’m drawing directly to the graphic context. I’m using the standard font, mostly in simple Label objects or using drawText(); I haven’t tried with the DemoRunner yet. I’m not sure what font is used by Juce as the standard font, so I haven’t tried it in a browser.
Btw the most important thing is the CPU and GPU load:
Top row, the application compiled with Juce7, bottom row compiled with Juce8. In both cases the app is in idle (not playing any audio, not animating anything on the UI, just waiting for user input).
When I start interacting with the UI (sliders, comboboxes, animating components, etc.) the CPU percentage jumps to 45~60% while the Juce7 version stays below 5%.
Apparently yes, even if I am suspecting that there’s a sort of interaction between an app compiled with JUCE 8 and the Windows magnifier, because if I don’t use the magnifier, take a screenshot of the two versions side by side, then magnify the screenshot, they still appear stlightly different but not so blurry like I see them via the magnifier. See this PNG:
These last screenshot without the magnifier seem pretty pixel perfect to me, aside from the differences in text rendering.
Could it be that the differences you are noticing, are due to the changes done to Font rendering to have Unicode support etc. , rather than Direct2D?
It’s also unclear which side is the JUCE 8 in the above screenshot, and whether it was rendered using the software renderer or Direct2D
To be clear, performance issues are being investigated, however have you looked in a profiler to see where the bottle necks are for you specifically?
As @yfede says, apart from font rendering, the two seem pixel perfect in the screenshot comparison. I wonder if something else is happening as far as the magnifier is concerned.
Regarding font rendering I’m not 100% sure all the text is rendering with the same font in those screen shots. There were significant changes surrounding font rendering in JUCE 8 that are independent of Direct2D so this may be a very seperate issue.
Let’s take the text “Group 1” as our example. If you have code for this that you’re expecting to be the same between JUCE 7 and JUCE 8 could you please share it? You say you’re using the “standard font”, do you mean you’re not specifying a typeface? I assume you specify the size? what about style?
It’s worth noting that text rendering is unlikely to be pixel perfect when comparing JUCE 7 to JUCE 8. One reason for this is because JUCE 8 now supports more font features than JUCE 7. For example if we take the “1” in the top left corner of the channel strip, the example on the left looks slightly sharper (in the screenshots not the magnifier) and this is likely because of hinting which was being ignored in JUCE 7.
Sorry, I forgot to mention that in this screenshot, the left side shows Juce 7 and right is Juce 8.
Yes, fonts are slightly different and look a little bit bigger as well.
Yes I use VS2022, I should run the profiler and see where’s the bottleneck. The last time I tried, I saw a lot of paint() calls involved but did not investigate any further.
Some images are PNG files read from the resources, some are new Image() objects to which I’m painting. In the screenshots above, the image buttons and the fader are PNG, the labels (Group 1) are just Label objects.
Exactly, I’m just not specifying a font face, at least in what is shown in the screenshots I posted. I use no style, just specify a size.
Now please watch this short video to appreciate the incredible improvements brought by Juce 8 over the old Juce 7.
The first executable has been compiled with JUCE 7.0.12 (actually the last develop);
Second executable has been compiled with JUCE 8;
Third executable has been compiled with JUCE 8 but with all Image() objects created or converted to the SoftwareImageType().
Of course I was sarcastic… the performance of Juce 8 is terrible, despite it uses the GPU (NVIDIA RTX 4060). Also see the greater CPU percentage of the JUCE 8 builds.
Now please stop telling me that this Direct2D thing is an improvement. I want the performance of JUCE 7 with the new fixes and updates of JUCE 8, is it possible?
Now please stop telling me that this Direct2D thing is an improvement.
We have explicitly said that we are not dismissing the issues you are facing, and we are trying to help.
Sarcasm is not helpful.
What would be helpful is if you could share some sample code that demonstrates the performance problems you’re seeing. From the screenshots and video it’s not clear what’s an image, how those images are being constructed and displayed, and what’s being drawn. If we can understand exactly what’s happening then we can tell you how to fix it.
I will try to create a “Hello world” example that shows how performance drops with JUCE 8, but at least I hope you now have the picture… What used to work like a rock with JUCE 7 has now become something else, this is evident.
It’s not that cut and dry. You might have a very GPU-unfriendly design (e.g. creating your channel strips as “BufferedToImage” and then repainting them), and now that the GPU is used, it creates unnecessary copies across that bus, that are VERY slow.
That’s why @t0m is asking for details. So he can help you avoid these pitfalls.
Just saying “it used to work fine, now it doesn’t” is not helpful for anybody.
As I said in the first post, I have removed all calls to BufferedToImage() for the JUCE 8 build.
An application like that is so complex that there’s not one single thing that has been implemented the wrong way, but whatever it is it was very well implemented for JUCE 7, now I just expected that the same code would perform equally well or even better with an updated and “improved” version of the library, maybe with just some adjustments… which I would like to know what they are, I’d be glad to try.