My iMac and Windows systems both have 1920x1080 “HD” screens - is there any way I can emulate 4K and Retina so I can check the UI resizing and retina 2x.pngs in my plugins?
I tried the “Quartz” HIDPI emulator but I’m confused how to use it because it magnifies the screen image - which seems the opposite of what Retina or 4K does (an X by Y pixel image on a 4k screen appears smaller).
Any tips appreciated!
on windows you can adjust the scaling for the display to 200%
Yes, but that’s going in the wrong direction. I want to see how the plugins look on a 4k screen which makes everything smaller. Windows only magnifies (i.e., 200%) it does not shrink down (50%).
It’s the right direction for how the pixels will draw, given that you the pixels on your non 4k screen are bigger than the ones a 4k screen.
It also activates the correct code paths (as far as I know) for a higher resolution display as it sets the screen scale (rather than the draw scale which is for user scaling/resizing).
Yes - an X by X pixel image appears smaller (in inches) on a 27" 4k screen than it does on an 27" HD screen. So to emulate a 4k screen on an HD screen it seems to me the image needs to be displayed scaled down, not up. If the automatic rescaling is working properly the plugin should then appear the correct size (in inches). What am I getting wrong here?
I’m not sure what you are trying to see - what size it will be. or what pixels will be displayed on the 4k screen - they are two different things.
Setting the scaling to 200% on windows should show you the pixels you’ll get. The exact details of rescaling can be a bit complex, but you can expect the actual size to be appropriate to the resolution of the screen for high-res situations.
When the plug-in GUI loads it will detect screen resolution and scale accordingly. Layout will be the same In both cases, but resolution and pixel sizes will change. The idea is that this happens seamlessly.
I designed all of my existing plugin graphics (iPlug1, bitmaps) on a 24" HD monitor (“2k” - 1920x1080).
Recently I have been getting complaints that my plugins are “way too small”. Upon inquiring I learned that these people have 4k monitors. My plugins will, indeed, display at half the intended size on a 24" 4k monitor because they were designed on 24" 2k monitor.
I would like to see exactly what the users are seeing - DAW and all - and was wondering if there is a way to “fake” 4k resolution on a 2k monitor. I can go down in resolution (e.g., to “1k” - 960x540) but I cannot go up in resolution (to 3840x2160) because my monitor does not support 4k. The “fake” would be a downscaling factor that would shrink the image on the screen. Windows 10 only supports upscaling (to a max of 175%).
The situation on windows is quite complicated, but I’m not sure you are quite following what might happen.
On a high-res screen if windows is set to a mode where this can be detected a scaling will be applied to make the UI bigger in pixels and use higher res bitmaps - thus making the size more similar to HD. However, there are a bunch of UI and app settings that may mean this does or doesn’t happen. Other possible outcomes are a suitably sized UI but a bit fuzzy, or a small one (as you describe) - adding user scaling is one way to counter this small UI issue - this can be done by supplying a corner resize, or with a UI selector (as I do in the surreal machines plugins). Importantly in iplug1 the result will ALWAYS be a small UI (but this is not the case for iplug2). This screen scaling is applied separately the draw (or user selectable) scaling.
There is no way to fake 4k on an HD screen I am aware of. I’d suggest you compile in iplug2 and send to some testers to get screenshots of what they actually experience.
My “hack” to simulating 4k on my 2k monitor is simply to take a screenshot of the plugin running in a DAW and then resize that screenshot by 50% (using Paint, Photoshop, etc.). If the plugin’s controls and text are too small when viewed at that scale I make them bigger and re-compile. (I now have a template for sizes established).
My new approach is to design all of my bitmaps at 2x size and then reduce down at runtime via MakeGraphics and CornerResizer OnDoubleClick set to 0.5f (rather than 1.0f and GetScaleForScreen). The plugin opens at 1/2 scale but then can be dragged up to 200% from there with no loss of quality because at 200% it is actually 1:1 scale of the source bitmap. So, in other words, my bitmaps are being scaled 0.25 to 1 verses the default of 0.5 to 2. There is no upscaling at plugin runtime, only downscaling, which remains clear at all sizes.
So I have achieved sharp graphics at all GUI scales with only 1 set of bitmaps. I am not using any autosize features but, instead, have chosen a basic plugin GUI “middle of the road” size that at 0.5 opening scale works well on both HD and 4k. The size can then be adjusted +/- by the user to taste with the corner resizer.
My solution may not be technically ideal but it works for me, solves the “too small” problem for 4k users and is simple to build and maintain.
BTW - I only build plugins for Mac OS and Windows. I am not building for iOS or Web so maybe that helps explain what I’m doing.
I’m afraid you don’t seem to be understanding me still.
If iplug2 detects a high-res screen it applies scaling automatically to compensate the size - you cannot turn this feature off - it is not optional, although it will be affected by the various windows settings about display (and the host app - this stuff is all a bit complex, but probably best to ignore those complexities for now). Any user scaling is separate from the high-res screen automatic scaling. Therefore, you should not expect your GUI to load half size on a 4k screen.
I would really suggest finding a way to test on a 4k screen, either yourself or another user so you can understand how this works.
My engineering approach is, and always has been, to “reinvent the wheel”. (I literally have a US patent on a special purpose wheel design)
I do think I understand the system and iPlug2 is extremely compliant. The issue (for me) is how it handles bitmaps. AFAIK it “auto detects” using “GetScaleForScreen”, right? And when it detects a high-res screen doesn’t it switch to/require a second set of @2x bitmaps?
I am doing it the other way around - using only one set of 2x bitmaps from the start and then downscaling by 50% for low-res screens.
It seems I have - by replacing “GetScaleForScreen” with a fixed scale number (0.5f) in MakeGraphics(). That makes it static vs. “auto detect” as far as I can tell. The function definition allows a fixed scale and it appears to work without issue in practice.
Back to the OP, I have no way to test this myself but I have sent my build to a beta tester who does have 4k and he says it’s working nicely. The plugin does not “autoscale” - it opens slightly large on an HD screen and slightly small on 4k screen - but it does allow the user to resize as needed. The advantage of what I have done is: 1) no upscaling of bitmaps and 2) only one set of bitmaps required. It looks good everywhere and is easy to build and maintain. Maybe it will fail somewhere, but so far so good.
Now, if plugins only use vector graphics then scaling by nearly any amount is of no consequence and iPlug2 as-designed - with auto-detection and scaling over a large range - is certainly superior.
GetScaleForScreen only appears in the iOS code as far as I’m aware so I’m not sure how that is relevant to your case.
I am also unaware of any way to override screen scale detection without altering the framework code (and although there have been some recent changes I’ve worked substantially on the scaling code).
On windows DPI awareness has several modes, and depending on the settings or host you may see different behaviours, but I would expect some of those scenarios to detect screen scale (“autoscale” as you call it). I would assume that if you are not seeing screen scaling it’s to do with the user’s settings or host, and not because you’ve bypassed this process, which there is no mechanism to do.
GetScaleForScreen() is used as the scale factor in MakeGraphics() in the example projects. I assumed it was applied to everything since there is no conditional check “#if iOS”, etc.
Anyhow, what I have is working and my users are pleased. They’re happy = I’m happy. Graphics are resizable and sharp on both HD and 4k screens and I only need one set of bitmaps to do it. Cool.
Yes, but if you are not on IOS it always returns 1 - it relates to finding the right size for an IOS screen, and is not related to the hi-res scaling I’ve mentioned above.
I guess what I’m suggesting is that it appears I have found a shortcut for making high quality raster graphics in iPlug2 that work on both HD and 4k monitors with only one set of bitmaps.
I wanted to see what iPlug2 was doing if it detected a high-res monitor and there were no @2x.pngs in the project . My test of iPlugControls using “HiDPI” mode on my iMac shows that iPlug resamples/upsizes a bitmap if there is no @2x.png for it and hi-res is required. You can tell it’s been resampled because the image gets blurry/loses its sharp edges.
By setting MakeGraphics() scale to 0.5 (instead of 1.0) and supplying large (2x size) bitmaps to begin with the image remains sharp even when rescaled in hi-res mode. That’s because 2 x 0.5 = 1, i.e., there is no upscaling, only downscaling. So I am getting the same resultant clarity of image as the “two sets of bitmaps approach” with only one set of bitmaps.
You are correct t that iplug2 will scale down if it only finds @x2 pngs (and vice versa). However, in your case it is possible that someone sets the display size to 1 (or 100%) on a 4k screen and that is being scaled up.
Ah…I guess I stumbled upon this but from the opposite direction (without the @2x identifiers).
I just tried building with only @2x.pngs and it doesn’t work. Apparently it doesn’t find those files unless you also have the corresponding 1x files. My “hack” does this with only 1 set of bitmaps (what would normally be the @2x bitmaps but without the @2x identifier). It seems to work well for my purposes (DAWs running on Mac and PC) but, as you say, will not work for the wide range of formats iPlug2 is designed to support.
To summarize what I’ve done:
- generate one set of large scale bitmaps (what would normally be the @2x.pngs)
- set the scale factor in MakeGraphics() to 0.5f
- modify CornerResizer “OnDoubleClick” to 0.5f
- use the full background bitmap size in the PLUG_WIDTH and PLUG_HEIGHT settings
When the plugin runs on an HD screen iPlug scales it down to 1x size (50%). When it runs on a 4k screen it shows up at full scale - which is the bitmap’s “as-created” size. Graphics render sharp on both systems.
This is backwards from how it’s normally done but just thought I’d share it. IMO, Apple’s @2x.png is an “add-on/after-the-fact” format designed to add high-res capability. What I believe I have done is to show that you could, instead, work backwards from the max size in iPlug with one set of bitmaps for both formats.
BTW - the image resizing algorithm in iPlug2 is really nice, IMO. Large images scaled down actually look better to me than a native bitmap created at the same scale. Not sure how that’s possible but it’s
1 Like
I’ve taken the same approach so far - design bitmaps and the UI layout at the largest scale I allow, without special naming, and just let the framework scale them down. this might be suboptimal depending on the downscaling quality (which will depend on the gfx framework too) so I might revisit, but it looks pretty good with NanoVG so far.
There does seem to be an issue with transparency at bitmap boundaries in NanoVG though, but I haven’t fully investigated yet. I only allow fixed resize options anyway so for now I’ve limited them to tweaked scales that avoid the artifacts.
1 Like