Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS 8 support for @3x screens. #1661

Closed
SDLBugzilla opened this issue Feb 10, 2021 · 0 comments
Closed

iOS 8 support for @3x screens. #1661

SDLBugzilla opened this issue Feb 10, 2021 · 0 comments

Comments

@SDLBugzilla
Copy link
Collaborator

SDLBugzilla commented Feb 10, 2021

This bug report was migrated from our old Bugzilla tracker.

Reported in version: 2.0.3
Reported for operating system, platform: iOS 6, ARM

Comments on the original bug report:

On 2014-10-14 21:49:55 +0000, Martijn Courteaux wrote:

Content scale for iOS 8 devices now can have a @3x content scale.
The code to change is in: src/video/uikit/SDL_uikitmodes.m

I modified the code of the UIKit_AddDisplay() method to this:

static int
UIKit_AddDisplay(UIScreen *uiscreen)
{
CGSize size = [uiscreen bounds].size;
CGFloat scale = [uiscreen scale];
size.width *= scale;
size.height *= scale;

/* When dealing with UIKit all coordinates are specified in terms of
 * what Apple refers to as points. [UIScreen scale] indicates the
 * relationship between points and pixels. Since SDL has no notion
 * of points, we must compensate in all cases where dealing with such
 * units.
 */

if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0"))
{
    size = [uiscreen nativeBounds].size;
    scale = [uiscreen nativeScale];
}

/* Make sure the width/height are oriented correctly */
if (UIKit_IsDisplayLandscape(uiscreen) != (size.width > size.height)) {
    CGFloat height = size.width;
    size.width = size.height;
    size.height = height;
}


SDL_VideoDisplay display;
SDL_DisplayMode mode;
SDL_zero(mode);
mode.format = SDL_PIXELFORMAT_ABGR8888;
mode.w = (int) size.width;
mode.h = (int) size.height;

UIScreenMode * uiscreenmode = [uiscreen currentMode];

if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
    return -1;
}

SDL_zero(display);
display.desktop_mode = mode;
display.current_mode = mode;

/* Allocate the display data */
SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data));
if (!data) {
    UIKit_FreeDisplayModeData(&display.desktop_mode);
    return SDL_OutOfMemory();
}

[uiscreen retain];
data->uiscreen = uiscreen;
data->scale = scale;

display.driverdata = data;
SDL_AddVideoDisplay(&display);

return 0;

}

However, the nativeScale and nativeBounds properties are only available in iOS 8. So that is why I added the check. The preprocessor macro used is this one:

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

I tested this on a prior iOS 8 device (iOS 6 device, iPod 4th gen) and on the iPhone 6 and 6 Plus simulator and the iPhone 5 simulator. And works. This method renders the content to big and scales it down. This is done on purpose by Apple. You can read about it here: http://stackoverflow.com/a/25755640/155137

Cheers!

On 2014-10-16 07:40:51 +0000, Alex Szpakowski wrote:

(In reply to Martijn Courteaux from comment # 0)

This method renders the content to big and scales it down. This is done on
purpose by Apple.

Actually (on an iPhone 6 Plus device, not the simulator) [UIScreen scale] will return 3.0 and [UIScreen nativeScale] will return ~2.6.

In other words, using the native scale value for the GLES view's content scale factor will make it use the actual physical resolution (1080x1920), whereas using the regular scale value will make it use the @3x resolution (1242x2208) which is downsampled to 1080x1920 by the OS.

When the iOS Simulator is used to simulate an iPhone 6 Plus, both the regular UIScreen scale value and the native scale value will be 3.0.

https://devforums.apple.com/message/1049355# 1049355

On 2014-10-16 07:47:20 +0000, Alex Szpakowski wrote:

It's also worth mentioning that in order for any of that to work, your app needs either iPhone 6 Plus @3x launch images (in your Xcode project), or the new iOS 8 Storyboard / xib launch screen ( https://developer.apple.com/library/ios/documentation/userexperience/conceptual/mobilehig/LaunchImages.html ).
If neither of those are present then the app will emulate older iPhone behaviour on the iPhone 6 Plus, so both the native and the regular scale will be 2.0.

On 2015-02-04 11:18:49 +0000, Martijn Courteaux wrote:

Now, what does that mean, actually? Is my patch invalid? Did I solve this problem wrong? I think I didn't. Is there any reason this isn't adopted in SDL yet?

On 2015-02-05 01:52:46 +0000, Alex Szpakowski wrote:

(In reply to Martijn Courteaux from comment # 3)

Now, what does that mean, actually? Is my patch invalid? Did I solve this
problem wrong? I think I didn't. Is there any reason this isn't adopted in
SDL yet?

The SDL 2.0.3 / current (unpatched) Mercurial code handles @3x screens without any issue already.

UIScreen.scale will return 3.0 on an iPhone 6 Plus (assuming your App uses a proprly sized Launch Image or the iOS 8+ Launch Screen nib to let Apple know that your App supports the device.)

The iPhone 6 Plus' resolution in points (not pixels) is 414x736. At @3x, that's 1242x2208.

On an actual device (not the iOS Simulator – it handles this differently than the actual device), the real physical resolution of the iPhone 6 Plus is 1080x1920. iOS still reports UIScreen.scale as 3.0, and it downsamples rendered content to account for the difference if the view's content scale factor is 3.0. So an iPhone 6 Plus hardware isn't really a '@3x' screen, Apple just reports that for its main APIs to make things simpler.

UIScreen.nativeScale on a physical iPhone 6 Plus device is around 2.6 (i.e. 1080/414), rather than 3.0. The iOS Simulator doesn't simulate this. To get a truly pixel-perfect framebuffer on an iPhone 6 Plus, you'd need to set SDL's OpenGL View's contentScaleFactor to UIScreen.nativeScale rather than UIScreen.scale.

SDL's current code doesn't do this yet (and neither does your patch), so on iPhone 6 Plus devices it renders at 3x rather than 2.6x.

I have a rather large set of changes for the iOS backend of SDL (in this bugzilla https://bugzilla.libsdl.org/show_bug.cgi?id=2798 ) which includes proper support for pixel-perfect rendering on iPhone 6 Plus devices, by using UIScreen.nativeScale in all the necessary places.

On 2015-02-05 02:04:21 +0000, Martijn Courteaux wrote:

Alright, thanks, that looks great! Is your patch ready yet? Can I use it for my game I'm planning to release pretty soon, or is there still work to do to make it stable and shippable? It looks like you haven't updated the topic in 10 days, so I'll just ask ;)

Thanks again

On 2015-02-05 02:07:25 +0000, Alex Szpakowski wrote:

It should be ready for use, but there's always the chance that I've included some horrible bug. :)

There's at least one shipped game that makes use of my changes, although since it was released several months ago it uses a much earlier revision: http://www.ohmygiraffe.com

On 2015-02-05 02:10:32 +0000, Martijn Courteaux wrote:

Very nice! Thanks. So do we both agree that this bug can be closed, since this is completely covered in your patch?

On 2015-04-10 02:46:50 +0000, Ryan C. Gordon wrote:

This bug should be fixed by the changes made for Bug # 2798. Please reopen if that's not the case.

Thanks!

--ryan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant