GUIs are mirrored vertically (mac)

Hi,

On macOS 10.13 our GUIs are mirrored vertically in Digital Performer 9.52. Perhaps also newer macOS versions are affected. This happens in both AU and VST. The same builds are okay in other hosts running on the same system.

This is likely VSTGUI related, but perhaps it helps to mention that this issue was introduced after we updated to VST SDK 3.7.7 and it hadn’t been present with the previous SDK version we were using (3.7.1) - we are always using the respective VSTGUI version that comes with the SDK. There weren’t any changes in the respective client code between the intact and the broken plugin builds.

Did anyone else observe this and can you tell us whether it’s been fixed in 3.7.9?

Thanks.

Best,
Ray

I can only guess but I think that this may be a side-effect of the “red bitmap” bugfix. See VSTGUI 4_10_3 red bitmaps?

Hi Arne,

That’s possible. Unfortunately, I don’t own Digital Performer, so we have to rely on the customer’s feedback. Can you guys investigate on your end, too or did anyone else encounter the same issue in their plugins as well?

It’s kind of weird that this only happens in DP, though.

EDIT: If I understand his last post correctly, the fix is obsolete since the CMultiFrameBitmap update as long as one uses “more quadratic” or smaller bitmap dimensions according to Matthias at BX. Is it possible to override the CALayer / red bitmap glitch changes, easily so I can prepare a test build for the customer?

Best,
Ray

We had a few e-mails that are not mirrored on the forum. Only both changes fixed the red bitmaps for him.
So it’s unlikely that we change this back as it is also something the Apple engineers recommended to us to prevent future issues.
And I’m sorry we are also not able to investigate this further, no DP license and no macOS 10.13 available anymore.
If you want to check if this is indeed the cause of the issue, you can just revert the specific commit in git (this one).

Okay, I’ll try that. That’s unfortunate, though, because I’m not sure whether this is really macOS 10.13 specific.

Can anyone with DP and a newer OS check whether the current Fuse Audio Labs builds plugins appear mirrored on their system?

@Arne: Which emails about GUIs not being mirrored are you referring to? This only seems to affect DP.

Best,
Ray

I meant e-mails with bx_matthias about the red bitmap issue.

I also don’t think that this is macOS 10.13 specific. It’s more likely to be specific to the SDK version DP was built with. Do you know which version of DP that is? Is it the current released version?

It’s DP 9.52

I see. We weren’t getting any reports about mirrored GUIs up until recently and these builds have been in the wild for a while. So I’m pretty sure this only happens on this very specific setup (or DP in general).

One more thought: I haven’t familiarised myself with the specifics of CALayer so I’m just guessing here. There’s a property named contentsAreFlipped (not sure about geometryFlipped) whereas isFlipped always returns YES in the VSTGUI_NSView class definition. Is it conceivable that this along with the embedded CALayer hierarchy should inherit the parent view’s property instead?

The user has also noted that it’s only the visual contents that are flipped but the controls react to the areas where they would normally be placed.

Hi Arne,

the user who reported the issue was kind enough to run a test build in DP which outputs the NSView and CALayer hierarchies in which the GUI is embedded (see screenshot)

Screen Shot 2023-12-01 at 12.59.28

It seems that both of the CALayers attached to the bottom NSView node (0x608000235180) have their contentsAreFlipped property set to NO, while the respective bottom NSView node has isFlipped set to YES.

Depending on the format and DAW you’re running this in, you will of course observe different hierarchies with different “flippings”, but in all correct cases the CALayers’ contentsAreFlipped will be equal to the isFlipped value of the NSLayer holding the layers.

I wonder why that is? I haven’t inspected the NSViewFrame code deeply, but are these properties touched by VSTGUI at all when the CALayer is created? Could this be in some way related to VSTGUI’s obj C class creator implementation?

One could fix this by inspecting the respective properties and then set the CALayer’s isGeometryFlipped to YES if required, but I wonder how and where this could be fixed elsewhere.

Here are two screenshots of cases with the correct appearance:

Best,
Ray

VSTGUI does not touch the CALayer properties contentsAreFlipped and isGeometryFlipped. And I just see that contentsAreFlipped is just a method and as we use a plain CALayer it returns the default value. This is the doc about it:

 * Returns true if the contents of the contents property of the layer
 * will be implicitly flipped when rendered in relation to the local
 * coordinate space (e.g. if there are an odd number of layers with
 * flippedGeometry=YES from the receiver up to and including the
 * implicit container of the root layer). Subclasses should not attempt
 * to redefine this method. When this method returns true the
 * CGContextRef object passed to -drawInContext: by the default
 * -display method will have been y- flipped (and rectangles passed to
 * -setNeedsDisplayInRect: will be similarly flipped). */

So this explains it. The drawInContext must flip the coordinates of the CGContext in this case.
Will have a look later.

Hi Arne,

And I just see that contentsAreFlipped is just a method…

Yes, I am aware of that and hence I was suggesting to use isGeometryFlipped which can be changed on the fly. A simple fix that would work for the scenarios I have observed would be something along the lines of the following code patched below line 964 in nsviewframe.mm and probably something similar using the CALayerDelegate view in caviewlayer.mm:

...
[nsView.layer addSublayer:caLayer];
caLayer.isGeometryFlipped = ([nsView isFlipped] != [caLayer contentsAreFlipped]? YES:NO);
...

However, it might be more involved than that in the general case so I’ll wait for your findings.

Best,
Ray

I think it’s unrelated to the NSView flipped state.
Please try if adding

caLayer.geometryFlipped = !nsView.layer.contentsAreFlipped;

after

[nsView.layer addSublayer:caLayer];

fixes the issue.

Hi Arne,

We tried exactly that first and unfortunately it didn’t solve it. If you inspect the examples from the screenshots, you’ll see that the broken case has the terminal layer “unflipped” while the containing view is flipped and in these cases the last two layers of the CALayer hierarchy have the same flipped state (the first screenshot shows the broken example in DP, the two others are fine).

EDIT: Sorry, we tried caLayer.geometryFlipped = ![nsView isFlipped]; which of course didn’t work. I’ll try your suggestion as well and report back. At least it doesn’t mess up the GUI orientation in the hosts I can test.

Best,
Ray

For me it’s a little bit unclear which NSView and which CALayer are the ones from VSTGUI in that hierarchies. Are they always the last ones?

Yes, that’s right. If you look at the first screenshot for instance, the NSView created by VSTGUI is the bottom one in the dumped hierarchy:

NSView: 0x60800032eec0

The layers added by VSTGUI are the two ones at the bottom:

CALayer: 0x608000057580
└CALayer: 0x608000235180

which are both attached to the above NSView (0x60800032eec0) - check the delegate pointer.

Just heard back from the DP user: The code I posted above seems to fix it without messing up the cases in which things were already working. The only pattern I could see was what I was describing about the discrepancy between the view and the layer flipping. I’m still a bit sceptic as to whether this is just a random side effect, so it could still break in other cases. I don’t mind admitting that I don’t yet fully understand what’s going on.

I’ll also provide a build to the user that includes your suggestion and report back. I already checked the setups available to me and at least it doesn’t break that way.

Would you mind elaborating why the two terminal layers added by VSTGUI should have opposite geometryFlipped states and why that would fix the issue?

EDIT: Yep, caLayer.geometryFlipped = ![nsView.layer contentsAreFlipped]; seems to work, too. I’d like to understand why and whether it’s a valid fix in all cases.

The CALayer and the NSView are independent of each other. So the NSView.isFlipped property does not affect the CALayer rendering. At least this is how I understand this.

Yes, okay, that’s what I gathered. But why should the two “terminal” CALayers have opposite geometryFlipped settings and why does that fix the issue. It seems like it does, but I don’t have a clue why.