[mutter] cursor-renderer: Rewrite HW cursors to be cleaner



commit a1ba480c8a19911ae0dd80d2dae75e315ab392a6
Author: Jasper St. Pierre <jstpierre mecheye net>
Date:   Tue Apr 22 15:39:09 2014 -0400

    cursor-renderer: Rewrite HW cursors to be cleaner

 src/backends/meta-cursor-renderer.c |  149 +++++++++++++---------------------
 src/backends/meta-monitor-manager.h |    4 +-
 2 files changed, 59 insertions(+), 94 deletions(-)
---
diff --git a/src/backends/meta-cursor-renderer.c b/src/backends/meta-cursor-renderer.c
index a92254b..767780b 100644
--- a/src/backends/meta-cursor-renderer.c
+++ b/src/backends/meta-cursor-renderer.c
@@ -54,21 +54,26 @@ typedef struct _MetaCursorRendererPrivate MetaCursorRendererPrivate;
 G_DEFINE_TYPE_WITH_PRIVATE (MetaCursorRenderer, meta_cursor_renderer, G_TYPE_OBJECT);
 
 static void
-set_crtc_has_hw_cursor (MetaCursorRenderer *renderer,
-                        MetaCRTC           *crtc,
-                        gboolean            has)
+set_crtc_cursor (MetaCursorRenderer  *renderer,
+                 MetaCRTC            *crtc,
+                 MetaCursorReference *cursor,
+                 gboolean             force)
 {
   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
 
-  if (has)
+  if (crtc->cursor == cursor && !force)
+    return;
+
+  crtc->cursor = cursor;
+
+  if (cursor)
     {
-      MetaCursorReference *displayed_cursor = priv->displayed_cursor;
       struct gbm_bo *bo;
       union gbm_bo_handle handle;
       int width, height;
       int hot_x, hot_y;
 
-      bo = meta_cursor_reference_get_gbm_bo (displayed_cursor, &hot_x, &hot_y);
+      bo = meta_cursor_reference_get_gbm_bo (cursor, &hot_x, &hot_y);
 
       handle = gbm_bo_get_handle (bo);
       width = gbm_bo_get_width (bo);
@@ -76,43 +81,60 @@ set_crtc_has_hw_cursor (MetaCursorRenderer *renderer,
 
       drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, handle.u32,
                          width, height, hot_x, hot_y);
-      crtc->has_hw_cursor = TRUE;
     }
   else
     {
       drmModeSetCursor2 (priv->drm_fd, crtc->crtc_id, 0, 0, 0, 0, 0);
-      crtc->has_hw_cursor = FALSE;
     }
 }
 
 static void
-on_monitors_changed (MetaMonitorManager *monitors,
-                     MetaCursorRenderer *renderer)
+update_hw_cursor (MetaCursorRenderer *renderer,
+                  gboolean            force)
 {
   MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
+  MetaRectangle *cursor_rect = &priv->current_rect;
+  MetaMonitorManager *monitors;
   MetaCRTC *crtcs;
   unsigned int i, n_crtcs;
 
-  if (!priv->has_hw_cursor)
-    return;
-
-  /* Go through the new list of monitors, find out where the cursor is */
+  monitors = meta_monitor_manager_get ();
   meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
 
   for (i = 0; i < n_crtcs; i++)
     {
-      MetaRectangle *rect = &crtcs[i].rect;
-      gboolean has;
+      gboolean crtc_should_have_cursor;
+      MetaCursorReference *cursor;
+      MetaRectangle *crtc_rect;
+
+      crtc_rect = &crtcs[i].rect;
 
-      has = meta_rectangle_overlap (&priv->current_rect, rect);
+      crtc_should_have_cursor = (priv->has_hw_cursor && meta_rectangle_overlap (cursor_rect, crtc_rect));
+      if (crtc_should_have_cursor)
+        cursor = priv->displayed_cursor;
+      else
+        cursor = NULL;
+
+      set_crtc_cursor (renderer, &crtcs[i], cursor, force);
 
-      /* Need to do it unconditionally here, our tracking is
-         wrong because we reloaded the CRTCs */
-      set_crtc_has_hw_cursor (renderer, &crtcs[i], has);
+      if (cursor)
+        {
+          drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
+                             cursor_rect->x - crtc_rect->x,
+                             cursor_rect->y - crtc_rect->y);
+        }
     }
 }
 
 static void
+on_monitors_changed (MetaMonitorManager *monitors,
+                     MetaCursorRenderer *renderer)
+{
+  /* Our tracking is all messed up, so force an update. */
+  update_hw_cursor (renderer, TRUE);
+}
+
+static void
 meta_cursor_renderer_finalize (GObject *object)
 {
   MetaCursorRenderer *renderer = META_CURSOR_RENDERER (object);
@@ -153,73 +175,6 @@ meta_cursor_renderer_init (MetaCursorRenderer *renderer)
 #endif
 }
 
-static gboolean
-should_have_hw_cursor (MetaCursorRenderer *renderer)
-{
-  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
-
-  if (priv->displayed_cursor)
-    return (meta_cursor_reference_get_gbm_bo (priv->displayed_cursor, NULL, NULL) != NULL);
-  else
-    return FALSE;
-}
-
-static void
-update_hw_cursor (MetaCursorRenderer *renderer)
-{
-  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
-  MetaMonitorManager *monitors;
-  MetaCRTC *crtcs;
-  unsigned int i, n_crtcs;
-  gboolean enabled;
-
-  enabled = should_have_hw_cursor (renderer);
-  priv->has_hw_cursor = enabled;
-
-  monitors = meta_monitor_manager_get ();
-  meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
-
-  for (i = 0; i < n_crtcs; i++)
-    {
-      MetaRectangle *rect = &crtcs[i].rect;
-      gboolean has;
-
-      has = enabled && meta_rectangle_overlap (&priv->current_rect, rect);
-
-      if (has || crtcs[i].has_hw_cursor)
-        set_crtc_has_hw_cursor (renderer, &crtcs[i], has);
-    }
-}
-
-static void
-move_hw_cursor (MetaCursorRenderer *renderer)
-{
-  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
-  MetaMonitorManager *monitors;
-  MetaCRTC *crtcs;
-  unsigned int i, n_crtcs;
-
-  monitors = meta_monitor_manager_get ();
-  meta_monitor_manager_get_resources (monitors, NULL, NULL, &crtcs, &n_crtcs, NULL, NULL);
-
-  g_assert (priv->has_hw_cursor);
-
-  for (i = 0; i < n_crtcs; i++)
-    {
-      MetaRectangle *rect = &crtcs[i].rect;
-      gboolean has;
-
-      has = meta_rectangle_overlap (&priv->current_rect, rect);
-
-      if (has != crtcs[i].has_hw_cursor)
-        set_crtc_has_hw_cursor (renderer, &crtcs[i], has);
-      if (has)
-        drmModeMoveCursor (priv->drm_fd, crtcs[i].crtc_id,
-                           priv->current_rect.x - rect->x,
-                           priv->current_rect.y - rect->y);
-    }
-}
-
 static void
 queue_redraw (MetaCursorRenderer *renderer)
 {
@@ -242,6 +197,17 @@ queue_redraw (MetaCursorRenderer *renderer)
                          &priv->current_rect);
 }
 
+static gboolean
+should_have_hw_cursor (MetaCursorRenderer *renderer)
+{
+  MetaCursorRendererPrivate *priv = meta_cursor_renderer_get_instance_private (renderer);
+
+  if (priv->displayed_cursor)
+    return (meta_cursor_reference_get_gbm_bo (priv->displayed_cursor, NULL, NULL) != NULL);
+  else
+    return FALSE;
+}
+
 static void
 update_cursor (MetaCursorRenderer *renderer)
 {
@@ -269,11 +235,10 @@ update_cursor (MetaCursorRenderer *renderer)
 
   if (meta_is_wayland_compositor ())
     {
-      update_hw_cursor (renderer);
+      priv->has_hw_cursor = should_have_hw_cursor (renderer);
+      update_hw_cursor (renderer, FALSE);
 
-      if (priv->has_hw_cursor)
-        move_hw_cursor (renderer);
-      else
+      if (!priv->has_hw_cursor)
         queue_redraw (renderer);
     }
 }
@@ -316,7 +281,7 @@ meta_cursor_renderer_force_update (MetaCursorRenderer *renderer)
 {
   g_assert (meta_is_wayland_compositor ());
 
-  update_hw_cursor (renderer);
+  update_hw_cursor (renderer, TRUE);
 }
 
 struct gbm_device *
diff --git a/src/backends/meta-monitor-manager.h b/src/backends/meta-monitor-manager.h
index 7f7fa8f..5330954 100644
--- a/src/backends/meta-monitor-manager.h
+++ b/src/backends/meta-monitor-manager.h
@@ -46,6 +46,7 @@
 
 #include "meta-display-config-shared.h"
 #include "meta-dbus-display-config.h"
+#include "meta-cursor.h"
 
 typedef struct _MetaMonitorManagerClass    MetaMonitorManagerClass;
 typedef struct _MetaMonitorManager         MetaMonitorManager;
@@ -123,8 +124,7 @@ struct _MetaCRTC
   /* Used when changing configuration */
   gboolean is_dirty;
 
-  /* Updated by MetaCursorTracker */
-  gboolean has_hw_cursor;
+  MetaCursorReference *cursor;
 };
 
 struct _MetaMonitorMode


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]