[mutter] cursor-render/native: Realize hw cursor lazilly
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] cursor-render/native: Realize hw cursor lazilly
- Date: Fri, 15 Jun 2018 19:13:36 +0000 (UTC)
commit 516fb524cbabdb543dbde5ed8e87978651cc2ad8
Author: Jonas Ådahl <jadahl gmail com>
Date: Wed May 2 20:32:43 2018 +0200
cursor-render/native: Realize hw cursor lazilly
Where to realize a hardware cursor depends on where on the screen it
will be displayed. For example it only needs buffers for the cursor
plane on a certain GPU if it overlaps with a monitor that is connected
said GPU.
Previously, we were too eager with uploading the cursor plane buffers,
which in effect resulted in the secondary GPU always being woken up
when changing the cursor, even though the cursor plane would actually
never be set unless the pointer cursor was moved to a monitor connected
to the secondary GPU. These wake-ups caused noticable stuttering; thus
by uploading the buffers more lazilly, the stuttering is avoided.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/77
src/backends/native/meta-cursor-renderer-native.c | 176 ++++++++++++----------
1 file changed, 100 insertions(+), 76 deletions(-)
---
diff --git a/src/backends/native/meta-cursor-renderer-native.c
b/src/backends/native/meta-cursor-renderer-native.c
index 910eb10ec..81df57b1c 100644
--- a/src/backends/native/meta-cursor-renderer-native.c
+++ b/src/backends/native/meta-cursor-renderer-native.c
@@ -121,7 +121,8 @@ G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRendererNative, meta_cursor_renderer_nativ
static void
realize_cursor_sprite (MetaCursorRenderer *renderer,
- MetaCursorSprite *cursor_sprite);
+ MetaCursorSprite *cursor_sprite,
+ GList *gpus);
static MetaCursorNativeGpuState *
get_cursor_gpu_state (MetaCursorNativePrivate *cursor_priv,
@@ -575,19 +576,15 @@ can_draw_cursor_unscaled (MetaCursorRenderer *renderer,
static gboolean
should_have_hw_cursor (MetaCursorRenderer *renderer,
- MetaCursorSprite *cursor_sprite)
+ MetaCursorSprite *cursor_sprite,
+ GList *gpus)
{
- MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (native);
- GList *gpus;
GList *l;
CoglTexture *texture;
if (!cursor_sprite)
return FALSE;
- gpus = meta_monitor_manager_get_gpus (priv->monitor_manager);
for (l = gpus; l; l = l->next)
{
MetaGpuKms *gpu_kms = l->data;
@@ -670,6 +667,54 @@ maybe_schedule_cursor_sprite_animation_frame (MetaCursorRendererNative *native,
}
}
+static GList *
+calculate_cursor_sprite_gpus (MetaCursorRenderer *renderer,
+ MetaCursorSprite *cursor_sprite)
+{
+ MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
+ MetaCursorRendererNativePrivate *priv =
+ meta_cursor_renderer_native_get_instance_private (native);
+ MetaMonitorManager *monitor_manager = priv->monitor_manager;
+ GList *gpus = NULL;
+ GList *logical_monitors;
+ GList *l;
+ ClutterRect cursor_rect;
+
+ cursor_rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
+
+ logical_monitors =
+ meta_monitor_manager_get_logical_monitors (monitor_manager);
+ for (l = logical_monitors; l; l = l->next)
+ {
+ MetaLogicalMonitor *logical_monitor = l->data;
+ MetaRectangle logical_monitor_layout;
+ ClutterRect logical_monitor_rect;
+ GList *monitors, *l_mon;
+
+ logical_monitor_layout =
+ meta_logical_monitor_get_layout (logical_monitor);
+ logical_monitor_rect =
+ meta_rectangle_to_clutter_rect (&logical_monitor_layout);
+
+ if (!clutter_rect_intersection (&cursor_rect, &logical_monitor_rect,
+ NULL))
+ continue;
+
+ monitors = meta_logical_monitor_get_monitors (logical_monitor);
+ for (l_mon = monitors; l_mon; l_mon = l_mon->next)
+ {
+ MetaMonitor *monitor = l_mon->data;
+ MetaGpu *gpu;
+
+ gpu = meta_monitor_get_gpu (monitor);
+ if (!g_list_find (gpus, gpu))
+ gpus = g_list_prepend (gpus, gpu);
+ }
+ }
+
+ return gpus;
+}
+
static gboolean
meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
MetaCursorSprite *cursor_sprite)
@@ -677,13 +722,18 @@ meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (native);
+ g_autoptr (GList) gpus = NULL;
if (cursor_sprite)
- realize_cursor_sprite (renderer, cursor_sprite);
+ {
+ meta_cursor_sprite_realize_texture (cursor_sprite);
+ gpus = calculate_cursor_sprite_gpus (renderer, cursor_sprite);
+ realize_cursor_sprite (renderer, cursor_sprite, gpus);
+ }
maybe_schedule_cursor_sprite_animation_frame (native, cursor_sprite);
- priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite);
+ priv->has_hw_cursor = should_have_hw_cursor (renderer, cursor_sprite, gpus);
update_hw_cursor (native, cursor_sprite);
return (priv->has_hw_cursor ||
@@ -875,8 +925,7 @@ is_cursor_hw_state_valid (MetaCursorSprite *cursor_sprite,
static void
realize_cursor_sprite_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer,
MetaGpuKms *gpu_kms,
- MetaCursorSpriteWayland *sprite_wayland,
- struct wl_resource *buffer)
+ MetaCursorSpriteWayland *sprite_wayland)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_wayland);
@@ -885,6 +934,9 @@ realize_cursor_sprite_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer,
uint64_t cursor_width, cursor_height;
CoglTexture *texture;
uint width, height;
+ MetaWaylandBuffer *buffer;
+ struct wl_resource *buffer_resource;
+ struct wl_shm_buffer *shm_buffer;
cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
@@ -898,7 +950,15 @@ realize_cursor_sprite_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer,
width = cogl_texture_get_width (texture);
height = cogl_texture_get_height (texture);
- struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
+ buffer = meta_cursor_sprite_wayland_get_buffer (sprite_wayland);
+ if (!buffer)
+ return;
+
+ buffer_resource = meta_wayland_buffer_get_resource (buffer);
+ if (!buffer_resource)
+ return;
+
+ shm_buffer = wl_shm_buffer_get (buffer_resource);
if (shm_buffer)
{
int rowstride = wl_shm_buffer_get_stride (shm_buffer);
@@ -972,49 +1032,17 @@ realize_cursor_sprite_from_wl_buffer_for_gpu (MetaCursorRenderer *renderer,
set_pending_cursor_sprite_gbm_bo (cursor_sprite, gpu_kms, bo);
}
}
-
-static void
-realize_cursor_sprite_from_wl_buffer (MetaCursorRenderer *renderer,
- MetaCursorSpriteWayland *sprite_wayland)
-{
- MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (native);
- MetaWaylandBuffer *buffer;
- struct wl_resource *buffer_resource;
- GList *gpus;
- GList *l;
-
- buffer = meta_cursor_sprite_wayland_get_buffer (sprite_wayland);
- if (!buffer)
- return;
-
- buffer_resource = meta_wayland_buffer_get_resource (buffer);
- if (!buffer_resource)
- return;
-
- gpus = meta_monitor_manager_get_gpus (priv->monitor_manager);
- for (l = gpus; l; l = l->next)
- {
- MetaGpuKms *gpu_kms = l->data;
-
- realize_cursor_sprite_from_wl_buffer_for_gpu (renderer,
- gpu_kms,
- sprite_wayland,
- buffer_resource);
- }
-}
#endif
static void
realize_cursor_sprite_from_xcursor_for_gpu (MetaCursorRenderer *renderer,
MetaGpuKms *gpu_kms,
- MetaCursorSpriteXcursor *sprite_xcursor,
- XcursorImage *xc_image)
+ MetaCursorSpriteXcursor *sprite_xcursor)
{
MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
MetaCursorRendererNativeGpuData *cursor_renderer_gpu_data;
MetaCursorSprite *cursor_sprite = META_CURSOR_SPRITE (sprite_xcursor);
+ XcursorImage *xc_image;
cursor_renderer_gpu_data =
meta_cursor_renderer_native_gpu_data_from_gpu (gpu_kms);
@@ -1024,6 +1052,8 @@ realize_cursor_sprite_from_xcursor_for_gpu (MetaCursorRenderer *renderer,
if (is_cursor_hw_state_valid (cursor_sprite, gpu_kms))
return;
+ xc_image = meta_cursor_sprite_xcursor_get_current_image (sprite_xcursor);
+
load_cursor_sprite_gbm_buffer_for_gpu (native,
gpu_kms,
cursor_sprite,
@@ -1035,41 +1065,18 @@ realize_cursor_sprite_from_xcursor_for_gpu (MetaCursorRenderer *renderer,
}
static void
-realize_cursor_sprite_from_xcursor (MetaCursorRenderer *renderer,
- MetaCursorSpriteXcursor *sprite_xcursor)
-{
- MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
- MetaCursorRendererNativePrivate *priv =
- meta_cursor_renderer_native_get_instance_private (native);
- XcursorImage *xc_image;
- GList *gpus;
- GList *l;
-
- xc_image = meta_cursor_sprite_xcursor_get_current_image (sprite_xcursor);
- gpus = meta_monitor_manager_get_gpus (priv->monitor_manager);
- for (l = gpus; l; l = l->next)
- {
- MetaGpuKms *gpu_kms = l->data;
-
- realize_cursor_sprite_from_xcursor_for_gpu (renderer,
- gpu_kms,
- sprite_xcursor,
- xc_image);
- }
-}
-
-static void
-realize_cursor_sprite (MetaCursorRenderer *renderer,
- MetaCursorSprite *cursor_sprite)
+realize_cursor_sprite_for_gpu (MetaCursorRenderer *renderer,
+ MetaGpuKms *gpu_kms,
+ MetaCursorSprite *cursor_sprite)
{
- meta_cursor_sprite_realize_texture (cursor_sprite);
-
if (META_IS_CURSOR_SPRITE_XCURSOR (cursor_sprite))
{
MetaCursorSpriteXcursor *sprite_xcursor =
META_CURSOR_SPRITE_XCURSOR (cursor_sprite);
- realize_cursor_sprite_from_xcursor (renderer, sprite_xcursor);
+ realize_cursor_sprite_from_xcursor_for_gpu (renderer,
+ gpu_kms,
+ sprite_xcursor);
}
#ifdef HAVE_WAYLAND
else if (META_IS_CURSOR_SPRITE_WAYLAND (cursor_sprite))
@@ -1077,11 +1084,28 @@ realize_cursor_sprite (MetaCursorRenderer *renderer,
MetaCursorSpriteWayland *sprite_wayland =
META_CURSOR_SPRITE_WAYLAND (cursor_sprite);
- realize_cursor_sprite_from_wl_buffer (renderer, sprite_wayland);
+ realize_cursor_sprite_from_wl_buffer_for_gpu (renderer,
+ gpu_kms,
+ sprite_wayland);
}
#endif
}
+static void
+realize_cursor_sprite (MetaCursorRenderer *renderer,
+ MetaCursorSprite *cursor_sprite,
+ GList *gpus)
+{
+ GList *l;
+
+ for (l = gpus; l; l = l->next)
+ {
+ MetaGpuKms *gpu_kms = l->data;
+
+ realize_cursor_sprite_for_gpu (renderer, gpu_kms, cursor_sprite);
+ }
+}
+
static void
meta_cursor_renderer_native_class_init (MetaCursorRendererNativeClass *klass)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]