[gtk+] wayland: fill in refresh_interval in GdkFrameTimings
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] wayland: fill in refresh_interval in GdkFrameTimings
- Date: Thu, 25 Apr 2013 17:56:13 +0000 (UTC)
commit 23031defde16e7f3dec2744b6c7c5e2033036135
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Thu Apr 25 11:19:31 2013 -0400
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
gdk/wayland/gdkprivate-wayland.h | 2 +
gdk/wayland/gdkscreen-wayland.c | 20 ++++++++++++++++
gdk/wayland/gdkwindow-wayland.c | 47 ++++++++++++++++++++++++++++++++++++++
3 files changed, 69 insertions(+), 0 deletions(-)
---
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index 5ce3deb..7aefedb 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -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);
diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c
index 7153eaf..5d621bb 100644
--- a/gdk/wayland/gdkscreen-wayland.c
+++ b/gdk/wayland/gdkscreen-wayland.c
@@ -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;
+}
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index e1a490e..32c23e7 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -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
@@ -713,6 +728,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,
uint32_t edges,
@@ -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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]