Sorry to bring this back to life but when you do this do you also remove the OpenGL module from the source like OP said contributed to the issue?
We’ve simply not attached to the OpenGL context any more.
We’d much more like OpenGL to work on Windows with JUCE, though…
Also still not sure what to do with this… With OpenGL deprecated on mac OS and stuff aswell. Did everyone already sign the ableton issue?
Unfortunately the issue is still there in Live 11 RC.
Only 4 people have upvoted the issue so that might explain why it went under their radar.
Coincidentially, while implementing a VulkanContext I got the same issue!
I think I found the cause of it. I’m not 100% sure though. My theory:
The problem is not VST or VST3 or windows hidpi related at all. It resides in
juce_opengl\opengl\juce_OpenGLContext.cpp and juce_opengl\native\juce_OpenGL_win32.h
Now first… What is the situation?
The “virtual” components are at the correct resolution. They are drawn correctly into the framebuffer.
Problem: Either the fullscreen quad is cut off, or they are drawn into the framebuffer at double the resolution. So the only cause can be a wrong GL viewport or a scale factor.
Before the components are drawn a LowLevelGraphics context is created.
juce_OpenGLContext.cpp : paintComponent()
std::unique_ptr<LowLevelGraphicsContext> g (createOpenGLGraphicsContext (context, cachedImageFrameBuffer));
g->clipToRectangleList (invalid);
g->addTransform (transform);
paintOwner (*g);
Now isn’t that addTransform interesting? I wonder how it’s calculated.
juce_OpenGLContext.cpp : updateViewportSize()
transform = AffineTransform::scale ((float) newArea.getWidth() / (float) localBounds.getWidth(),
(float) newArea.getHeight() / (float) localBounds.getHeight());
And the bounds depend on the OS / DAW scale factor.
auto localBounds = component.getLocalBounds();
auto displayScale = Desktop::getInstance().getDisplays().getDisplayForRect (component.getTopLevelComponent()->getScreenBounds())->scale;
auto newArea = peer->getComponent().getLocalArea (&component, localBounds).withZeroOrigin() * displayScale;
Now I think the problem here is: The transform is only updated if the viewport size is changed and somehow some DAWs will not trigger it at the correct time. Or even not at all. Not sure why. I tried to debug it. Really hard to guess the order, since there is a timer involved too.
Anyway. To avoid this hassle I just recalculated the transform before the components are drawn.
void paintComponent(FrameState& frame)
{
// you mustn't set your own cached image object when attaching a context!
jassert(get (component) == this);
std::unique_ptr<juce::LowLevelGraphicsContext> g(createVulkanGraphicsContext(frame));
const auto transform = getPaintTransform();
g->addTransform(transform);
paintOwner (*g);
}
And getPaintTransform does something like this:
juce::AffineTransform getPaintTransform() const
{
if (auto* peer = component.getPeer())
{
const auto localBounds = component.getLocalBounds();
const auto displayScale = juce::Desktop::getInstance().getDisplays().getDisplayForRect (component.getTopLevelComponent()->getScreenBounds())->scale;
const auto newArea = peer->getComponent().getLocalArea (&component, localBounds).withZeroOrigin().toDouble() * displayScale;
return juce::AffineTransform::scale ((float) newArea.getWidth() / (float) localBounds.getWidth(),
(float) newArea.getHeight() / (float) localBounds.getHeight());
}
return juce::AffineTransform();
}
Maybe someone in the JUCE team wants to try a similar solution. I mean, calculating it once before the components are drawn isn’t much work.
tl;dr
I copy pasted the Open GL Context code to implement the same behavior in Vulkan.
The scale bug is in the logic! Easy fix: rip out the scale != newScale state and calculate
the transform + scale on the fly everytime it’s used. It’s the easiest way to avoid DAW specific window behavior.
Has anyone tried this out? I’ll take a look this weekend, thanks for the work parawave looks promising.
I actually did give that a shot and it didn’t solve the problem for me but I didn’t dive too deep into it
