Retina images

Mac OSX specific forum
tucker
User
User
Posts: 16
Joined: Thu Oct 03, 2019 1:26 pm

Retina images

Post by tucker »

Using PureBasic 6.10 beta 6 - C Backend (MacOS X - arm64) - on MacBook Air M1 and Mac mini M2 with Studio Display both in default retina resolution. I noticed some issues with images and created a few tests in PureBasic and Objective-C using AppKit. Keeping it simple I created an image or bitmap in each, created a rainbow of horizontal lines then draw them image to the window/view. I noticed PureBasic images appeared small and on investigation established they seem to display at native resolution rather than expected retina resolution. Placing PureBasic and AppKit Windows side by side it was obvious - exactly half the size and clearly much finer pixels. Otherwise images were identical.

I kept the code simple. In PureBasaic simply open a window, StartDrawing to ImageOutput(0), StopDrawing then create an ImageGadget with Image. In Obj-C create a Window, add a view, create a bitmap context with CGBitmapContextCreate, create an pixel buffer of unsigned int, render horizontal lines, in drawRect create an NSGraphicsContext, draw the image at 1:1 size using CGContextDrawImage using unsigned int pixel buffer and release the context.

To investigate I tried the same with C and SDL2. Same basic workflow and same outcome. SDL2 can be set to support HighDPI or not. Default on macOS seems to be HighDPI aware.

Both create the same image and display this. AppKit shows what I would expect. PureBasic shows it at half size and width as if it is unaware of HighDPI. Has anyone come across this and is there a fix for it? I had thought of detecting highDPI and resizing image but that seemed to add complexity and overhead.

Thanks in advance for any help or suggestions.

Kind regards
Andrew
Fred
Administrator
Administrator
Posts: 16679
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Retina images

Post by Fred »

Did you check the 'Enable DPI aware' switch in compiler options ?
tucker
User
User
Posts: 16
Joined: Thu Oct 03, 2019 1:26 pm

Re: Retina images

Post by tucker »

When you mentioned that I had a panic spell for a moment - did I confirm the obvious? Phew ... I had ticked it. Yes, I had spotted it and made a note to select DPI aware executable.

Just ran the checks again and the image displayed in PB image gadget is exactly half size of same 128x128 image rendered to texture in SDL2 and to CGBitmapContext in AppKit/Obj-C. Images in SDL2 and AppKit are same size and measure on screen as 128x128 retina pixels. PureBasic is half that so rendering in 64x64 retina pixels or 128x128 physical pixels. I hope that makes sense.

Which library is used on macOS? Is it native AppKit or some other? I could have a look at the binary and connect to lldb though without intermediate C it may be hard going.

If I can carry out any other tests please let me know. Keen to find out if it can be resolved.

Kind regards
Andrew
Fred
Administrator
Administrator
Posts: 16679
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Retina images

Post by Fred »

And if you untick the DPI aware flag ?

On OS X, here is how it works for DPI: if a retina screen is detected and the DPI aware option is checked then all the displayed bitmap (with CanvasGadget(), ImageGadget() etc.) needs to be twice the actual size of the gadget (if the gadget is 200x200 in retina, the bitmap should be 400x400). Could you post a code ?
tucker
User
User
Posts: 16
Joined: Thu Oct 03, 2019 1:26 pm

Re: Retina images

Post by tucker »

Hi Fred,

Thanks for comments. I unticked the option and the image is now the same size as in AppKit and SDL2 versions. Comparing the images generated within each they also appear identical. That seems to have solved it.

I feel a little obtuse. I have read the menu option a few times and I suppose I can now see it makes sense. DPI aware exposes the monitor DPI to application. Unticked does not and exposes the scaled resolution and applies the UI scaling designated by OS/backend. AppKit by default seems to hide DPI awareness and instead expose the virtual resolution. SDL2 is/can be a bit random depending on platform backend in use. It clearly causes confusion in many areas especially cross-platform for SDL as noted by numerous ImGUI posts and discussions on SDL3 development about changes to SDL handling of DPI.

I have a few things that make C, Python and others via SDL, AppKit and so on more usable without disappearing down the sinkhole of makefiles, project files and so on. A few libraries that wrap underlying in independent way and the excellent CodeRunner on macOS to deliver the same lighter IDE (compared to Xcode, VSCode and so on) that PureBasic offers. CodeRunner has a very similar feel to PB I suppose with just a little more Mac-specific key shortcuts (at least by default) than cross-platform function code of PB.

I can post code if you wish. What dod you want? PB, AppKit and SDL2 code? I can extract just the essentials from each for brevity. Well, PureBasic code as ever is compact to achieve results, SDL2 and AppKit need a bunch of code just to do what PB can do in 10 lines! I don't want to consume your time though as unticking corrects the issue.

Thanks for the help and assistance. I appreciate your time and attention.

Kind regards
Andrew
Fred
Administrator
Administrator
Posts: 16679
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Retina images

Post by Fred »

Yes, it's the expected behaviour, when you tick it you need to use twice sized bitmaps to avoid blurring on retina display
tucker
User
User
Posts: 16
Joined: Thu Oct 03, 2019 1:26 pm

Re: Retina images

Post by tucker »

That is now very clear and noted. I will ensure I untick it for any projects it may affect.

I noticed an option in Preferences/Compiler/Defaults that would allow default to be off. That option (and all from Enable modern theme support to enable dll preloading protection (Windows)) are disabled. Two are set (modern theme and enable dpi aware) and all others are not set. I will have a look on RaspberryPI and Windows machines and see if they are similarly disabled.

I have not yet had a proper search or look at any files so not sure if there is an easy way to change/enable these disabled/set options. Do you have any suggestion? Would be handy to have default behaviour in PB same on all platforms I use and also between C/Obj-C/AppKit/SDL via make/terminal and CodeRunner provide same DPI handling of bitmaps.

Kind regards
Andrew
Post Reply