`juce7` technical preview branch

Which linker flags are needed? I’m facing the same issue.

Decided to try out this branch today and I’ve tried re-exporting and I’m being able to compile still. A bit stumped as to what I need to add!

Edit: I’m even having problems with the demos.

Are you using a build of the Projucer from the juce7 branch to save/export the projects?

Ah thanks, that was it. I naively looked at the version number and didn’t think it would make a difference…

First impressions of the graphics rendering is really good, great stuff!

Interesting find - I display a waveform in one of my plugins which used to be done in openGL. Its now drawing fantastically in most hosts using the JUCE renderer as an animated app component.

However, if “Enable graphics hardware acceleration” is turned on in Studio One, repaints become extremely sporadic; sometimes it takes a couple of seconds to repaint. Not sure if this is a JUCE or Studio One issue? Continuous mouse movement over the top of the plugin however makes it repaint as normal.

(Monterey M1 Mac mini)

Thanks JUCE team for this amazing update! The Metal-layer backed rendering makes an enormous difference for my project’s performance on macOS:

Screen Recording 2022-05-18 at 01.03.10 2

10 Likes

We’re now also syncing Windows drawing with display adapter refreshes:

7 Likes

If we’re using CMake, is Metal rendering enabled by default on MacOS or are there flags we should set?

1 Like

Async drawing is enabled by default, and the preprocessor flag JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS will enable the new Metal layer renderer on platforms that support it.

3 Likes

Is Metal rendering now work for iOS ?

Isn’t that a bit confusing, why not JUCE_METAL_LAYER? And give a #error for the old unused flag.

I use JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS since years (even when it does not work as expected anymore) , and this would silently introduce the new metal-layer, which maybe perform less well?

I also have the assumption that some people already mix up the reason for the new speed increases due to asynchronous repainting with the metal layer, which is actually not a new renderer, just another method/wrapper for the regions which are repainted via CoreGraphics, or I am missing something?

Can I still use OpenGL (with the new metal-layer?), especially with fps synchronised renderOpenGL() calls with custom OpenGL commands (like the teapot demo)?

3 Likes

That would be even more confusing.

The fact that we have Core Graphics rendering into a Metal layer is an implementation detail. We are not expecting any performance benefit from using a Metal layer over the default layer provided automatically by Core Graphics, other than the fact that we can provide a mechanism where individual dirty rects are redrawn individually. All of the drawing commands are identical.

Without getting bogged down in detail: JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS has been broken for a long time and we have now fixed it. The type of layer used is unimportant.

If you were previously setting this flag to improve the performance of your drawing then when moving from JUCE 6 to JUCE 7 you will probably also see the same performance benefit as you did back when JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS was actually doing something useful. This flag has never been risk-free, and has always required some testing to make sure you’re not going to harm performance. The difference now is that the new default rendering mechanism has also been improved, so the use of this flag needs to be reevaluated.

This is all detailed in BREAKING-CHANGES.txt.

2 Likes

Thanks for clarification, because I have the feeling people already using “Metal” as synonym for fast rendering. I still plea for a fresh start, because using “multiple paint calls” will not use async-rendering, so everybody needs to actively re-evaulate, unused macros should throw an #error. (It remembers me a little bit on my JucePlugin_AUHighResolutionParameters-drama, even though it was much worse)

2 Likes

This is somewhat chicken and egg. I’m in favour of starting work on the egg here and getting CLAP support in JUCE.

Also, from breaking-changes:

Constructors of AudioParameterBool, AudioParameterChoice, AudioParameterFloat,
AudioParameterInt, and AudioProcessorParameterWithID have been deprecated and
replaced with new constructors taking an 'Attributes' argument.

Can we get a compiler flag to disable this particular deprecation warning JUCE_ALLOW_LEGACY_FEATURES. I don’t see there’s any benefit in updating old code here that’s working fine? And we’ve got quite a lot of it!

3 Likes

Can CLAP support be added in a way that doesn’t lose the main benefits of the format? What would be the benefits to including it in Juce? Simply being not-VST isn’t something I’d be interested in, so I’m interested to know more of what are the killer features we’d retain once we’ve been through the lowest common denominator format wash of adding it to Juce?

1 Like

Interesting, so the performance boost I was seeing is just because JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS used to be broken!

I also wanted to report that currently, there’s no audio in the standalone for a plugin, tested on Mac and Linux.

Do you see the same issue with JUCE’s audio plug-in example? Audio appears to be working as expected there.

That was a good clue, thanks! It was caused by using audioDeviceIOCallback instead of audioDeviceIOCallbackWithContext in my StandaloneFilterApp.

If audioDeviceIOCallback doesn’t work anymore, maybe it should be removed? I marked it as override, but got no warnings. JUCE has a macro to supply your own StandaloneFilterApp, so not getting any warnings could end up confusing some people.

The default implementation of audioDeviceIOCallbackWithContext just calls through to audioDeviceIOCallback, so it’s difficult to see how things have gone wrong.

Could you please provide a minimal example?

I’m using the unmodified code of the old StandaloneFilterApp, so the callbacks look like this:

  //  Callback in size enforcer
        void audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples) override
        {
            jassertquiet(static_cast<int>(storedInputChannels.size()) == numInputChannels);
            jassertquiet(static_cast<int>(storedOutputChannels.size()) == numOutputChannels);

            int position = 0;

            while (position < numSamples)
            {
                const auto blockLength = jmin(maximumSize, numSamples - position);

                initChannelPointers(inputChannelData, storedInputChannels, position);
                initChannelPointers(outputChannelData, storedOutputChannels, position);

                inner.audioDeviceIOCallback(storedInputChannels.data(), static_cast<int>(storedInputChannels.size()), storedOutputChannels.data(), static_cast<int>(storedOutputChannels.size()), blockLength);

                position += blockLength;
            }
        }


        // Callback on StandalonePluginHolder
        void audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples) override
        {
            jassertquiet(static_cast<int>(storedInputChannels.size()) == numInputChannels);
            jassertquiet(static_cast<int>(storedOutputChannels.size()) == numOutputChannels);

            int position = 0;

            while (position < numSamples)
            {
                const auto blockLength = jmin(maximumSize, numSamples - position);

                initChannelPointers(inputChannelData, storedInputChannels, position);
                initChannelPointers(outputChannelData, storedOutputChannels, position);

                inner.audioDeviceIOCallback(storedInputChannels.data(), static_cast<int>(storedInputChannels.size()), storedOutputChannels.data(), static_cast<int>(storedOutputChannels.size()), blockLength);

                position += blockLength;
            }
        }

My plugin has no audio at all when I use this. If I open audio settings and hit the “test” button, I will get a test tone, but the tone will hang and never fully fades away.

We’re now also syncing Windows drawing with display adapter refreshes:

What kind of real world impact is this showing?

1 Like