Delve into the world of graphics and game development. Discuss creating stunning visuals, optimizing game mechanics, and share resources for game developers.

All subtopics
Posts under Graphics & Games topic

Post

Replies

Boosts

Views

Activity

PHASE occluder silences direct sound instead of muffling it
I’m using PHASE for an outdoor soundscape with only .directPathTransmission enabled. A point source and listener are 2 metres apart. Between them is a PHASEOccluder built from a 2 × 2 × 0.02 metre MDLMesh box, with a .cardboard material assigned to every shape element. Without the occluder, the sound is loud. With it, the sound is completely inaudible. Switching to .glass and setting the sampler’s cullOption to .doNotCull makes no audible difference. This happens on both iOS Simulator and a physical iPhone. Adding .lateReverb produces faint audible sound, but room reverb is inappropriate for this outdoor scene and doesn’t establish whether direct transmission works. Is this expected attenuation, or is additional configuration required to hear muffled sound through an occluder? Is there a working sample demonstrating material-dependent transmission with reverb disabled?
3
1
2.0k
2w
System protocol CPU performance question
Hello guys In my game the player sits in the middle of the screen and shoots on enemies coming all around it. (none vr/ar game) I have 3 :systems protocol already to spawn the enemies using timer and budget a different one to move them to the player direction pool system that turned off dead enemies Because reality kit is a high level framework i dont know what is the fastest way to design the bullet system for better cpu speed A. Seperated system for the bullets, asking to know the closest enemy to travel to, hit, and move to the disable pool system if died. or B. Use the same system that moving the enemies but in a seperated loop (prabably one before moving the enemies) Thanks for the help
1
0
73
2w
NSOpenGLView / NSOpenGLContext setView: get no drawable on macOS 15.8.2 RC (24H219), windows render blank (FB25133383)
After updating a MacBook Pro (M1 Pro) from macOS 15.8 to the 15.8.2 release candidate (24H219), every OpenGL context that is attached to a window has no default framebuffer. NSOpenGLView and -[NSOpenGLContext setView:] are both affected, so anything drawn that way shows a blank window. I filed FB25133383 with a minimal sample, kernel log and call trace. Symptoms kCGLCPHasDrawable is 0, glCheckFramebufferStatus(GL_FRAMEBUFFER) returns GL_FRAMEBUFFER_UNDEFINED (0x8219), and glClear raises GL_INVALID_FRAMEBUFFER_OPERATION (0x506). For every attach attempt the kernel logs: (IOGPUFamily) IOGPUGLDrawableUserClient::set_surface(sIOGPUGLDrawableClientSetSurfaceData *): Invalid surface ID = N CGLSetSurface returns kCGLBadDrawable (10005). Stepping through it, CGSBindSurface succeeds and the IOGPU user-client call then fails with kIOReturnBadArgument. What still works Offscreen FBOs in the same context. CAOpenGLLayer and NSOpenGLLayer render correctly in the same process. Only the window-surface path is broken. Minimal sample (public API only) // clang -fobjc-arc -Wno-deprecated-declarations -framework Cocoa -framework OpenGL repro.m -o repro && ./repro #define GL_SILENCE_DEPRECATION 1 #import <Cocoa/Cocoa.h> #import <OpenGL/OpenGL.h> #import <OpenGL/gl.h> #import <OpenGL/glext.h> @interface ReproView : NSOpenGLView @end @implementation ReproView - (void)drawRect:(NSRect)dirtyRect { NSOpenGLContext *ctx = [self openGLContext]; [ctx makeCurrentContext]; GLint hasDrawable = -1; CGLGetParameter(ctx.CGLContextObj, kCGLCPHasDrawable, &hasDrawable); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); glClearColor(0, 1, 0, 1); glClear(GL_COLOR_BUFFER_BIT); GLenum err = glGetError(); printf("hasDrawable=%d status=0x%x glError=0x%x\n", hasDrawable, status, err); fflush(stdout); [ctx flushBuffer]; } @end int main(void) { @autoreleasepool { NSApplication *app = [NSApplication sharedApplication]; [app setActivationPolicy:NSApplicationActivationPolicyRegular]; NSWindow *win = [[NSWindow alloc] initWithContentRect:NSMakeRect(200, 300, 240, 240) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:NO]; NSOpenGLPixelFormatAttribute attrs[] = { NSOpenGLPFADoubleBuffer, NSOpenGLPFAAccelerated, 0 }; NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; [win.contentView addSubview:[[ReproView alloc] initWithFrame:NSMakeRect(20, 20, 200, 200) pixelFormat:pf]]; [win makeKeyAndOrderFront:nil]; [app activateIgnoringOtherApps:YES]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ [app terminate:nil]; }); [app run]; } return 0; } Expected: a green square and hasDrawable=1 status=0x8cd5 glError=0x0. On 24H219: nothing is drawn and it prints hasDrawable=0 status=0x8219 glError=0x506. Scope Same result for arm64 and x86_64 under Rosetta, layer-backed or not, main thread or background thread. Affected on my Mac: Sony Imaging Edge Desktop Viewer (NSOpenGLView), DJI Studio (Qt 6, NSOpenGLContext) and its Quick Look extension. Public reports with the same symptom on 24H219: kitty #10645, Alacritty #9067, Godot #124311, Bambu Studio #12530 (all on GitHub). They cover M1, M4, M4 Pro and M4 Max, and the Alacritty report says 15.8.1 was fine. Questions Is this a known issue in the 15.8.2 RC, and will it be fixed before 15.8.2 ships? Is anyone seeing it on the macOS 26.7.2 RC or the 27.2 beta? Workaround for developers in the meantime: render into an IOSurface-backed FBO and present that surface in a CALayer, or use CAOpenGLLayer.
8
4
22k
2w
macOS 27.2 RC (26B118) Built-in display canvas cropped with black bar at bottom-right after login
Description: MacBook Air M5, using only built-in display. The login window renders full screen normally. After logging into desktop session, the display canvas gets cropped with a black bar on the bottom-right corner. This issue is reproducible in Safe Mode and with a brand-new admin user account. No third-party display or window management software installed. Suspected WindowServer display coordinate calculation bug within user session. Environment Device: MacBook Air M5 OS: macOS 27.2 RC (26B118) Display: Built-in display only, no external monitor Reproduction steps Boot to login window, display works fine Log into desktop session Display canvas cropped, black bar appears at bottom-right
1
0
1k
2w
M5 Pro external display pipeline width limits and native HiDPI support
Hello Apple Engineering Team, I would like to clarify a technical question regarding the external display architecture of the M5 Pro MacBook Pro. I use a single ultrawide monitor with a native resolution of 3440 × 1440. To achieve true 2× HiDPI rendering at this logical resolution, macOS would need to render a framebuffer of 6880 × 2880. Third-party diagnostic tools and firmware reverse-engineering reports appear to indicate that M5 Pro has display-pipeline source-width limits of 6720 and 7680 pixels. Could you please clarify the following? Are these reported source-width limits accurate for the M5 Pro? Can macOS assign a single external display to the display pipeline that supports a 7680-pixel source width? Is there a supported way to influence or change this pipeline allocation, such as changing the connection port, connection order, or display configuration? Can a single 3440 × 1440 external monitor use native 2× HiDPI rendering (6880 × 2880) on the M5 Pro without virtual-display mirroring? If this configuration is unsupported, is the limitation imposed by hardware, firmware, or macOS display allocation policy? I understand that Apple may not disclose all internal implementation details. Any clarification regarding supported configurations or known limitations would be greatly appreciated. Thank you.
0
0
510
2w
Game Center Dashboard overlay doesn't have Done or x button
From this WWDC video -> https://developer.apple.com/videos/play/wwdc2020/10618/ I see the examples show that almost each screen have a "Done" button on top trailing, document sites also show the x button on top trailing, however, in my app, the overlay shows without any Done or x button, it doesn't look very apparent how to "close" this popup. I soon learned the hardware that the trick is to tap on empty areas. Is there a way to enable the Done or x button in it?
0
0
471
3w
Photogrammetry with Object masks hangs and terminates with masks of objects
[PhotogrammetrySample]) with objectMask set and traps on my ios26.5.2, see the attached screenshot on feedback FB24379913 , it gets to the function and hangs . Even the folder reconstruction with lazy sequence as recommended from your video sample also doesn;t complete as it can't find alignment and displays the CoreOC.PhotogrammetrySession.Error error 6 means alignment failed. What can be done or do you guys expose any functions that can be used to check or trace or handle these internally The ObjectMasks are actually segmentation masks from an segmentation algorithm I will appreciate a timely response and willing to provide more clarity and informations, thank you so much for your understanding
3
0
1.4k
3w
Metal CSM Shadows GPU Culling+Indirect+Vertex Amplification - empty some Shadow Cascades
Hi! I'm porting Cascaded Shadow Maps(CSM) from HLSL Direct3D12/Vulkan I'm using GPU Culling, indirect Call + Vertex Amplification for shadow Casters for creating Shadow map texture. Shadow map texture - Texture2DArray Shadow castes are rendering using Instancing and IndirectDraw, VS shader are checking [amplification_id]] and view mask CS shader are finding shadow caster using InstanceId and view mask for each shadow cascade: // dataIndex - Instance index for featching Instance Matrix // viewMask - for VS [[amplification_id]] uint PackInstanceData(uint viewMask, uint dataIndex) { return (viewMask << 28u) | dataIndex; } kernel void CullObjects(uint2 DTid [[thread_position_in_grid]], constant ArgBuf& argBuf [[buffer(0)]], uint groupIndex [[thread_index_in_threadgroup]]) { threadgroup atomic_uint sharedNumObjects; threadgroup uint sharedInstanceId[32]; threadgroup uint globalBufferIndex; constant auto& cbData = *argBuf.cbData; uint index = DTid.x; if (!groupIndex) { atomic_store_explicit(&sharedNumObjects, 0u, memory_order_relaxed); globalBufferIndex = 0u; } threadgroup_barrier(mem_flags::mem_threadgroup); bool visible = false; uint viewMask = 0; if (index < cbData.numInstanceObjects) { const device CullingObjInfo& cullingObjectInfo = argBuf.cullingObjInfo[index]; // find shadow casters for each shadow cascade for (uint i = 0u; i < NUM_FRUSTUMS; ++i) { constant Frustum& frustum = cbData.frustums[i]; visible = SphereInFrustum(frustum, cullingObjectInfo.boundingSphere); if (visible) { visible = BoundingBoxInFrustum(frustum, cullingObjectInfo.boundingBox.minPoint, cullingObjectInfo.boundingBox.maxPoint); } if (visible) { viewMask |= (1u << i); } } visible = bool(viewMask); } } if (visible) { uint bufferIndex = atomic_fetch_add_explicit(&sharedNumObjects, 1u, memory_order_relaxed); sharedInstanceId[bufferIndex] = PackInstanceData(viewMask, index); } threadgroup_barrier(mem_flags::mem_threadgroup); uint localNumObjects = atomic_load_explicit(&sharedNumObjects, memory_order_relaxed); if (!groupIndex && localNumObjects) { globalBufferIndex = atomic_fetch_add_explicit(&argBuf.numObjects->instanceCount, localNumObjects, memory_order_relaxed); } threadgroup_barrier(mem_flags::mem_threadgroup); if (groupIndex < localNumObjects) { argBuf.instanceId[globalBufferIndex + groupIndex] = sharedInstanceId[groupIndex]; } } VS shader for depth shadow map rendering: // struct PSOutput { float4 pos [[position]]; float2 Depth [[user(locn0)]]; float CullDist [[clip_distance]]; uint layer [[render_target_array_index]]; }; struct VS { float4 pos [[attribute(0)]]; uint InstanceId [[attribute(9)]]; }; struct b { float4x4 lightViewProj[NUM_SM_CASCADES]; }; struct Arg { const device float3x4* InstanceData [[id(0)]]; constant b* cb [[id(1)]]; }; uint UnpackViewInstancingMask(uint packedData) { return packedData >> 28u; } uint UnpackInstanceIndex(uint packedData) { return packedData & 0x0FFFFFFFu; } vertex PSOutput vsMain(VS In [[stage_in]], constant Arg& arg [[buffer(VSArgumentBufferIndex)]], ushort ampID [[amplification_id]]) { constant auto& b0 = *arg.cb; PSOutput output; float4 WorldPos = float4(In.pos.xyz, 1.0f); uint viewMask = UnpackViewInstancingMask(In.InstanceId); output.layer = ampID; // check shadow caster rendering for each cascade using ampID and viewMask if (viewMask & (1u << ampID)) { float3x4 instanceMatrix = arg.InstanceData[UnpackInstanceIndex(In.InstanceId)]; WorldPos = float4((WorldPos * instanceMatrix).xyz, 1.0f); output.CullDist = 1.0f; } else { output.pos = float4(0.0f, 0.0f, 2.0f, 1.0f); // skeep unvisible object for this cascade output.CullDist = -1.0f; return output; } output.pos = b0.lightViewProj[ampID] * WorldPos; output.Depth.xy = output.pos.zz; return output; } I have result left part: CPU Version - separate rendering for each layer for texture2Darray shadow map right part: GPU culling + Indirect + Vertex Amplification Got to fix error ? Why 1 and 3 cascade are empty? 0 cascade has duplicate data from other cascades.
2
0
763
3w
Processing RAW files using CIRAWFilter slows down after opening a few different images
Is there some cleanup required if you are opening multiple different RAW files - I am seeing a slow down each time I open a new file and things grind to a halt after opening 5 or 6 files, one after the other - even allowing some time between opening them. Currently I have a single view with a CAMetalLayer and a single Renderer and CIContent - should I be creating a new CAMetalLayer, render and CIContext each time a new image is opened ? Alternately is there some way to clear the cache or something to maintain performance.
1
0
478
3w
GKMatch: GameKitServices crashes in GCKSessionReceiveDOOB on the second real-time match — the finished session is never reclaimed
We ship a two-player real-time GameKit game. On iOS 27 the app crashes inside GameKitServices on the second real-time match of any app session — nine times out of nine yesterday. Filed as FB24789094 (and FB24788999 for a separate reinvitation problem). Posting the measurements here because the unified log makes the mechanism visible, and because everything I tried at the app level failed — maybe somebody has the missing piece. THE CRASH Main thread, no application frame anywhere on the stack: CFRetain + 52 GCKSessionReceiveDOOB + 1632 -[GKSessionInternal receiveDOOB:fromPeer:inSession:context:] + 320 -[GKSessionInternal(_private) tellDelegate_didReceiveBand_RetryICE:] + 212 __NSThreadPerformPerform + 264 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ EXC_BAD_ACCESS (SIGBUS), EXC_ARM_DA_ALIGN at 0x9 (0xa in one report). In every report the faulting address is exactly x0 + 8, and x0 is 1 or 2 — CFRetain is handed a small integer, not a pointer. A use-after-free would fault on a large plausible-looking address; 1 and 2 are not addresses at all. Address Sanitizer agrees: no heap error is reported before the fault, only __asan::ReportDeadlySignal directly above the same three GameKitServices frames. It reads like type confusion in the RetryICE band path. Not the SDK: a build made with Xcode 26.6 against iphoneos26.5 crashes identically — same stack, same registers. The peer's OS does not matter either (iPadOS 17.7.11, iOS 26.6.1 and iOS 27.0 all seen on the other side, and in one case an older build of our own app). Only the crashing device is always on iOS 27.0 (24A435), an iPhone 15 Pro. RECIPE Two devices, two Game Center accounts. Form a two-player real-time GKMatch — GKMatchmaker.findMatch(for:) or an invitation, both reproduce. Wait for the peer to connect, call finishMatchmaking(for:). Play for ten seconds or so, so data really flows. End it: match.disconnect(), release the GKMatch. In the SAME process, form a SECOND real-time match. Play. The crash lands roughly ten to thirty seconds after the second match starts exchanging data. A first match in a freshly launched process has never crashed for us. Out of eleven app sessions that reached a second match, two were force quit by hand during other tests and the remaining nine all crashed here. THE SESSION IS NEVER RECLAIMED GameKit runs one "com.apple.gamekitservices.gcksession.recvproc" / "sendproc" thread pair per live real-time session, in the app's own process. You can count them from inside the app, which turns out to be the only way to see what is going on: var threads: thread_act_array_t? var count: mach_msg_type_number_t = 0 task_threads(mach_task_self_, &threads, &count) // then pthread_from_mach_thread_np(threads[i]) + pthread_getname_np, and compare the name Measured across one app session: after Game Center authentication, before any match ......... 0 first match live ........................................... 1 right after match.disconnect() returns ..................... 1 <- not reclaimed before the second match is adopted ......................... 2 right after the second match's disconnect() ................ 2 Every crash report shows two of those pairs alive, although the app holds exactly one GKMatch at a time and releases the finished one the instant disconnect() returns. The same leak is visible on iOS 26.6.1 (an iPhone 11 Pro leaks identically) — it just does not crash there. WHAT THE LEFTOVER SESSION DOES Each match gets its own CDXClient. The first match's is never torn down, and keeps poking its hole on a 30-second keep-alive, on the same local port (:16402) the second match then binds: 15:28:05.117 <CDXClient: 0x155872e40> requesting-hole-punch <- match 1 15:28:35.289 <CDXClient: 0x155872e40> requesting-hole-punch <- match 1, +30s, match already over 15:28:50.197 <CDXClient: 0x12d4bda40> requesting-hole-punch <- match 2 15:29:05.287 <CDXClient: 0x155872e40> requesting-hole-punch <- match 1 again, 4s before the crash GCKSessionCreate:6425 globalscopelaunch appears once per process; the second match only does 6509 globalscoperequest and reuses the global scope. During the second match's ICE setup a packet arrives belonging to no live session: -[CDXClient handleFDEvent]:1066 packet-from-unknown-session -[CDXClient handleFDEvent]:1067 Incoming packet from unknown session. SID = ... immediately followed by [ERROR] ICEStopConnectivityCheck:2763 ICEStopConnectivityCheck() found no ICE check with call id (...) [ERROR] gckSessionCheckPendingConnections:1545 iICEChecksLeft=0, iUnconnectedNodeCount=0, iDDsExpected=1 Those lines appear exactly three times in a 28-minute window, all three in the two processes that went on to crash, never during a first match. About fourteen seconds later the RetryICE band is delivered and CFRetain is called on the garbage. WHAT DID NOT WORK Releasing the GKMatch immediately after disconnect(). The session threads stay. Waiting. Gaps of 17, 19, 22, 25, 30 and 45 seconds between the two matches all crashed. Tearing the match down cleanly. I suspected that calling disconnect() while match.players was still non-empty was the trigger — five out of five such teardowns were followed by a crash. So I made the quitting side announce its departure, wait for match(_:player:didChange:) to report the peer gone, and only then disconnect. It works (disconnect now runs with players == 0) and it changes nothing: the count still reads 1 afterwards, and the next match still crashes. Worth saying explicitly, because the correlation was strong enough to look causal. Skipping finishMatchmaking(for:). No effect. The only thing that reliably avoids it is allowing a single real-time match per app launch, which is a poor thing to ship. QUESTIONS Is there a supported way to make GameKit release a finished GKMatch's session inside the process? A GKMatch that never connected (peer wait timed out, disconnect() on an empty match) appears to leave the same residue, so it is not about how the match ended. And has anyone else seen GCKSessionReceiveDOOB / tellDelegate_didReceiveBand_RetryICE? I could not find a single mention of these symbols anywhere.
3
2
1.6k
3w
Public API for system-wide SDR luminance control on built-in XDR?
I am investigating whether a macOS display utility can adjust the luminance of normal SDR desktop content system-wide, including other apps, on the built-in Liquid Retina XDR display of a 2021 M1 Max MacBook Pro. Is there a documented public API, or combination of public APIs, for this scope? The research target is SDR white around 1000 cd/m² while retaining HDR highlight capability, where supported by the hardware and OS. This is a feasibility question, not a claim that this output has been achieved or is supported. The approach must preserve OS color management and respect thermal, power and brightness limits, including protective dimming. I am not seeking gamma-table changes, screen capture and HDR re-display, private APIs, or bypasses of system protections. I understand that enabling EDR for an app's own layer is different from controlling ordinary SDR content in other apps. I am specifically asking about the latter. If this is supported, could you point to the API names, primary documentation, applicable macOS versions and hardware limitations? If it is not supported through public APIs, an explicit clarification would also be helpful.
2
0
1.4k
3w
Clarifying Fence Behavior in Metal 4
I have some clarifying questions on how fences work in Metal 4. If two encoders A, B update the same fence and encoder C waits on that fence, is the work encoded by C guaranteed to execute after both A and B have completed, or after either A or B have completed? The following quotes in the waitForFence() documentation seem contradictory. "Encodes a command that instructs the GPU to pause before starting one or more stages of the pass until a pass updates a fence." "When encoding a pass that reuses a fence, wait for other passes to update the fence before repurposing that fence..." Are fences unsignaled when they are waited on? Specifically, can two (or more) encoders wait on a fence that is only updated in a single prior encoder? If an encoder updates a fence, no subsequent encoders in the command queue wait on the fence, and the command queue is committed, is that fence still signaled when used in a subsequent command buffer?
1
0
2.1k
Oct ’26
Does an empty CollisionFilter prevent RealityKit input on macOS and iOS?
Apple's InputTargetComponent documentation shows this code for an entity that should receive input without participating in physics: // Create a collision component with an empty group and mask. var collision = CollisionComponent(shapes: [.generateSphere(radius: 0.1)]) collision.filter = CollisionFilter(group: [], mask: []) myEntity.components.set(collision) In my RealityKit scene, myEntity also has an enabled InputTargetComponent and a GestureComponent with a TapGesture callback. I use .trigger collision mode. With the empty group and mask, the callback runs on visionOS but does not run on macOS or iOS. Changing the filter to CollisionFilter.default makes the callback run on macOS and iOS. The entity and gesture setup are otherwise the same. Should the documented empty filter still allow input hit testing on macOS and iOS? Is this a RealityKit bug, or does input targeting on those platforms require a different collision filter or additional setup?
2
0
1.4k
Oct ’26
On-screen RealityView starves CADisplayLink to 30 Hz on ProMotion (Mac Catalyst)
FB24536235 On Mac Catalyst under macOS 27, a plain CADisplayLink asking for CAFrameRateRange(minimum: 60, maximum: 60, preferred: 60) gets serviced at 30 Hz for as long as a RealityView is on screen in the same window. The link does nothing per tick but count, so there's nothing of mine to blame it on. RealityKit's own statistics overlay reads 60.41 fps in the same frame. Click a segmented control that removes the RealityView and the same link goes straight back to 60. Nothing else changes. That's the whole reproducer, and I've attached it to the radar. It only happens while the display panel is in ProMotion mode. Set the built-in to a fixed 60 Hz and it's correct again. With an external 60 Hz display attached the roles swap: the built-in is fine and the external drops to somewhere between 18 and 30, and setting the built-in to 60 Hz fixes that one too without touching the external's own settings. A raw MTKView presenting continuously at 60, at 120, and on a 120 Hz link presenting every second callback are all fine, so it isn't continuous presentation and it isn't the requested rate. It's RealityKit specifically. Worth knowing if you're testing: RealityView on Catalyst is an ARView underneath, so both paths give you the same answer. This is VERY rough for anything that puts RealityKit next to a UI. In an editor that's the sidebar, the inspector, gizmos, drag handles, every display-link-driven or UIKit animation in the window running at half rate around a viewport that stays smooth. Likely Related to FB24091347, which is the same defect seen as SwiftUI scroll judder. If you can reproduce either, please file a duplicate. Attached two screenshots; first with promotion enabled, second with promotion off. PLEASE fix this, it drives me crazy and there seems to be no workaround. On release day of macOS 27 our app will likely be blamed for it by users and my hands are tied. Thank you!
2
1
1.4k
Oct ’26
Native Genshin Impact Support on macOS — Feedback ID: FB25106712
Hello, I recently submitted an enhancement request through Feedback Assistant requesting official native macOS support for Genshin Impact. Feedback ID: FB25106712 I am an Apple Developer Beta tester, a Mac user, and a passionate gamer. I regularly test macOS developer beta releases and provide feedback on performance, stability, compatibility, and the overall system experience. I also genuinely enjoy testing games on Mac and seeing what Apple Silicon is capable of. I have personally tested games such as Wuthering Waves, Cyberpunk 2077, and Minecraft on Mac, and my experience with them has been extremely positive. Wuthering Waves in particular runs very smoothly and seamlessly on my Mac. These experiences have made me feel that the capability for excellent gaming on Apple Silicon is already there. The larger limitation, in my experience, is the availability of native support. As a major HoYoverse fan, Genshin Impact is one of the games I would most like to experience and test natively on macOS. At present, Mac users have to rely on third-party workarounds such as PlayCover, compatibility solutions, or cloud gaming rather than having an officially supported native client. I would really like to see Apple work with HoYoverse to bring Genshin Impact natively to macOS, properly optimized for Apple Silicon and Metal. I would also be very happy to test such a release across macOS versions and provide detailed feedback on performance, graphics, stability, thermals, controller support, and the overall gaming experience. Could this enhancement request be brought to the attention of the appropriate Apple team, or is there an appropriate channel through which I can provide further feedback regarding this request? Thank you for your time.
0
0
254
Oct ’26
ScreenCaptureKit is NOT a full replacement for CGWindowListCreateImage
My sandbox app on MAS (Hide Icons) simply toggles the visibility of the Desktop icons and Widgets on or off. It does this by display customized NSWindow on window level given by NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.desktopIconWindow))+1) This custom NSWindow can either have a copy of the Desktop background/wallpaper CGImage or a solid color depending on user preference. Until macOS 27, this worked fine. To find all the Desktop background/wallpaper images (there can be multiple screens and each screen can have multiple Spaces), Apple provided code that avoided any TCC dialog boxes. Namely func getDesktopWindowIds() -> [CGWindowID] { let windows = CGWindowListCopyWindowInfo([.optionAll], kCGNullWindowID)! as! [[String: AnyObject]] let DesktopWindowLevel = CGWindowLevelForKey(.desktopWindow)-1 let DesktopWindows = windows.filter { let windowLevel = $0[kCGWindowLayer as String] as! CGWindowLevel return windowLevel == desktopWindowLevel } return desktopWindows.map { $0[kCGWindowNumber as String] as! CGWindowID } } which returns [CGWindowID] of all the Desktop background/wallpaper windows. Then for any one, say cgID, a simple let cgImage = CGWindowListCreateImage(CGRectNull, [.optionIncludingWindow], cgID, [.bestResolution]) gave an CGImage which then can be applied to my custom NSWindow. No where is TCC triggered. All is great. I followed Apple's ideas about Security and Privacy since I'm only using the data I need (i.e. [CGWindowID]) and the data is only used during execution. Never saved or shared. macOS 27 beta 4 and beyond broke CGWindowListCreateImage(...). It compiles and when called it returns some gray image. Documentation tells me to use ScreenCaptureKit. The newest versions of ScreenCaptureKit introduce SCScreenshotManager.captureImage(contentFilter:, configuration) which can return a CGImage of the CGWindowID. Here is when the problem occurs. To capture that CGWindowID CGImage, one would use SCContentFilter(desktopIndependentWindow: desktopWindow) but to get desktopWindow you first need to find the SCWindow that corresponds to CGWindowID. You can grab a set of SCWindow with SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: false) But when any method of SCShareableContent is called, TCC throws up this warning I do not want this. Too many permissions are being granted. I only want the [CGWindowID] of the Desktop background/wallpaper. This, if the user grants, gives me much more which is bad for Security and Privacy. One way to avoid the TCC in ScreenCaptureKit is to use the new SCContentSharingPicker.shared. This allows the user to pick what they want to share. I first tried var pickerConfiguration = SCContentSharingPickerConfiguration() pickerConfiguration.allowedPickerModes = [.multipleWindows, .singleWindow] but the picker does not allow the user to select the Desktop background/wallpaper. Using var pickerConfiguration = SCContentSharingPickerConfiguration() pickerConfiguration.allowedPickerModes = [.singleDisplay] also doesn't give me Desktop background/wallpaper access. Trying to use [.singleApplication] and limiting the choices to WindowServer (what SCWindow claims is the owner) also doesn't allow picking of the Desktop background/wallpaper. So, is it true to get access to the Desktop background/wallpaper CGWindowID's CGImage, I must have the user give me full access via TCC? Please tell me of a work around. The obvious fix is on Apple's side. The corresponding list of [SCWindow] corresponding to [CGWindowID] should always be included in SCContentFilter.includedWindows. Or simply leave them out of the TCC domain as before.
2
0
628
Oct ’26
Update license of D3DMetal for redistribution
CrossOvers and Whisky both redistribute D3DMetal in their app. We would like to do so as well but the included license does not make it clear. Please update the license to make the exception clear so we can distribute under the same terms as those apps. FB24262864 is also filed regarding this issue.
Replies
2
Boosts
0
Views
786
Activity
1w
PHASE occluder silences direct sound instead of muffling it
I’m using PHASE for an outdoor soundscape with only .directPathTransmission enabled. A point source and listener are 2 metres apart. Between them is a PHASEOccluder built from a 2 × 2 × 0.02 metre MDLMesh box, with a .cardboard material assigned to every shape element. Without the occluder, the sound is loud. With it, the sound is completely inaudible. Switching to .glass and setting the sampler’s cullOption to .doNotCull makes no audible difference. This happens on both iOS Simulator and a physical iPhone. Adding .lateReverb produces faint audible sound, but room reverb is inappropriate for this outdoor scene and doesn’t establish whether direct transmission works. Is this expected attenuation, or is additional configuration required to hear muffled sound through an occluder? Is there a working sample demonstrating material-dependent transmission with reverb disabled?
Replies
3
Boosts
1
Views
2.0k
Activity
2w
System protocol CPU performance question
Hello guys In my game the player sits in the middle of the screen and shoots on enemies coming all around it. (none vr/ar game) I have 3 :systems protocol already to spawn the enemies using timer and budget a different one to move them to the player direction pool system that turned off dead enemies Because reality kit is a high level framework i dont know what is the fastest way to design the bullet system for better cpu speed A. Seperated system for the bullets, asking to know the closest enemy to travel to, hit, and move to the disable pool system if died. or B. Use the same system that moving the enemies but in a seperated loop (prabably one before moving the enemies) Thanks for the help
Replies
1
Boosts
0
Views
73
Activity
2w
NSOpenGLView / NSOpenGLContext setView: get no drawable on macOS 15.8.2 RC (24H219), windows render blank (FB25133383)
After updating a MacBook Pro (M1 Pro) from macOS 15.8 to the 15.8.2 release candidate (24H219), every OpenGL context that is attached to a window has no default framebuffer. NSOpenGLView and -[NSOpenGLContext setView:] are both affected, so anything drawn that way shows a blank window. I filed FB25133383 with a minimal sample, kernel log and call trace. Symptoms kCGLCPHasDrawable is 0, glCheckFramebufferStatus(GL_FRAMEBUFFER) returns GL_FRAMEBUFFER_UNDEFINED (0x8219), and glClear raises GL_INVALID_FRAMEBUFFER_OPERATION (0x506). For every attach attempt the kernel logs: (IOGPUFamily) IOGPUGLDrawableUserClient::set_surface(sIOGPUGLDrawableClientSetSurfaceData *): Invalid surface ID = N CGLSetSurface returns kCGLBadDrawable (10005). Stepping through it, CGSBindSurface succeeds and the IOGPU user-client call then fails with kIOReturnBadArgument. What still works Offscreen FBOs in the same context. CAOpenGLLayer and NSOpenGLLayer render correctly in the same process. Only the window-surface path is broken. Minimal sample (public API only) // clang -fobjc-arc -Wno-deprecated-declarations -framework Cocoa -framework OpenGL repro.m -o repro && ./repro #define GL_SILENCE_DEPRECATION 1 #import <Cocoa/Cocoa.h> #import <OpenGL/OpenGL.h> #import <OpenGL/gl.h> #import <OpenGL/glext.h> @interface ReproView : NSOpenGLView @end @implementation ReproView - (void)drawRect:(NSRect)dirtyRect { NSOpenGLContext *ctx = [self openGLContext]; [ctx makeCurrentContext]; GLint hasDrawable = -1; CGLGetParameter(ctx.CGLContextObj, kCGLCPHasDrawable, &hasDrawable); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); glClearColor(0, 1, 0, 1); glClear(GL_COLOR_BUFFER_BIT); GLenum err = glGetError(); printf("hasDrawable=%d status=0x%x glError=0x%x\n", hasDrawable, status, err); fflush(stdout); [ctx flushBuffer]; } @end int main(void) { @autoreleasepool { NSApplication *app = [NSApplication sharedApplication]; [app setActivationPolicy:NSApplicationActivationPolicyRegular]; NSWindow *win = [[NSWindow alloc] initWithContentRect:NSMakeRect(200, 300, 240, 240) styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:NO]; NSOpenGLPixelFormatAttribute attrs[] = { NSOpenGLPFADoubleBuffer, NSOpenGLPFAAccelerated, 0 }; NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; [win.contentView addSubview:[[ReproView alloc] initWithFrame:NSMakeRect(20, 20, 200, 200) pixelFormat:pf]]; [win makeKeyAndOrderFront:nil]; [app activateIgnoringOtherApps:YES]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ [app terminate:nil]; }); [app run]; } return 0; } Expected: a green square and hasDrawable=1 status=0x8cd5 glError=0x0. On 24H219: nothing is drawn and it prints hasDrawable=0 status=0x8219 glError=0x506. Scope Same result for arm64 and x86_64 under Rosetta, layer-backed or not, main thread or background thread. Affected on my Mac: Sony Imaging Edge Desktop Viewer (NSOpenGLView), DJI Studio (Qt 6, NSOpenGLContext) and its Quick Look extension. Public reports with the same symptom on 24H219: kitty #10645, Alacritty #9067, Godot #124311, Bambu Studio #12530 (all on GitHub). They cover M1, M4, M4 Pro and M4 Max, and the Alacritty report says 15.8.1 was fine. Questions Is this a known issue in the 15.8.2 RC, and will it be fixed before 15.8.2 ships? Is anyone seeing it on the macOS 26.7.2 RC or the 27.2 beta? Workaround for developers in the meantime: render into an IOSurface-backed FBO and present that surface in a CALayer, or use CAOpenGLLayer.
Replies
8
Boosts
4
Views
22k
Activity
2w
macOS 27.2 RC (26B118) Built-in display canvas cropped with black bar at bottom-right after login
Description: MacBook Air M5, using only built-in display. The login window renders full screen normally. After logging into desktop session, the display canvas gets cropped with a black bar on the bottom-right corner. This issue is reproducible in Safe Mode and with a brand-new admin user account. No third-party display or window management software installed. Suspected WindowServer display coordinate calculation bug within user session. Environment Device: MacBook Air M5 OS: macOS 27.2 RC (26B118) Display: Built-in display only, no external monitor Reproduction steps Boot to login window, display works fine Log into desktop session Display canvas cropped, black bar appears at bottom-right
Replies
1
Boosts
0
Views
1k
Activity
2w
M5 Pro external display pipeline width limits and native HiDPI support
Hello Apple Engineering Team, I would like to clarify a technical question regarding the external display architecture of the M5 Pro MacBook Pro. I use a single ultrawide monitor with a native resolution of 3440 × 1440. To achieve true 2× HiDPI rendering at this logical resolution, macOS would need to render a framebuffer of 6880 × 2880. Third-party diagnostic tools and firmware reverse-engineering reports appear to indicate that M5 Pro has display-pipeline source-width limits of 6720 and 7680 pixels. Could you please clarify the following? Are these reported source-width limits accurate for the M5 Pro? Can macOS assign a single external display to the display pipeline that supports a 7680-pixel source width? Is there a supported way to influence or change this pipeline allocation, such as changing the connection port, connection order, or display configuration? Can a single 3440 × 1440 external monitor use native 2× HiDPI rendering (6880 × 2880) on the M5 Pro without virtual-display mirroring? If this configuration is unsupported, is the limitation imposed by hardware, firmware, or macOS display allocation policy? I understand that Apple may not disclose all internal implementation details. Any clarification regarding supported configurations or known limitations would be greatly appreciated. Thank you.
Replies
0
Boosts
0
Views
510
Activity
2w
Game Center Dashboard overlay doesn't have Done or x button
From this WWDC video -> https://developer.apple.com/videos/play/wwdc2020/10618/ I see the examples show that almost each screen have a "Done" button on top trailing, document sites also show the x button on top trailing, however, in my app, the overlay shows without any Done or x button, it doesn't look very apparent how to "close" this popup. I soon learned the hardware that the trick is to tap on empty areas. Is there a way to enable the Done or x button in it?
Replies
0
Boosts
0
Views
471
Activity
3w
Photogrammetry with Object masks hangs and terminates with masks of objects
[PhotogrammetrySample]) with objectMask set and traps on my ios26.5.2, see the attached screenshot on feedback FB24379913 , it gets to the function and hangs . Even the folder reconstruction with lazy sequence as recommended from your video sample also doesn;t complete as it can't find alignment and displays the CoreOC.PhotogrammetrySession.Error error 6 means alignment failed. What can be done or do you guys expose any functions that can be used to check or trace or handle these internally The ObjectMasks are actually segmentation masks from an segmentation algorithm I will appreciate a timely response and willing to provide more clarity and informations, thank you so much for your understanding
Replies
3
Boosts
0
Views
1.4k
Activity
3w
Metal CSM Shadows GPU Culling+Indirect+Vertex Amplification - empty some Shadow Cascades
Hi! I'm porting Cascaded Shadow Maps(CSM) from HLSL Direct3D12/Vulkan I'm using GPU Culling, indirect Call + Vertex Amplification for shadow Casters for creating Shadow map texture. Shadow map texture - Texture2DArray Shadow castes are rendering using Instancing and IndirectDraw, VS shader are checking [amplification_id]] and view mask CS shader are finding shadow caster using InstanceId and view mask for each shadow cascade: // dataIndex - Instance index for featching Instance Matrix // viewMask - for VS [[amplification_id]] uint PackInstanceData(uint viewMask, uint dataIndex) { return (viewMask << 28u) | dataIndex; } kernel void CullObjects(uint2 DTid [[thread_position_in_grid]], constant ArgBuf& argBuf [[buffer(0)]], uint groupIndex [[thread_index_in_threadgroup]]) { threadgroup atomic_uint sharedNumObjects; threadgroup uint sharedInstanceId[32]; threadgroup uint globalBufferIndex; constant auto& cbData = *argBuf.cbData; uint index = DTid.x; if (!groupIndex) { atomic_store_explicit(&sharedNumObjects, 0u, memory_order_relaxed); globalBufferIndex = 0u; } threadgroup_barrier(mem_flags::mem_threadgroup); bool visible = false; uint viewMask = 0; if (index < cbData.numInstanceObjects) { const device CullingObjInfo& cullingObjectInfo = argBuf.cullingObjInfo[index]; // find shadow casters for each shadow cascade for (uint i = 0u; i < NUM_FRUSTUMS; ++i) { constant Frustum& frustum = cbData.frustums[i]; visible = SphereInFrustum(frustum, cullingObjectInfo.boundingSphere); if (visible) { visible = BoundingBoxInFrustum(frustum, cullingObjectInfo.boundingBox.minPoint, cullingObjectInfo.boundingBox.maxPoint); } if (visible) { viewMask |= (1u << i); } } visible = bool(viewMask); } } if (visible) { uint bufferIndex = atomic_fetch_add_explicit(&sharedNumObjects, 1u, memory_order_relaxed); sharedInstanceId[bufferIndex] = PackInstanceData(viewMask, index); } threadgroup_barrier(mem_flags::mem_threadgroup); uint localNumObjects = atomic_load_explicit(&sharedNumObjects, memory_order_relaxed); if (!groupIndex && localNumObjects) { globalBufferIndex = atomic_fetch_add_explicit(&argBuf.numObjects->instanceCount, localNumObjects, memory_order_relaxed); } threadgroup_barrier(mem_flags::mem_threadgroup); if (groupIndex < localNumObjects) { argBuf.instanceId[globalBufferIndex + groupIndex] = sharedInstanceId[groupIndex]; } } VS shader for depth shadow map rendering: // struct PSOutput { float4 pos [[position]]; float2 Depth [[user(locn0)]]; float CullDist [[clip_distance]]; uint layer [[render_target_array_index]]; }; struct VS { float4 pos [[attribute(0)]]; uint InstanceId [[attribute(9)]]; }; struct b { float4x4 lightViewProj[NUM_SM_CASCADES]; }; struct Arg { const device float3x4* InstanceData [[id(0)]]; constant b* cb [[id(1)]]; }; uint UnpackViewInstancingMask(uint packedData) { return packedData >> 28u; } uint UnpackInstanceIndex(uint packedData) { return packedData & 0x0FFFFFFFu; } vertex PSOutput vsMain(VS In [[stage_in]], constant Arg& arg [[buffer(VSArgumentBufferIndex)]], ushort ampID [[amplification_id]]) { constant auto& b0 = *arg.cb; PSOutput output; float4 WorldPos = float4(In.pos.xyz, 1.0f); uint viewMask = UnpackViewInstancingMask(In.InstanceId); output.layer = ampID; // check shadow caster rendering for each cascade using ampID and viewMask if (viewMask & (1u << ampID)) { float3x4 instanceMatrix = arg.InstanceData[UnpackInstanceIndex(In.InstanceId)]; WorldPos = float4((WorldPos * instanceMatrix).xyz, 1.0f); output.CullDist = 1.0f; } else { output.pos = float4(0.0f, 0.0f, 2.0f, 1.0f); // skeep unvisible object for this cascade output.CullDist = -1.0f; return output; } output.pos = b0.lightViewProj[ampID] * WorldPos; output.Depth.xy = output.pos.zz; return output; } I have result left part: CPU Version - separate rendering for each layer for texture2Darray shadow map right part: GPU culling + Indirect + Vertex Amplification Got to fix error ? Why 1 and 3 cascade are empty? 0 cascade has duplicate data from other cascades.
Replies
2
Boosts
0
Views
763
Activity
3w
Processing RAW files using CIRAWFilter slows down after opening a few different images
Is there some cleanup required if you are opening multiple different RAW files - I am seeing a slow down each time I open a new file and things grind to a halt after opening 5 or 6 files, one after the other - even allowing some time between opening them. Currently I have a single view with a CAMetalLayer and a single Renderer and CIContent - should I be creating a new CAMetalLayer, render and CIContext each time a new image is opened ? Alternately is there some way to clear the cache or something to maintain performance.
Replies
1
Boosts
0
Views
478
Activity
3w
GKMatch: GameKitServices crashes in GCKSessionReceiveDOOB on the second real-time match — the finished session is never reclaimed
We ship a two-player real-time GameKit game. On iOS 27 the app crashes inside GameKitServices on the second real-time match of any app session — nine times out of nine yesterday. Filed as FB24789094 (and FB24788999 for a separate reinvitation problem). Posting the measurements here because the unified log makes the mechanism visible, and because everything I tried at the app level failed — maybe somebody has the missing piece. THE CRASH Main thread, no application frame anywhere on the stack: CFRetain + 52 GCKSessionReceiveDOOB + 1632 -[GKSessionInternal receiveDOOB:fromPeer:inSession:context:] + 320 -[GKSessionInternal(_private) tellDelegate_didReceiveBand_RetryICE:] + 212 __NSThreadPerformPerform + 264 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ EXC_BAD_ACCESS (SIGBUS), EXC_ARM_DA_ALIGN at 0x9 (0xa in one report). In every report the faulting address is exactly x0 + 8, and x0 is 1 or 2 — CFRetain is handed a small integer, not a pointer. A use-after-free would fault on a large plausible-looking address; 1 and 2 are not addresses at all. Address Sanitizer agrees: no heap error is reported before the fault, only __asan::ReportDeadlySignal directly above the same three GameKitServices frames. It reads like type confusion in the RetryICE band path. Not the SDK: a build made with Xcode 26.6 against iphoneos26.5 crashes identically — same stack, same registers. The peer's OS does not matter either (iPadOS 17.7.11, iOS 26.6.1 and iOS 27.0 all seen on the other side, and in one case an older build of our own app). Only the crashing device is always on iOS 27.0 (24A435), an iPhone 15 Pro. RECIPE Two devices, two Game Center accounts. Form a two-player real-time GKMatch — GKMatchmaker.findMatch(for:) or an invitation, both reproduce. Wait for the peer to connect, call finishMatchmaking(for:). Play for ten seconds or so, so data really flows. End it: match.disconnect(), release the GKMatch. In the SAME process, form a SECOND real-time match. Play. The crash lands roughly ten to thirty seconds after the second match starts exchanging data. A first match in a freshly launched process has never crashed for us. Out of eleven app sessions that reached a second match, two were force quit by hand during other tests and the remaining nine all crashed here. THE SESSION IS NEVER RECLAIMED GameKit runs one "com.apple.gamekitservices.gcksession.recvproc" / "sendproc" thread pair per live real-time session, in the app's own process. You can count them from inside the app, which turns out to be the only way to see what is going on: var threads: thread_act_array_t? var count: mach_msg_type_number_t = 0 task_threads(mach_task_self_, &threads, &count) // then pthread_from_mach_thread_np(threads[i]) + pthread_getname_np, and compare the name Measured across one app session: after Game Center authentication, before any match ......... 0 first match live ........................................... 1 right after match.disconnect() returns ..................... 1 <- not reclaimed before the second match is adopted ......................... 2 right after the second match's disconnect() ................ 2 Every crash report shows two of those pairs alive, although the app holds exactly one GKMatch at a time and releases the finished one the instant disconnect() returns. The same leak is visible on iOS 26.6.1 (an iPhone 11 Pro leaks identically) — it just does not crash there. WHAT THE LEFTOVER SESSION DOES Each match gets its own CDXClient. The first match's is never torn down, and keeps poking its hole on a 30-second keep-alive, on the same local port (:16402) the second match then binds: 15:28:05.117 <CDXClient: 0x155872e40> requesting-hole-punch <- match 1 15:28:35.289 <CDXClient: 0x155872e40> requesting-hole-punch <- match 1, +30s, match already over 15:28:50.197 <CDXClient: 0x12d4bda40> requesting-hole-punch <- match 2 15:29:05.287 <CDXClient: 0x155872e40> requesting-hole-punch <- match 1 again, 4s before the crash GCKSessionCreate:6425 globalscopelaunch appears once per process; the second match only does 6509 globalscoperequest and reuses the global scope. During the second match's ICE setup a packet arrives belonging to no live session: -[CDXClient handleFDEvent]:1066 packet-from-unknown-session -[CDXClient handleFDEvent]:1067 Incoming packet from unknown session. SID = ... immediately followed by [ERROR] ICEStopConnectivityCheck:2763 ICEStopConnectivityCheck() found no ICE check with call id (...) [ERROR] gckSessionCheckPendingConnections:1545 iICEChecksLeft=0, iUnconnectedNodeCount=0, iDDsExpected=1 Those lines appear exactly three times in a 28-minute window, all three in the two processes that went on to crash, never during a first match. About fourteen seconds later the RetryICE band is delivered and CFRetain is called on the garbage. WHAT DID NOT WORK Releasing the GKMatch immediately after disconnect(). The session threads stay. Waiting. Gaps of 17, 19, 22, 25, 30 and 45 seconds between the two matches all crashed. Tearing the match down cleanly. I suspected that calling disconnect() while match.players was still non-empty was the trigger — five out of five such teardowns were followed by a crash. So I made the quitting side announce its departure, wait for match(_:player:didChange:) to report the peer gone, and only then disconnect. It works (disconnect now runs with players == 0) and it changes nothing: the count still reads 1 afterwards, and the next match still crashes. Worth saying explicitly, because the correlation was strong enough to look causal. Skipping finishMatchmaking(for:). No effect. The only thing that reliably avoids it is allowing a single real-time match per app launch, which is a poor thing to ship. QUESTIONS Is there a supported way to make GameKit release a finished GKMatch's session inside the process? A GKMatch that never connected (peer wait timed out, disconnect() on an empty match) appears to leave the same residue, so it is not about how the match ended. And has anyone else seen GCKSessionReceiveDOOB / tellDelegate_didReceiveBand_RetryICE? I could not find a single mention of these symbols anywhere.
Replies
3
Boosts
2
Views
1.6k
Activity
3w
Public API for system-wide SDR luminance control on built-in XDR?
I am investigating whether a macOS display utility can adjust the luminance of normal SDR desktop content system-wide, including other apps, on the built-in Liquid Retina XDR display of a 2021 M1 Max MacBook Pro. Is there a documented public API, or combination of public APIs, for this scope? The research target is SDR white around 1000 cd/m² while retaining HDR highlight capability, where supported by the hardware and OS. This is a feasibility question, not a claim that this output has been achieved or is supported. The approach must preserve OS color management and respect thermal, power and brightness limits, including protective dimming. I am not seeking gamma-table changes, screen capture and HDR re-display, private APIs, or bypasses of system protections. I understand that enabling EDR for an app's own layer is different from controlling ordinary SDR content in other apps. I am specifically asking about the latter. If this is supported, could you point to the API names, primary documentation, applicable macOS versions and hardware limitations? If it is not supported through public APIs, an explicit clarification would also be helpful.
Replies
2
Boosts
0
Views
1.4k
Activity
3w
Clarifying Fence Behavior in Metal 4
I have some clarifying questions on how fences work in Metal 4. If two encoders A, B update the same fence and encoder C waits on that fence, is the work encoded by C guaranteed to execute after both A and B have completed, or after either A or B have completed? The following quotes in the waitForFence() documentation seem contradictory. "Encodes a command that instructs the GPU to pause before starting one or more stages of the pass until a pass updates a fence." "When encoding a pass that reuses a fence, wait for other passes to update the fence before repurposing that fence..." Are fences unsignaled when they are waited on? Specifically, can two (or more) encoders wait on a fence that is only updated in a single prior encoder? If an encoder updates a fence, no subsequent encoders in the command queue wait on the fence, and the command queue is committed, is that fence still signaled when used in a subsequent command buffer?
Replies
1
Boosts
0
Views
2.1k
Activity
Oct ’26
Does an empty CollisionFilter prevent RealityKit input on macOS and iOS?
Apple's InputTargetComponent documentation shows this code for an entity that should receive input without participating in physics: // Create a collision component with an empty group and mask. var collision = CollisionComponent(shapes: [.generateSphere(radius: 0.1)]) collision.filter = CollisionFilter(group: [], mask: []) myEntity.components.set(collision) In my RealityKit scene, myEntity also has an enabled InputTargetComponent and a GestureComponent with a TapGesture callback. I use .trigger collision mode. With the empty group and mask, the callback runs on visionOS but does not run on macOS or iOS. Changing the filter to CollisionFilter.default makes the callback run on macOS and iOS. The entity and gesture setup are otherwise the same. Should the documented empty filter still allow input hit testing on macOS and iOS? Is this a RealityKit bug, or does input targeting on those platforms require a different collision filter or additional setup?
Replies
2
Boosts
0
Views
1.4k
Activity
Oct ’26
On-screen RealityView starves CADisplayLink to 30 Hz on ProMotion (Mac Catalyst)
FB24536235 On Mac Catalyst under macOS 27, a plain CADisplayLink asking for CAFrameRateRange(minimum: 60, maximum: 60, preferred: 60) gets serviced at 30 Hz for as long as a RealityView is on screen in the same window. The link does nothing per tick but count, so there's nothing of mine to blame it on. RealityKit's own statistics overlay reads 60.41 fps in the same frame. Click a segmented control that removes the RealityView and the same link goes straight back to 60. Nothing else changes. That's the whole reproducer, and I've attached it to the radar. It only happens while the display panel is in ProMotion mode. Set the built-in to a fixed 60 Hz and it's correct again. With an external 60 Hz display attached the roles swap: the built-in is fine and the external drops to somewhere between 18 and 30, and setting the built-in to 60 Hz fixes that one too without touching the external's own settings. A raw MTKView presenting continuously at 60, at 120, and on a 120 Hz link presenting every second callback are all fine, so it isn't continuous presentation and it isn't the requested rate. It's RealityKit specifically. Worth knowing if you're testing: RealityView on Catalyst is an ARView underneath, so both paths give you the same answer. This is VERY rough for anything that puts RealityKit next to a UI. In an editor that's the sidebar, the inspector, gizmos, drag handles, every display-link-driven or UIKit animation in the window running at half rate around a viewport that stays smooth. Likely Related to FB24091347, which is the same defect seen as SwiftUI scroll judder. If you can reproduce either, please file a duplicate. Attached two screenshots; first with promotion enabled, second with promotion off. PLEASE fix this, it drives me crazy and there seems to be no workaround. On release day of macOS 27 our app will likely be blamed for it by users and my hands are tied. Thank you!
Replies
2
Boosts
1
Views
1.4k
Activity
Oct ’26
Native Genshin Impact Support on macOS — Feedback ID: FB25106712
Hello, I recently submitted an enhancement request through Feedback Assistant requesting official native macOS support for Genshin Impact. Feedback ID: FB25106712 I am an Apple Developer Beta tester, a Mac user, and a passionate gamer. I regularly test macOS developer beta releases and provide feedback on performance, stability, compatibility, and the overall system experience. I also genuinely enjoy testing games on Mac and seeing what Apple Silicon is capable of. I have personally tested games such as Wuthering Waves, Cyberpunk 2077, and Minecraft on Mac, and my experience with them has been extremely positive. Wuthering Waves in particular runs very smoothly and seamlessly on my Mac. These experiences have made me feel that the capability for excellent gaming on Apple Silicon is already there. The larger limitation, in my experience, is the availability of native support. As a major HoYoverse fan, Genshin Impact is one of the games I would most like to experience and test natively on macOS. At present, Mac users have to rely on third-party workarounds such as PlayCover, compatibility solutions, or cloud gaming rather than having an officially supported native client. I would really like to see Apple work with HoYoverse to bring Genshin Impact natively to macOS, properly optimized for Apple Silicon and Metal. I would also be very happy to test such a release across macOS versions and provide detailed feedback on performance, graphics, stability, thermals, controller support, and the overall gaming experience. Could this enhancement request be brought to the attention of the appropriate Apple team, or is there an appropriate channel through which I can provide further feedback regarding this request? Thank you for your time.
Replies
0
Boosts
0
Views
254
Activity
Oct ’26
ScreenCaptureKit is NOT a full replacement for CGWindowListCreateImage
My sandbox app on MAS (Hide Icons) simply toggles the visibility of the Desktop icons and Widgets on or off. It does this by display customized NSWindow on window level given by NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.desktopIconWindow))+1) This custom NSWindow can either have a copy of the Desktop background/wallpaper CGImage or a solid color depending on user preference. Until macOS 27, this worked fine. To find all the Desktop background/wallpaper images (there can be multiple screens and each screen can have multiple Spaces), Apple provided code that avoided any TCC dialog boxes. Namely func getDesktopWindowIds() -> [CGWindowID] { let windows = CGWindowListCopyWindowInfo([.optionAll], kCGNullWindowID)! as! [[String: AnyObject]] let DesktopWindowLevel = CGWindowLevelForKey(.desktopWindow)-1 let DesktopWindows = windows.filter { let windowLevel = $0[kCGWindowLayer as String] as! CGWindowLevel return windowLevel == desktopWindowLevel } return desktopWindows.map { $0[kCGWindowNumber as String] as! CGWindowID } } which returns [CGWindowID] of all the Desktop background/wallpaper windows. Then for any one, say cgID, a simple let cgImage = CGWindowListCreateImage(CGRectNull, [.optionIncludingWindow], cgID, [.bestResolution]) gave an CGImage which then can be applied to my custom NSWindow. No where is TCC triggered. All is great. I followed Apple's ideas about Security and Privacy since I'm only using the data I need (i.e. [CGWindowID]) and the data is only used during execution. Never saved or shared. macOS 27 beta 4 and beyond broke CGWindowListCreateImage(...). It compiles and when called it returns some gray image. Documentation tells me to use ScreenCaptureKit. The newest versions of ScreenCaptureKit introduce SCScreenshotManager.captureImage(contentFilter:, configuration) which can return a CGImage of the CGWindowID. Here is when the problem occurs. To capture that CGWindowID CGImage, one would use SCContentFilter(desktopIndependentWindow: desktopWindow) but to get desktopWindow you first need to find the SCWindow that corresponds to CGWindowID. You can grab a set of SCWindow with SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: false) But when any method of SCShareableContent is called, TCC throws up this warning I do not want this. Too many permissions are being granted. I only want the [CGWindowID] of the Desktop background/wallpaper. This, if the user grants, gives me much more which is bad for Security and Privacy. One way to avoid the TCC in ScreenCaptureKit is to use the new SCContentSharingPicker.shared. This allows the user to pick what they want to share. I first tried var pickerConfiguration = SCContentSharingPickerConfiguration() pickerConfiguration.allowedPickerModes = [.multipleWindows, .singleWindow] but the picker does not allow the user to select the Desktop background/wallpaper. Using var pickerConfiguration = SCContentSharingPickerConfiguration() pickerConfiguration.allowedPickerModes = [.singleDisplay] also doesn't give me Desktop background/wallpaper access. Trying to use [.singleApplication] and limiting the choices to WindowServer (what SCWindow claims is the owner) also doesn't allow picking of the Desktop background/wallpaper. So, is it true to get access to the Desktop background/wallpaper CGWindowID's CGImage, I must have the user give me full access via TCC? Please tell me of a work around. The obvious fix is on Apple's side. The corresponding list of [SCWindow] corresponding to [CGWindowID] should always be included in SCContentFilter.includedWindows. Or simply leave them out of the TCC domain as before.
Replies
2
Boosts
0
Views
628
Activity
Oct ’26