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.
This commit is contained in:
Qiu Qiang
2026-01-01 23:59:51 -05:00
committed by Sam Lantinga
parent 91f22b15cd
commit 3ee8d1406c
4 changed files with 20 additions and 5 deletions
+10 -1
View File
@@ -331,9 +331,12 @@ static bool Cocoa_GetUsableBounds(CGDirectDisplayID displayID, SDL_Rect *rect)
return false; return false;
} }
SDL_VideoDevice *device = SDL_GetVideoDevice();
SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)device->internal;
const NSRect frame = [screen visibleFrame]; const NSRect frame = [screen visibleFrame];
rect->x = (int)frame.origin.x; 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->w = (int)frame.size.width;
rect->h = (int)frame.size.height; rect->h = (int)frame.size.height;
return true; return true;
@@ -493,14 +496,20 @@ static void Cocoa_DisplayReconfigurationCallback(CGDirectDisplayID displayid, CG
if (flags & kCGDisplayDesktopShapeChangedFlag) { if (flags & kCGDisplayDesktopShapeChangedFlag) {
SDL_UpdateDesktopBounds(); SDL_UpdateDesktopBounds();
} }
SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal;
data.mainDisplayHeight = CGDisplayPixelsHigh(kCGDirectMainDisplay);
} }
void Cocoa_InitModes(SDL_VideoDevice *_this) void Cocoa_InitModes(SDL_VideoDevice *_this)
{ {
@autoreleasepool { @autoreleasepool {
SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal;
CGDisplayErr result; CGDisplayErr result;
CGDisplayCount numDisplays = 0; CGDisplayCount numDisplays = 0;
data.mainDisplayHeight = CGDisplayPixelsHigh(kCGDirectMainDisplay);
result = CGGetOnlineDisplayList(0, NULL, &numDisplays); result = CGGetOnlineDisplayList(0, NULL, &numDisplays);
if (result != kCGErrorSuccess) { if (result != kCGErrorSuccess) {
CG_SetError("CGGetOnlineDisplayList()", result); CG_SetError("CGGetOnlineDisplayList()", result);
+5 -2
View File
@@ -409,9 +409,11 @@ static SDL_MouseButtonFlags Cocoa_GetGlobalMouseState(float *x, float *y)
const NSUInteger cocoaButtons = [NSEvent pressedMouseButtons]; const NSUInteger cocoaButtons = [NSEvent pressedMouseButtons];
const NSPoint cocoaLocation = [NSEvent mouseLocation]; const NSPoint cocoaLocation = [NSEvent mouseLocation];
SDL_MouseButtonFlags result = 0; SDL_MouseButtonFlags result = 0;
SDL_VideoDevice *device = SDL_GetVideoDevice();
SDL_CocoaVideoData *videodata = (__bridge SDL_CocoaVideoData *)device->internal;
*x = cocoaLocation.x; *x = cocoaLocation.x;
*y = (CGDisplayPixelsHigh(kCGDirectMainDisplay) - cocoaLocation.y); *y = (videodata.mainDisplayHeight - cocoaLocation.y);
result |= (cocoaButtons & (1 << 0)) ? SDL_BUTTON_LMASK : 0; result |= (cocoaButtons & (1 << 0)) ? SDL_BUTTON_LMASK : 0;
result |= (cocoaButtons & (1 << 1)) ? SDL_BUTTON_RMASK : 0; result |= (cocoaButtons & (1 << 1)) ? SDL_BUTTON_RMASK : 0;
@@ -600,8 +602,9 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event)
deltaY = [event deltaY]; deltaY = [event deltaY];
if (seenWarp) { if (seenWarp) {
SDL_CocoaVideoData *videodata = (__bridge SDL_CocoaVideoData *)_this->internal;
deltaX += (lastMoveX - data->lastWarpX); 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); DLog("Motion was (%g, %g), offset to (%g, %g)", [event deltaX], [event deltaY], deltaX, deltaY);
} }
+1
View File
@@ -62,6 +62,7 @@ typedef enum
@property(nonatomic) IOPMAssertionID screensaver_assertion; @property(nonatomic) IOPMAssertionID screensaver_assertion;
@property(nonatomic) SDL_Mutex *swaplock; @property(nonatomic) SDL_Mutex *swaplock;
@property(nonatomic) OptionAsAlt option_as_alt; @property(nonatomic) OptionAsAlt option_as_alt;
@property(nonatomic) CGFloat mainDisplayHeight;
@end @end
// Utility functions // Utility functions
+4 -2
View File
@@ -507,7 +507,8 @@ static NSScreen *ScreenForRect(const NSRect *rect)
static void ConvertNSRect(NSRect *r) 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) static void ScheduleContextUpdates(SDL_CocoaWindowData *data)
@@ -2249,12 +2250,13 @@ static void Cocoa_UpdateMouseFocus()
} }
*stop = YES; *stop = YES;
if (sdlwindow) { if (sdlwindow) {
SDL_CocoaVideoData *videodata = (__bridge SDL_CocoaVideoData *)vid->internal;
int wx, wy; int wx, wy;
SDL_RelativeToGlobalForWindow(sdlwindow, sdlwindow->x, sdlwindow->y, &wx, &wy); SDL_RelativeToGlobalForWindow(sdlwindow, sdlwindow->x, sdlwindow->y, &wx, &wy);
// Calculate the cursor coordinates relative to the window. // Calculate the cursor coordinates relative to the window.
const float dx = mouseLocation.x - wx; 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); SDL_SendMouseMotion(0, sdlwindow, SDL_GLOBAL_MOUSE_ID, false, dx, dy);
} }
} }