ui/cocoa: Take refresh rate into account
authorAkihiko Odaki <akihiko.odaki@gmail.com>
Sat, 2 Jul 2022 14:25:19 +0000 (23:25 +0900)
committerPhilippe Mathieu-Daudé <f4bug@amsat.org>
Tue, 12 Jul 2022 22:06:02 +0000 (00:06 +0200)
Retrieve the refresh rate of the display and reflect it with
dpy_set_ui_info() and update_displaychangelistener(), allowing the
guest and DisplayChangeListener to consume the information.

The information will be used as a hint how often the display should
be updated. For example, when we run 30 Hz physical display updates
it is pointless for the guest to update the screen at 60Hz
frequency, the guest can spare some work instead.

Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-Id: <20220702142519.12188-1-akihiko.odaki@gmail.com>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
meson.build
ui/cocoa.m

index ad92d288a678c93409dde025e7ae7eb13ebc00c3..fea3566ea84bd3ee4ceec9a54cbd9a11152cdf19 100644 (file)
@@ -583,7 +583,8 @@ if get_option('attr').allowed()
   endif
 endif
 
-cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
+cocoa = dependency('appleframeworks', modules: ['Cocoa', 'CoreVideo'],
+                   required: get_option('cocoa'))
 if cocoa.found() and get_option('sdl').enabled()
   error('Cocoa and SDL cannot be enabled at the same time')
 endif
index e883c7466e2bea5e92e59c82ff8ea30ffd5d894e..5a8bd5dd84e0029170987cd759915e879da9e103 100644 (file)
@@ -561,8 +561,20 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
         CGDirectDisplayID display = [[description objectForKey:@"NSScreenNumber"] unsignedIntValue];
         NSSize screenSize = [[[self window] screen] frame].size;
         CGSize screenPhysicalSize = CGDisplayScreenSize(display);
+        CVDisplayLinkRef displayLink;
 
         frameSize = isFullscreen ? screenSize : [self frame].size;
+
+        if (!CVDisplayLinkCreateWithCGDisplay(display, &displayLink)) {
+            CVTime period = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(displayLink);
+            CVDisplayLinkRelease(displayLink);
+            if (!(period.flags & kCVTimeIsIndefinite)) {
+                update_displaychangelistener(&dcl,
+                                             1000 * period.timeValue / period.timeScale);
+                info.refresh_rate = (int64_t)1000 * period.timeScale / period.timeValue;
+            }
+        }
+
         info.width_mm = frameSize.width / screenSize.width * screenPhysicalSize.width;
         info.height_mm = frameSize.height / screenSize.height * screenPhysicalSize.height;
     } else {