The state of HiDPI plugins on windows


#1

I've run into some issues with hidpi scaling on windows and plugins. Now there is at least one host that supports it and it's Studio One v3. I made a plugin that can resize to any scale, but I'm having troubles getting this to work with the JUCE vst3 wrapper. This is all with Studio One in hi dpi mode. Presonus has published vst2 and vst3 extensions for hidpi, but I'm actually not sure they are needed and I'm trying to find a solution without extensions. Their extensions basically allow to choose a different scaling factor for the app & plugins than what the system is set to. That feels like a bit too much flexibilty. I believe it should be the system's responsibility to deal with the screen resolution and the size of content.

I could get VST2 to work right by asking windows about the display scaling factor when the plugin is created. JUCE hides that from plugins by limiting the Desktop::getInstance().getGlobalScaleFactor() call to always return 1.0 for plugins. So I just used GetDeviceCaps(dc, LOGPIXELSX) instead. I don't understand why JUCE won't return the right value for plugins though. If a host is run in scaled mode on a hidpi screen, then windows always returns 96 dpi anyway. So it feels like an unneeded guard and now with at least one real hidpi host it turned out to be a bit of a problem.

Anyway I then just scale VST2 by dpi/96 when the editor is created and that makes things work fine in Studio One. But it's a bit of a hack solution.

However with the vst3 wrapper things don't work so well. I appears as in that case the host is already creating a larger window in hidpi mode, expecting the plugin to fill it in order to show up in correct scale. If the JUCE Demo plugin is built as vst3 and loaded in Studio One, the result is that every time the plugin GUI is reopened, the plugin is enlarged by the system scaling factor, so it keeps getting bigger and bigger. In my case everything breaks currently because of what I did for VST2.

Somehow I think vst3 would do the correct thing, but JUCE ignores scaling completely for all plugins and thus things break. Or maybe Studio One's vst3 implementation is the problem?

Has anyone created a solution with JUCE that works for vst3 and hidpi? Are there any other hidpi vst2/vst3 hosts available on windows to test with? Btw. I tried on win7 win8.1 and win10 and things at least behave the same way everywhere with Studio One.

I just realized there is of course the JUCE Plugin Host that does support HiDPI mode. I just tried and here my vst2 hack solution works just fine for both vst2 and vst3 versions of my plugin. 


#2

Hi pflugshaupt!

We are currently working on better windows HiDPI support. Currently, Windows is the big exception on how JUCE deals with display scaling. On OS X/iOS/Linux/Android JUCE always works with "logical" pixels (aka 1 logical pixel is 2 physical pixels on a retina/HiDPI display) and all scaling is done completely transparently. For instance, all window and display dimensions are given in logical pixel units on these platforms and getGlobalScalingFactor() returns 1 by default as the output of getGlobalScalingFactor is the user-overridable scaling factor in "logical" pixels and should not depend on the physical dpi of the screens. This allows the same paint code to function correctly regardless if the window is dragged to a HiDPI display or not on a multi-monitor multi-scale setup.

However, on Windows, JUCE still uses "physical" pixels for window sizes and display dimensions and getGlobalScalingFactor will return the Windows global scaling factor. Windows 8.1 recently introduced per-display scaling which JUCE currently completely ignores and having a single global scaling factor won't work anymore anyway. Therefore, it makes sense to have the same approach of "everything in logical pixels" as we already have on OS X/iOS/Linux/Android. During the re-factoring of the code, we will also look at the behaviour of JUCE plug-ins in various hosts and make sure that behaviour is reasonably consistent.

On OS X/iOS/Linux/Android, if you really need to do something in physical pixels (for example when interfacing with legacy APIs) then the correct approach is to query the per-display scaling factor by looking at the scale field of the Display array in juce_Desktop.h. This will also apply to Windows once we have re-factored the code.

Fabian


#3

Awesome to hear. I don't want any physical pixels anymore :).

So I'll just try to find a minimal working solution for myself in the meantime. I learned Fruity Loops 12 also supports windows HiDPI mode, but unfortunately in the case of VST3 it works differently than Studio One 3 while VST2 works the same :(. I guess getting this to work in all hosts on windows (once they finally support scaled modes at all) will be painful.


#4

Any updates on this?


#5

As far as I know it's all fine now (?)