forked from AuroraMiddleware/gtk
macos: use video mode for refresh rate and interval
Using the mode allows better detection of refresh rate and refresh interval for the CVDisplayLink bridge to GdkFrameClock. Using it can help ensure that our 144hz displays can actually reach that rather than falling back to just 60hz. This will also need future commits to rework the displaylink source to be per-monitor.
This commit is contained in:
parent
48c650c102
commit
df2fb3b520
@ -65,7 +65,7 @@ gdk_display_link_source_dispatch (GSource *source,
|
||||
|
||||
impl->needs_dispatch = FALSE;
|
||||
|
||||
if (callback != NULL)
|
||||
if (!impl->paused && callback != NULL)
|
||||
ret = callback (user_data);
|
||||
|
||||
return ret;
|
||||
@ -76,7 +76,9 @@ gdk_display_link_source_finalize (GSource *source)
|
||||
{
|
||||
GdkDisplayLinkSource *impl = (GdkDisplayLinkSource *)source;
|
||||
|
||||
CVDisplayLinkStop (impl->display_link);
|
||||
if (!impl->paused)
|
||||
CVDisplayLinkStop (impl->display_link);
|
||||
|
||||
CVDisplayLinkRelease (impl->display_link);
|
||||
}
|
||||
|
||||
@ -90,12 +92,18 @@ static GSourceFuncs gdk_display_link_source_funcs = {
|
||||
void
|
||||
gdk_display_link_source_pause (GdkDisplayLinkSource *source)
|
||||
{
|
||||
g_return_if_fail (source->paused == FALSE);
|
||||
|
||||
source->paused = TRUE;
|
||||
CVDisplayLinkStop (source->display_link);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_link_source_unpause (GdkDisplayLinkSource *source)
|
||||
{
|
||||
g_return_if_fail (source->paused == TRUE);
|
||||
|
||||
source->paused = FALSE;
|
||||
CVDisplayLinkStart (source->display_link);
|
||||
}
|
||||
|
||||
@ -160,16 +168,16 @@ gdk_display_link_source_frame_cb (CVDisplayLinkRef display_link,
|
||||
* Returns: (transfer full): A newly created `GSource`
|
||||
*/
|
||||
GSource *
|
||||
gdk_display_link_source_new (CGDirectDisplayID display_id)
|
||||
gdk_display_link_source_new (CGDirectDisplayID display_id,
|
||||
CGDisplayModeRef mode)
|
||||
{
|
||||
GdkDisplayLinkSource *impl;
|
||||
GSource *source;
|
||||
CVReturn ret;
|
||||
double period;
|
||||
|
||||
source = g_source_new (&gdk_display_link_source_funcs, sizeof *impl);
|
||||
impl = (GdkDisplayLinkSource *)source;
|
||||
impl->display_id = display_id;
|
||||
impl->paused = TRUE;
|
||||
|
||||
/* Create DisplayLink for timing information for the display in
|
||||
* question so that we can produce graphics for that display at whatever
|
||||
@ -178,21 +186,34 @@ gdk_display_link_source_new (CGDirectDisplayID display_id)
|
||||
if (CVDisplayLinkCreateWithCGDisplay (display_id, &impl->display_link) != kCVReturnSuccess)
|
||||
{
|
||||
g_warning ("Failed to initialize CVDisplayLink!");
|
||||
return source;
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine our nominal period between frames.
|
||||
*/
|
||||
period = CVDisplayLinkGetActualOutputVideoRefreshPeriod (impl->display_link);
|
||||
if (period == 0.0)
|
||||
period = 1.0 / 60.0;
|
||||
impl->refresh_interval = period * 1000000L;
|
||||
impl->refresh_rate = 1.0 / period * 1000L;
|
||||
impl->refresh_rate = CGDisplayModeGetRefreshRate (mode) * 1000.0;
|
||||
|
||||
/*
|
||||
* Wire up our callback to be executed within the high-priority thread.
|
||||
*/
|
||||
if (impl->refresh_rate == 0)
|
||||
{
|
||||
const CVTime time = CVDisplayLinkGetNominalOutputVideoRefreshPeriod (impl->display_link);
|
||||
if (!(time.flags & kCVTimeIsIndefinite))
|
||||
impl->refresh_rate = (double)time.timeScale / (double)time.timeValue * 1000.0;
|
||||
}
|
||||
|
||||
if (impl->refresh_rate != 0)
|
||||
{
|
||||
impl->refresh_interval = 1000000.0 / (double)impl->refresh_rate * 1000.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
double period = CVDisplayLinkGetActualOutputVideoRefreshPeriod (impl->display_link);
|
||||
|
||||
if (period == 0.0)
|
||||
period = 1.0 / 60.0;
|
||||
|
||||
impl->refresh_rate = 1.0 / period * 1000L;
|
||||
impl->refresh_interval = period * 1000000L;
|
||||
}
|
||||
|
||||
/* Wire up our callback to be executed within the high-priority thread. */
|
||||
CVDisplayLinkSetOutputCallback (impl->display_link,
|
||||
gdk_display_link_source_frame_cb,
|
||||
source);
|
||||
@ -200,6 +221,10 @@ gdk_display_link_source_new (CGDirectDisplayID display_id)
|
||||
g_source_set_static_name (source, "[gdk] quartz frame clock");
|
||||
|
||||
return source;
|
||||
|
||||
failure:
|
||||
g_source_unref (source);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gint64
|
||||
|
@ -36,12 +36,14 @@ typedef struct
|
||||
CVDisplayLinkRef display_link;
|
||||
gint64 refresh_interval;
|
||||
guint refresh_rate;
|
||||
guint paused : 1;
|
||||
|
||||
volatile gint64 presentation_time;
|
||||
volatile guint needs_dispatch;
|
||||
} GdkDisplayLinkSource;
|
||||
|
||||
GSource *gdk_display_link_source_new (CGDirectDisplayID display_id);
|
||||
GSource *gdk_display_link_source_new (CGDirectDisplayID display_id,
|
||||
CGDisplayModeRef mode);
|
||||
void gdk_display_link_source_pause (GdkDisplayLinkSource *source);
|
||||
void gdk_display_link_source_unpause (GdkDisplayLinkSource *source);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user