kms/device: Use device pool to open/close dri devices

This replaces the usage of MetaLauncher.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1828>
This commit is contained in:
Jonas Ådahl 2021-03-31 18:34:45 +02:00
parent ee8c252a8c
commit f3457b678c
3 changed files with 104 additions and 148 deletions

View File

@ -28,7 +28,8 @@
#include <sys/types.h>
#include <xf86drm.h>
#include "backends/native/meta-backend-native.h"
#include "backends/native/meta-backend-native-private.h"
#include "backends/native/meta-device-pool.h"
#include "backends/native/meta-kms-impl-device-atomic.h"
#include "backends/native/meta-kms-impl-device-dummy.h"
#include "backends/native/meta-kms-impl-device-simple.h"
@ -229,7 +230,7 @@ meta_kms_device_add_fake_plane_in_impl (MetaKmsDevice *device,
typedef struct _CreateImplDeviceData
{
MetaKmsDevice *device;
int fd;
MetaDeviceFile *device_file;
const char *path;
MetaKmsDeviceFlag flags;
@ -281,7 +282,7 @@ get_driver_info (int fd,
static MetaKmsImplDevice *
meta_create_kms_impl_device (MetaKmsDevice *device,
MetaKmsImpl *impl,
int fd,
MetaDeviceFile *device_file,
const char *path,
MetaKmsDeviceFlag flags,
GError **error)
@ -291,12 +292,13 @@ meta_create_kms_impl_device (MetaKmsDevice *device,
g_autofree char *driver_name = NULL;
g_autofree char *driver_description = NULL;
const char *atomic_kms_enable_env;
int impl_fd;
g_autofree char *impl_path = NULL;
int fd;
g_autoptr (MetaDeviceFile) impl_device_file = NULL;
MetaKmsImplDevice *impl_device;
meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl));
fd = meta_device_file_get_fd (device_file);
if (!get_driver_info (fd, &driver_name, &driver_description))
{
driver_name = g_strdup ("unknown");
@ -308,6 +310,7 @@ meta_create_kms_impl_device (MetaKmsDevice *device,
if (flags & META_KMS_DEVICE_FLAG_NO_MODE_SETTING)
{
g_autofree char *render_node_path = NULL;
MetaDevicePool *device_pool;
render_node_path = drmGetRenderDeviceNameFromFd (fd);
if (!render_node_path)
@ -318,19 +321,17 @@ meta_create_kms_impl_device (MetaKmsDevice *device,
return NULL;
}
impl_fd = open (render_node_path, O_RDWR | O_CLOEXEC, 0);
if (impl_fd == -1)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
"Failed to open render node '%s': %s",
render_node_path, g_strerror (errno));
return NULL;
}
device_pool = meta_device_file_get_pool (device_file);
impl_device_file = meta_device_pool_open (device_pool, render_node_path,
META_DEVICE_FILE_FLAG_NONE,
error);
if (!impl_device_file)
return NULL;
g_message ("Adding device '%s' (from '%s', %s) using no mode setting.",
render_node_path, path, driver_name);
impl_path = g_steal_pointer (&render_node_path);
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_DUMMY;
}
else if (atomic_kms_enable_env)
@ -355,8 +356,7 @@ meta_create_kms_impl_device (MetaKmsDevice *device,
atomic_kms_enable_env);
}
impl_fd = dup (fd);
impl_path = g_strdup (path);
impl_device_file = meta_device_file_acquire (device_file);
g_message ("Mode setting implementation for '%s' (%s) forced (%s).",
path, driver_name,
@ -368,8 +368,7 @@ meta_create_kms_impl_device (MetaKmsDevice *device,
g_message ("Adding device '%s' (%s) using non-atomic mode setting"
" (using atomic mode setting not allowed).",
path, driver_name);
impl_fd = dup (fd);
impl_path = g_strdup (path);
impl_device_file = meta_device_file_acquire (device_file);
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_SIMPLE;
}
else
@ -395,26 +394,19 @@ meta_create_kms_impl_device (MetaKmsDevice *device,
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_SIMPLE;
}
impl_fd = dup (fd);
impl_path = g_strdup (path);
impl_device_file = meta_device_file_acquire (device_file);
}
impl_device = g_initable_new (impl_device_type, NULL, error,
"device", device,
"impl", impl,
"fd", impl_fd,
"path", impl_path,
"device-file", impl_device_file,
"flags", flags,
"driver-name", driver_name,
"driver-description", driver_description,
NULL);
if (!impl_device)
{
close (impl_fd);
return NULL;
}
close (fd);
return NULL;
return impl_device;
}
@ -429,7 +421,7 @@ create_impl_device_in_impl (MetaKmsImpl *impl,
impl_device = meta_create_kms_impl_device (data->device,
impl,
data->fd,
data->device_file,
data->path,
data->flags,
error);
@ -462,44 +454,33 @@ meta_kms_device_new (MetaKms *kms,
{
MetaBackend *backend = meta_kms_get_backend (kms);
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
MetaDevicePool *device_pool =
meta_backend_native_get_device_pool (backend_native);
MetaKmsDevice *device;
CreateImplDeviceData data;
int fd;
g_autoptr (MetaDeviceFile) device_file = NULL;
MetaDeviceFileFlags device_file_flags;
if (flags & META_KMS_DEVICE_FLAG_NO_MODE_SETTING)
{
fd = open (path, O_RDWR | O_CLOEXEC, 0);
if (fd == -1)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
"Failed to open DRM device: %s", g_strerror (errno));
return NULL;
}
}
else
{
fd = meta_launcher_open_restricted (launcher, path, error);
if (fd == -1)
return NULL;
}
device_file_flags = META_DEVICE_FILE_FLAG_NONE;
if (!(flags & META_KMS_DEVICE_FLAG_NO_MODE_SETTING))
device_file_flags |= META_DEVICE_FILE_FLAG_TAKE_CONTROL;
device_file = meta_device_pool_open (device_pool, path, flags, error);
if (!device_file)
return NULL;
device = g_object_new (META_TYPE_KMS_DEVICE, NULL);
device->kms = kms;
data = (CreateImplDeviceData) {
.device = device,
.fd = fd,
.device_file = device_file,
.path = path,
.flags = flags,
};
if (!meta_kms_run_impl_task_sync (kms, create_impl_device_in_impl, &data,
error))
{
if (flags & META_KMS_DEVICE_FLAG_NO_MODE_SETTING)
close (fd);
else
meta_launcher_close_restricted (launcher, fd);
g_object_unref (device);
return NULL;
}
@ -520,27 +501,15 @@ meta_kms_device_new (MetaKms *kms,
return device;
}
typedef struct _FreeImplDeviceData
{
MetaKmsImplDevice *impl_device;
int out_fd;
} FreeImplDeviceData;
static gpointer
free_impl_device_in_impl (MetaKmsImpl *impl,
gpointer user_data,
GError **error)
{
FreeImplDeviceData *data = user_data;
MetaKmsImplDevice *impl_device = data->impl_device;
int fd;
MetaKmsImplDevice *impl_device = user_data;
fd = meta_kms_impl_device_close (impl_device);
g_object_unref (impl_device);
data->out_fd = fd;
return GINT_TO_POINTER (TRUE);
}
@ -548,9 +517,6 @@ static void
meta_kms_device_finalize (GObject *object)
{
MetaKmsDevice *device = META_KMS_DEVICE (object);
MetaBackend *backend = meta_kms_get_backend (device->kms);
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
g_free (device->path);
g_list_free (device->crtcs);
@ -559,26 +525,11 @@ meta_kms_device_finalize (GObject *object)
if (device->impl_device)
{
FreeImplDeviceData data;
GError *error = NULL;
data = (FreeImplDeviceData) {
.impl_device = device->impl_device,
};
if (!meta_kms_run_impl_task_sync (device->kms, free_impl_device_in_impl, &data,
&error))
{
g_warning ("Failed to close KMS impl device: %s", error->message);
g_error_free (error);
}
else
{
if (device->flags & META_KMS_DEVICE_FLAG_NO_MODE_SETTING)
close (data.out_fd);
else
meta_launcher_close_restricted (launcher, data.out_fd);
}
meta_kms_run_impl_task_sync (device->kms, free_impl_device_in_impl,
device->impl_device,
NULL);
}
G_OBJECT_CLASS (meta_kms_device_parent_class)->finalize (object);
}

View File

@ -24,6 +24,8 @@
#include <errno.h>
#include <xf86drm.h>
#include "backends/native/meta-backend-native.h"
#include "backends/native/meta-device-pool.h"
#include "backends/native/meta-kms-connector-private.h"
#include "backends/native/meta-kms-connector.h"
#include "backends/native/meta-kms-crtc-private.h"
@ -45,8 +47,7 @@ enum
PROP_DEVICE,
PROP_IMPL,
PROP_FD,
PROP_PATH,
PROP_DEVICE_FILE,
PROP_FLAGS,
PROP_DRIVER_NAME,
PROP_DRIVER_DESCRIPTION,
@ -61,7 +62,7 @@ typedef struct _MetaKmsImplDevicePrivate
MetaKmsDevice *device;
MetaKmsImpl *impl;
int fd;
MetaDeviceFile *device_file;
GSource *fd_source;
char *path;
MetaKmsDeviceFlag flags;
@ -197,6 +198,7 @@ meta_kms_impl_device_dispatch (MetaKmsImplDevice *impl_device,
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
int fd;
drmEventContext drm_event_context;
@ -205,9 +207,11 @@ meta_kms_impl_device_dispatch (MetaKmsImplDevice *impl_device,
drm_event_context = (drmEventContext) { 0 };
klass->setup_drm_event_context (impl_device, &drm_event_context);
fd = meta_device_file_get_fd (priv->device_file);
while (TRUE)
{
if (drmHandleEvent (priv->fd, &drm_event_context) != 0)
if (drmHandleEvent (fd, &drm_event_context) != 0)
{
struct pollfd pfd;
int ret;
@ -220,7 +224,7 @@ meta_kms_impl_device_dispatch (MetaKmsImplDevice *impl_device,
return FALSE;
}
pfd.fd = priv->fd;
pfd.fd = fd;
pfd.events = POLL_IN | POLL_ERR;
do
{
@ -257,15 +261,18 @@ meta_kms_impl_device_find_property (MetaKmsImplDevice *impl_device,
{
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
int fd;
unsigned int i;
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
fd = meta_device_file_get_fd (priv->device_file);
for (i = 0; i < props->count_props; i++)
{
drmModePropertyPtr prop;
prop = drmModeGetProperty (priv->fd, props->props[i]);
prop = drmModeGetProperty (fd, props->props[i]);
if (!prop)
continue;
@ -286,9 +293,10 @@ init_caps (MetaKmsImplDevice *impl_device)
{
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
int fd = priv->fd;
int fd;
uint64_t cursor_width, cursor_height;
fd = meta_device_file_get_fd (priv->device_file);
if (drmGetCap (fd, DRM_CAP_CURSOR_WIDTH, &cursor_width) == 0 &&
drmGetCap (fd, DRM_CAP_CURSOR_HEIGHT, &cursor_height) == 0)
{
@ -305,6 +313,9 @@ init_crtcs (MetaKmsImplDevice *impl_device,
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
int idx;
int fd;
fd = meta_device_file_get_fd (priv->device_file);
for (idx = 0; idx < drm_resources->count_crtcs; idx++)
{
@ -314,7 +325,7 @@ init_crtcs (MetaKmsImplDevice *impl_device,
g_autoptr (GError) error = NULL;
crtc_id = drm_resources->crtcs[idx];
drm_crtc = drmModeGetCrtc (priv->fd, crtc_id);
drm_crtc = drmModeGetCrtc (fd, crtc_id);
if (!drm_crtc)
{
g_warning ("Failed to get CRTC %u info on '%s': %s",
@ -365,14 +376,16 @@ update_connectors (MetaKmsImplDevice *impl_device,
meta_kms_impl_device_get_instance_private (impl_device);
GList *connectors = NULL;
unsigned int i;
int fd;
fd = meta_device_file_get_fd (priv->device_file);
for (i = 0; i < drm_resources->count_connectors; i++)
{
drmModeConnector *drm_connector;
MetaKmsConnector *connector;
drm_connector = drmModeGetConnector (priv->fd,
drm_resources->connectors[i]);
drm_connector = drmModeGetConnector (fd, drm_resources->connectors[i]);
if (!drm_connector)
continue;
@ -510,10 +523,12 @@ init_planes (MetaKmsImplDevice *impl_device)
{
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
int fd = priv->fd;
int fd;
drmModePlaneRes *drm_planes;
unsigned int i;
fd = meta_device_file_get_fd (priv->device_file);
drm_planes = drmModeGetPlaneResources (fd);
if (!drm_planes)
return;
@ -589,13 +604,15 @@ meta_kms_impl_device_update_states (MetaKmsImplDevice *impl_device)
{
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
int fd;
drmModeRes *drm_resources;
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
meta_topic (META_DEBUG_KMS, "Updating device state for %s", priv->path);
drm_resources = drmModeGetResources (priv->fd);
fd = meta_device_file_get_fd (priv->device_file);
drm_resources = drmModeGetResources (fd);
if (!drm_resources)
{
g_list_free_full (priv->planes, g_object_unref);
@ -637,7 +654,7 @@ meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device)
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
return priv->fd;
return meta_device_file_get_fd (priv->device_file);
}
int
@ -646,7 +663,7 @@ meta_kms_impl_device_leak_fd (MetaKmsImplDevice *impl_device)
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
return priv->fd;
return meta_device_file_get_fd (priv->device_file);
}
MetaKmsFeedback *
@ -676,22 +693,6 @@ meta_kms_impl_device_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
klass->discard_pending_page_flips (impl_device);
}
int
meta_kms_impl_device_close (MetaKmsImplDevice *impl_device)
{
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
int fd;
meta_assert_in_kms_impl (meta_kms_impl_get_kms (priv->impl));
g_clear_pointer (&priv->fd_source, g_source_destroy);
fd = priv->fd;
priv->fd = -1;
return fd;
}
static void
meta_kms_impl_device_get_property (GObject *object,
guint prop_id,
@ -710,11 +711,8 @@ meta_kms_impl_device_get_property (GObject *object,
case PROP_IMPL:
g_value_set_object (value, priv->impl);
break;
case PROP_FD:
g_value_set_int (value, priv->fd);
break;
case PROP_PATH:
g_value_set_string (value, priv->path);
case PROP_DEVICE_FILE:
g_value_set_pointer (value, priv->device_file);
break;
case PROP_FLAGS:
g_value_set_flags (value, priv->flags);
@ -749,11 +747,9 @@ meta_kms_impl_device_set_property (GObject *object,
case PROP_IMPL:
priv->impl = g_value_get_object (value);
break;
case PROP_FD:
priv->fd = g_value_get_int (value);
break;
case PROP_PATH:
priv->path = g_value_dup_string (value);
case PROP_DEVICE_FILE:
priv->device_file =
meta_device_file_acquire (g_value_get_pointer (value));
break;
case PROP_FLAGS:
priv->flags = g_value_get_flags (value);
@ -784,6 +780,9 @@ meta_kms_impl_device_finalize (GObject *object)
g_list_free_full (priv->connectors, g_object_unref);
g_list_free_full (priv->fallback_modes,
(GDestroyNotify) meta_kms_mode_free);
g_clear_pointer (&priv->device_file, meta_device_file_release);
g_free (priv->driver_name);
g_free (priv->driver_description);
g_free (priv->path);
@ -797,10 +796,13 @@ meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
{
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
int fd;
int ret;
drmModeRes *drm_resources;
ret = drmSetClientCap (priv->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
fd = meta_device_file_get_fd (priv->device_file);
ret = drmSetClientCap (fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
if (ret != 0)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
@ -809,7 +811,7 @@ meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
return FALSE;
}
drm_resources = drmModeGetResources (priv->fd);
drm_resources = drmModeGetResources (fd);
if (!drm_resources)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
@ -830,7 +832,8 @@ meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
drmModeFreeResources (drm_resources);
priv->fd_source =
meta_kms_register_fd_in_impl (meta_kms_impl_get_kms (priv->impl), priv->fd,
meta_kms_register_fd_in_impl (meta_kms_impl_get_kms (priv->impl),
fd,
kms_event_dispatch_in_impl,
impl_device);
@ -846,6 +849,18 @@ meta_kms_impl_device_prepare_shutdown (MetaKmsImplDevice *impl_device)
klass->prepare_shutdown (impl_device);
}
static void
meta_kms_impl_device_constructed (GObject *object)
{
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (object);
MetaKmsImplDevicePrivate *priv =
meta_kms_impl_device_get_instance_private (impl_device);
priv->path = g_strdup (meta_device_file_get_path (priv->device_file));
G_OBJECT_CLASS (meta_kms_impl_device_parent_class)->constructed (object);
}
static void
meta_kms_impl_device_init (MetaKmsImplDevice *impl_device)
{
@ -858,6 +873,7 @@ meta_kms_impl_device_class_init (MetaKmsImplDeviceClass *klass)
object_class->get_property = meta_kms_impl_device_get_property;
object_class->set_property = meta_kms_impl_device_set_property;
object_class->constructed = meta_kms_impl_device_constructed;
object_class->finalize = meta_kms_impl_device_finalize;
obj_props[PROP_DEVICE] =
@ -876,22 +892,13 @@ meta_kms_impl_device_class_init (MetaKmsImplDeviceClass *klass)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_FD] =
g_param_spec_int ("fd",
"fd",
"DRM device file descriptor",
INT_MIN, INT_MAX, 0,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_PATH] =
g_param_spec_string ("path",
"path",
"DRM device file path",
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_DEVICE_FILE] =
g_param_spec_pointer ("device-file",
"device-file",
"Device file",
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
obj_props[PROP_FLAGS] =
g_param_spec_flags ("flags",
"flags",

View File

@ -142,8 +142,6 @@ void meta_kms_impl_device_handle_page_flip_callback (MetaKmsImplDevice *impl_d
void meta_kms_impl_device_discard_pending_page_flips (MetaKmsImplDevice *impl_device);
int meta_kms_impl_device_close (MetaKmsImplDevice *impl_device);
gboolean meta_kms_impl_device_init_mode_setting (MetaKmsImplDevice *impl_device,
GError **error);