mirror of
https://github.com/brl/mutter.git
synced 2024-12-24 12:02:04 +00:00
backends/native: Move KMS fd management to monitor manager
Move finding, opening and managment of the KMS file descriptor to MetaMonitorManagerKms. This means that the monitor manager creation can now fail, both if more than one GPU with connectors is discovered, or if finding or opening the primary GPU fails. https://bugzilla.gnome.org/show_bug.cgi?id=785381
This commit is contained in:
parent
518fb9fb5e
commit
16a6aef5a7
@ -61,7 +61,8 @@ struct _MetaBackendClass
|
|||||||
|
|
||||||
MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend,
|
MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend,
|
||||||
int device_id);
|
int device_id);
|
||||||
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend);
|
MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend,
|
||||||
|
GError **error);
|
||||||
MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend);
|
MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend);
|
||||||
MetaRenderer * (* create_renderer) (MetaBackend *backend,
|
MetaRenderer * (* create_renderer) (MetaBackend *backend,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
@ -571,12 +571,14 @@ experimental_features_changed (MetaSettings *settings,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MetaMonitorManager *
|
static MetaMonitorManager *
|
||||||
meta_backend_create_monitor_manager (MetaBackend *backend)
|
meta_backend_create_monitor_manager (MetaBackend *backend,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
if (g_getenv ("META_DUMMY_MONITORS"))
|
if (g_getenv ("META_DUMMY_MONITORS"))
|
||||||
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
|
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
|
||||||
|
|
||||||
return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend);
|
return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend,
|
||||||
|
error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaRenderer *
|
static MetaRenderer *
|
||||||
@ -603,12 +605,14 @@ meta_backend_initable_init (GInitable *initable,
|
|||||||
|
|
||||||
priv->orientation_manager = g_object_new (META_TYPE_ORIENTATION_MANAGER, NULL);
|
priv->orientation_manager = g_object_new (META_TYPE_ORIENTATION_MANAGER, NULL);
|
||||||
|
|
||||||
|
priv->monitor_manager = meta_backend_create_monitor_manager (backend, error);
|
||||||
|
if (!priv->monitor_manager)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
priv->renderer = meta_backend_create_renderer (backend, error);
|
priv->renderer = meta_backend_create_renderer (backend, error);
|
||||||
if (!priv->renderer)
|
if (!priv->renderer)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
priv->monitor_manager = meta_backend_create_monitor_manager (backend);
|
|
||||||
|
|
||||||
priv->cursor_tracker = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
|
priv->cursor_tracker = g_object_new (META_TYPE_CURSOR_TRACKER, NULL);
|
||||||
|
|
||||||
priv->dnd = g_object_new (META_TYPE_DND, NULL);
|
priv->dnd = g_object_new (META_TYPE_DND, NULL);
|
||||||
|
@ -400,9 +400,10 @@ meta_backend_native_create_idle_monitor (MetaBackend *backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MetaMonitorManager *
|
static MetaMonitorManager *
|
||||||
meta_backend_native_create_monitor_manager (MetaBackend *backend)
|
meta_backend_native_create_monitor_manager (MetaBackend *backend,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
return g_object_new (META_TYPE_MONITOR_MANAGER_KMS, NULL);
|
return g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaCursorRenderer *
|
static MetaCursorRenderer *
|
||||||
@ -415,16 +416,13 @@ static MetaRenderer *
|
|||||||
meta_backend_native_create_renderer (MetaBackend *backend,
|
meta_backend_native_create_renderer (MetaBackend *backend,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaBackendNative *native = META_BACKEND_NATIVE (backend);
|
MetaMonitorManager *monitor_manager =
|
||||||
MetaBackendNativePrivate *priv =
|
meta_backend_get_monitor_manager (backend);
|
||||||
meta_backend_native_get_instance_private (native);
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
int kms_fd;
|
META_MONITOR_MANAGER_KMS (monitor_manager);
|
||||||
const char *kms_file_path;
|
|
||||||
MetaRendererNative *renderer_native;
|
MetaRendererNative *renderer_native;
|
||||||
|
|
||||||
kms_fd = meta_launcher_get_kms_fd (priv->launcher);
|
renderer_native = meta_renderer_native_new (monitor_manager_kms, error);
|
||||||
kms_file_path = meta_launcher_get_kms_file_path (priv->launcher);
|
|
||||||
renderer_native = meta_renderer_native_new (kms_fd, kms_file_path, error);
|
|
||||||
if (!renderer_native)
|
if (!renderer_native)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -621,14 +619,23 @@ meta_backend_native_init (MetaBackendNative *native)
|
|||||||
native);
|
native);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaLauncher *
|
||||||
|
meta_backend_native_get_launcher (MetaBackendNative *native)
|
||||||
|
{
|
||||||
|
MetaBackendNativePrivate *priv =
|
||||||
|
meta_backend_native_get_instance_private (native);
|
||||||
|
|
||||||
|
return priv->launcher;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_activate_vt (int vt, GError **error)
|
meta_activate_vt (int vt, GError **error)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaBackendNative *native = META_BACKEND_NATIVE (backend);
|
MetaBackendNative *native = META_BACKEND_NATIVE (backend);
|
||||||
MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native);
|
MetaLauncher *launcher = meta_backend_native_get_launcher (native);
|
||||||
|
|
||||||
return meta_launcher_activate_vt (priv->launcher, vt, error);
|
return meta_launcher_activate_vt (launcher, vt, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaBarrierManagerNative *
|
MetaBarrierManagerNative *
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "backends/meta-backend-private.h"
|
#include "backends/meta-backend-private.h"
|
||||||
#include "backends/native/meta-clutter-backend-native.h"
|
#include "backends/native/meta-clutter-backend-native.h"
|
||||||
|
#include "backends/native/meta-launcher.h"
|
||||||
|
|
||||||
#define META_TYPE_BACKEND_NATIVE (meta_backend_native_get_type ())
|
#define META_TYPE_BACKEND_NATIVE (meta_backend_native_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (MetaBackendNative, meta_backend_native,
|
G_DECLARE_FINAL_TYPE (MetaBackendNative, meta_backend_native,
|
||||||
@ -38,4 +39,6 @@ void meta_backend_native_pause (MetaBackendNative *backend_native);
|
|||||||
|
|
||||||
void meta_backend_native_resume (MetaBackendNative *backend_native);
|
void meta_backend_native_resume (MetaBackendNative *backend_native);
|
||||||
|
|
||||||
|
MetaLauncher * meta_backend_native_get_launcher (MetaBackendNative *native);
|
||||||
|
|
||||||
#endif /* META_BACKEND_NATIVE_H */
|
#endif /* META_BACKEND_NATIVE_H */
|
||||||
|
@ -862,8 +862,12 @@ meta_cursor_renderer_native_init (MetaCursorRendererNative *native)
|
|||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||||
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
||||||
|
MetaMonitorManager *monitor_manager =
|
||||||
|
meta_backend_get_monitor_manager (backend);
|
||||||
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
|
META_MONITOR_MANAGER_KMS (monitor_manager);
|
||||||
|
|
||||||
priv->drm_fd = meta_renderer_native_get_kms_fd (renderer_native);
|
priv->drm_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms);
|
||||||
priv->gbm = meta_renderer_native_get_gbm (renderer_native);
|
priv->gbm = meta_renderer_native_get_gbm (renderer_native);
|
||||||
|
|
||||||
uint64_t width, height;
|
uint64_t width, height;
|
||||||
|
@ -47,20 +47,22 @@
|
|||||||
#include "meta-idle-monitor-native.h"
|
#include "meta-idle-monitor-native.h"
|
||||||
#include "meta-renderer-native.h"
|
#include "meta-renderer-native.h"
|
||||||
|
|
||||||
#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor"
|
|
||||||
|
|
||||||
struct _MetaLauncher
|
struct _MetaLauncher
|
||||||
{
|
{
|
||||||
Login1Session *session_proxy;
|
Login1Session *session_proxy;
|
||||||
Login1Seat *seat_proxy;
|
Login1Seat *seat_proxy;
|
||||||
|
char *seat_id;
|
||||||
|
|
||||||
GHashTable *sysfs_fds;
|
GHashTable *sysfs_fds;
|
||||||
gboolean session_active;
|
gboolean session_active;
|
||||||
|
|
||||||
int kms_fd;
|
|
||||||
char *kms_file_path;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *
|
||||||
|
meta_launcher_get_seat_id (MetaLauncher *launcher)
|
||||||
|
{
|
||||||
|
return launcher->seat_id;
|
||||||
|
}
|
||||||
|
|
||||||
static Login1Session *
|
static Login1Session *
|
||||||
get_session_proxy (GCancellable *cancellable,
|
get_session_proxy (GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -171,6 +173,54 @@ get_device_info_from_fd (int fd,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
meta_launcher_open_restricted (MetaLauncher *launcher,
|
||||||
|
const char *path,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int major, minor;
|
||||||
|
|
||||||
|
if (!get_device_info_from_path (path, &major, &minor))
|
||||||
|
{
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_NOT_FOUND,
|
||||||
|
"Could not get device info for path %s: %m", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!take_device (launcher->session_proxy, major, minor, &fd, NULL, error))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_launcher_close_restricted (MetaLauncher *launcher,
|
||||||
|
int fd)
|
||||||
|
{
|
||||||
|
int major, minor;
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
if (!get_device_info_from_fd (fd, &major, &minor))
|
||||||
|
{
|
||||||
|
g_warning ("Could not get device info for fd %d: %m", fd);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!login1_session_call_release_device_sync (launcher->session_proxy,
|
||||||
|
major, minor,
|
||||||
|
NULL, &error))
|
||||||
|
{
|
||||||
|
g_warning ("Could not release device (%d,%d): %s",
|
||||||
|
major, minor, error->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
close (fd);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
on_evdev_device_open (const char *path,
|
on_evdev_device_open (const char *path,
|
||||||
int flags,
|
int flags,
|
||||||
@ -178,12 +228,12 @@ on_evdev_device_open (const char *path,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaLauncher *self = user_data;
|
MetaLauncher *self = user_data;
|
||||||
int fd;
|
|
||||||
int major, minor;
|
|
||||||
|
|
||||||
/* Allow readonly access to sysfs */
|
/* Allow readonly access to sysfs */
|
||||||
if (g_str_has_prefix (path, "/sys/"))
|
if (g_str_has_prefix (path, "/sys/"))
|
||||||
{
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
fd = open (path, flags);
|
fd = open (path, flags);
|
||||||
@ -203,19 +253,7 @@ on_evdev_device_open (const char *path,
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_device_info_from_path (path, &major, &minor))
|
return meta_launcher_open_restricted (self, path, error);
|
||||||
{
|
|
||||||
g_set_error (error,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_NOT_FOUND,
|
|
||||||
"Could not get device info for path %s: %m", path);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!take_device (self->session_proxy, major, minor, &fd, NULL, error))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return fd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -223,8 +261,6 @@ on_evdev_device_close (int fd,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaLauncher *self = user_data;
|
MetaLauncher *self = user_data;
|
||||||
int major, minor;
|
|
||||||
GError *error = NULL;
|
|
||||||
|
|
||||||
if (g_hash_table_lookup (self->sysfs_fds, GINT_TO_POINTER (fd)))
|
if (g_hash_table_lookup (self->sysfs_fds, GINT_TO_POINTER (fd)))
|
||||||
{
|
{
|
||||||
@ -234,21 +270,7 @@ on_evdev_device_close (int fd,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_device_info_from_fd (fd, &major, &minor))
|
meta_launcher_close_restricted (self, fd);
|
||||||
{
|
|
||||||
g_warning ("Could not get device info for fd %d: %m", fd);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!login1_session_call_release_device_sync (self->session_proxy,
|
|
||||||
major, minor,
|
|
||||||
NULL, &error))
|
|
||||||
{
|
|
||||||
g_warning ("Could not release device %d,%d: %s", major, minor, error->message);
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
close (fd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -278,194 +300,6 @@ on_active_changed (Login1Session *session,
|
|||||||
sync_active (self);
|
sync_active (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static guint
|
|
||||||
count_devices_with_connectors (const gchar *seat_name,
|
|
||||||
GList *devices)
|
|
||||||
{
|
|
||||||
g_autoptr (GHashTable) cards = NULL;
|
|
||||||
GList *tmp;
|
|
||||||
|
|
||||||
cards = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
|
|
||||||
for (tmp = devices; tmp != NULL; tmp = tmp->next)
|
|
||||||
{
|
|
||||||
GUdevDevice *device = tmp->data;
|
|
||||||
g_autoptr (GUdevDevice) parent_device = NULL;
|
|
||||||
const gchar *parent_device_type = NULL;
|
|
||||||
const gchar *parent_device_name = NULL;
|
|
||||||
const gchar *card_seat;
|
|
||||||
|
|
||||||
/* filter out the real card devices, we only care about the connectors */
|
|
||||||
if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_NONE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* only connectors have a modes attribute */
|
|
||||||
if (!g_udev_device_has_sysfs_attr (device, "modes"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
parent_device = g_udev_device_get_parent (device);
|
|
||||||
|
|
||||||
if (g_udev_device_get_device_type (parent_device) == G_UDEV_DEVICE_TYPE_CHAR)
|
|
||||||
parent_device_type = g_udev_device_get_property (parent_device, "DEVTYPE");
|
|
||||||
|
|
||||||
if (g_strcmp0 (parent_device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
card_seat = g_udev_device_get_property (parent_device, "ID_SEAT");
|
|
||||||
|
|
||||||
if (!card_seat)
|
|
||||||
card_seat = "seat0";
|
|
||||||
|
|
||||||
if (g_strcmp0 (seat_name, card_seat) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
parent_device_name = g_udev_device_get_name (parent_device);
|
|
||||||
g_hash_table_insert (cards,
|
|
||||||
(gpointer) parent_device_name ,
|
|
||||||
g_steal_pointer (&parent_device));
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_hash_table_size (cards);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gchar *
|
|
||||||
get_primary_gpu_path (const gchar *seat_name)
|
|
||||||
{
|
|
||||||
const gchar *subsystems[] = {"drm", NULL};
|
|
||||||
gchar *path = NULL;
|
|
||||||
GList *devices, *tmp;
|
|
||||||
|
|
||||||
g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems);
|
|
||||||
g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client);
|
|
||||||
|
|
||||||
g_udev_enumerator_add_match_name (enumerator, "card*");
|
|
||||||
g_udev_enumerator_add_match_tag (enumerator, "seat");
|
|
||||||
|
|
||||||
/* We need to explicitly match the subsystem for now.
|
|
||||||
* https://bugzilla.gnome.org/show_bug.cgi?id=773224
|
|
||||||
*/
|
|
||||||
g_udev_enumerator_add_match_subsystem (enumerator, "drm");
|
|
||||||
|
|
||||||
devices = g_udev_enumerator_execute (enumerator);
|
|
||||||
if (!devices)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
/* For now, fail on systems where some of the connectors
|
|
||||||
* are connected to secondary gpus.
|
|
||||||
*
|
|
||||||
* https://bugzilla.gnome.org/show_bug.cgi?id=771442
|
|
||||||
*/
|
|
||||||
if (g_getenv ("MUTTER_ALLOW_HYBRID_GPUS") == NULL)
|
|
||||||
{
|
|
||||||
guint num_devices;
|
|
||||||
|
|
||||||
num_devices = count_devices_with_connectors (seat_name, devices);
|
|
||||||
if (num_devices != 1)
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (tmp = devices; tmp != NULL; tmp = tmp->next)
|
|
||||||
{
|
|
||||||
g_autoptr (GUdevDevice) platform_device = NULL;
|
|
||||||
g_autoptr (GUdevDevice) pci_device = NULL;
|
|
||||||
GUdevDevice *dev = tmp->data;
|
|
||||||
gint boot_vga;
|
|
||||||
const gchar *device_type;
|
|
||||||
const gchar *device_seat;
|
|
||||||
|
|
||||||
/* filter out devices that are not character device, like card0-VGA-1 */
|
|
||||||
if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
device_type = g_udev_device_get_property (dev, "DEVTYPE");
|
|
||||||
if (g_strcmp0 (device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
device_seat = g_udev_device_get_property (dev, "ID_SEAT");
|
|
||||||
if (!device_seat)
|
|
||||||
{
|
|
||||||
/* when ID_SEAT is not set, it means seat0 */
|
|
||||||
device_seat = "seat0";
|
|
||||||
}
|
|
||||||
else if (g_strcmp0 (device_seat, "seat0") != 0)
|
|
||||||
{
|
|
||||||
/* if the device has been explicitly assigned other seat
|
|
||||||
* than seat0, it is probably the right device to use */
|
|
||||||
path = g_strdup (g_udev_device_get_device_file (dev));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* skip devices that do not belong to our seat */
|
|
||||||
if (g_strcmp0 (seat_name, device_seat))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
platform_device = g_udev_device_get_parent_with_subsystem (dev, "platform", NULL);
|
|
||||||
if (platform_device != NULL)
|
|
||||||
{
|
|
||||||
path = g_strdup (g_udev_device_get_device_file (dev));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
|
|
||||||
if (pci_device != NULL)
|
|
||||||
{
|
|
||||||
/* get value of boot_vga attribute or 0 if the device has no boot_vga */
|
|
||||||
boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga");
|
|
||||||
if (boot_vga == 1)
|
|
||||||
{
|
|
||||||
/* found the boot_vga device */
|
|
||||||
path = g_strdup (g_udev_device_get_device_file (dev));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
g_list_free_full (devices, g_object_unref);
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
get_kms_fd (Login1Session *session_proxy,
|
|
||||||
const gchar *seat_id,
|
|
||||||
int *fd_out,
|
|
||||||
char **kms_file_path_out,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
int major, minor;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
g_autofree gchar *path = get_primary_gpu_path (seat_id);
|
|
||||||
if (!path)
|
|
||||||
{
|
|
||||||
g_set_error (error,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_NOT_FOUND,
|
|
||||||
"could not find drm kms device");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!get_device_info_from_path (path, &major, &minor))
|
|
||||||
{
|
|
||||||
g_set_error (error,
|
|
||||||
G_IO_ERROR,
|
|
||||||
G_IO_ERROR_NOT_FOUND,
|
|
||||||
"Could not get device info for path %s: %m", path);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!take_device (session_proxy, major, minor, &fd, NULL, error))
|
|
||||||
{
|
|
||||||
g_prefix_error (error, "Could not open DRM device: ");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*fd_out = fd;
|
|
||||||
*kms_file_path_out = g_steal_pointer (&path);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
get_seat_id (GError **error)
|
get_seat_id (GError **error)
|
||||||
{
|
{
|
||||||
@ -504,8 +338,6 @@ meta_launcher_new (GError **error)
|
|||||||
g_autoptr (Login1Seat) seat_proxy = NULL;
|
g_autoptr (Login1Seat) seat_proxy = NULL;
|
||||||
g_autofree char *seat_id = NULL;
|
g_autofree char *seat_id = NULL;
|
||||||
gboolean have_control = FALSE;
|
gboolean have_control = FALSE;
|
||||||
int kms_fd;
|
|
||||||
char *kms_file_path;
|
|
||||||
|
|
||||||
session_proxy = get_session_proxy (NULL, error);
|
session_proxy = get_session_proxy (NULL, error);
|
||||||
if (!session_proxy)
|
if (!session_proxy)
|
||||||
@ -527,25 +359,21 @@ meta_launcher_new (GError **error)
|
|||||||
if (!seat_proxy)
|
if (!seat_proxy)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (!get_kms_fd (session_proxy, seat_id, &kms_fd, &kms_file_path, error))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
self = g_slice_new0 (MetaLauncher);
|
self = g_slice_new0 (MetaLauncher);
|
||||||
self->session_proxy = g_object_ref (session_proxy);
|
self->session_proxy = g_object_ref (session_proxy);
|
||||||
self->seat_proxy = g_object_ref (seat_proxy);
|
self->seat_proxy = g_object_ref (seat_proxy);
|
||||||
|
self->seat_id = g_steal_pointer (&seat_id);
|
||||||
self->sysfs_fds = g_hash_table_new (NULL, NULL);
|
self->sysfs_fds = g_hash_table_new (NULL, NULL);
|
||||||
|
|
||||||
self->session_active = TRUE;
|
self->session_active = TRUE;
|
||||||
self->kms_fd = kms_fd;
|
|
||||||
self->kms_file_path = kms_file_path;
|
|
||||||
|
|
||||||
clutter_evdev_set_seat_id (seat_id);
|
clutter_evdev_set_seat_id (self->seat_id);
|
||||||
|
|
||||||
clutter_evdev_set_device_callbacks (on_evdev_device_open,
|
clutter_evdev_set_device_callbacks (on_evdev_device_open,
|
||||||
on_evdev_device_close,
|
on_evdev_device_close,
|
||||||
self);
|
self);
|
||||||
|
|
||||||
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -557,10 +385,10 @@ meta_launcher_new (GError **error)
|
|||||||
void
|
void
|
||||||
meta_launcher_free (MetaLauncher *self)
|
meta_launcher_free (MetaLauncher *self)
|
||||||
{
|
{
|
||||||
|
g_free (self->seat_id);
|
||||||
g_object_unref (self->seat_proxy);
|
g_object_unref (self->seat_proxy);
|
||||||
g_object_unref (self->session_proxy);
|
g_object_unref (self->session_proxy);
|
||||||
g_hash_table_destroy (self->sysfs_fds);
|
g_hash_table_destroy (self->sysfs_fds);
|
||||||
g_free (self->kms_file_path);
|
|
||||||
g_slice_free (MetaLauncher, self);
|
g_slice_free (MetaLauncher, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,15 +410,3 @@ meta_launcher_activate_vt (MetaLauncher *launcher,
|
|||||||
{
|
{
|
||||||
return login1_seat_call_switch_to_sync (launcher->seat_proxy, vt, NULL, error);
|
return login1_seat_call_switch_to_sync (launcher->seat_proxy, vt, NULL, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
meta_launcher_get_kms_fd (MetaLauncher *self)
|
|
||||||
{
|
|
||||||
return self->kms_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
meta_launcher_get_kms_file_path (MetaLauncher *self)
|
|
||||||
{
|
|
||||||
return self->kms_file_path;
|
|
||||||
}
|
|
||||||
|
@ -34,8 +34,14 @@ gboolean meta_launcher_activate_vt (MetaLauncher *self,
|
|||||||
signed char vt,
|
signed char vt,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
int meta_launcher_get_kms_fd (MetaLauncher *self);
|
const char * meta_launcher_get_seat_id (MetaLauncher *launcher);
|
||||||
|
|
||||||
|
int meta_launcher_open_restricted (MetaLauncher *launcher,
|
||||||
|
const char *path,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
void meta_launcher_close_restricted (MetaLauncher *launcher,
|
||||||
|
int fd);
|
||||||
|
|
||||||
const char * meta_launcher_get_kms_file_path (MetaLauncher *self);
|
|
||||||
|
|
||||||
#endif /* META_LAUNCHER_H */
|
#endif /* META_LAUNCHER_H */
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
|
|
||||||
#include "meta-monitor-manager-kms.h"
|
#include "meta-monitor-manager-kms.h"
|
||||||
#include "meta-monitor-config-manager.h"
|
#include "meta-monitor-config-manager.h"
|
||||||
|
#include "meta-backend-native.h"
|
||||||
#include "meta-crtc.h"
|
#include "meta-crtc.h"
|
||||||
|
#include "meta-launcher.h"
|
||||||
#include "meta-output.h"
|
#include "meta-output.h"
|
||||||
#include "meta-backend-private.h"
|
#include "meta-backend-private.h"
|
||||||
#include "meta-renderer-native.h"
|
#include "meta-renderer-native.h"
|
||||||
@ -49,6 +51,8 @@
|
|||||||
|
|
||||||
#include "meta-default-modes.h"
|
#include "meta-default-modes.h"
|
||||||
|
|
||||||
|
#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
GSource source;
|
GSource source;
|
||||||
@ -62,6 +66,7 @@ struct _MetaMonitorManagerKms
|
|||||||
MetaMonitorManager parent_instance;
|
MetaMonitorManager parent_instance;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
|
char *file_path;
|
||||||
MetaKmsSource *source;
|
MetaKmsSource *source;
|
||||||
|
|
||||||
drmModeConnector **connectors;
|
drmModeConnector **connectors;
|
||||||
@ -81,7 +86,13 @@ struct _MetaMonitorManagerKmsClass
|
|||||||
MetaMonitorManagerClass parent_class;
|
MetaMonitorManagerClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaMonitorManagerKms, meta_monitor_manager_kms, META_TYPE_MONITOR_MANAGER);
|
static void
|
||||||
|
initable_iface_init (GInitableIface *initable_iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (MetaMonitorManagerKms, meta_monitor_manager_kms,
|
||||||
|
META_TYPE_MONITOR_MANAGER,
|
||||||
|
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
|
||||||
|
initable_iface_init))
|
||||||
|
|
||||||
int
|
int
|
||||||
meta_monitor_manager_kms_get_fd (MetaMonitorManagerKms *manager_kms)
|
meta_monitor_manager_kms_get_fd (MetaMonitorManagerKms *manager_kms)
|
||||||
@ -89,6 +100,12 @@ meta_monitor_manager_kms_get_fd (MetaMonitorManagerKms *manager_kms)
|
|||||||
return manager_kms->fd;
|
return manager_kms->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
meta_monitor_manager_kms_get_file_path (MetaMonitorManagerKms *manager_kms)
|
||||||
|
{
|
||||||
|
return manager_kms->file_path;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_resources (MetaMonitorManagerKms *manager_kms)
|
free_resources (MetaMonitorManagerKms *manager_kms)
|
||||||
{
|
{
|
||||||
@ -1076,6 +1093,235 @@ meta_monitor_manager_kms_get_default_layout_mode (MetaMonitorManager *manager)
|
|||||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static guint
|
||||||
|
count_devices_with_connectors (const char *seat_id,
|
||||||
|
GList *devices)
|
||||||
|
{
|
||||||
|
g_autoptr (GHashTable) cards = NULL;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
cards = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
|
||||||
|
for (l = devices; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
GUdevDevice *device = l->data;
|
||||||
|
g_autoptr (GUdevDevice) parent_device = NULL;
|
||||||
|
const gchar *parent_device_type = NULL;
|
||||||
|
const gchar *parent_device_name = NULL;
|
||||||
|
const gchar *card_seat;
|
||||||
|
|
||||||
|
/* Filter out the real card devices, we only care about the connectors. */
|
||||||
|
if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Only connectors have a modes attribute. */
|
||||||
|
if (!g_udev_device_has_sysfs_attr (device, "modes"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
parent_device = g_udev_device_get_parent (device);
|
||||||
|
|
||||||
|
if (g_udev_device_get_device_type (parent_device) ==
|
||||||
|
G_UDEV_DEVICE_TYPE_CHAR)
|
||||||
|
parent_device_type = g_udev_device_get_property (parent_device,
|
||||||
|
"DEVTYPE");
|
||||||
|
|
||||||
|
if (g_strcmp0 (parent_device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
card_seat = g_udev_device_get_property (parent_device, "ID_SEAT");
|
||||||
|
|
||||||
|
if (!card_seat)
|
||||||
|
card_seat = "seat0";
|
||||||
|
|
||||||
|
if (g_strcmp0 (seat_id, card_seat) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
parent_device_name = g_udev_device_get_name (parent_device);
|
||||||
|
g_hash_table_insert (cards,
|
||||||
|
(gpointer) parent_device_name ,
|
||||||
|
g_steal_pointer (&parent_device));
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_hash_table_size (cards);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
get_primary_gpu_path (MetaMonitorManagerKms *manager_kms)
|
||||||
|
{
|
||||||
|
MetaBackend *backend = meta_get_backend ();
|
||||||
|
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||||
|
MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
|
||||||
|
g_autoptr (GUdevEnumerator) enumerator = NULL;
|
||||||
|
const char *seat_id;
|
||||||
|
char *path = NULL;
|
||||||
|
GList *devices;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
enumerator = g_udev_enumerator_new (manager_kms->udev);
|
||||||
|
|
||||||
|
g_udev_enumerator_add_match_name (enumerator, "card*");
|
||||||
|
g_udev_enumerator_add_match_tag (enumerator, "seat");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to explicitly match the subsystem for now.
|
||||||
|
* https://bugzilla.gnome.org/show_bug.cgi?id=773224
|
||||||
|
*/
|
||||||
|
g_udev_enumerator_add_match_subsystem (enumerator, "drm");
|
||||||
|
|
||||||
|
devices = g_udev_enumerator_execute (enumerator);
|
||||||
|
if (!devices)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
seat_id = meta_launcher_get_seat_id (launcher);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For now, fail on systems where some of the connectors are connected to
|
||||||
|
* secondary gpus.
|
||||||
|
*
|
||||||
|
* https://bugzilla.gnome.org/show_bug.cgi?id=771442
|
||||||
|
*/
|
||||||
|
if (g_getenv ("MUTTER_ALLOW_HYBRID_GPUS") == NULL)
|
||||||
|
{
|
||||||
|
unsigned int num_devices;
|
||||||
|
|
||||||
|
num_devices = count_devices_with_connectors (seat_id, devices);
|
||||||
|
if (num_devices != 1)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = devices; l; l = l->next)
|
||||||
|
{
|
||||||
|
GUdevDevice *dev = l->data;
|
||||||
|
g_autoptr (GUdevDevice) platform_device = NULL;
|
||||||
|
g_autoptr (GUdevDevice) pci_device = NULL;
|
||||||
|
const char *device_type;
|
||||||
|
const char *device_seat;
|
||||||
|
|
||||||
|
/* Filter out devices that are not character device, like card0-VGA-1. */
|
||||||
|
if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
device_type = g_udev_device_get_property (dev, "DEVTYPE");
|
||||||
|
if (g_strcmp0 (device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
device_seat = g_udev_device_get_property (dev, "ID_SEAT");
|
||||||
|
if (!device_seat)
|
||||||
|
{
|
||||||
|
/* When ID_SEAT is not set, it means seat0. */
|
||||||
|
device_seat = "seat0";
|
||||||
|
}
|
||||||
|
else if (g_strcmp0 (device_seat, "seat0") != 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the device has been explicitly assigned other seat
|
||||||
|
* than seat0, it is probably the right device to use.
|
||||||
|
*/
|
||||||
|
path = g_strdup (g_udev_device_get_device_file (dev));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip devices that do not belong to our seat. */
|
||||||
|
if (g_strcmp0 (seat_id, device_seat))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
platform_device = g_udev_device_get_parent_with_subsystem (dev,
|
||||||
|
"platform",
|
||||||
|
NULL);
|
||||||
|
if (platform_device != NULL)
|
||||||
|
{
|
||||||
|
path = g_strdup (g_udev_device_get_device_file (dev));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
|
||||||
|
if (pci_device != NULL)
|
||||||
|
{
|
||||||
|
int boot_vga;
|
||||||
|
|
||||||
|
boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device,
|
||||||
|
"boot_vga");
|
||||||
|
if (boot_vga == 1)
|
||||||
|
{
|
||||||
|
path = g_strdup (g_udev_device_get_device_file (dev));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_list_free_full (devices, g_object_unref);
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
open_primary_gpu (MetaMonitorManagerKms *manager_kms,
|
||||||
|
int *fd_out,
|
||||||
|
char **kms_file_path_out,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
MetaBackend *backend = meta_get_backend ();
|
||||||
|
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||||
|
MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
|
||||||
|
g_autofree char *path = NULL;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
path = get_primary_gpu_path (manager_kms);
|
||||||
|
if (!path)
|
||||||
|
{
|
||||||
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||||
|
"Could not find drm kms device");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = meta_launcher_open_restricted (launcher, path, error);
|
||||||
|
if (fd == -1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*fd_out = fd;
|
||||||
|
*kms_file_path_out = g_steal_pointer (&path);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
meta_monitor_manager_kms_initable_init (GInitable *initable,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (initable);
|
||||||
|
GSource *source;
|
||||||
|
const char *subsystems[2] = { "drm", NULL };
|
||||||
|
|
||||||
|
manager_kms->udev = g_udev_client_new (subsystems);
|
||||||
|
|
||||||
|
if (!open_primary_gpu (manager_kms,
|
||||||
|
&manager_kms->fd,
|
||||||
|
&manager_kms->file_path,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
drmSetClientCap (manager_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||||
|
|
||||||
|
meta_monitor_manager_kms_connect_uevent_handler (manager_kms);
|
||||||
|
|
||||||
|
source = g_source_new (&kms_event_funcs, sizeof (MetaKmsSource));
|
||||||
|
manager_kms->source = (MetaKmsSource *) source;
|
||||||
|
manager_kms->source->fd_tag = g_source_add_unix_fd (source,
|
||||||
|
manager_kms->fd,
|
||||||
|
G_IO_IN | G_IO_ERR);
|
||||||
|
manager_kms->source->manager_kms = manager_kms;
|
||||||
|
g_source_attach (source, NULL);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
initable_iface_init (GInitableIface *initable_iface)
|
||||||
|
{
|
||||||
|
initable_iface->init = meta_monitor_manager_kms_initable_init;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_monitor_manager_kms_dispose (GObject *object)
|
meta_monitor_manager_kms_dispose (GObject *object)
|
||||||
{
|
{
|
||||||
@ -1090,6 +1336,13 @@ static void
|
|||||||
meta_monitor_manager_kms_finalize (GObject *object)
|
meta_monitor_manager_kms_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
|
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
|
||||||
|
MetaBackend *backend = meta_get_backend ();
|
||||||
|
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||||
|
MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
|
||||||
|
|
||||||
|
if (manager_kms->fd != -1)
|
||||||
|
meta_launcher_close_restricted (launcher, manager_kms->fd);
|
||||||
|
g_clear_pointer (&manager_kms->file_path, g_free);
|
||||||
|
|
||||||
free_resources (manager_kms);
|
free_resources (manager_kms);
|
||||||
g_source_destroy ((GSource *) manager_kms->source);
|
g_source_destroy ((GSource *) manager_kms->source);
|
||||||
@ -1100,26 +1353,7 @@ meta_monitor_manager_kms_finalize (GObject *object)
|
|||||||
static void
|
static void
|
||||||
meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
|
meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
manager_kms->fd = -1;
|
||||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
|
||||||
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
|
||||||
GSource *source;
|
|
||||||
|
|
||||||
manager_kms->fd = meta_renderer_native_get_kms_fd (renderer_native);
|
|
||||||
|
|
||||||
drmSetClientCap (manager_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
|
||||||
|
|
||||||
const char *subsystems[2] = { "drm", NULL };
|
|
||||||
manager_kms->udev = g_udev_client_new (subsystems);
|
|
||||||
meta_monitor_manager_kms_connect_uevent_handler (manager_kms);
|
|
||||||
|
|
||||||
source = g_source_new (&kms_event_funcs, sizeof (MetaKmsSource));
|
|
||||||
manager_kms->source = (MetaKmsSource *) source;
|
|
||||||
manager_kms->source->fd_tag = g_source_add_unix_fd (source,
|
|
||||||
manager_kms->fd,
|
|
||||||
G_IO_IN | G_IO_ERR);
|
|
||||||
manager_kms->source->manager_kms = manager_kms;
|
|
||||||
g_source_attach (source, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -44,6 +44,8 @@ typedef void (*MetaKmsFlipCallback) (void *user_data);
|
|||||||
|
|
||||||
int meta_monitor_manager_kms_get_fd (MetaMonitorManagerKms *manager_kms);
|
int meta_monitor_manager_kms_get_fd (MetaMonitorManagerKms *manager_kms);
|
||||||
|
|
||||||
|
const char * meta_monitor_manager_kms_get_file_path (MetaMonitorManagerKms *manager_kms);
|
||||||
|
|
||||||
gboolean meta_drm_mode_equal (const drmModeModeInfo *one,
|
gboolean meta_drm_mode_equal (const drmModeModeInfo *one,
|
||||||
const drmModeModeInfo *two);
|
const drmModeModeInfo *two);
|
||||||
|
|
||||||
|
@ -67,12 +67,13 @@ enum
|
|||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
|
||||||
PROP_KMS_FD,
|
PROP_MONITOR_MANAGER,
|
||||||
PROP_KMS_FILE_PATH,
|
|
||||||
|
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static GParamSpec *obj_props[PROP_LAST];
|
||||||
|
|
||||||
typedef struct _MetaOnscreenNative
|
typedef struct _MetaOnscreenNative
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
@ -112,8 +113,7 @@ struct _MetaRendererNative
|
|||||||
{
|
{
|
||||||
MetaRenderer parent;
|
MetaRenderer parent;
|
||||||
|
|
||||||
int kms_fd;
|
MetaMonitorManagerKms *monitor_manager_kms;
|
||||||
char *kms_file_path;
|
|
||||||
|
|
||||||
MetaRendererNativeMode mode;
|
MetaRendererNativeMode mode;
|
||||||
|
|
||||||
@ -224,11 +224,15 @@ free_current_bo (CoglOnscreen *onscreen)
|
|||||||
CoglRenderer *cogl_renderer = cogl_context->display->renderer;
|
CoglRenderer *cogl_renderer = cogl_context->display->renderer;
|
||||||
CoglRendererEGL *egl_renderer = cogl_renderer->winsys;
|
CoglRendererEGL *egl_renderer = cogl_renderer->winsys;
|
||||||
MetaRendererNative *renderer_native = egl_renderer->platform;
|
MetaRendererNative *renderer_native = egl_renderer->platform;
|
||||||
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
|
renderer_native->monitor_manager_kms;
|
||||||
|
int kms_fd;
|
||||||
|
|
||||||
|
kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms);
|
||||||
|
|
||||||
if (onscreen_native->gbm.current_fb_id)
|
if (onscreen_native->gbm.current_fb_id)
|
||||||
{
|
{
|
||||||
drmModeRmFB (renderer_native->kms_fd,
|
drmModeRmFB (kms_fd, onscreen_native->gbm.current_fb_id);
|
||||||
onscreen_native->gbm.current_fb_id);
|
|
||||||
onscreen_native->gbm.current_fb_id = 0;
|
onscreen_native->gbm.current_fb_id = 0;
|
||||||
}
|
}
|
||||||
if (onscreen_native->gbm.current_bo)
|
if (onscreen_native->gbm.current_bo)
|
||||||
@ -499,7 +503,12 @@ flip_closure_destroyed (MetaRendererView *view)
|
|||||||
case META_RENDERER_NATIVE_MODE_GBM:
|
case META_RENDERER_NATIVE_MODE_GBM:
|
||||||
if (onscreen_native->gbm.next_fb_id)
|
if (onscreen_native->gbm.next_fb_id)
|
||||||
{
|
{
|
||||||
drmModeRmFB (renderer_native->kms_fd, onscreen_native->gbm.next_fb_id);
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
|
renderer_native->monitor_manager_kms;
|
||||||
|
int kms_fd;
|
||||||
|
|
||||||
|
kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms);
|
||||||
|
drmModeRmFB (kms_fd, onscreen_native->gbm.next_fb_id);
|
||||||
gbm_surface_release_buffer (onscreen_native->gbm.surface,
|
gbm_surface_release_buffer (onscreen_native->gbm.surface,
|
||||||
onscreen_native->gbm.next_bo);
|
onscreen_native->gbm.next_bo);
|
||||||
onscreen_native->gbm.next_bo = NULL;
|
onscreen_native->gbm.next_bo = NULL;
|
||||||
@ -581,10 +590,8 @@ meta_onscreen_native_flip_crtc (MetaOnscreenNative *onscreen_native,
|
|||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||||
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
||||||
MetaMonitorManager *monitor_manager =
|
|
||||||
meta_backend_get_monitor_manager (backend);
|
|
||||||
MetaMonitorManagerKms *monitor_manager_kms =
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
renderer_native->monitor_manager_kms;
|
||||||
|
|
||||||
if (!meta_monitor_manager_kms_is_crtc_active (monitor_manager_kms,
|
if (!meta_monitor_manager_kms_is_crtc_active (monitor_manager_kms,
|
||||||
crtc))
|
crtc))
|
||||||
@ -618,7 +625,7 @@ meta_onscreen_native_flip_crtc (MetaOnscreenNative *onscreen_native,
|
|||||||
|
|
||||||
typedef struct _SetCrtcFbData
|
typedef struct _SetCrtcFbData
|
||||||
{
|
{
|
||||||
MetaMonitorManager *monitor_manager;
|
MetaMonitorManagerKms *monitor_manager_kms;
|
||||||
MetaLogicalMonitor *logical_monitor;
|
MetaLogicalMonitor *logical_monitor;
|
||||||
uint32_t fb_id;
|
uint32_t fb_id;
|
||||||
} SetCrtcFbData;
|
} SetCrtcFbData;
|
||||||
@ -629,8 +636,7 @@ set_crtc_fb (MetaLogicalMonitor *logical_monitor,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
SetCrtcFbData *data = user_data;
|
SetCrtcFbData *data = user_data;
|
||||||
MetaMonitorManagerKms *monitor_manager_kms =
|
MetaMonitorManagerKms *monitor_manager_kms = data->monitor_manager_kms;
|
||||||
META_MONITOR_MANAGER_KMS (data->monitor_manager);
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
x = crtc->rect.x - logical_monitor->rect.x;
|
x = crtc->rect.x - logical_monitor->rect.x;
|
||||||
@ -648,10 +654,8 @@ meta_onscreen_native_set_crtc_modes (MetaOnscreenNative *onscreen_native)
|
|||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||||
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
||||||
MetaMonitorManager *monitor_manager =
|
|
||||||
meta_backend_get_monitor_manager (backend);
|
|
||||||
MetaMonitorManagerKms *monitor_manager_kms =
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
renderer_native->monitor_manager_kms;
|
||||||
MetaRendererView *view = onscreen_native->view;
|
MetaRendererView *view = onscreen_native->view;
|
||||||
uint32_t fb_id = 0;
|
uint32_t fb_id = 0;
|
||||||
MetaLogicalMonitor *logical_monitor;
|
MetaLogicalMonitor *logical_monitor;
|
||||||
@ -674,7 +678,7 @@ meta_onscreen_native_set_crtc_modes (MetaOnscreenNative *onscreen_native)
|
|||||||
if (logical_monitor)
|
if (logical_monitor)
|
||||||
{
|
{
|
||||||
SetCrtcFbData data = {
|
SetCrtcFbData data = {
|
||||||
.monitor_manager = monitor_manager,
|
.monitor_manager_kms = monitor_manager_kms,
|
||||||
.fb_id = fb_id
|
.fb_id = fb_id
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -684,6 +688,8 @@ meta_onscreen_native_set_crtc_modes (MetaOnscreenNative *onscreen_native)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
MetaMonitorManager *monitor_manager =
|
||||||
|
META_MONITOR_MANAGER (monitor_manager_kms);
|
||||||
GList *crtcs;
|
GList *crtcs;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
@ -730,10 +736,13 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
|
|||||||
{
|
{
|
||||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
MetaOnscreenNative *onscreen_native = egl_onscreen->platform;
|
MetaOnscreenNative *onscreen_native = egl_onscreen->platform;
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
MetaMonitorManager *monitor_manager =
|
|
||||||
meta_backend_get_monitor_manager (backend);
|
|
||||||
MetaRendererView *view = onscreen_native->view;
|
MetaRendererView *view = onscreen_native->view;
|
||||||
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
CoglContext *cogl_context = framebuffer->context;
|
||||||
|
CoglDisplay *cogl_display = cogl_context->display;
|
||||||
|
CoglRenderer *cogl_renderer = cogl_display->renderer;
|
||||||
|
CoglRendererEGL *egl_renderer = cogl_renderer->winsys;
|
||||||
|
MetaRendererNative *renderer_native = egl_renderer->platform;
|
||||||
GClosure *flip_closure;
|
GClosure *flip_closure;
|
||||||
MetaLogicalMonitor *logical_monitor;
|
MetaLogicalMonitor *logical_monitor;
|
||||||
gboolean fb_in_use = FALSE;
|
gboolean fb_in_use = FALSE;
|
||||||
@ -771,6 +780,8 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
MetaMonitorManager *monitor_manager =
|
||||||
|
META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
|
||||||
GList *crtcs;
|
GList *crtcs;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
@ -793,9 +804,6 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
|
|||||||
*/
|
*/
|
||||||
if (fb_in_use && onscreen_native->pending_flips == 0)
|
if (fb_in_use && onscreen_native->pending_flips == 0)
|
||||||
{
|
{
|
||||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
|
||||||
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
|
||||||
|
|
||||||
switch (renderer_native->mode)
|
switch (renderer_native->mode)
|
||||||
{
|
{
|
||||||
case META_RENDERER_NATIVE_MODE_GBM:
|
case META_RENDERER_NATIVE_MODE_GBM:
|
||||||
@ -824,9 +832,12 @@ gbm_get_next_fb_id (CoglOnscreen *onscreen,
|
|||||||
MetaRendererNative *renderer_native = egl_renderer->platform;
|
MetaRendererNative *renderer_native = egl_renderer->platform;
|
||||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
MetaOnscreenNative *onscreen_native = egl_onscreen->platform;
|
MetaOnscreenNative *onscreen_native = egl_onscreen->platform;
|
||||||
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
|
renderer_native->monitor_manager_kms;
|
||||||
uint32_t handle, stride;
|
uint32_t handle, stride;
|
||||||
struct gbm_bo *next_bo;
|
struct gbm_bo *next_bo;
|
||||||
uint32_t next_fb_id;
|
uint32_t next_fb_id;
|
||||||
|
int kms_fd;
|
||||||
|
|
||||||
/* Now we need to set the CRTC to whatever is the front buffer */
|
/* Now we need to set the CRTC to whatever is the front buffer */
|
||||||
next_bo = gbm_surface_lock_front_buffer (onscreen_native->gbm.surface);
|
next_bo = gbm_surface_lock_front_buffer (onscreen_native->gbm.surface);
|
||||||
@ -834,7 +845,9 @@ gbm_get_next_fb_id (CoglOnscreen *onscreen,
|
|||||||
stride = gbm_bo_get_stride (next_bo);
|
stride = gbm_bo_get_stride (next_bo);
|
||||||
handle = gbm_bo_get_handle (next_bo).u32;
|
handle = gbm_bo_get_handle (next_bo).u32;
|
||||||
|
|
||||||
if (drmModeAddFB (renderer_native->kms_fd,
|
kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms);
|
||||||
|
|
||||||
|
if (drmModeAddFB (kms_fd,
|
||||||
cogl_framebuffer_get_width (COGL_FRAMEBUFFER (onscreen)),
|
cogl_framebuffer_get_width (COGL_FRAMEBUFFER (onscreen)),
|
||||||
cogl_framebuffer_get_height (COGL_FRAMEBUFFER (onscreen)),
|
cogl_framebuffer_get_height (COGL_FRAMEBUFFER (onscreen)),
|
||||||
24, /* depth */
|
24, /* depth */
|
||||||
@ -864,11 +877,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
MetaRendererNative *renderer_native = egl_renderer->platform;
|
MetaRendererNative *renderer_native = egl_renderer->platform;
|
||||||
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
|
||||||
MetaOnscreenNative *onscreen_native = egl_onscreen->platform;
|
MetaOnscreenNative *onscreen_native = egl_onscreen->platform;
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
MetaMonitorManager *monitor_manager =
|
|
||||||
meta_backend_get_monitor_manager (backend);
|
|
||||||
MetaMonitorManagerKms *monitor_manager_kms =
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
renderer_native->monitor_manager_kms;
|
||||||
CoglFrameInfo *frame_info;
|
CoglFrameInfo *frame_info;
|
||||||
|
|
||||||
frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
|
frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
|
||||||
@ -1106,19 +1116,23 @@ init_dumb_fb (MetaRendererNative *renderer_native,
|
|||||||
int height,
|
int height,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
|
renderer_native->monitor_manager_kms;
|
||||||
struct drm_mode_create_dumb create_arg;
|
struct drm_mode_create_dumb create_arg;
|
||||||
struct drm_mode_destroy_dumb destroy_arg;
|
struct drm_mode_destroy_dumb destroy_arg;
|
||||||
struct drm_mode_map_dumb map_arg;
|
struct drm_mode_map_dumb map_arg;
|
||||||
uint32_t fb_id = 0;
|
uint32_t fb_id = 0;
|
||||||
void *map;
|
void *map;
|
||||||
|
int kms_fd;
|
||||||
|
|
||||||
|
kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms);
|
||||||
|
|
||||||
create_arg = (struct drm_mode_create_dumb) {
|
create_arg = (struct drm_mode_create_dumb) {
|
||||||
.bpp = 32, /* RGBX8888 */
|
.bpp = 32, /* RGBX8888 */
|
||||||
.width = width,
|
.width = width,
|
||||||
.height = height
|
.height = height
|
||||||
};
|
};
|
||||||
if (drmIoctl (renderer_native->kms_fd, DRM_IOCTL_MODE_CREATE_DUMB,
|
if (drmIoctl (kms_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg) != 0)
|
||||||
&create_arg) != 0)
|
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR,
|
g_set_error (error, G_IO_ERROR,
|
||||||
G_IO_ERROR_FAILED,
|
G_IO_ERROR_FAILED,
|
||||||
@ -1133,7 +1147,7 @@ init_dumb_fb (MetaRendererNative *renderer_native,
|
|||||||
uint32_t pitches[4] = { create_arg.pitch, };
|
uint32_t pitches[4] = { create_arg.pitch, };
|
||||||
uint32_t offsets[4] = { 0 };
|
uint32_t offsets[4] = { 0 };
|
||||||
|
|
||||||
if (drmModeAddFB2 (renderer_native->kms_fd, width, height,
|
if (drmModeAddFB2 (kms_fd, width, height,
|
||||||
GBM_FORMAT_XRGB8888,
|
GBM_FORMAT_XRGB8888,
|
||||||
handles, pitches, offsets,
|
handles, pitches, offsets,
|
||||||
&fb_id, 0) != 0)
|
&fb_id, 0) != 0)
|
||||||
@ -1146,7 +1160,7 @@ init_dumb_fb (MetaRendererNative *renderer_native,
|
|||||||
|
|
||||||
if (renderer_native->no_add_fb2)
|
if (renderer_native->no_add_fb2)
|
||||||
{
|
{
|
||||||
if (drmModeAddFB (renderer_native->kms_fd, width, height,
|
if (drmModeAddFB (kms_fd, width, height,
|
||||||
24 /* depth of RGBX8888 */,
|
24 /* depth of RGBX8888 */,
|
||||||
32 /* bpp of RGBX8888 */,
|
32 /* bpp of RGBX8888 */,
|
||||||
create_arg.pitch,
|
create_arg.pitch,
|
||||||
@ -1164,7 +1178,7 @@ init_dumb_fb (MetaRendererNative *renderer_native,
|
|||||||
map_arg = (struct drm_mode_map_dumb) {
|
map_arg = (struct drm_mode_map_dumb) {
|
||||||
.handle = create_arg.handle
|
.handle = create_arg.handle
|
||||||
};
|
};
|
||||||
if (drmIoctl (renderer_native->kms_fd, DRM_IOCTL_MODE_MAP_DUMB,
|
if (drmIoctl (kms_fd, DRM_IOCTL_MODE_MAP_DUMB,
|
||||||
&map_arg) != 0)
|
&map_arg) != 0)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR,
|
g_set_error (error, G_IO_ERROR,
|
||||||
@ -1175,8 +1189,7 @@ init_dumb_fb (MetaRendererNative *renderer_native,
|
|||||||
}
|
}
|
||||||
|
|
||||||
map = mmap (NULL, create_arg.size, PROT_WRITE, MAP_SHARED,
|
map = mmap (NULL, create_arg.size, PROT_WRITE, MAP_SHARED,
|
||||||
renderer_native->kms_fd,
|
kms_fd, map_arg.offset);
|
||||||
map_arg.offset);
|
|
||||||
if (map == MAP_FAILED)
|
if (map == MAP_FAILED)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR,
|
g_set_error (error, G_IO_ERROR,
|
||||||
@ -1195,13 +1208,13 @@ init_dumb_fb (MetaRendererNative *renderer_native,
|
|||||||
|
|
||||||
err_mmap:
|
err_mmap:
|
||||||
err_map_dumb:
|
err_map_dumb:
|
||||||
drmModeRmFB (renderer_native->kms_fd, fb_id);
|
drmModeRmFB (kms_fd, fb_id);
|
||||||
|
|
||||||
err_add_fb:
|
err_add_fb:
|
||||||
destroy_arg = (struct drm_mode_destroy_dumb) {
|
destroy_arg = (struct drm_mode_destroy_dumb) {
|
||||||
.handle = create_arg.handle
|
.handle = create_arg.handle
|
||||||
};
|
};
|
||||||
drmIoctl (renderer_native->kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
|
drmIoctl (kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
|
||||||
|
|
||||||
err_ioctl:
|
err_ioctl:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1211,7 +1224,10 @@ static void
|
|||||||
release_dumb_fb (MetaRendererNative *renderer_native,
|
release_dumb_fb (MetaRendererNative *renderer_native,
|
||||||
MetaOnscreenNative *onscreen_native)
|
MetaOnscreenNative *onscreen_native)
|
||||||
{
|
{
|
||||||
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
|
renderer_native->monitor_manager_kms;
|
||||||
struct drm_mode_destroy_dumb destroy_arg;
|
struct drm_mode_destroy_dumb destroy_arg;
|
||||||
|
int kms_fd;
|
||||||
|
|
||||||
if (!onscreen_native->egl.dumb_fb.map)
|
if (!onscreen_native->egl.dumb_fb.map)
|
||||||
return;
|
return;
|
||||||
@ -1220,13 +1236,14 @@ release_dumb_fb (MetaRendererNative *renderer_native,
|
|||||||
onscreen_native->egl.dumb_fb.map_size);
|
onscreen_native->egl.dumb_fb.map_size);
|
||||||
onscreen_native->egl.dumb_fb.map = NULL;
|
onscreen_native->egl.dumb_fb.map = NULL;
|
||||||
|
|
||||||
drmModeRmFB (renderer_native->kms_fd,
|
kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms);
|
||||||
onscreen_native->egl.dumb_fb.fb_id);
|
|
||||||
|
drmModeRmFB (kms_fd, onscreen_native->egl.dumb_fb.fb_id);
|
||||||
|
|
||||||
destroy_arg = (struct drm_mode_destroy_dumb) {
|
destroy_arg = (struct drm_mode_destroy_dumb) {
|
||||||
.handle = onscreen_native->egl.dumb_fb.handle
|
.handle = onscreen_native->egl.dumb_fb.handle
|
||||||
};
|
};
|
||||||
drmIoctl (renderer_native->kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
|
drmIoctl (kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_EGL_DEVICE */
|
#endif /* HAVE_EGL_DEVICE */
|
||||||
|
|
||||||
@ -1417,12 +1434,6 @@ meta_renderer_native_get_gbm (MetaRendererNative *renderer_native)
|
|||||||
return renderer_native->gbm.device;
|
return renderer_native->gbm.device;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
|
||||||
meta_renderer_native_get_kms_fd (MetaRendererNative *renderer_native)
|
|
||||||
{
|
|
||||||
return renderer_native->kms_fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native)
|
meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native)
|
||||||
{
|
{
|
||||||
@ -1532,11 +1543,8 @@ meta_renderer_native_set_legacy_view_size (MetaRendererNative *renderer_native,
|
|||||||
|
|
||||||
if (width != view_layout.width || height != view_layout.height)
|
if (width != view_layout.width || height != view_layout.height)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
MetaMonitorManager *monitor_manager =
|
|
||||||
meta_backend_get_monitor_manager (backend);
|
|
||||||
MetaMonitorManagerKms *monitor_manager_kms =
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
renderer_native->monitor_manager_kms;
|
||||||
CoglFramebuffer *framebuffer =
|
CoglFramebuffer *framebuffer =
|
||||||
clutter_stage_view_get_onscreen (stage_view);
|
clutter_stage_view_get_onscreen (stage_view);
|
||||||
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
|
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
|
||||||
@ -1669,19 +1677,16 @@ meta_onscreen_native_set_view (CoglOnscreen *onscreen,
|
|||||||
MetaRendererView *
|
MetaRendererView *
|
||||||
meta_renderer_native_create_legacy_view (MetaRendererNative *renderer_native)
|
meta_renderer_native_create_legacy_view (MetaRendererNative *renderer_native)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
|
||||||
MetaMonitorManager *monitor_manager =
|
MetaMonitorManager *monitor_manager =
|
||||||
meta_backend_get_monitor_manager (backend);
|
META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
|
||||||
CoglOnscreen *onscreen = NULL;
|
CoglOnscreen *onscreen = NULL;
|
||||||
|
MetaBackend *backend = meta_get_backend ();
|
||||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||||
cairo_rectangle_int_t view_layout = { 0 };
|
cairo_rectangle_int_t view_layout = { 0 };
|
||||||
MetaRendererView *view;
|
MetaRendererView *view;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
if (!monitor_manager)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
meta_monitor_manager_get_screen_size (monitor_manager,
|
meta_monitor_manager_get_screen_size (monitor_manager,
|
||||||
&view_layout.width,
|
&view_layout.width,
|
||||||
&view_layout.height);
|
&view_layout.height);
|
||||||
@ -1742,9 +1747,10 @@ static MetaRendererView *
|
|||||||
meta_renderer_native_create_view (MetaRenderer *renderer,
|
meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||||
MetaLogicalMonitor *logical_monitor)
|
MetaLogicalMonitor *logical_monitor)
|
||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
||||||
MetaMonitorManager *monitor_manager =
|
MetaMonitorManager *monitor_manager =
|
||||||
meta_backend_get_monitor_manager (backend);
|
META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
|
||||||
|
MetaBackend *backend = meta_get_backend ();
|
||||||
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
|
||||||
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
|
||||||
CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
|
CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
|
||||||
@ -1867,11 +1873,8 @@ meta_renderer_native_get_property (GObject *object,
|
|||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_KMS_FD:
|
case PROP_MONITOR_MANAGER:
|
||||||
g_value_set_int (value, renderer_native->kms_fd);
|
g_value_set_object (value, renderer_native->monitor_manager_kms);
|
||||||
break;
|
|
||||||
case PROP_KMS_FILE_PATH:
|
|
||||||
g_value_set_string (value, renderer_native->kms_file_path);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@ -1889,11 +1892,8 @@ meta_renderer_native_set_property (GObject *object,
|
|||||||
|
|
||||||
switch (prop_id)
|
switch (prop_id)
|
||||||
{
|
{
|
||||||
case PROP_KMS_FD:
|
case PROP_MONITOR_MANAGER:
|
||||||
renderer_native->kms_fd = g_value_get_int (value);
|
renderer_native->monitor_manager_kms = g_value_get_object (value);
|
||||||
break;
|
|
||||||
case PROP_KMS_FILE_PATH:
|
|
||||||
renderer_native->kms_file_path = g_strdup (g_value_get_string (value));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
@ -1908,8 +1908,6 @@ meta_renderer_native_finalize (GObject *object)
|
|||||||
|
|
||||||
g_clear_pointer (&renderer_native->gbm.device, gbm_device_destroy);
|
g_clear_pointer (&renderer_native->gbm.device, gbm_device_destroy);
|
||||||
|
|
||||||
g_free (renderer_native->kms_file_path);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (meta_renderer_native_parent_class)->finalize (object);
|
G_OBJECT_CLASS (meta_renderer_native_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1917,10 +1915,13 @@ static gboolean
|
|||||||
init_gbm (MetaRendererNative *renderer_native,
|
init_gbm (MetaRendererNative *renderer_native,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
|
renderer_native->monitor_manager_kms;
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaEgl *egl = meta_backend_get_egl (backend);
|
MetaEgl *egl = meta_backend_get_egl (backend);
|
||||||
struct gbm_device *gbm_device;
|
struct gbm_device *gbm_device;
|
||||||
EGLDisplay egl_display;
|
EGLDisplay egl_display;
|
||||||
|
int kms_fd;
|
||||||
|
|
||||||
if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL,
|
if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL,
|
||||||
"EGL_MESA_platform_gbm",
|
"EGL_MESA_platform_gbm",
|
||||||
@ -1932,7 +1933,9 @@ init_gbm (MetaRendererNative *renderer_native,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gbm_device = gbm_create_device (renderer_native->kms_fd);
|
kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms);
|
||||||
|
|
||||||
|
gbm_device = gbm_create_device (kms_fd);
|
||||||
if (!gbm_device)
|
if (!gbm_device)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR,
|
g_set_error (error, G_IO_ERROR,
|
||||||
@ -1983,11 +1986,14 @@ static EGLDeviceEXT
|
|||||||
find_egl_device (MetaRendererNative *renderer_native,
|
find_egl_device (MetaRendererNative *renderer_native,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
|
renderer_native->monitor_manager_kms;
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaEgl *egl = meta_backend_get_egl (backend);
|
MetaEgl *egl = meta_backend_get_egl (backend);
|
||||||
char **missing_extensions;
|
char **missing_extensions;
|
||||||
EGLint num_devices;
|
EGLint num_devices;
|
||||||
EGLDeviceEXT *devices;
|
EGLDeviceEXT *devices;
|
||||||
|
const char *kms_file_path;
|
||||||
EGLDeviceEXT device;
|
EGLDeviceEXT device;
|
||||||
EGLint i;
|
EGLint i;
|
||||||
|
|
||||||
@ -2020,6 +2026,8 @@ find_egl_device (MetaRendererNative *renderer_native,
|
|||||||
return EGL_NO_DEVICE_EXT;
|
return EGL_NO_DEVICE_EXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kms_file_path = meta_monitor_manager_kms_get_file_path (monitor_manager_kms);
|
||||||
|
|
||||||
device = EGL_NO_DEVICE_EXT;
|
device = EGL_NO_DEVICE_EXT;
|
||||||
for (i = 0; i < num_devices; i++)
|
for (i = 0; i < num_devices; i++)
|
||||||
{
|
{
|
||||||
@ -2031,7 +2039,7 @@ find_egl_device (MetaRendererNative *renderer_native,
|
|||||||
if (!egl_device_drm_path)
|
if (!egl_device_drm_path)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (g_str_equal (egl_device_drm_path, renderer_native->kms_file_path))
|
if (g_str_equal (egl_device_drm_path, kms_file_path))
|
||||||
{
|
{
|
||||||
device = devices[i];
|
device = devices[i];
|
||||||
break;
|
break;
|
||||||
@ -2058,8 +2066,11 @@ get_egl_device_display (MetaRendererNative *renderer_native,
|
|||||||
{
|
{
|
||||||
MetaBackend *backend = meta_get_backend ();
|
MetaBackend *backend = meta_get_backend ();
|
||||||
MetaEgl *egl = meta_backend_get_egl (backend);
|
MetaEgl *egl = meta_backend_get_egl (backend);
|
||||||
|
MetaMonitorManagerKms *monitor_manager_kms =
|
||||||
|
renderer_native->monitor_manager_kms;
|
||||||
|
int kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms);
|
||||||
EGLint platform_attribs[] = {
|
EGLint platform_attribs[] = {
|
||||||
EGL_DRM_MASTER_FD_EXT, renderer_native->kms_fd,
|
EGL_DRM_MASTER_FD_EXT, kms_fd,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2204,34 +2215,25 @@ meta_renderer_native_class_init (MetaRendererNativeClass *klass)
|
|||||||
renderer_class->create_cogl_renderer = meta_renderer_native_create_cogl_renderer;
|
renderer_class->create_cogl_renderer = meta_renderer_native_create_cogl_renderer;
|
||||||
renderer_class->create_view = meta_renderer_native_create_view;
|
renderer_class->create_view = meta_renderer_native_create_view;
|
||||||
|
|
||||||
g_object_class_install_property (object_class,
|
obj_props[PROP_MONITOR_MANAGER] =
|
||||||
PROP_KMS_FD,
|
g_param_spec_object ("monitor-manager",
|
||||||
g_param_spec_int ("kms-fd",
|
"monitor-manager",
|
||||||
"KMS fd",
|
"MetaMonitorManagerKms",
|
||||||
"The KMS file descriptor",
|
META_TYPE_MONITOR_MANAGER_KMS,
|
||||||
0, G_MAXINT, 0,
|
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_CONSTRUCT_ONLY));
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
g_object_class_install_property (object_class,
|
G_PARAM_STATIC_STRINGS);
|
||||||
PROP_KMS_FILE_PATH,
|
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
|
||||||
g_param_spec_string ("kms-file-path",
|
|
||||||
"KMS file path",
|
|
||||||
"The KMS file path",
|
|
||||||
NULL,
|
|
||||||
G_PARAM_READWRITE |
|
|
||||||
G_PARAM_CONSTRUCT_ONLY));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MetaRendererNative *
|
MetaRendererNative *
|
||||||
meta_renderer_native_new (int kms_fd,
|
meta_renderer_native_new (MetaMonitorManagerKms *monitor_manager_kms,
|
||||||
const char *kms_file_path,
|
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaRendererNative *renderer_native;
|
MetaRendererNative *renderer_native;
|
||||||
|
|
||||||
renderer_native = g_object_new (META_TYPE_RENDERER_NATIVE,
|
renderer_native = g_object_new (META_TYPE_RENDERER_NATIVE,
|
||||||
"kms-fd", kms_fd,
|
"monitor-manager", monitor_manager_kms,
|
||||||
"kms-file-path", kms_file_path,
|
|
||||||
NULL);
|
NULL);
|
||||||
if (!g_initable_init (G_INITABLE (renderer_native), NULL, error))
|
if (!g_initable_init (G_INITABLE (renderer_native), NULL, error))
|
||||||
{
|
{
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <xf86drmMode.h>
|
#include <xf86drmMode.h>
|
||||||
|
|
||||||
#include "backends/meta-renderer.h"
|
#include "backends/meta-renderer.h"
|
||||||
|
#include "backends/native/meta-monitor-manager-kms.h"
|
||||||
|
|
||||||
#define META_TYPE_RENDERER_NATIVE (meta_renderer_native_get_type ())
|
#define META_TYPE_RENDERER_NATIVE (meta_renderer_native_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE (MetaRendererNative, meta_renderer_native,
|
G_DECLARE_FINAL_TYPE (MetaRendererNative, meta_renderer_native,
|
||||||
@ -43,16 +44,13 @@ typedef enum _MetaRendererNativeMode
|
|||||||
#endif
|
#endif
|
||||||
} MetaRendererNativeMode;
|
} MetaRendererNativeMode;
|
||||||
|
|
||||||
MetaRendererNative *meta_renderer_native_new (int kms_fd,
|
MetaRendererNative * meta_renderer_native_new (MetaMonitorManagerKms *monitor_manager_kms,
|
||||||
const char *kms_file_path,
|
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
MetaRendererNativeMode meta_renderer_native_get_mode (MetaRendererNative *renderer_native);
|
MetaRendererNativeMode meta_renderer_native_get_mode (MetaRendererNative *renderer_native);
|
||||||
|
|
||||||
struct gbm_device * meta_renderer_native_get_gbm (MetaRendererNative *renderer_native);
|
struct gbm_device * meta_renderer_native_get_gbm (MetaRendererNative *renderer_native);
|
||||||
|
|
||||||
int meta_renderer_native_get_kms_fd (MetaRendererNative *renderer_native);
|
|
||||||
|
|
||||||
void meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native);
|
void meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native);
|
||||||
|
|
||||||
gboolean meta_renderer_native_set_legacy_view_size (MetaRendererNative *renderer_native,
|
gboolean meta_renderer_native_set_legacy_view_size (MetaRendererNative *renderer_native,
|
||||||
|
@ -99,7 +99,8 @@ meta_backend_x11_cm_create_renderer (MetaBackend *backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MetaMonitorManager *
|
static MetaMonitorManager *
|
||||||
meta_backend_x11_cm_create_monitor_manager (MetaBackend *backend)
|
meta_backend_x11_cm_create_monitor_manager (MetaBackend *backend,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
|
return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,8 @@ meta_backend_x11_nested_create_renderer (MetaBackend *backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MetaMonitorManager *
|
static MetaMonitorManager *
|
||||||
meta_backend_x11_nested_create_monitor_manager (MetaBackend *backend)
|
meta_backend_x11_nested_create_monitor_manager (MetaBackend *backend,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
|
return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,8 @@ meta_backend_test_init (MetaBackendTest *backend_test)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MetaMonitorManager *
|
static MetaMonitorManager *
|
||||||
meta_backend_test_create_monitor_manager (MetaBackend *backend)
|
meta_backend_test_create_monitor_manager (MetaBackend *backend,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
return g_object_new (META_TYPE_MONITOR_MANAGER_TEST, NULL);
|
return g_object_new (META_TYPE_MONITOR_MANAGER_TEST, NULL);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user