mirror of
https://github.com/brl/mutter.git
synced 2024-12-25 12:32:05 +00:00
kms: Have the device impl open device files themself
This changes the way the KMS backends load; if we're headless, we always use the dummy one and fail otherwise; in other cases, we first try the atomic backend, and if that fails, fall back on the simple one. The aim for this is to have the impl device open and close the device when needed, using the device pool directly. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1828>
This commit is contained in:
parent
f3457b678c
commit
e6421dc5da
@ -230,7 +230,6 @@ meta_kms_device_add_fake_plane_in_impl (MetaKmsDevice *device,
|
||||
typedef struct _CreateImplDeviceData
|
||||
{
|
||||
MetaKmsDevice *device;
|
||||
MetaDeviceFile *device_file;
|
||||
const char *path;
|
||||
MetaKmsDeviceFlag flags;
|
||||
|
||||
@ -245,170 +244,70 @@ typedef struct _CreateImplDeviceData
|
||||
char *out_path;
|
||||
} CreateImplDeviceData;
|
||||
|
||||
static gboolean
|
||||
is_atomic_allowed (const char *driver_name)
|
||||
static const char *
|
||||
impl_device_type_to_string (GType type)
|
||||
{
|
||||
const char *atomic_driver_deny_list[] = {
|
||||
"qxl",
|
||||
"vmwgfx",
|
||||
"vboxvideo",
|
||||
"nvidia-drm",
|
||||
NULL,
|
||||
};
|
||||
|
||||
return !g_strv_contains (atomic_driver_deny_list, driver_name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_driver_info (int fd,
|
||||
char **name,
|
||||
char **description)
|
||||
{
|
||||
drmVersion *drm_version;
|
||||
|
||||
drm_version = drmGetVersion (fd);
|
||||
if (!drm_version)
|
||||
return FALSE;
|
||||
|
||||
*name = g_strndup (drm_version->name,
|
||||
drm_version->name_len);
|
||||
*description = g_strndup (drm_version->desc,
|
||||
drm_version->desc_len);
|
||||
drmFreeVersion (drm_version);
|
||||
|
||||
return TRUE;
|
||||
if (type == META_TYPE_KMS_IMPL_DEVICE_ATOMIC)
|
||||
return "atomic modesetting";
|
||||
else if (type == META_TYPE_KMS_IMPL_DEVICE_SIMPLE)
|
||||
return "legacy modesetting";
|
||||
else if (type == META_TYPE_KMS_IMPL_DEVICE_DUMMY)
|
||||
return "no modesetting";
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
static MetaKmsImplDevice *
|
||||
meta_create_kms_impl_device (MetaKmsDevice *device,
|
||||
MetaKmsImpl *impl,
|
||||
MetaDeviceFile *device_file,
|
||||
const char *path,
|
||||
MetaKmsDeviceFlag flags,
|
||||
GError **error)
|
||||
{
|
||||
GType impl_device_type;
|
||||
gboolean supports_atomic_mode_setting;
|
||||
g_autofree char *driver_name = NULL;
|
||||
g_autofree char *driver_description = NULL;
|
||||
const char *atomic_kms_enable_env;
|
||||
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");
|
||||
driver_description = g_strdup ("Unknown");
|
||||
}
|
||||
|
||||
atomic_kms_enable_env = getenv ("MUTTER_DEBUG_ENABLE_ATOMIC_KMS");
|
||||
|
||||
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)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Couldn't find render node device for '%s' (%s)",
|
||||
path, driver_name);
|
||||
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_device_type = META_TYPE_KMS_IMPL_DEVICE_DUMMY;
|
||||
}
|
||||
else if (atomic_kms_enable_env)
|
||||
{
|
||||
if (g_strcmp0 (atomic_kms_enable_env, "1") == 0)
|
||||
{
|
||||
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_ATOMIC;
|
||||
if (drmSetClientCap (fd, DRM_CLIENT_CAP_ATOMIC, 1) != 0)
|
||||
{
|
||||
g_error ("Failed to force atomic mode setting on '%s' (%s).",
|
||||
path, driver_name);
|
||||
}
|
||||
}
|
||||
else if (g_strcmp0 (atomic_kms_enable_env, "0") == 0)
|
||||
{
|
||||
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_SIMPLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_error ("Invalid value '%s' for MUTTER_DEBUG_ENABLE_ATOMIC_KMS, "
|
||||
"bailing.",
|
||||
atomic_kms_enable_env);
|
||||
}
|
||||
|
||||
impl_device_file = meta_device_file_acquire (device_file);
|
||||
|
||||
g_message ("Mode setting implementation for '%s' (%s) forced (%s).",
|
||||
path, driver_name,
|
||||
impl_device_type == META_TYPE_KMS_IMPL_DEVICE_ATOMIC ?
|
||||
"atomic" : "non-atomic");
|
||||
}
|
||||
else if (!is_atomic_allowed (driver_name))
|
||||
{
|
||||
g_message ("Adding device '%s' (%s) using non-atomic mode setting"
|
||||
" (using atomic mode setting not allowed).",
|
||||
path, driver_name);
|
||||
impl_device_file = meta_device_file_acquire (device_file);
|
||||
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_SIMPLE;
|
||||
return g_initable_new (META_TYPE_KMS_IMPL_DEVICE_DUMMY,
|
||||
NULL, error,
|
||||
"device", device,
|
||||
"impl", impl,
|
||||
"path", path,
|
||||
"flags", flags,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
int ret;
|
||||
GType impl_device_types[] = {
|
||||
META_TYPE_KMS_IMPL_DEVICE_ATOMIC,
|
||||
META_TYPE_KMS_IMPL_DEVICE_SIMPLE,
|
||||
};
|
||||
int i;
|
||||
|
||||
ret = drmSetClientCap (fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
||||
if (ret == 0)
|
||||
supports_atomic_mode_setting = TRUE;
|
||||
else
|
||||
supports_atomic_mode_setting = FALSE;
|
||||
for (i = 0; i < G_N_ELEMENTS (impl_device_types); i++)
|
||||
{
|
||||
MetaKmsImplDevice *impl_device;
|
||||
g_autoptr (GError) local_error = NULL;
|
||||
|
||||
if (supports_atomic_mode_setting)
|
||||
{
|
||||
g_message ("Adding device '%s' (%s) using atomic mode setting.",
|
||||
path, driver_name);
|
||||
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_ATOMIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_message ("Adding device '%s' (%s) using non-atomic mode setting.",
|
||||
path, driver_name);
|
||||
impl_device_type = META_TYPE_KMS_IMPL_DEVICE_SIMPLE;
|
||||
impl_device = g_initable_new (impl_device_types[i],
|
||||
NULL, &local_error,
|
||||
"device", device,
|
||||
"impl", impl,
|
||||
"path", path,
|
||||
"flags", flags,
|
||||
NULL);
|
||||
if (impl_device)
|
||||
return impl_device;
|
||||
|
||||
if (local_error->domain != META_KMS_ERROR)
|
||||
{
|
||||
g_warning ("Failed to open %s backend: %s",
|
||||
impl_device_type_to_string (impl_device_types[i]),
|
||||
local_error->message);
|
||||
}
|
||||
}
|
||||
|
||||
impl_device_file = meta_device_file_acquire (device_file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
impl_device = g_initable_new (impl_device_type, NULL, error,
|
||||
"device", device,
|
||||
"impl", impl,
|
||||
"device-file", impl_device_file,
|
||||
"flags", flags,
|
||||
"driver-name", driver_name,
|
||||
"driver-description", driver_description,
|
||||
NULL);
|
||||
if (!impl_device)
|
||||
return NULL;
|
||||
|
||||
return impl_device;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
@ -421,7 +320,6 @@ create_impl_device_in_impl (MetaKmsImpl *impl,
|
||||
|
||||
impl_device = meta_create_kms_impl_device (data->device,
|
||||
impl,
|
||||
data->device_file,
|
||||
data->path,
|
||||
data->flags,
|
||||
error);
|
||||
@ -452,29 +350,14 @@ meta_kms_device_new (MetaKms *kms,
|
||||
MetaKmsDeviceFlag flags,
|
||||
GError **error)
|
||||
{
|
||||
MetaBackend *backend = meta_kms_get_backend (kms);
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaDevicePool *device_pool =
|
||||
meta_backend_native_get_device_pool (backend_native);
|
||||
MetaKmsDevice *device;
|
||||
CreateImplDeviceData data;
|
||||
g_autoptr (MetaDeviceFile) device_file = NULL;
|
||||
MetaDeviceFileFlags device_file_flags;
|
||||
|
||||
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,
|
||||
.device_file = device_file,
|
||||
.path = path,
|
||||
.flags = flags,
|
||||
};
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "backends/native/meta-kms-impl-device-atomic.h"
|
||||
|
||||
#include "backends/native/meta-backend-native-private.h"
|
||||
#include "backends/native/meta-kms-connector-private.h"
|
||||
#include "backends/native/meta-kms-crtc-private.h"
|
||||
#include "backends/native/meta-kms-device-private.h"
|
||||
@ -44,6 +45,8 @@ struct _MetaKmsImplDeviceAtomic
|
||||
GHashTable *page_flip_datas;
|
||||
};
|
||||
|
||||
static GInitableIface *initable_parent_iface;
|
||||
|
||||
static void
|
||||
initable_iface_init (GInitableIface *iface);
|
||||
|
||||
@ -1039,14 +1042,83 @@ meta_kms_impl_device_atomic_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (meta_kms_impl_device_atomic_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static MetaDeviceFile *
|
||||
meta_kms_impl_device_atomic_open_device_file (MetaKmsImplDevice *impl_device,
|
||||
const char *path,
|
||||
GError **error)
|
||||
{
|
||||
MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
|
||||
MetaKms *kms = meta_kms_device_get_kms (device);
|
||||
MetaBackend *backend = meta_kms_get_backend (kms);
|
||||
MetaDevicePool *device_pool =
|
||||
meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
|
||||
g_autoptr (MetaDeviceFile) device_file = NULL;
|
||||
|
||||
device_file = meta_device_pool_open (device_pool, path,
|
||||
META_DEVICE_FILE_FLAG_TAKE_CONTROL,
|
||||
error);
|
||||
if (!device_file)
|
||||
return NULL;
|
||||
|
||||
if (drmSetClientCap (meta_device_file_get_fd (device_file),
|
||||
DRM_CLIENT_CAP_ATOMIC, 1) != 0)
|
||||
{
|
||||
g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_NOT_SUPPORTED,
|
||||
"DRM_CLIENT_CAP_ATOMIC not supported");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_steal_pointer (&device_file);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_atomic_allowed (const char *driver_name)
|
||||
{
|
||||
const char *atomic_driver_deny_list[] = {
|
||||
"qxl",
|
||||
"vmwgfx",
|
||||
"vboxvideo",
|
||||
"nvidia-drm",
|
||||
NULL,
|
||||
};
|
||||
|
||||
return !g_strv_contains (atomic_driver_deny_list, driver_name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_kms_impl_device_atomic_initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable);
|
||||
const char *atomic_kms_enable_env;
|
||||
|
||||
return meta_kms_impl_device_init_mode_setting (impl_device, error);
|
||||
atomic_kms_enable_env = getenv ("MUTTER_DEBUG_ENABLE_ATOMIC_KMS");
|
||||
if (atomic_kms_enable_env && g_strcmp0 (atomic_kms_enable_env, "1") != 0)
|
||||
{
|
||||
g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_USER_INHIBITED,
|
||||
"Atomic mode setting disable via env var");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!initable_parent_iface->init (initable, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!is_atomic_allowed (meta_kms_impl_device_get_driver_name (impl_device)))
|
||||
{
|
||||
g_set_error (error, META_KMS_ERROR, META_KMS_ERROR_DENY_LISTED,
|
||||
"Atomic mode setting disable via driver deny list");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!meta_kms_impl_device_init_mode_setting (impl_device, error))
|
||||
return FALSE;
|
||||
|
||||
g_message ("Added device '%s' (%s) using atomic mode setting.",
|
||||
meta_kms_impl_device_get_path (impl_device),
|
||||
meta_kms_impl_device_get_driver_name (impl_device));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1058,6 +1130,8 @@ meta_kms_impl_device_atomic_init (MetaKmsImplDeviceAtomic *impl_device_atomic)
|
||||
static void
|
||||
initable_iface_init (GInitableIface *iface)
|
||||
{
|
||||
initable_parent_iface = g_type_interface_peek_parent (iface);
|
||||
|
||||
iface->init = meta_kms_impl_device_atomic_initable_init;
|
||||
}
|
||||
|
||||
@ -1070,6 +1144,8 @@ meta_kms_impl_device_atomic_class_init (MetaKmsImplDeviceAtomicClass *klass)
|
||||
|
||||
object_class->finalize = meta_kms_impl_device_atomic_finalize;
|
||||
|
||||
impl_device_class->open_device_file =
|
||||
meta_kms_impl_device_atomic_open_device_file;
|
||||
impl_device_class->setup_drm_event_context =
|
||||
meta_kms_impl_device_atomic_setup_drm_event_context;
|
||||
impl_device_class->process_update =
|
||||
|
@ -21,15 +21,21 @@
|
||||
|
||||
#include "backends/native/meta-kms-impl-device-dummy.h"
|
||||
|
||||
#include "backends/native/meta-backend-native-private.h"
|
||||
#include "backends/native/meta-kms.h"
|
||||
|
||||
struct _MetaKmsImplDeviceDummy
|
||||
{
|
||||
MetaKmsImplDevice parent;
|
||||
};
|
||||
|
||||
static GInitableIface *initable_parent_iface;
|
||||
|
||||
static void
|
||||
initable_iface_init (GInitableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDeviceDummy, meta_kms_impl_device_dummy,
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDeviceDummy,
|
||||
meta_kms_impl_device_dummy,
|
||||
META_TYPE_KMS_IMPL_DEVICE,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init))
|
||||
@ -39,9 +45,43 @@ meta_kms_impl_device_dummy_discard_pending_page_flips (MetaKmsImplDevice *impl_d
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_device_dummy_init (MetaKmsImplDeviceDummy *impl_device_dummy)
|
||||
static MetaDeviceFile *
|
||||
meta_kms_impl_device_dummy_open_device_file (MetaKmsImplDevice *impl_device,
|
||||
const char *path,
|
||||
GError **error)
|
||||
{
|
||||
MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
|
||||
MetaKms *kms = meta_kms_device_get_kms (device);
|
||||
MetaBackend *backend = meta_kms_get_backend (kms);
|
||||
MetaDevicePool *device_pool =
|
||||
meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
|
||||
g_autoptr (MetaDeviceFile) device_file = NULL;
|
||||
int fd;
|
||||
g_autofree char *render_node_path = NULL;
|
||||
|
||||
device_file = meta_device_pool_open (device_pool, path,
|
||||
META_DEVICE_FILE_FLAG_NONE,
|
||||
error);
|
||||
if (!device_file)
|
||||
return NULL;
|
||||
|
||||
fd = meta_device_file_get_fd (device_file);
|
||||
render_node_path = drmGetRenderDeviceNameFromFd (fd);
|
||||
if (!render_node_path)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Couldn't find render node device for '%s' (%s)",
|
||||
meta_kms_impl_device_get_path (impl_device),
|
||||
meta_kms_impl_device_get_driver_name (impl_device));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
meta_topic (META_DEBUG_KMS, "Found render node '%s' from '%s'",
|
||||
render_node_path, path);
|
||||
|
||||
return meta_device_pool_open (device_pool, render_node_path,
|
||||
META_DEVICE_FILE_FLAG_NONE,
|
||||
error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -49,21 +89,39 @@ meta_kms_impl_device_dummy_initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable);
|
||||
|
||||
if (!initable_parent_iface->init (initable, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
g_message ("Added device '%s' (%s) using no mode setting.",
|
||||
meta_kms_impl_device_get_path (impl_device),
|
||||
meta_kms_impl_device_get_driver_name (impl_device));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
initable_iface_init (GInitableIface *iface)
|
||||
{
|
||||
initable_parent_iface = g_type_interface_peek_parent (iface);
|
||||
|
||||
iface->init = meta_kms_impl_device_dummy_initable_init;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_device_dummy_init (MetaKmsImplDeviceDummy *impl_device_dummy)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_device_dummy_class_init (MetaKmsImplDeviceDummyClass *klass)
|
||||
{
|
||||
MetaKmsImplDeviceClass *impl_device_class =
|
||||
META_KMS_IMPL_DEVICE_CLASS (klass);
|
||||
|
||||
impl_device_class->open_device_file =
|
||||
meta_kms_impl_device_dummy_open_device_file;
|
||||
impl_device_class->discard_pending_page_flips =
|
||||
meta_kms_impl_device_dummy_discard_pending_page_flips;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "backends/native/meta-kms-impl-device-simple.h"
|
||||
|
||||
#include "backends/native/meta-backend-native-private.h"
|
||||
#include "backends/native/meta-drm-buffer-gbm.h"
|
||||
#include "backends/native/meta-kms-connector-private.h"
|
||||
#include "backends/native/meta-kms-crtc-private.h"
|
||||
@ -60,6 +61,8 @@ struct _MetaKmsImplDeviceSimple
|
||||
GHashTable *cached_mode_sets;
|
||||
};
|
||||
|
||||
static GInitableIface *initable_parent_iface;
|
||||
|
||||
static void
|
||||
initable_iface_init (GInitableIface *iface);
|
||||
|
||||
@ -1534,6 +1537,22 @@ meta_kms_impl_device_simple_finalize (GObject *object)
|
||||
G_OBJECT_CLASS (meta_kms_impl_device_simple_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static MetaDeviceFile *
|
||||
meta_kms_impl_device_simple_open_device_file (MetaKmsImplDevice *impl_device,
|
||||
const char *path,
|
||||
GError **error)
|
||||
{
|
||||
MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
|
||||
MetaKms *kms = meta_kms_device_get_kms (device);
|
||||
MetaBackend *backend = meta_kms_get_backend (kms);
|
||||
MetaDevicePool *device_pool =
|
||||
meta_backend_native_get_device_pool (META_BACKEND_NATIVE (backend));
|
||||
|
||||
return meta_device_pool_open (device_pool, path,
|
||||
META_DEVICE_FILE_FLAG_TAKE_CONTROL,
|
||||
error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_kms_impl_device_simple_initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
@ -1545,6 +1564,9 @@ meta_kms_impl_device_simple_initable_init (GInitable *initable,
|
||||
MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
|
||||
GList *l;
|
||||
|
||||
if (!initable_parent_iface->init (initable, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (!meta_kms_impl_device_init_mode_setting (impl_device, error))
|
||||
return FALSE;
|
||||
|
||||
@ -1573,6 +1595,10 @@ meta_kms_impl_device_simple_initable_init (GInitable *initable,
|
||||
crtc);
|
||||
}
|
||||
|
||||
g_message ("Added device '%s' (%s) using non-atomic mode setting.",
|
||||
meta_kms_impl_device_get_path (impl_device),
|
||||
meta_kms_impl_device_get_driver_name (impl_device));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1584,6 +1610,8 @@ meta_kms_impl_device_simple_init (MetaKmsImplDeviceSimple *impl_device_simple)
|
||||
static void
|
||||
initable_iface_init (GInitableIface *iface)
|
||||
{
|
||||
initable_parent_iface = g_type_interface_peek_parent (iface);
|
||||
|
||||
iface->init = meta_kms_impl_device_simple_initable_init;
|
||||
}
|
||||
|
||||
@ -1596,6 +1624,8 @@ meta_kms_impl_device_simple_class_init (MetaKmsImplDeviceSimpleClass *klass)
|
||||
|
||||
object_class->finalize = meta_kms_impl_device_simple_finalize;
|
||||
|
||||
impl_device_class->open_device_file =
|
||||
meta_kms_impl_device_simple_open_device_file;
|
||||
impl_device_class->setup_drm_event_context =
|
||||
meta_kms_impl_device_simple_setup_drm_event_context;
|
||||
impl_device_class->process_update =
|
||||
|
@ -47,10 +47,8 @@ enum
|
||||
|
||||
PROP_DEVICE,
|
||||
PROP_IMPL,
|
||||
PROP_DEVICE_FILE,
|
||||
PROP_PATH,
|
||||
PROP_FLAGS,
|
||||
PROP_DRIVER_NAME,
|
||||
PROP_DRIVER_DESCRIPTION,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
@ -79,9 +77,16 @@ typedef struct _MetaKmsImplDevicePrivate
|
||||
GList *fallback_modes;
|
||||
} MetaKmsImplDevicePrivate;
|
||||
|
||||
static void
|
||||
initable_iface_init (GInitableIface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDevice, meta_kms_impl_device,
|
||||
G_TYPE_OBJECT,
|
||||
G_ADD_PRIVATE (MetaKmsImplDevice))
|
||||
G_ADD_PRIVATE (MetaKmsImplDevice)
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||
initable_iface_init))
|
||||
|
||||
G_DEFINE_QUARK (-meta-kms-error-quark, meta_kms_error)
|
||||
|
||||
MetaKmsDevice *
|
||||
meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device)
|
||||
@ -711,18 +716,9 @@ meta_kms_impl_device_get_property (GObject *object,
|
||||
case PROP_IMPL:
|
||||
g_value_set_object (value, priv->impl);
|
||||
break;
|
||||
case PROP_DEVICE_FILE:
|
||||
g_value_set_pointer (value, priv->device_file);
|
||||
break;
|
||||
case PROP_FLAGS:
|
||||
g_value_set_flags (value, priv->flags);
|
||||
break;
|
||||
case PROP_DRIVER_NAME:
|
||||
g_value_set_string (value, priv->driver_name);
|
||||
break;
|
||||
case PROP_DRIVER_DESCRIPTION:
|
||||
g_value_set_string (value, priv->driver_name);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -747,19 +743,12 @@ meta_kms_impl_device_set_property (GObject *object,
|
||||
case PROP_IMPL:
|
||||
priv->impl = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_DEVICE_FILE:
|
||||
priv->device_file =
|
||||
meta_device_file_acquire (g_value_get_pointer (value));
|
||||
case PROP_PATH:
|
||||
priv->path = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_FLAGS:
|
||||
priv->flags = g_value_get_flags (value);
|
||||
break;
|
||||
case PROP_DRIVER_NAME:
|
||||
priv->driver_name = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_DRIVER_DESCRIPTION:
|
||||
priv->driver_description = g_value_dup_string (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -849,16 +838,52 @@ meta_kms_impl_device_prepare_shutdown (MetaKmsImplDevice *impl_device)
|
||||
klass->prepare_shutdown (impl_device);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_device_constructed (GObject *object)
|
||||
static gboolean
|
||||
get_driver_info (int fd,
|
||||
char **name,
|
||||
char **description)
|
||||
{
|
||||
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (object);
|
||||
drmVersion *drm_version;
|
||||
|
||||
drm_version = drmGetVersion (fd);
|
||||
if (!drm_version)
|
||||
return FALSE;
|
||||
|
||||
*name = g_strndup (drm_version->name,
|
||||
drm_version->name_len);
|
||||
*description = g_strndup (drm_version->desc,
|
||||
drm_version->desc_len);
|
||||
drmFreeVersion (drm_version);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_kms_impl_device_initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (initable);
|
||||
MetaKmsImplDevicePrivate *priv =
|
||||
meta_kms_impl_device_get_instance_private (impl_device);
|
||||
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
|
||||
int fd;
|
||||
|
||||
priv->device_file = klass->open_device_file (impl_device, priv->path, error);
|
||||
if (!priv->device_file)
|
||||
return FALSE;
|
||||
|
||||
g_clear_pointer (&priv->path, g_free);
|
||||
priv->path = g_strdup (meta_device_file_get_path (priv->device_file));
|
||||
|
||||
G_OBJECT_CLASS (meta_kms_impl_device_parent_class)->constructed (object);
|
||||
fd = meta_device_file_get_fd (priv->device_file);
|
||||
if (!get_driver_info (fd, &priv->driver_name, &priv->driver_description))
|
||||
{
|
||||
priv->driver_name = g_strdup ("unknown");
|
||||
priv->driver_description = g_strdup ("Unknown");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -866,6 +891,12 @@ meta_kms_impl_device_init (MetaKmsImplDevice *impl_device)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
initable_iface_init (GInitableIface *iface)
|
||||
{
|
||||
iface->init = meta_kms_impl_device_initable_init;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_kms_impl_device_class_init (MetaKmsImplDeviceClass *klass)
|
||||
{
|
||||
@ -873,7 +904,6 @@ 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] =
|
||||
@ -892,13 +922,14 @@ meta_kms_impl_device_class_init (MetaKmsImplDeviceClass *klass)
|
||||
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_PATH] =
|
||||
g_param_spec_string ("path",
|
||||
"path",
|
||||
"Device path",
|
||||
NULL,
|
||||
G_PARAM_WRITABLE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_FLAGS] =
|
||||
g_param_spec_flags ("flags",
|
||||
"flags",
|
||||
@ -908,21 +939,5 @@ meta_kms_impl_device_class_init (MetaKmsImplDeviceClass *klass)
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_DRIVER_NAME] =
|
||||
g_param_spec_string ("driver-name",
|
||||
"driver-name",
|
||||
"DRM device driver name",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_DRIVER_DESCRIPTION] =
|
||||
g_param_spec_string ("driver-description",
|
||||
"driver-description",
|
||||
"DRM device driver description",
|
||||
NULL,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#include "backends/native/meta-device-pool.h"
|
||||
#include "backends/native/meta-kms-device.h"
|
||||
#include "backends/native/meta-kms-page-flip-private.h"
|
||||
#include "backends/native/meta-kms-types.h"
|
||||
@ -62,6 +63,9 @@ struct _MetaKmsImplDeviceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
MetaDeviceFile * (* open_device_file) (MetaKmsImplDevice *impl_device,
|
||||
const char *path,
|
||||
GError **error);
|
||||
void (* setup_drm_event_context) (MetaKmsImplDevice *impl_device,
|
||||
drmEventContext *drm_event_context);
|
||||
MetaKmsFeedback * (* process_update) (MetaKmsImplDevice *impl_device,
|
||||
@ -73,6 +77,16 @@ struct _MetaKmsImplDeviceClass
|
||||
void (* prepare_shutdown) (MetaKmsImplDevice *impl_device);
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
META_KMS_ERROR_USER_INHIBITED,
|
||||
META_KMS_ERROR_DENY_LISTED,
|
||||
META_KMS_ERROR_NOT_SUPPORTED,
|
||||
};
|
||||
|
||||
#define META_KMS_ERROR meta_kms_error_quark ()
|
||||
GQuark meta_kms_error_quark (void);
|
||||
|
||||
MetaKmsDevice * meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device);
|
||||
|
||||
GList * meta_kms_impl_device_copy_connectors (MetaKmsImplDevice *impl_device);
|
||||
|
Loading…
Reference in New Issue
Block a user