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
This commit is contained in:
Jonas Ådahl 2020-02-21 12:06:28 +01:00 committed by Florian Müllner
parent 79920d66d4
commit 227eea1e31
12 changed files with 133 additions and 8 deletions

View File

@ -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 */

View File

@ -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;

View File

@ -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)
{

View File

@ -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,

View File

@ -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;
}

View File

@ -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,

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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,

View File

@ -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 */

View File

@ -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;