Parcourir la source

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.
Qiu Qiang il y a 2 mois
Parent
commit
3ee8d1406c

+ 10 - 1
src/video/cocoa/SDL_cocoamodes.m

@@ -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
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 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 - 0
src/video/cocoa/SDL_cocoavideo.h

@@ -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
src/video/cocoa/SDL_cocoawindow.m

@@ -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);
                                   }
                                   }
                               }
                               }