forked from AuroraMiddleware/gtk
wayland: fill in refresh_interval in GdkFrameTimings
Track the outputs that a window is on, and use the refresh rate from a random one of those outputs for the refresh_interval in GdkFrameTimings. https://bugzilla.gnome.org/show_bug.cgi?id=698864
This commit is contained in:
parent
f1ce727b06
commit
23031defde
@ -164,6 +164,8 @@ void _gdk_wayland_screen_add_output (GdkScreen *screen,
|
||||
struct wl_output *output);
|
||||
void _gdk_wayland_screen_remove_output (GdkScreen *screen,
|
||||
guint32 id);
|
||||
int _gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
|
||||
struct wl_output *output);
|
||||
|
||||
void _gdk_wayland_display_manager_add_display (GdkDisplayManager *manager,
|
||||
GdkDisplay *display);
|
||||
|
@ -87,6 +87,7 @@ struct _GdkWaylandMonitor
|
||||
int height_mm;
|
||||
char * output_name;
|
||||
char * manufacturer;
|
||||
int refresh_rate;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
|
||||
@ -917,6 +918,7 @@ output_handle_mode(void *data,
|
||||
|
||||
monitor->geometry.width = width;
|
||||
monitor->geometry.height = height;
|
||||
monitor->refresh_rate = refresh;
|
||||
|
||||
g_signal_emit_by_name (monitor->screen, "monitors-changed");
|
||||
update_screen_size (monitor->screen);
|
||||
@ -965,3 +967,21 @@ _gdk_wayland_screen_remove_output (GdkScreen *screen,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
_gdk_wayland_screen_get_output_refresh_rate (GdkScreen *screen,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < screen_wayland->monitors->len; i++)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
|
||||
|
||||
if (monitor->output == output)
|
||||
return monitor->refresh_rate;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -96,6 +96,9 @@ struct _GdkWindowImplWayland
|
||||
|
||||
GdkCursor *cursor;
|
||||
|
||||
/* The wl_outputs that this window currently touches */
|
||||
GSList *outputs;
|
||||
|
||||
struct wl_surface *surface;
|
||||
struct wl_shell_surface *shell_surface;
|
||||
unsigned int mapped : 1;
|
||||
@ -267,6 +270,7 @@ frame_callback (void *data,
|
||||
{
|
||||
GdkWindow *window = data;
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
|
||||
GdkFrameClock *clock = gdk_window_get_frame_clock (window);
|
||||
GdkFrameTimings *timings;
|
||||
|
||||
@ -279,6 +283,17 @@ frame_callback (void *data,
|
||||
if (timings == NULL)
|
||||
return;
|
||||
|
||||
timings->refresh_interval = 16667; /* default to 1/60th of a second */
|
||||
if (impl->outputs)
|
||||
{
|
||||
/* We pick a random output out of the outputs that the window touches
|
||||
* The rate here is in milli-hertz */
|
||||
int refresh_rate = _gdk_wayland_screen_get_output_refresh_rate (wayland_display->screen,
|
||||
impl->outputs->data);
|
||||
if (refresh_rate != 0)
|
||||
timings->refresh_interval = G_GINT64_CONSTANT(1000000000) / refresh_rate;
|
||||
}
|
||||
|
||||
timings->complete = TRUE;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
@ -712,6 +727,28 @@ gdk_wayland_window_map (GdkWindow *window)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
surface_enter (void *data,
|
||||
struct wl_surface *wl_surface,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWindow *window = GDK_WINDOW (data);
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
impl->outputs = g_slist_prepend (impl->outputs, output);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_leave (void *data,
|
||||
struct wl_surface *wl_surface,
|
||||
struct wl_output *output)
|
||||
{
|
||||
GdkWindow *window = GDK_WINDOW (data);
|
||||
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
|
||||
|
||||
impl->outputs = g_slist_remove (impl->outputs, output);
|
||||
}
|
||||
|
||||
static void
|
||||
shell_surface_handle_configure(void *data,
|
||||
struct wl_shell_surface *shell_surface,
|
||||
@ -760,6 +797,11 @@ shell_surface_ping (void *data,
|
||||
wl_shell_surface_pong(shell_surface, serial);
|
||||
}
|
||||
|
||||
static const struct wl_surface_listener surface_listener = {
|
||||
surface_enter,
|
||||
surface_leave
|
||||
};
|
||||
|
||||
static const struct wl_shell_surface_listener shell_surface_listener = {
|
||||
shell_surface_ping,
|
||||
shell_surface_handle_configure,
|
||||
@ -775,6 +817,8 @@ gdk_wayland_window_create_surface (GdkWindow *window)
|
||||
impl->surface = wl_compositor_create_surface (display_wayland->compositor);
|
||||
|
||||
wl_surface_set_user_data(impl->surface, window);
|
||||
wl_surface_add_listener(impl->surface,
|
||||
&surface_listener, window);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -838,6 +882,9 @@ gdk_wayland_window_hide_surface (GdkWindow *window,
|
||||
{
|
||||
wl_surface_destroy(impl->surface);
|
||||
impl->surface = NULL;
|
||||
|
||||
g_slist_free (impl->outputs);
|
||||
impl->outputs = NULL;
|
||||
}
|
||||
impl->shell_surface = NULL;
|
||||
cairo_surface_destroy(impl->server_surface);
|
||||
|
Loading…
Reference in New Issue
Block a user