[mutter] kms-impl-simple: Add fake cursor planes if no real ones



commit 227eea1e31d98af9896d58bc50fd4135785604ee
Author: Jonas Ådahl <jadahl gmail com>
Date:   Fri Feb 21 12:06:28 2020 +0100

    kms-impl-simple: Add fake cursor planes if no real ones
    
    Non-atomic drivers may support drmModeSetCursor() even if no cursor
    plane is advertised. To deal with this, add a fake cursor plane for
    every CRTC when using MetaKmsImplSimple. This will eventually be
    translated to drmModeSetCursor() calls without any explicit cursor plane
    usage.
    
    Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1058
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/1079

 src/backends/native/meta-kms-device-private.h |  4 +++
 src/backends/native/meta-kms-device.c         | 16 ++++++++++
 src/backends/native/meta-kms-impl-device.c    | 13 ++++++++
 src/backends/native/meta-kms-impl-device.h    |  4 +++
 src/backends/native/meta-kms-impl-simple.c    | 22 +++++++++++++
 src/backends/native/meta-kms-impl.c           |  7 +++++
 src/backends/native/meta-kms-impl.h           |  5 +++
 src/backends/native/meta-kms-plane-private.h  |  4 +++
 src/backends/native/meta-kms-plane.c          | 45 +++++++++++++++++++++++----
 src/backends/native/meta-kms-plane.h          |  4 +--
 src/backends/native/meta-kms-types.h          |  2 ++
 src/backends/native/meta-kms.c                | 15 +++++++++
 12 files changed, 133 insertions(+), 8 deletions(-)
---
diff --git a/src/backends/native/meta-kms-device-private.h b/src/backends/native/meta-kms-device-private.h
index 876fb30fc..41e05a2f7 100644
--- a/src/backends/native/meta-kms-device-private.h
+++ b/src/backends/native/meta-kms-device-private.h
@@ -29,4 +29,8 @@ void meta_kms_device_update_states_in_impl (MetaKmsDevice *device);
 void meta_kms_device_predict_states_in_impl (MetaKmsDevice *device,
                                              MetaKmsUpdate *update);
 
+void meta_kms_device_add_fake_plane_in_impl (MetaKmsDevice    *device,
+                                             MetaKmsPlaneType  plane_type,
+                                             MetaKmsCrtc      *crtc);
+
 #endif /* META_KMS_DEVICE_PRIVATE_H */
diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c
index c9a54952b..a31dce8bd 100644
--- a/src/backends/native/meta-kms-device.c
+++ b/src/backends/native/meta-kms-device.c
@@ -221,6 +221,22 @@ meta_kms_device_dispatch_sync (MetaKmsDevice  *device,
   return meta_kms_flush_callbacks (device->kms);
 }
 
+void
+meta_kms_device_add_fake_plane_in_impl (MetaKmsDevice    *device,
+                                        MetaKmsPlaneType  plane_type,
+                                        MetaKmsCrtc      *crtc)
+{
+  MetaKmsImplDevice *impl_device = device->impl_device;
+  MetaKmsPlane *plane;
+
+  meta_assert_in_kms_impl (device->kms);
+
+  plane = meta_kms_impl_device_add_fake_plane (impl_device,
+                                               plane_type,
+                                               crtc);
+  device->planes = g_list_append (device->planes, plane);
+}
+
 typedef struct _CreateImplDeviceData
 {
   MetaKmsDevice *device;
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
index b35b19e55..e4f10d66e 100644
--- a/src/backends/native/meta-kms-impl-device.c
+++ b/src/backends/native/meta-kms-impl-device.c
@@ -298,6 +298,19 @@ get_plane_type (MetaKmsImplDevice       *impl_device,
     }
 }
 
+MetaKmsPlane *
+meta_kms_impl_device_add_fake_plane (MetaKmsImplDevice *impl_device,
+                                     MetaKmsPlaneType   plane_type,
+                                     MetaKmsCrtc       *crtc)
+{
+  MetaKmsPlane *plane;
+
+  plane = meta_kms_plane_new_fake (plane_type, crtc);
+  impl_device->planes = g_list_append (impl_device->planes, plane);
+
+  return plane;
+}
+
 static void
 init_planes (MetaKmsImplDevice *impl_device)
 {
diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h
index fba0fdb69..e8c08f19f 100644
--- a/src/backends/native/meta-kms-impl-device.h
+++ b/src/backends/native/meta-kms-impl-device.h
@@ -67,6 +67,10 @@ void meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device);
 void meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device,
                                           MetaKmsUpdate     *update);
 
+MetaKmsPlane * meta_kms_impl_device_add_fake_plane (MetaKmsImplDevice *impl_device,
+                                                    MetaKmsPlaneType   plane_type,
+                                                    MetaKmsCrtc       *crtc);
+
 int meta_kms_impl_device_close (MetaKmsImplDevice *impl_device);
 
 MetaKmsImplDevice * meta_kms_impl_device_new (MetaKmsDevice  *device,
diff --git a/src/backends/native/meta-kms-impl-simple.c b/src/backends/native/meta-kms-impl-simple.c
index 2b6df146a..1bb84538c 100644
--- a/src/backends/native/meta-kms-impl-simple.c
+++ b/src/backends/native/meta-kms-impl-simple.c
@@ -1018,6 +1018,27 @@ meta_kms_impl_simple_dispatch_idle (MetaKmsImpl *impl)
     mode_set_fallback_feedback_idle (impl_simple);
 }
 
+static void
+meta_kms_impl_simple_notify_device_created (MetaKmsImpl   *impl,
+                                            MetaKmsDevice *device)
+{
+  GList *l;
+
+  for (l = meta_kms_device_get_crtcs (device); l; l = l->next)
+    {
+      MetaKmsCrtc *crtc = l->data;
+      MetaKmsPlane *plane;
+
+      plane = meta_kms_device_get_cursor_plane_for (device, crtc);
+      if (plane)
+        continue;
+
+      meta_kms_device_add_fake_plane_in_impl (device,
+                                              META_KMS_PLANE_TYPE_CURSOR,
+                                              crtc);
+    }
+}
+
 static void
 meta_kms_impl_simple_finalize (GObject *object)
 {
@@ -1058,4 +1079,5 @@ meta_kms_impl_simple_class_init (MetaKmsImplSimpleClass *klass)
   impl_class->handle_page_flip_callback = meta_kms_impl_simple_handle_page_flip_callback;
   impl_class->discard_pending_page_flips = meta_kms_impl_simple_discard_pending_page_flips;
   impl_class->dispatch_idle = meta_kms_impl_simple_dispatch_idle;
+  impl_class->notify_device_created = meta_kms_impl_simple_notify_device_created;
 }
diff --git a/src/backends/native/meta-kms-impl.c b/src/backends/native/meta-kms-impl.c
index 6bf3de745..055273d5c 100644
--- a/src/backends/native/meta-kms-impl.c
+++ b/src/backends/native/meta-kms-impl.c
@@ -71,6 +71,13 @@ meta_kms_impl_dispatch_idle (MetaKmsImpl *impl)
   META_KMS_IMPL_GET_CLASS (impl)->dispatch_idle (impl);
 }
 
+void
+meta_kms_impl_notify_device_created (MetaKmsImpl   *impl,
+                                     MetaKmsDevice *device)
+{
+  META_KMS_IMPL_GET_CLASS (impl)->notify_device_created (impl, device);
+}
+
 static void
 meta_kms_impl_set_property (GObject      *object,
                             guint         prop_id,
diff --git a/src/backends/native/meta-kms-impl.h b/src/backends/native/meta-kms-impl.h
index f16cff4be..80ec8a5c2 100644
--- a/src/backends/native/meta-kms-impl.h
+++ b/src/backends/native/meta-kms-impl.h
@@ -39,6 +39,8 @@ struct _MetaKmsImplClass
                                       MetaKmsPageFlipData *page_flip_data);
   void (* discard_pending_page_flips) (MetaKmsImpl *impl);
   void (* dispatch_idle) (MetaKmsImpl *impl);
+  void (* notify_device_created) (MetaKmsImpl   *impl,
+                                  MetaKmsDevice *impl_device);
 };
 
 MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl);
@@ -53,4 +55,7 @@ void meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl);
 
 void meta_kms_impl_dispatch_idle (MetaKmsImpl *impl);
 
+void meta_kms_impl_notify_device_created (MetaKmsImpl   *impl,
+                                          MetaKmsDevice *impl_device);
+
 #endif /* META_KMS_IMPL_H */
diff --git a/src/backends/native/meta-kms-plane-private.h b/src/backends/native/meta-kms-plane-private.h
index 741c05f4d..2a36d4917 100644
--- a/src/backends/native/meta-kms-plane-private.h
+++ b/src/backends/native/meta-kms-plane-private.h
@@ -30,4 +30,8 @@ MetaKmsPlane * meta_kms_plane_new (MetaKmsPlaneType         type,
                                    MetaKmsImplDevice       *impl_device,
                                    drmModePlane            *drm_plane,
                                    drmModeObjectProperties *drm_plane_props);
+
+MetaKmsPlane * meta_kms_plane_new_fake (MetaKmsPlaneType  type,
+                                        MetaKmsCrtc      *crtc);
+
 #endif /* META_KMS_PLANE_PRIVATE_H */
diff --git a/src/backends/native/meta-kms-plane.c b/src/backends/native/meta-kms-plane.c
index 4eb75f290..152077036 100644
--- a/src/backends/native/meta-kms-plane.c
+++ b/src/backends/native/meta-kms-plane.c
@@ -35,6 +35,8 @@ struct _MetaKmsPlane
   GObject parent;
 
   MetaKmsPlaneType type;
+  gboolean is_fake;
+
   uint32_t id;
 
   uint32_t possible_crtcs;
@@ -64,6 +66,8 @@ meta_kms_plane_get_device (MetaKmsPlane *plane)
 uint32_t
 meta_kms_plane_get_id (MetaKmsPlane *plane)
 {
+  g_return_val_if_fail (!plane->is_fake, 0);
+
   return plane->id;
 }
 
@@ -332,12 +336,6 @@ init_formats (MetaKmsPlane            *plane,
   drmModePropertyPtr prop;
   int idx;
 
-  plane->formats_modifiers =
-    g_hash_table_new_full (g_direct_hash,
-                           g_direct_equal,
-                           NULL,
-                           (GDestroyNotify) free_modifier_array);
-
   prop = meta_kms_impl_device_find_property (impl_device, drm_plane_props,
                                              "IN_FORMATS", &idx);
   if (prop)
@@ -385,6 +383,36 @@ meta_kms_plane_new (MetaKmsPlaneType         type,
   return plane;
 }
 
+MetaKmsPlane *
+meta_kms_plane_new_fake (MetaKmsPlaneType  type,
+                         MetaKmsCrtc      *crtc)
+{
+  MetaKmsPlane *plane;
+
+  static const uint32_t fake_plane_drm_formats[] =
+    {
+      DRM_FORMAT_XRGB8888,
+      DRM_FORMAT_ARGB8888,
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+      /* OpenGL GL_RGBA, GL_UNSIGNED_BYTE format, hopefully supported */
+      DRM_FORMAT_XBGR8888,
+      DRM_FORMAT_ABGR8888
+#endif
+    };
+
+  plane = g_object_new (META_TYPE_KMS_PLANE, NULL);
+  plane->type = type;
+  plane->is_fake = TRUE;
+  plane->possible_crtcs = 1 << meta_kms_crtc_get_idx (crtc);
+  plane->device = meta_kms_crtc_get_device (crtc);
+
+  set_formats_from_array (plane,
+                          fake_plane_drm_formats,
+                          G_N_ELEMENTS (fake_plane_drm_formats));
+
+  return plane;
+}
+
 static void
 meta_kms_plane_finalize (GObject *object)
 {
@@ -398,6 +426,11 @@ meta_kms_plane_finalize (GObject *object)
 static void
 meta_kms_plane_init (MetaKmsPlane *plane)
 {
+  plane->formats_modifiers =
+    g_hash_table_new_full (g_direct_hash,
+                           g_direct_equal,
+                           NULL,
+                           (GDestroyNotify) free_modifier_array);
 }
 
 static void
diff --git a/src/backends/native/meta-kms-plane.h b/src/backends/native/meta-kms-plane.h
index aaa1790a6..941c16680 100644
--- a/src/backends/native/meta-kms-plane.h
+++ b/src/backends/native/meta-kms-plane.h
@@ -27,12 +27,12 @@
 #include "backends/native/meta-kms-types.h"
 #include "backends/meta-monitor-transform.h"
 
-typedef enum _MetaKmsPlaneType
+enum _MetaKmsPlaneType
 {
   META_KMS_PLANE_TYPE_PRIMARY,
   META_KMS_PLANE_TYPE_CURSOR,
   META_KMS_PLANE_TYPE_OVERLAY,
-} MetaKmsPlaneType;
+};
 
 #define META_TYPE_KMS_PLANE meta_kms_plane_get_type ()
 G_DECLARE_FINAL_TYPE (MetaKmsPlane, meta_kms_plane,
diff --git a/src/backends/native/meta-kms-types.h b/src/backends/native/meta-kms-types.h
index 4685ba7cc..ec36d226a 100644
--- a/src/backends/native/meta-kms-types.h
+++ b/src/backends/native/meta-kms-types.h
@@ -58,4 +58,6 @@ typedef enum _MetaKmsDeviceFlag
   META_KMS_DEVICE_FLAG_PLATFORM_DEVICE = 1 << 1,
 } MetaKmsDeviceFlag;
 
+typedef enum _MetaKmsPlaneType MetaKmsPlaneType;
+
 #endif /* META_KMS_IMPL_TYPES_H */
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
index 14331918e..e542d6257 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
@@ -530,6 +530,18 @@ meta_kms_get_backend (MetaKms *kms)
   return kms->backend;
 }
 
+static gpointer
+notify_device_created_in_impl (MetaKmsImpl  *impl,
+                               gpointer      user_data,
+                               GError      **error)
+{
+  MetaKmsDevice *device = user_data;
+
+  meta_kms_impl_notify_device_created (impl, device);
+
+  return GINT_TO_POINTER (TRUE);
+}
+
 MetaKmsDevice *
 meta_kms_create_device (MetaKms            *kms,
                         const char         *path,
@@ -542,6 +554,9 @@ meta_kms_create_device (MetaKms            *kms,
   if (!device)
     return NULL;
 
+  meta_kms_run_impl_task_sync (kms, notify_device_created_in_impl,
+                               device, NULL);
+
   kms->devices = g_list_append (kms->devices, device);
 
   return device;


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