SDL: Cache CGDisplayPixelsHigh result on macOS to reduce IPC overhead

From 3ee8d1406c1068eeeffd8e5662e69b96fa50f5a7 Mon Sep 17 00:00:00 2001
From: Qiu Qiang <[EMAIL REDACTED]>
Date: Thu, 1 Jan 2026 23:59:51 -0500
Subject: [PATCH] Cache CGDisplayPixelsHigh result on macOS to reduce IPC
 overhead

CGDisplayPixelsHigh(kCGDirectMainDisplay) involves an IPC call to the
Window Server on each invocation. Cache the main display height in
SDL_CocoaVideoData and update it only when display configuration changes,
reducing overhead during high-frequency mouse event processing.
---
 src/video/cocoa/SDL_cocoamodes.m  | 11 ++++++++++-
 src/video/cocoa/SDL_cocoamouse.m  |  7 +++++--
 src/video/cocoa/SDL_cocoavideo.h  |  1 +
 src/video/cocoa/SDL_cocoawindow.m |  6 ++++--
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/video/cocoa/SDL_cocoamodes.m b/src/video/cocoa/SDL_cocoamodes.m
index f2a856b74783d..700e700afef10 100644
--- a/src/video/cocoa/SDL_cocoamodes.m
+++ b/src/video/cocoa/SDL_cocoamodes.m
@@ -331,9 +331,12 @@ static bool Cocoa_GetUsableBounds(CGDirectDisplayID displayID, SDL_Rect *rect)
         return false;
     }
 
+    SDL_VideoDevice *device = SDL_GetVideoDevice();
+    SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)device->internal;
+
     const NSRect frame = [screen visibleFrame];
     rect->x = (int)frame.origin.x;
-    rect->y = (int)(CGDisplayPixelsHigh(kCGDirectMainDisplay) - frame.origin.y - frame.size.height);
+    rect->y = (int)(data.mainDisplayHeight - frame.origin.y - frame.size.height);
     rect->w = (int)frame.size.width;
     rect->h = (int)frame.size.height;
     return true;
@@ -493,14 +496,20 @@ static void Cocoa_DisplayReconfigurationCallback(CGDirectDisplayID displayid, CG
     if (flags & kCGDisplayDesktopShapeChangedFlag) {
         SDL_UpdateDesktopBounds();
     }
+
+    SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal;
+    data.mainDisplayHeight = CGDisplayPixelsHigh(kCGDirectMainDisplay);
 }
 
 void Cocoa_InitModes(SDL_VideoDevice *_this)
 {
     @autoreleasepool {
+        SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal;
         CGDisplayErr result;
         CGDisplayCount numDisplays = 0;
 
+        data.mainDisplayHeight = CGDisplayPixelsHigh(kCGDirectMainDisplay);
+
         result = CGGetOnlineDisplayList(0, NULL, &numDisplays);
         if (result != kCGErrorSuccess) {
             CG_SetError("CGGetOnlineDisplayList()", result);
diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m
index 639bc84251990..632f8e1bfb98e 100644
--- a/src/video/cocoa/SDL_cocoamouse.m
+++ b/src/video/cocoa/SDL_cocoamouse.m
@@ -409,9 +409,11 @@ static SDL_MouseButtonFlags Cocoa_GetGlobalMouseState(float *x, float *y)
     const NSUInteger cocoaButtons = [NSEvent pressedMouseButtons];
     const NSPoint cocoaLocation = [NSEvent mouseLocation];
     SDL_MouseButtonFlags result = 0;
+    SDL_VideoDevice *device = SDL_GetVideoDevice();
+    SDL_CocoaVideoData *videodata = (__bridge SDL_CocoaVideoData *)device->internal;
 
     *x = cocoaLocation.x;
-    *y = (CGDisplayPixelsHigh(kCGDirectMainDisplay) - cocoaLocation.y);
+    *y = (videodata.mainDisplayHeight - cocoaLocation.y);
 
     result |= (cocoaButtons & (1 << 0)) ? SDL_BUTTON_LMASK : 0;
     result |= (cocoaButtons & (1 << 1)) ? SDL_BUTTON_RMASK : 0;
@@ -600,8 +602,9 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event)
     deltaY = [event deltaY];
 
     if (seenWarp) {
+        SDL_CocoaVideoData *videodata = (__bridge SDL_CocoaVideoData *)_this->internal;
         deltaX += (lastMoveX - data->lastWarpX);
-        deltaY += ((CGDisplayPixelsHigh(kCGDirectMainDisplay) - lastMoveY) - data->lastWarpY);
+        deltaY += ((videodata.mainDisplayHeight - lastMoveY) - data->lastWarpY);
 
         DLog("Motion was (%g, %g), offset to (%g, %g)", [event deltaX], [event deltaY], deltaX, deltaY);
     }
diff --git a/src/video/cocoa/SDL_cocoavideo.h b/src/video/cocoa/SDL_cocoavideo.h
index f46d58d301efb..75983c99fa47a 100644
--- a/src/video/cocoa/SDL_cocoavideo.h
+++ b/src/video/cocoa/SDL_cocoavideo.h
@@ -62,6 +62,7 @@ typedef enum
 @property(nonatomic) IOPMAssertionID screensaver_assertion;
 @property(nonatomic) SDL_Mutex *swaplock;
 @property(nonatomic) OptionAsAlt option_as_alt;
+@property(nonatomic) CGFloat mainDisplayHeight;
 @end
 
 // Utility functions
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index f7dfd61f32fac..1c2dbf8a60ae8 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -507,7 +507,8 @@ void Cocoa_MenuVisibilityCallback(void *userdata, const char *name, const char *
 
 static void ConvertNSRect(NSRect *r)
 {
-    r->origin.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - r->origin.y - r->size.height;
+    SDL_CocoaVideoData *videodata = (__bridge SDL_CocoaVideoData *)SDL_GetVideoDevice()->internal;
+    r->origin.y = videodata.mainDisplayHeight - r->origin.y - r->size.height;
 }
 
 static void ScheduleContextUpdates(SDL_CocoaWindowData *data)
@@ -2249,12 +2250,13 @@ static void Cocoa_UpdateMouseFocus()
                                   }
                                   *stop = YES;
                                   if (sdlwindow) {
+                                      SDL_CocoaVideoData *videodata = (__bridge SDL_CocoaVideoData *)vid->internal;
                                       int wx, wy;
                                       SDL_RelativeToGlobalForWindow(sdlwindow, sdlwindow->x, sdlwindow->y, &wx, &wy);
 
                                       // Calculate the cursor coordinates relative to the window.
                                       const float dx = mouseLocation.x - wx;
-                                      const float dy = (CGDisplayPixelsHigh(kCGDirectMainDisplay) - mouseLocation.y) - wy;
+                                      const float dy = (videodata.mainDisplayHeight - mouseLocation.y) - wy;
                                       SDL_SendMouseMotion(0, sdlwindow, SDL_GLOBAL_MOUSE_ID, false, dx, dy);
                                   }
                               }