-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Restore support for older macOS/iOS version. Determine features at init, and use at runtime. #3284
Conversation
…it, and use at runtime.
Instead of: CHECK_FEATURE_AVAILABLE(m_usesNewMetalAPI, macOS 13.0, iOS 16.0, tvOS 16.0, macCatalyst 16.0, VISION_OS_MINIMUM *); Why you don't do this? m_usesNewMetalAPI = @available(macOS 13.0, iOS 16.0, tvOS 16.0, macCatalyst 16.0, VISION_OS_MINIMUM *); And what's this |
I just read that |
Also you might want to switch visionOS to |
I thought
It seems to be some SDK variant that works for both macOS and iPad. Like where you can write your app once against the macCatalyst SDK and you get it on both.
Compiler complains that this is not the correct way to use #define USES_NEW_API @available(macOS 13.0, iOS 16.0, tvOS 16.0, macCatalyst 16.0, VISION_OS_MINIMUM *)
if (USES_NEW_API) {
} else {
} |
Yes, please do. Because then this would be solution to have no warnings, and by looking at the code it would be clear what's going on: #define USES_NEW_API @available(macOS 13.0, iOS 16.0, tvOS 16.0, macCatalyst 16.0, VISION_OS_MINIMUM *)
if (USES_NEW_API)
... |
From:
|
Also The best feature naming is to be specific about feature you're naming. |
Looking at a compiled version of a simple @available check, gives me this under -O2 (pseudocode generated by Hopper Disassembler): int _main() {
puts("before");
COND = ___isPlatformVersionAtLeast(0x1, 0xd, 0x0, 0x0) == 0x0;
rdi = "macOS 13.0";
if (COND) {
rdi = "NOT macOS 13.0";
}
puts(rdi);
return 0x0;
}
int ___isPlatformVersionAtLeast(int arg0, int arg1, int arg2, int arg3) {
stack[-16] = r15;
stack[-24] = r14;
stack[-32] = r12;
stack[-40] = rbx;
rsp = rsp - 0x30;
r14 = arg3;
r12 = arg2;
rbx = arg1;
rbp = arg0;
if (*_DispatchOnceCounter == 0xffffffffffffffff) {
if (*_AvailabilityVersionCheck != 0x0) {
rax = _AvailabilityVersionCheck(0x1, &var_38, r14 & 0xff | r12 << 0x8 & 0xffff | rbx << 0x10, r12 << 0x8 & 0xffff | rbx << 0x10);
r15 = rax;
}
else {
r15 = 0x1;
if (rbp == 0x1) {
if (*_CompatibilityDispatchOnceCounter == 0xffffffffffffffff) {
r15 = 0x1;
if (*(int32_t *)_GlobalMajor <= rbx) {
if (*(int32_t *)_GlobalMajor >= rbx) {
r15 = 0x1;
if (*(int32_t *)_GlobalMinor <= r12) {
if (*(int32_t *)_GlobalMinor < r12) {
r15 = 0x0;
}
else {
r15 = *(int32_t *)_GlobalSubminor >= r14 ? 0x1 : 0x0;
}
}
}
else {
r15 = 0x0;
}
}
}
else {
dispatch_once_f(_CompatibilityDispatchOnceCounter, 0x0, _compatibilityInitializeAvailabilityCheck);
if (*(int32_t *)_GlobalMajor > rbx) {
r15 = 0x1;
}
else {
if (*(int32_t *)_GlobalMajor >= rbx) {
r15 = 0x1;
if (*(int32_t *)_GlobalMinor <= r12) {
if (*(int32_t *)_GlobalMinor < r12) {
r15 = 0x0;
}
else {
r15 = *(int32_t *)_GlobalSubminor >= r14 ? 0x1 : 0x0;
}
}
}
else {
r15 = 0x0;
}
}
}
}
}
}
else {
dispatch_once_f(_DispatchOnceCounter, 0x0, _initializeAvailabilityCheck);
if (*_AvailabilityVersionCheck == 0x0) {
r15 = 0x1;
if (rbp == 0x1) {
if (*_CompatibilityDispatchOnceCounter == 0xffffffffffffffff) {
r15 = 0x1;
if (*(int32_t *)_GlobalMajor <= rbx) {
if (*(int32_t *)_GlobalMajor >= rbx) {
r15 = 0x1;
if (*(int32_t *)_GlobalMinor <= r12) {
if (*(int32_t *)_GlobalMinor < r12) {
r15 = 0x0;
}
else {
r15 = *(int32_t *)_GlobalSubminor >= r14 ? 0x1 : 0x0;
}
}
}
else {
r15 = 0x0;
}
}
}
else {
dispatch_once_f(_CompatibilityDispatchOnceCounter, 0x0, _compatibilityInitializeAvailabilityCheck);
if (*(int32_t *)_GlobalMajor > rbx) {
r15 = 0x1;
}
else {
if (*(int32_t *)_GlobalMajor >= rbx) {
r15 = 0x1;
if (*(int32_t *)_GlobalMinor <= r12) {
if (*(int32_t *)_GlobalMinor < r12) {
r15 = 0x0;
}
else {
r15 = *(int32_t *)_GlobalSubminor >= r14 ? 0x1 : 0x0;
}
}
}
else {
r15 = 0x0;
}
}
}
}
}
else {
rax = _AvailabilityVersionCheck(0x1, &var_38, r14 & 0xff | r12 << 0x8 & 0xffff | rbx << 0x10, r12 << 0x8 & 0xffff | rbx << 0x10);
r15 = rax;
}
}
if (**___stack_chk_guard == **___stack_chk_guard) {
rax = r15 & 0xff;
}
else {
rax = __stack_chk_fail();
}
return rax;
} So it does get initialized once, but afterwards the check is still quite involved as it doesn't merge the major,minor,patch numbers into one big number, so a lot of branches are evaluated needlessly... 😞 Our approach should still be faster unfortunately. Code of the helper function does not change under different levels -O0 to -O3. |
Is there way to disable deprecated warnings with some define before including Apple's header files? Or we have to do it with pragma? Since you're checking features with |
@bkaradzic Have a look at the latest version. I silenced the warnings with specific pragmas. I am kind of bummed that the whole list of texture formats is silenced by one block, as it is informative to have the compiler yell at us if the list has a format that is not supported. This makes it easy to spot unsupported formats in the future as well. Right now we'd miss out on that information. Other than that, I don't know if you would accept that I put the |
I believe you misinterpreted that: I think what they mean is that in both Obj-C and Swift you can both specify and check for OS versions. The syntax is the languages is different, as documented below that.
I addressed this as well. It's now called |
…it, and use at runtime. (bkaradzic#3284) * Restore support for older macOS/iOS version. Determine features at init, and use at runtime. * Fix typo for visionOS macro expansion. * Silence warnings with pragmas and pointer casts where possible. * Pragma macros.
Hey, just want to outline that |
…it, and use at runtime. (bkaradzic#3284) * Restore support for older macOS/iOS version. Determine features at init, and use at runtime. * Fix typo for visionOS macro expansion. * Silence warnings with pragmas and pointer casts where possible. * Pragma macros.
…it, and use at runtime. (bkaradzic#3284) * Restore support for older macOS/iOS version. Determine features at init, and use at runtime. * Fix typo for visionOS macro expansion. * Silence warnings with pragmas and pointer casts where possible. * Pragma macros.
A lot of the warnings could be silenced by doing what Apple suggests: using the
@available
check at the code. However, I agree that readability increases if you name the feature you are testing for, instead of just random-looking version number checks.Examples still work.