kms: Move impl backend inherit MetaKmsImplDevice instead of MetaKmsImpl

This allows different types of backends to coexist, would e.g. one
device support atomic but another not.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
Jonas Ådahl 2020-07-17 09:38:11 +02:00 committed by Marge Bot
parent 37fe30c515
commit 7137bd4b10
12 changed files with 334 additions and 297 deletions

View File

@ -22,7 +22,7 @@
#include <xf86drmMode.h> #include <xf86drmMode.h>
#include "backends/native/meta-kms-types.h" #include "backends/native/meta-kms-crtc.h"
typedef enum _MetaKmsCrtcProp typedef enum _MetaKmsCrtcProp
{ {

View File

@ -26,6 +26,7 @@
#include <xf86drm.h> #include <xf86drm.h>
#include "backends/native/meta-backend-native.h" #include "backends/native/meta-backend-native.h"
#include "backends/native/meta-kms-impl-device-simple.h"
#include "backends/native/meta-kms-impl-device.h" #include "backends/native/meta-kms-impl-device.h"
#include "backends/native/meta-kms-impl.h" #include "backends/native/meta-kms-impl.h"
#include "backends/native/meta-kms-plane.h" #include "backends/native/meta-kms-plane.h"
@ -254,7 +255,7 @@ meta_create_kms_impl_device (MetaKmsDevice *device,
return NULL; return NULL;
} }
return g_initable_new (META_TYPE_KMS_IMPL_DEVICE, NULL, error, return g_initable_new (META_TYPE_KMS_IMPL_DEVICE_SIMPLE, NULL, error,
"device", device, "device", device,
"impl", impl, "impl", impl,
"fd", fd, "fd", fd,

View File

@ -1,6 +1,5 @@
/* /*
* Copyright (C) 2018-2019 Red Hat * Copyright (C) 2019-2020 Red Hat
* Copyright (C) 2019-2020 DisplayLink (UK) Ltd.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@ -20,17 +19,12 @@
#include "config.h" #include "config.h"
#include "backends/native/meta-kms-impl-simple.h" #include "backends/native/meta-kms-impl-device-simple.h"
#include <errno.h>
#include <gbm.h>
#include <xf86drmMode.h>
#include "backends/native/meta-kms-connector-private.h" #include "backends/native/meta-kms-connector-private.h"
#include "backends/native/meta-kms-crtc.h" #include "backends/native/meta-kms-crtc-private.h"
#include "backends/native/meta-kms-device-private.h" #include "backends/native/meta-kms-device-private.h"
#include "backends/native/meta-kms-mode.h" #include "backends/native/meta-kms-mode-private.h"
#include "backends/native/meta-kms-page-flip-private.h"
#include "backends/native/meta-kms-plane-private.h" #include "backends/native/meta-kms-plane-private.h"
#include "backends/native/meta-kms-private.h" #include "backends/native/meta-kms-private.h"
#include "backends/native/meta-kms-update-private.h" #include "backends/native/meta-kms-update-private.h"
@ -42,9 +36,9 @@ typedef struct _CachedModeSet
drmModeModeInfo *drm_mode; drmModeModeInfo *drm_mode;
} CachedModeSet; } CachedModeSet;
struct _MetaKmsImplSimple struct _MetaKmsImplDeviceSimple
{ {
MetaKmsImpl parent; MetaKmsImplDevice parent;
GSource *mode_set_fallback_feedback_source; GSource *mode_set_fallback_feedback_source;
GList *mode_set_fallback_page_flip_datas; GList *mode_set_fallback_page_flip_datas;
@ -58,29 +52,26 @@ struct _MetaKmsImplSimple
GHashTable *cached_mode_sets; GHashTable *cached_mode_sets;
}; };
G_DEFINE_TYPE (MetaKmsImplSimple, meta_kms_impl_simple, static GInitableIface *initable_parent_iface;
META_TYPE_KMS_IMPL)
static void static void
flush_postponed_page_flip_datas (MetaKmsImplSimple *impl_simple); initable_iface_init (GInitableIface *iface);
MetaKmsImplSimple * G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDeviceSimple, meta_kms_impl_device_simple,
meta_kms_impl_simple_new (MetaKms *kms, META_TYPE_KMS_IMPL_DEVICE,
GError **error) G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
{ initable_iface_init))
return g_object_new (META_TYPE_KMS_IMPL_SIMPLE,
"kms", kms, static void
NULL); flush_postponed_page_flip_datas (MetaKmsImplDeviceSimple *impl_device_simple);
}
static gboolean static gboolean
set_connector_property (MetaKmsConnector *connector, set_connector_property (MetaKmsImplDevice *impl_device,
MetaKmsConnector *connector,
MetaKmsConnectorProp prop, MetaKmsConnectorProp prop,
uint64_t value, uint64_t value,
GError **error) GError **error)
{ {
MetaKmsDevice *device = meta_kms_connector_get_device (connector);
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
uint32_t prop_id; uint32_t prop_id;
int fd; int fd;
int ret; int ret;
@ -116,7 +107,7 @@ set_connector_property (MetaKmsConnector *connector,
} }
static gboolean static gboolean
process_connector_update (MetaKmsImpl *impl, process_connector_update (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update, MetaKmsUpdate *update,
gpointer update_entry, gpointer update_entry,
GError **error) GError **error)
@ -126,7 +117,8 @@ process_connector_update (MetaKmsImpl *impl,
if (connector_update->dpms.has_update) if (connector_update->dpms.has_update)
{ {
if (!set_connector_property (connector, if (!set_connector_property (impl_device,
connector,
META_KMS_CONNECTOR_PROP_DPMS, META_KMS_CONNECTOR_PROP_DPMS,
connector_update->dpms.state, connector_update->dpms.state,
error)) error))
@ -136,17 +128,20 @@ process_connector_update (MetaKmsImpl *impl,
if (connector_update->underscanning.has_update && if (connector_update->underscanning.has_update &&
connector_update->underscanning.is_active) connector_update->underscanning.is_active)
{ {
if (!set_connector_property (connector, if (!set_connector_property (impl_device,
connector,
META_KMS_CONNECTOR_PROP_UNDERSCAN, META_KMS_CONNECTOR_PROP_UNDERSCAN,
1, 1,
error)) error))
return FALSE; return FALSE;
if (!set_connector_property (connector, if (!set_connector_property (impl_device,
connector,
META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER, META_KMS_CONNECTOR_PROP_UNDERSCAN_HBORDER,
connector_update->underscanning.hborder, connector_update->underscanning.hborder,
error)) error))
return FALSE; return FALSE;
if (!set_connector_property (connector, if (!set_connector_property (impl_device,
connector,
META_KMS_CONNECTOR_PROP_UNDERSCAN_VBORDER, META_KMS_CONNECTOR_PROP_UNDERSCAN_VBORDER,
connector_update->underscanning.vborder, connector_update->underscanning.vborder,
error)) error))
@ -154,7 +149,8 @@ process_connector_update (MetaKmsImpl *impl,
} }
else if (connector_update->underscanning.has_update) else if (connector_update->underscanning.has_update)
{ {
if (!set_connector_property (connector, if (!set_connector_property (impl_device,
connector,
META_KMS_CONNECTOR_PROP_UNDERSCAN, META_KMS_CONNECTOR_PROP_UNDERSCAN,
0, 0,
error)) error))
@ -207,13 +203,11 @@ fill_connector_ids_array (GList *connectors,
} }
static gboolean static gboolean
set_plane_rotation (MetaKmsImpl *impl, set_plane_rotation (MetaKmsImplDevice *impl_device,
MetaKmsPlane *plane, MetaKmsPlane *plane,
uint64_t rotation, uint64_t rotation,
GError **error) GError **error)
{ {
MetaKmsDevice *device = meta_kms_plane_get_device (plane);
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
int fd; int fd;
uint32_t rotation_prop_id; uint32_t rotation_prop_id;
int ret; int ret;
@ -243,16 +237,15 @@ set_plane_rotation (MetaKmsImpl *impl,
} }
static gboolean static gboolean
process_mode_set (MetaKmsImpl *impl, process_mode_set (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update, MetaKmsUpdate *update,
gpointer update_entry, gpointer update_entry,
GError **error) GError **error)
{ {
MetaKmsImplDeviceSimple *impl_device_simple =
META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
MetaKmsModeSet *mode_set = update_entry; MetaKmsModeSet *mode_set = update_entry;
MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (impl);
MetaKmsCrtc *crtc = mode_set->crtc; MetaKmsCrtc *crtc = mode_set->crtc;
MetaKmsDevice *device = meta_kms_crtc_get_device (crtc);
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
g_autofree uint32_t *connectors = NULL; g_autofree uint32_t *connectors = NULL;
int n_connectors; int n_connectors;
MetaKmsPlaneAssignment *plane_assignment; MetaKmsPlaneAssignment *plane_assignment;
@ -288,7 +281,7 @@ process_mode_set (MetaKmsImpl *impl,
if (plane_assignment->rotation) if (plane_assignment->rotation)
{ {
if (!set_plane_rotation (impl, if (!set_plane_rotation (impl_device,
plane_assignment->plane, plane_assignment->plane,
plane_assignment->rotation, plane_assignment->rotation,
error)) error))
@ -325,29 +318,27 @@ process_mode_set (MetaKmsImpl *impl,
if (drm_mode) if (drm_mode)
{ {
g_hash_table_replace (impl_simple->cached_mode_sets, g_hash_table_replace (impl_device_simple->cached_mode_sets,
crtc, crtc,
cached_mode_set_new (mode_set->connectors, cached_mode_set_new (mode_set->connectors,
drm_mode)); drm_mode));
} }
else else
{ {
g_hash_table_remove (impl_simple->cached_mode_sets, crtc); g_hash_table_remove (impl_device_simple->cached_mode_sets, crtc);
} }
return TRUE; return TRUE;
} }
static gboolean static gboolean
process_crtc_gamma (MetaKmsImpl *impl, process_crtc_gamma (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update, MetaKmsUpdate *update,
gpointer update_entry, gpointer update_entry,
GError **error) GError **error)
{ {
MetaKmsCrtcGamma *gamma = update_entry; MetaKmsCrtcGamma *gamma = update_entry;
MetaKmsCrtc *crtc = gamma->crtc; MetaKmsCrtc *crtc = gamma->crtc;
MetaKmsDevice *device = meta_kms_crtc_get_device (crtc);
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
int fd; int fd;
int ret; int ret;
@ -398,43 +389,44 @@ retry_page_flip_data_free (RetryPageFlipData *retry_page_flip_data)
} }
static CachedModeSet * static CachedModeSet *
get_cached_mode_set (MetaKmsImplSimple *impl_simple, get_cached_mode_set (MetaKmsImplDeviceSimple *impl_device_simple,
MetaKmsCrtc *crtc) MetaKmsCrtc *crtc)
{ {
return g_hash_table_lookup (impl_simple->cached_mode_sets, crtc); return g_hash_table_lookup (impl_device_simple->cached_mode_sets, crtc);
} }
static float static float
get_cached_crtc_refresh_rate (MetaKmsImplSimple *impl_simple, get_cached_crtc_refresh_rate (MetaKmsImplDeviceSimple *impl_device_simple,
MetaKmsCrtc *crtc) MetaKmsCrtc *crtc)
{ {
CachedModeSet *cached_mode_set; CachedModeSet *cached_mode_set;
cached_mode_set = g_hash_table_lookup (impl_simple->cached_mode_sets, cached_mode_set = g_hash_table_lookup (impl_device_simple->cached_mode_sets,
crtc); crtc);
g_assert (cached_mode_set); g_assert (cached_mode_set);
return meta_calculate_drm_mode_refresh_rate (cached_mode_set->drm_mode); return meta_calculate_drm_mode_refresh_rate (cached_mode_set->drm_mode);
} }
#define meta_assert_in_kms_impl(kms) \
g_assert (meta_kms_in_impl_task (kms))
static gboolean static gboolean
retry_page_flips (gpointer user_data) retry_page_flips (gpointer user_data)
{ {
MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (user_data); MetaKmsImplDeviceSimple *impl_device_simple =
META_KMS_IMPL_DEVICE_SIMPLE (user_data);
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
uint64_t now_us; uint64_t now_us;
GList *l; GList *l;
meta_assert_in_kms_impl (meta_kms_impl_get_kms (META_KMS_IMPL (impl_simple))); now_us = g_source_get_time (impl_device_simple->retry_page_flips_source);
now_us = g_source_get_time (impl_simple->retry_page_flips_source); l = impl_device_simple->pending_page_flip_retries;
l = impl_simple->pending_page_flip_retries;
while (l) while (l)
{ {
RetryPageFlipData *retry_page_flip_data = l->data; RetryPageFlipData *retry_page_flip_data = l->data;
MetaKmsCrtc *crtc = retry_page_flip_data->crtc; MetaKmsCrtc *crtc = retry_page_flip_data->crtc;
MetaKmsDevice *device = meta_kms_crtc_get_device (crtc);
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
GList *l_next = l->next; GList *l_next = l->next;
int fd; int fd;
int ret; int ret;
@ -468,15 +460,16 @@ retry_page_flips (gpointer user_data)
{ {
float refresh_rate; float refresh_rate;
refresh_rate = get_cached_crtc_refresh_rate (impl_simple, crtc); refresh_rate =
get_cached_crtc_refresh_rate (impl_device_simple, crtc);
retry_page_flip_data->retry_time_us += retry_page_flip_data->retry_time_us +=
(uint64_t) (G_USEC_PER_SEC / refresh_rate); (uint64_t) (G_USEC_PER_SEC / refresh_rate);
l = l_next; l = l_next;
continue; continue;
} }
impl_simple->pending_page_flip_retries = impl_device_simple->pending_page_flip_retries =
g_list_remove_link (impl_simple->pending_page_flip_retries, l); g_list_remove_link (impl_device_simple->pending_page_flip_retries, l);
page_flip_data = g_steal_pointer (&retry_page_flip_data->page_flip_data); page_flip_data = g_steal_pointer (&retry_page_flip_data->page_flip_data);
if (ret != 0) if (ret != 0)
@ -500,38 +493,38 @@ retry_page_flips (gpointer user_data)
l = l_next; l = l_next;
} }
if (impl_simple->pending_page_flip_retries) if (impl_device_simple->pending_page_flip_retries)
{ {
GList *l; GList *l;
uint64_t earliest_retry_time_us = 0; uint64_t earliest_retry_time_us = 0;
for (l = impl_simple->pending_page_flip_retries; l; l = l->next) for (l = impl_device_simple->pending_page_flip_retries; l; l = l->next)
{ {
RetryPageFlipData *retry_page_flip_data = l->data; RetryPageFlipData *retry_page_flip_data = l->data;
if (l == impl_simple->pending_page_flip_retries || if (l == impl_device_simple->pending_page_flip_retries ||
is_timestamp_earlier_than (retry_page_flip_data->retry_time_us, is_timestamp_earlier_than (retry_page_flip_data->retry_time_us,
earliest_retry_time_us)) earliest_retry_time_us))
earliest_retry_time_us = retry_page_flip_data->retry_time_us; earliest_retry_time_us = retry_page_flip_data->retry_time_us;
} }
g_source_set_ready_time (impl_simple->retry_page_flips_source, g_source_set_ready_time (impl_device_simple->retry_page_flips_source,
earliest_retry_time_us); earliest_retry_time_us);
return G_SOURCE_CONTINUE; return G_SOURCE_CONTINUE;
} }
else else
{ {
g_clear_pointer (&impl_simple->retry_page_flips_source, g_clear_pointer (&impl_device_simple->retry_page_flips_source,
g_source_unref); g_source_unref);
flush_postponed_page_flip_datas (impl_simple); flush_postponed_page_flip_datas (impl_device_simple);
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
} }
static void static void
schedule_retry_page_flip (MetaKmsImplSimple *impl_simple, schedule_retry_page_flip (MetaKmsImplDeviceSimple *impl_device_simple,
MetaKmsCrtc *crtc, MetaKmsCrtc *crtc,
uint32_t fb_id, uint32_t fb_id,
float refresh_rate, float refresh_rate,
@ -557,22 +550,25 @@ schedule_retry_page_flip (MetaKmsImplSimple *impl_simple,
.custom_page_flip_user_data = custom_page_flip_user_data, .custom_page_flip_user_data = custom_page_flip_user_data,
}; };
if (!impl_simple->retry_page_flips_source) if (!impl_device_simple->retry_page_flips_source)
{ {
MetaKms *kms = meta_kms_impl_get_kms (META_KMS_IMPL (impl_simple)); MetaKmsImplDevice *impl_device =
META_KMS_IMPL_DEVICE (impl_device_simple);
MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
MetaKms *kms = meta_kms_device_get_kms (device);
GSource *source; GSource *source;
source = meta_kms_add_source_in_impl (kms, retry_page_flips, source = meta_kms_add_source_in_impl (kms, retry_page_flips,
impl_simple, NULL); impl_device_simple, NULL);
g_source_set_ready_time (source, retry_time_us); g_source_set_ready_time (source, retry_time_us);
impl_simple->retry_page_flips_source = source; impl_device_simple->retry_page_flips_source = source;
} }
else else
{ {
GList *l; GList *l;
for (l = impl_simple->pending_page_flip_retries; l; l = l->next) for (l = impl_device_simple->pending_page_flip_retries; l; l = l->next)
{ {
RetryPageFlipData *pending_retry_page_flip_data = l->data; RetryPageFlipData *pending_retry_page_flip_data = l->data;
uint64_t pending_retry_time_us = uint64_t pending_retry_time_us =
@ -580,15 +576,15 @@ schedule_retry_page_flip (MetaKmsImplSimple *impl_simple,
if (is_timestamp_earlier_than (retry_time_us, pending_retry_time_us)) if (is_timestamp_earlier_than (retry_time_us, pending_retry_time_us))
{ {
g_source_set_ready_time (impl_simple->retry_page_flips_source, g_source_set_ready_time (impl_device_simple->retry_page_flips_source,
retry_time_us); retry_time_us);
break; break;
} }
} }
} }
impl_simple->pending_page_flip_retries = impl_device_simple->pending_page_flip_retries =
g_list_append (impl_simple->pending_page_flip_retries, g_list_append (impl_device_simple->pending_page_flip_retries,
retry_page_flip_data); retry_page_flip_data);
} }
@ -610,38 +606,38 @@ clear_page_flip_datas (GList **page_flip_datas)
static gboolean static gboolean
mode_set_fallback_feedback_idle (gpointer user_data) mode_set_fallback_feedback_idle (gpointer user_data)
{ {
MetaKmsImplSimple *impl_simple = user_data; MetaKmsImplDeviceSimple *impl_device_simple = user_data;
g_clear_pointer (&impl_simple->mode_set_fallback_feedback_source, g_clear_pointer (&impl_device_simple->mode_set_fallback_feedback_source,
g_source_unref); g_source_unref);
if (impl_simple->pending_page_flip_retries) if (impl_device_simple->pending_page_flip_retries)
{ {
impl_simple->postponed_mode_set_fallback_datas = impl_device_simple->postponed_mode_set_fallback_datas =
g_steal_pointer (&impl_simple->mode_set_fallback_page_flip_datas); g_steal_pointer (&impl_device_simple->mode_set_fallback_page_flip_datas);
} }
else else
{ {
invoke_page_flip_datas (impl_simple->mode_set_fallback_page_flip_datas, invoke_page_flip_datas (impl_device_simple->mode_set_fallback_page_flip_datas,
meta_kms_page_flip_data_mode_set_fallback_in_impl); meta_kms_page_flip_data_mode_set_fallback_in_impl);
clear_page_flip_datas (&impl_simple->mode_set_fallback_page_flip_datas); clear_page_flip_datas (&impl_device_simple->mode_set_fallback_page_flip_datas);
} }
return G_SOURCE_REMOVE; return G_SOURCE_REMOVE;
} }
static gboolean static gboolean
mode_set_fallback (MetaKmsImplSimple *impl_simple, mode_set_fallback (MetaKmsImplDeviceSimple *impl_device_simple,
MetaKmsUpdate *update, MetaKmsUpdate *update,
MetaKmsPageFlip *page_flip, MetaKmsPageFlip *page_flip,
MetaKmsPlaneAssignment *plane_assignment, MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPageFlipData *page_flip_data, MetaKmsPageFlipData *page_flip_data,
GError **error) GError **error)
{ {
MetaKms *kms = meta_kms_impl_get_kms (META_KMS_IMPL (impl_simple)); MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
MetaKms *kms = meta_kms_device_get_kms (device);
MetaKmsCrtc *crtc = page_flip->crtc; MetaKmsCrtc *crtc = page_flip->crtc;
MetaKmsDevice *device = meta_kms_crtc_get_device (crtc);
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
CachedModeSet *cached_mode_set; CachedModeSet *cached_mode_set;
g_autofree uint32_t *connectors = NULL; g_autofree uint32_t *connectors = NULL;
int n_connectors; int n_connectors;
@ -649,7 +645,7 @@ mode_set_fallback (MetaKmsImplSimple *impl_simple,
int fd; int fd;
int ret; int ret;
cached_mode_set = g_hash_table_lookup (impl_simple->cached_mode_sets, cached_mode_set = g_hash_table_lookup (impl_device_simple->cached_mode_sets,
crtc); crtc);
if (!cached_mode_set) if (!cached_mode_set)
{ {
@ -682,35 +678,34 @@ mode_set_fallback (MetaKmsImplSimple *impl_simple,
return FALSE; return FALSE;
} }
if (!impl_simple->mode_set_fallback_feedback_source) if (!impl_device_simple->mode_set_fallback_feedback_source)
{ {
GSource *source; GSource *source;
source = meta_kms_add_source_in_impl (kms, source = meta_kms_add_source_in_impl (kms,
mode_set_fallback_feedback_idle, mode_set_fallback_feedback_idle,
impl_simple, impl_device_simple,
NULL); NULL);
impl_simple->mode_set_fallback_feedback_source = source; impl_device_simple->mode_set_fallback_feedback_source = source;
} }
impl_simple->mode_set_fallback_page_flip_datas = impl_device_simple->mode_set_fallback_page_flip_datas =
g_list_prepend (impl_simple->mode_set_fallback_page_flip_datas, g_list_prepend (impl_device_simple->mode_set_fallback_page_flip_datas,
meta_kms_page_flip_data_ref (page_flip_data)); meta_kms_page_flip_data_ref (page_flip_data));
return TRUE; return TRUE;
} }
static gboolean static gboolean
process_page_flip (MetaKmsImpl *impl, process_page_flip (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update, MetaKmsUpdate *update,
gpointer update_entry, gpointer update_entry,
GError **error) GError **error)
{ {
MetaKmsImplDeviceSimple *impl_device_simple =
META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
MetaKmsPageFlip *page_flip = update_entry; MetaKmsPageFlip *page_flip = update_entry;
MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (impl);
MetaKmsCrtc *crtc; MetaKmsCrtc *crtc;
MetaKmsDevice *device;
MetaKmsImplDevice *impl_device;
MetaKmsPlaneAssignment *plane_assignment; MetaKmsPlaneAssignment *plane_assignment;
MetaKmsPageFlipData *page_flip_data; MetaKmsPageFlipData *page_flip_data;
MetaKmsCustomPageFlipFunc custom_page_flip_func; MetaKmsCustomPageFlipFunc custom_page_flip_func;
@ -721,13 +716,11 @@ process_page_flip (MetaKmsImpl *impl,
plane_assignment = meta_kms_update_get_primary_plane_assignment (update, plane_assignment = meta_kms_update_get_primary_plane_assignment (update,
crtc); crtc);
page_flip_data = meta_kms_page_flip_data_new (impl, page_flip_data = meta_kms_page_flip_data_new (impl_device,
crtc, crtc,
page_flip->feedback, page_flip->feedback,
page_flip->user_data); page_flip->user_data);
device = meta_kms_crtc_get_device (crtc);
impl_device = meta_kms_device_get_impl_device (device);
fd = meta_kms_impl_device_get_fd (impl_device); fd = meta_kms_impl_device_get_fd (impl_device);
custom_page_flip_func = page_flip->custom_page_flip_func; custom_page_flip_func = page_flip->custom_page_flip_func;
if (custom_page_flip_func) if (custom_page_flip_func)
@ -751,7 +744,7 @@ process_page_flip (MetaKmsImpl *impl,
{ {
CachedModeSet *cached_mode_set; CachedModeSet *cached_mode_set;
cached_mode_set = get_cached_mode_set (impl_simple, crtc); cached_mode_set = get_cached_mode_set (impl_device_simple, crtc);
if (cached_mode_set) if (cached_mode_set)
{ {
drmModeModeInfo *drm_mode; drmModeModeInfo *drm_mode;
@ -759,7 +752,7 @@ process_page_flip (MetaKmsImpl *impl,
drm_mode = cached_mode_set->drm_mode; drm_mode = cached_mode_set->drm_mode;
refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode);
schedule_retry_page_flip (impl_simple, schedule_retry_page_flip (impl_device_simple,
crtc, crtc,
plane_assignment ? plane_assignment ?
plane_assignment->fb_id : 0, plane_assignment->fb_id : 0,
@ -779,7 +772,7 @@ process_page_flip (MetaKmsImpl *impl,
} }
else if (ret == -EINVAL) else if (ret == -EINVAL)
{ {
if (!mode_set_fallback (impl_simple, if (!mode_set_fallback (impl_device_simple,
update, update,
page_flip, page_flip,
plane_assignment, plane_assignment,
@ -805,7 +798,7 @@ process_page_flip (MetaKmsImpl *impl,
} }
static void static void
discard_page_flip (MetaKmsImpl *impl, discard_page_flip (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update, MetaKmsUpdate *update,
MetaKmsPageFlip *page_flip) MetaKmsPageFlip *page_flip)
{ {
@ -813,7 +806,7 @@ discard_page_flip (MetaKmsImpl *impl,
MetaKmsPageFlipData *page_flip_data; MetaKmsPageFlipData *page_flip_data;
crtc = page_flip->crtc; crtc = page_flip->crtc;
page_flip_data = meta_kms_page_flip_data_new (impl, page_flip_data = meta_kms_page_flip_data_new (impl_device,
crtc, crtc,
page_flip->feedback, page_flip->feedback,
page_flip->user_data); page_flip->user_data);
@ -822,10 +815,10 @@ discard_page_flip (MetaKmsImpl *impl,
} }
static gboolean static gboolean
process_entries (MetaKmsImpl *impl, process_entries (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update, MetaKmsUpdate *update,
GList *entries, GList *entries,
gboolean (* func) (MetaKmsImpl *impl, gboolean (* func) (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update, MetaKmsUpdate *update,
gpointer entry_data, gpointer entry_data,
GError **error), GError **error),
@ -835,7 +828,7 @@ process_entries (MetaKmsImpl *impl,
for (l = entries; l; l = l->next) for (l = entries; l; l = l->next)
{ {
if (!func (impl, update, l->data, error)) if (!func (impl_device, update, l->data, error))
return FALSE; return FALSE;
} }
@ -843,19 +836,15 @@ process_entries (MetaKmsImpl *impl,
} }
static gboolean static gboolean
process_cursor_plane_assignment (MetaKmsImpl *impl, process_cursor_plane_assignment (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update, MetaKmsUpdate *update,
MetaKmsPlaneAssignment *plane_assignment, MetaKmsPlaneAssignment *plane_assignment,
GError **error) GError **error)
{ {
MetaKmsPlane *plane; uint32_t crtc_id;
MetaKmsDevice *device;
MetaKmsImplDevice *impl_device;
int fd; int fd;
plane = plane_assignment->plane; crtc_id = meta_kms_crtc_get_id (plane_assignment->crtc),
device = meta_kms_plane_get_device (plane);
impl_device = meta_kms_device_get_impl_device (device);
fd = meta_kms_impl_device_get_fd (impl_device); fd = meta_kms_impl_device_get_fd (impl_device);
if (!(plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED)) if (!(plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED))
@ -868,7 +857,8 @@ process_cursor_plane_assignment (MetaKmsImpl *impl,
if (plane_assignment->cursor_hotspot.is_valid) if (plane_assignment->cursor_hotspot.is_valid)
{ {
ret = drmModeSetCursor2 (fd, meta_kms_crtc_get_id (plane_assignment->crtc), ret = drmModeSetCursor2 (fd,
crtc_id,
plane_assignment->fb_id, plane_assignment->fb_id,
width, height, width, height,
plane_assignment->cursor_hotspot.x, plane_assignment->cursor_hotspot.x,
@ -877,7 +867,7 @@ process_cursor_plane_assignment (MetaKmsImpl *impl,
if (ret != 0) if (ret != 0)
{ {
ret = drmModeSetCursor (fd, meta_kms_crtc_get_id (plane_assignment->crtc), ret = drmModeSetCursor (fd, crtc_id,
plane_assignment->fb_id, plane_assignment->fb_id,
width, height); width, height);
} }
@ -891,7 +881,7 @@ process_cursor_plane_assignment (MetaKmsImpl *impl,
} }
drmModeMoveCursor (fd, drmModeMoveCursor (fd,
meta_kms_crtc_get_id (plane_assignment->crtc), crtc_id,
meta_fixed_16_to_int (plane_assignment->dst_rect.x), meta_fixed_16_to_int (plane_assignment->dst_rect.x),
meta_fixed_16_to_int (plane_assignment->dst_rect.y)); meta_fixed_16_to_int (plane_assignment->dst_rect.y));
@ -899,7 +889,7 @@ process_cursor_plane_assignment (MetaKmsImpl *impl,
} }
static gboolean static gboolean
process_plane_assignment (MetaKmsImpl *impl, process_plane_assignment (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update, MetaKmsUpdate *update,
MetaKmsPlaneAssignment *plane_assignment, MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPlaneFeedback **plane_feedback) MetaKmsPlaneFeedback **plane_feedback)
@ -916,7 +906,7 @@ process_plane_assignment (MetaKmsImpl *impl,
/* Handled as part of the mode-set and page flip. */ /* Handled as part of the mode-set and page flip. */
return TRUE; return TRUE;
case META_KMS_PLANE_TYPE_CURSOR: case META_KMS_PLANE_TYPE_CURSOR:
if (!process_cursor_plane_assignment (impl, update, if (!process_cursor_plane_assignment (impl_device, update,
plane_assignment, plane_assignment,
&error)) &error))
{ {
@ -944,7 +934,7 @@ process_plane_assignment (MetaKmsImpl *impl,
} }
static GList * static GList *
process_plane_assignments (MetaKmsImpl *impl, process_plane_assignments (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update) MetaKmsUpdate *update)
{ {
GList *failed_planes = NULL; GList *failed_planes = NULL;
@ -955,7 +945,7 @@ process_plane_assignments (MetaKmsImpl *impl,
MetaKmsPlaneAssignment *plane_assignment = l->data; MetaKmsPlaneAssignment *plane_assignment = l->data;
MetaKmsPlaneFeedback *plane_feedback; MetaKmsPlaneFeedback *plane_feedback;
if (!process_plane_assignment (impl, update, plane_assignment, if (!process_plane_assignment (impl_device, update, plane_assignment,
&plane_feedback)) &plane_feedback))
failed_planes = g_list_prepend (failed_planes, plane_feedback); failed_planes = g_list_prepend (failed_planes, plane_feedback);
} }
@ -1000,37 +990,35 @@ generate_all_failed_feedbacks (MetaKmsUpdate *update)
} }
static MetaKmsFeedback * static MetaKmsFeedback *
meta_kms_impl_simple_process_update (MetaKmsImpl *impl, meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update) MetaKmsUpdate *update)
{ {
GError *error = NULL; GError *error = NULL;
GList *failed_planes; GList *failed_planes;
GList *l; GList *l;
meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl)); if (!process_entries (impl_device,
if (!process_entries (impl,
update, update,
meta_kms_update_get_connector_updates (update), meta_kms_update_get_connector_updates (update),
process_connector_update, process_connector_update,
&error)) &error))
goto err_planes_not_assigned; goto err_planes_not_assigned;
if (!process_entries (impl, if (!process_entries (impl_device,
update, update,
meta_kms_update_get_mode_sets (update), meta_kms_update_get_mode_sets (update),
process_mode_set, process_mode_set,
&error)) &error))
goto err_planes_not_assigned; goto err_planes_not_assigned;
if (!process_entries (impl, if (!process_entries (impl_device,
update, update,
meta_kms_update_get_crtc_gammas (update), meta_kms_update_get_crtc_gammas (update),
process_crtc_gamma, process_crtc_gamma,
&error)) &error))
goto err_planes_not_assigned; goto err_planes_not_assigned;
failed_planes = process_plane_assignments (impl, update); failed_planes = process_plane_assignments (impl_device, update);
if (failed_planes) if (failed_planes)
{ {
g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
@ -1038,7 +1026,7 @@ meta_kms_impl_simple_process_update (MetaKmsImpl *impl,
goto err_planes_assigned; goto err_planes_assigned;
} }
if (!process_entries (impl, if (!process_entries (impl_device,
update, update,
meta_kms_update_get_page_flips (update), meta_kms_update_get_page_flips (update),
process_page_flip, process_page_flip,
@ -1058,34 +1046,35 @@ err_planes_assigned:
if (page_flip->flags & META_KMS_PAGE_FLIP_FLAG_NO_DISCARD_FEEDBACK) if (page_flip->flags & META_KMS_PAGE_FLIP_FLAG_NO_DISCARD_FEEDBACK)
continue; continue;
discard_page_flip (impl, update, page_flip); discard_page_flip (impl_device, update, page_flip);
} }
return meta_kms_feedback_new_failed (failed_planes, error); return meta_kms_feedback_new_failed (failed_planes, error);
} }
static void static void
flush_postponed_page_flip_datas (MetaKmsImplSimple *impl_simple) flush_postponed_page_flip_datas (MetaKmsImplDeviceSimple *impl_device_simple)
{ {
invoke_page_flip_datas (impl_simple->postponed_page_flip_datas, invoke_page_flip_datas (impl_device_simple->postponed_page_flip_datas,
meta_kms_page_flip_data_flipped_in_impl); meta_kms_page_flip_data_flipped_in_impl);
clear_page_flip_datas (&impl_simple->postponed_page_flip_datas); clear_page_flip_datas (&impl_device_simple->postponed_page_flip_datas);
invoke_page_flip_datas (impl_simple->postponed_mode_set_fallback_datas, invoke_page_flip_datas (impl_device_simple->postponed_mode_set_fallback_datas,
meta_kms_page_flip_data_mode_set_fallback_in_impl); meta_kms_page_flip_data_mode_set_fallback_in_impl);
clear_page_flip_datas (&impl_simple->postponed_mode_set_fallback_datas); clear_page_flip_datas (&impl_device_simple->postponed_mode_set_fallback_datas);
} }
static void static void
meta_kms_impl_simple_handle_page_flip_callback (MetaKmsImpl *impl, meta_kms_impl_device_simple_handle_page_flip_callback (MetaKmsImplDevice *impl_device,
MetaKmsPageFlipData *page_flip_data) MetaKmsPageFlipData *page_flip_data)
{ {
MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (impl); MetaKmsImplDeviceSimple *impl_device_simple =
META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
if (impl_simple->pending_page_flip_retries) if (impl_device_simple->pending_page_flip_retries)
{ {
impl_simple->postponed_page_flip_datas = impl_device_simple->postponed_page_flip_datas =
g_list_append (impl_simple->postponed_page_flip_datas, g_list_append (impl_device_simple->postponed_page_flip_datas,
meta_kms_page_flip_data_ref (page_flip_data)); meta_kms_page_flip_data_ref (page_flip_data));
} }
else else
@ -1097,15 +1086,16 @@ meta_kms_impl_simple_handle_page_flip_callback (MetaKmsImpl *impl,
} }
static void static void
meta_kms_impl_simple_discard_pending_page_flips (MetaKmsImpl *impl) meta_kms_impl_device_simple_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
{ {
MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (impl); MetaKmsImplDeviceSimple *impl_device_simple =
META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
GList *l; GList *l;
if (!impl_simple->pending_page_flip_retries) if (!impl_device_simple->pending_page_flip_retries)
return; return;
for (l = impl_simple->pending_page_flip_retries; l; l = l->next) for (l = impl_device_simple->pending_page_flip_retries; l; l = l->next)
{ {
RetryPageFlipData *retry_page_flip_data = l->data; RetryPageFlipData *retry_page_flip_data = l->data;
MetaKmsPageFlipData *page_flip_data; MetaKmsPageFlipData *page_flip_data;
@ -1114,18 +1104,52 @@ meta_kms_impl_simple_discard_pending_page_flips (MetaKmsImpl *impl)
meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL); meta_kms_page_flip_data_discard_in_impl (page_flip_data, NULL);
retry_page_flip_data_free (retry_page_flip_data); retry_page_flip_data_free (retry_page_flip_data);
} }
g_clear_pointer (&impl_simple->pending_page_flip_retries, g_list_free); g_clear_pointer (&impl_device_simple->pending_page_flip_retries, g_list_free);
g_clear_pointer (&impl_simple->retry_page_flips_source, g_clear_pointer (&impl_device_simple->retry_page_flips_source,
g_source_destroy); g_source_destroy);
} }
static void static void
meta_kms_impl_simple_notify_device_created (MetaKmsImpl *impl, meta_kms_impl_device_simple_finalize (GObject *object)
MetaKmsDevice *device)
{ {
MetaKmsImplDeviceSimple *impl_device_simple =
META_KMS_IMPL_DEVICE_SIMPLE (object);
g_list_free_full (impl_device_simple->pending_page_flip_retries,
(GDestroyNotify) retry_page_flip_data_free);
g_list_free_full (impl_device_simple->postponed_page_flip_datas,
(GDestroyNotify) meta_kms_page_flip_data_unref);
g_list_free_full (impl_device_simple->postponed_mode_set_fallback_datas,
(GDestroyNotify) meta_kms_page_flip_data_unref);
g_clear_pointer (&impl_device_simple->mode_set_fallback_feedback_source,
g_source_destroy);
g_hash_table_destroy (impl_device_simple->cached_mode_sets);
G_OBJECT_CLASS (meta_kms_impl_device_simple_parent_class)->finalize (object);
}
static gboolean
meta_kms_impl_device_simple_initable_init (GInitable *initable,
GCancellable *cancellable,
GError **error)
{
MetaKmsImplDeviceSimple *impl_device_simple =
META_KMS_IMPL_DEVICE_SIMPLE (initable);
MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
GList *l; GList *l;
if (!initable_parent_iface->init (initable, cancellable, error))
return FALSE;
impl_device_simple->cached_mode_sets =
g_hash_table_new_full (NULL,
NULL,
NULL,
(GDestroyNotify) cached_mode_set_free);
for (l = meta_kms_device_get_crtcs (device); l; l = l->next) for (l = meta_kms_device_get_crtcs (device); l; l = l->next)
{ {
MetaKmsCrtc *crtc = l->data; MetaKmsCrtc *crtc = l->data;
@ -1139,46 +1163,36 @@ meta_kms_impl_simple_notify_device_created (MetaKmsImpl *impl,
META_KMS_PLANE_TYPE_CURSOR, META_KMS_PLANE_TYPE_CURSOR,
crtc); crtc);
} }
return TRUE;
} }
static void static void
meta_kms_impl_simple_finalize (GObject *object) meta_kms_impl_device_simple_init (MetaKmsImplDeviceSimple *impl_device_simple)
{ {
MetaKmsImplSimple *impl_simple = META_KMS_IMPL_SIMPLE (object);
g_list_free_full (impl_simple->pending_page_flip_retries,
(GDestroyNotify) retry_page_flip_data_free);
g_list_free_full (impl_simple->postponed_page_flip_datas,
(GDestroyNotify) meta_kms_page_flip_data_unref);
g_list_free_full (impl_simple->postponed_mode_set_fallback_datas,
(GDestroyNotify) meta_kms_page_flip_data_unref);
g_clear_pointer (&impl_simple->mode_set_fallback_feedback_source,
g_source_destroy);
g_hash_table_destroy (impl_simple->cached_mode_sets);
G_OBJECT_CLASS (meta_kms_impl_simple_parent_class)->finalize (object);
} }
static void static void
meta_kms_impl_simple_init (MetaKmsImplSimple *impl_simple) initable_iface_init (GInitableIface *iface)
{ {
impl_simple->cached_mode_sets = initable_parent_iface = g_type_interface_peek_parent (iface);
g_hash_table_new_full (NULL,
NULL, iface->init = meta_kms_impl_device_simple_initable_init;
NULL,
(GDestroyNotify) cached_mode_set_free);
} }
static void static void
meta_kms_impl_simple_class_init (MetaKmsImplSimpleClass *klass) meta_kms_impl_device_simple_class_init (MetaKmsImplDeviceSimpleClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
MetaKmsImplClass *impl_class = META_KMS_IMPL_CLASS (klass); MetaKmsImplDeviceClass *impl_device_class =
META_KMS_IMPL_DEVICE_CLASS (klass);
object_class->finalize = meta_kms_impl_simple_finalize; object_class->finalize = meta_kms_impl_device_simple_finalize;
impl_class->process_update = meta_kms_impl_simple_process_update; impl_device_class->process_update =
impl_class->handle_page_flip_callback = meta_kms_impl_simple_handle_page_flip_callback; meta_kms_impl_device_simple_process_update;
impl_class->discard_pending_page_flips = meta_kms_impl_simple_discard_pending_page_flips; impl_device_class->handle_page_flip_callback =
impl_class->notify_device_created = meta_kms_impl_simple_notify_device_created; meta_kms_impl_device_simple_handle_page_flip_callback;
impl_device_class->discard_pending_page_flips =
meta_kms_impl_device_simple_discard_pending_page_flips;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2018 Red Hat * Copyright (C) 2018-2020 Red Hat
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
@ -17,16 +17,13 @@
* 02111-1307, USA. * 02111-1307, USA.
*/ */
#ifndef META_KMS_IMPL_SIMPLE_H #ifndef META_KMS_IMPL_DEVICE_SIMPLE_H
#define META_KMS_IMPL_SIMPLE_H #define META_KMS_IMPL_DEVICE_SIMPLE_H
#include "backends/native/meta-kms-impl.h" #include "backends/native/meta-kms-impl-device.h"
#define META_TYPE_KMS_IMPL_SIMPLE meta_kms_impl_simple_get_type () #define META_TYPE_KMS_IMPL_DEVICE_SIMPLE (meta_kms_impl_device_simple_get_type ())
G_DECLARE_FINAL_TYPE (MetaKmsImplSimple, meta_kms_impl_simple, G_DECLARE_FINAL_TYPE (MetaKmsImplDeviceSimple, meta_kms_impl_device_simple,
META, KMS_IMPL_SIMPLE, MetaKmsImpl) META, KMS_IMPL_DEVICE_SIMPLE, MetaKmsImplDevice)
MetaKmsImplSimple * meta_kms_impl_simple_new (MetaKms *kms, #endif /* META_KMS_IMPL_DEVICE_SIMPLE_H */
GError **error);
#endif /* META_KMS_IMPL_SIMPLE_H */

View File

@ -80,6 +80,10 @@ G_DEFINE_TYPE_WITH_CODE (MetaKmsImplDevice, meta_kms_impl_device,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
initable_iface_init)) initable_iface_init))
static void
meta_kms_impl_device_handle_page_flip_callback (MetaKmsImplDevice *impl_device,
MetaKmsPageFlipData *page_flip_data);
MetaKmsDevice * MetaKmsDevice *
meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device) meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device)
{ {
@ -160,13 +164,13 @@ page_flip_handler (int fd,
void *user_data) void *user_data)
{ {
MetaKmsPageFlipData *page_flip_data = user_data; MetaKmsPageFlipData *page_flip_data = user_data;
MetaKmsImpl *impl; MetaKmsImplDevice *impl_device;
meta_kms_page_flip_data_set_timings_in_impl (page_flip_data, meta_kms_page_flip_data_set_timings_in_impl (page_flip_data,
sequence, sec, usec); sequence, sec, usec);
impl = meta_kms_page_flip_data_get_kms_impl (page_flip_data); impl_device = meta_kms_page_flip_data_get_impl_device (page_flip_data);
meta_kms_impl_handle_page_flip_callback (impl, page_flip_data); meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data);
} }
gboolean gboolean
@ -626,6 +630,32 @@ meta_kms_impl_device_leak_fd (MetaKmsImplDevice *impl_device)
return priv->fd; return priv->fd;
} }
MetaKmsFeedback *
meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update)
{
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
return klass->process_update (impl_device, update);
}
static void
meta_kms_impl_device_handle_page_flip_callback (MetaKmsImplDevice *impl_device,
MetaKmsPageFlipData *page_flip_data)
{
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
klass->handle_page_flip_callback (impl_device, page_flip_data);
}
void
meta_kms_impl_device_discard_pending_page_flips (MetaKmsImplDevice *impl_device)
{
MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
klass->discard_pending_page_flips (impl_device);
}
int int
meta_kms_impl_device_close (MetaKmsImplDevice *impl_device) meta_kms_impl_device_close (MetaKmsImplDevice *impl_device)
{ {

View File

@ -25,6 +25,7 @@
#include <xf86drmMode.h> #include <xf86drmMode.h>
#include "backends/native/meta-kms-device.h" #include "backends/native/meta-kms-device.h"
#include "backends/native/meta-kms-page-flip-private.h"
#include "backends/native/meta-kms-types.h" #include "backends/native/meta-kms-types.h"
#include "backends/native/meta-kms-update.h" #include "backends/native/meta-kms-update.h"
@ -58,6 +59,12 @@ G_DECLARE_DERIVABLE_TYPE (MetaKmsImplDevice, meta_kms_impl_device,
struct _MetaKmsImplDeviceClass struct _MetaKmsImplDeviceClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
MetaKmsFeedback * (* process_update) (MetaKmsImplDevice *impl,
MetaKmsUpdate *update);
void (* handle_page_flip_callback) (MetaKmsImplDevice *impl,
MetaKmsPageFlipData *page_flip_data);
void (* discard_pending_page_flips) (MetaKmsImplDevice *impl);
}; };
MetaKmsDevice * meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device); MetaKmsDevice * meta_kms_impl_device_get_device (MetaKmsImplDevice *impl_device);
@ -105,6 +112,11 @@ void meta_kms_impl_device_init_prop_table (MetaKmsImplDevice *impl_device,
int n_props, int n_props,
gpointer user_data); gpointer user_data);
MetaKmsFeedback * meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
MetaKmsUpdate *update);
void meta_kms_impl_device_discard_pending_page_flips (MetaKmsImplDevice *impl_device);
int meta_kms_impl_device_close (MetaKmsImplDevice *impl_device); int meta_kms_impl_device_close (MetaKmsImplDevice *impl_device);
#endif /* META_KMS_IMPL_DEVICE_H */ #endif /* META_KMS_IMPL_DEVICE_H */

View File

@ -23,6 +23,8 @@
#include "backends/native/meta-kms-impl.h" #include "backends/native/meta-kms-impl.h"
#include "backends/native/meta-kms-private.h" #include "backends/native/meta-kms-private.h"
#include "backends/native/meta-kms-device-private.h"
#include "backends/native/meta-kms-update-private.h"
enum enum
{ {
@ -31,6 +33,11 @@ enum
PROP_KMS, PROP_KMS,
}; };
struct _MetaKmsImpl
{
GObject parent;
};
typedef struct _MetaKmsImplPrivate typedef struct _MetaKmsImplPrivate
{ {
MetaKms *kms; MetaKms *kms;
@ -38,7 +45,7 @@ typedef struct _MetaKmsImplPrivate
GList *impl_devices; GList *impl_devices;
} MetaKmsImplPrivate; } MetaKmsImplPrivate;
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaKmsImpl, meta_kms_impl, G_TYPE_OBJECT) G_DEFINE_TYPE_WITH_PRIVATE (MetaKmsImpl, meta_kms_impl, G_TYPE_OBJECT)
MetaKms * MetaKms *
meta_kms_impl_get_kms (MetaKmsImpl *impl) meta_kms_impl_get_kms (MetaKmsImpl *impl)
@ -74,28 +81,34 @@ MetaKmsFeedback *
meta_kms_impl_process_update (MetaKmsImpl *impl, meta_kms_impl_process_update (MetaKmsImpl *impl,
MetaKmsUpdate *update) MetaKmsUpdate *update)
{ {
return META_KMS_IMPL_GET_CLASS (impl)->process_update (impl, update); MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
} MetaKmsDevice *device;
MetaKmsImplDevice *impl_device;
void meta_assert_in_kms_impl (priv->kms);
meta_kms_impl_handle_page_flip_callback (MetaKmsImpl *impl,
MetaKmsPageFlipData *page_flip_data) device = meta_kms_update_get_device (update);
{ impl_device = meta_kms_device_get_impl_device (device);
META_KMS_IMPL_GET_CLASS (impl)->handle_page_flip_callback (impl,
page_flip_data); return meta_kms_impl_device_process_update (impl_device, update);
} }
void void
meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl) meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl)
{ {
META_KMS_IMPL_GET_CLASS (impl)->discard_pending_page_flips (impl); MetaKmsImplPrivate *priv = meta_kms_impl_get_instance_private (impl);
g_list_foreach (priv->impl_devices,
(GFunc) meta_kms_impl_device_discard_pending_page_flips,
NULL);
} }
void MetaKmsImpl *
meta_kms_impl_notify_device_created (MetaKmsImpl *impl, meta_kms_impl_new (MetaKms *kms)
MetaKmsDevice *device)
{ {
META_KMS_IMPL_GET_CLASS (impl)->notify_device_created (impl, device); return g_object_new (META_TYPE_KMS_IMPL,
"kms", kms,
NULL);
} }
static void static void

View File

@ -26,22 +26,9 @@
#include "backends/native/meta-kms.h" #include "backends/native/meta-kms.h"
#define META_TYPE_KMS_IMPL (meta_kms_impl_get_type ()) #define META_TYPE_KMS_IMPL (meta_kms_impl_get_type ())
G_DECLARE_DERIVABLE_TYPE (MetaKmsImpl, meta_kms_impl, G_DECLARE_FINAL_TYPE (MetaKmsImpl, meta_kms_impl,
META, KMS_IMPL, GObject) META, KMS_IMPL, GObject)
struct _MetaKmsImplClass
{
GObjectClass parent_class;
MetaKmsFeedback * (* process_update) (MetaKmsImpl *impl,
MetaKmsUpdate *update);
void (* handle_page_flip_callback) (MetaKmsImpl *impl,
MetaKmsPageFlipData *page_flip_data);
void (* discard_pending_page_flips) (MetaKmsImpl *impl);
void (* notify_device_created) (MetaKmsImpl *impl,
MetaKmsDevice *impl_device);
};
MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl); MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl);
MetaKmsFeedback * meta_kms_impl_process_update (MetaKmsImpl *impl, MetaKmsFeedback * meta_kms_impl_process_update (MetaKmsImpl *impl,
@ -53,12 +40,8 @@ void meta_kms_impl_add_impl_device (MetaKmsImpl *impl,
void meta_kms_impl_remove_impl_device (MetaKmsImpl *impl, void meta_kms_impl_remove_impl_device (MetaKmsImpl *impl,
MetaKmsImplDevice *impl_device); MetaKmsImplDevice *impl_device);
void meta_kms_impl_handle_page_flip_callback (MetaKmsImpl *impl,
MetaKmsPageFlipData *page_flip_data);
void meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl); void meta_kms_impl_discard_pending_page_flips (MetaKmsImpl *impl);
void meta_kms_impl_notify_device_created (MetaKmsImpl *impl, MetaKmsImpl * meta_kms_impl_new (MetaKms *kms);
MetaKmsDevice *impl_device);
#endif /* META_KMS_IMPL_H */ #endif /* META_KMS_IMPL_H */

View File

@ -28,7 +28,7 @@ typedef struct _MetaKmsPageFlipData MetaKmsPageFlipData;
typedef void (* MetaPageFlipDataFeedbackFunc) (MetaKmsPageFlipData *page_flip_data); typedef void (* MetaPageFlipDataFeedbackFunc) (MetaKmsPageFlipData *page_flip_data);
MetaKmsPageFlipData * meta_kms_page_flip_data_new (MetaKmsImpl *impl, MetaKmsPageFlipData * meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
MetaKmsCrtc *crtc, MetaKmsCrtc *crtc,
const MetaKmsPageFlipFeedback *feedback, const MetaKmsPageFlipFeedback *feedback,
gpointer user_data); gpointer user_data);
@ -37,7 +37,7 @@ MetaKmsPageFlipData * meta_kms_page_flip_data_ref (MetaKmsPageFlipData *page_fli
void meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data); void meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data);
MetaKmsImpl * meta_kms_page_flip_data_get_kms_impl (MetaKmsPageFlipData *page_flip_data); MetaKmsImplDevice * meta_kms_page_flip_data_get_impl_device (MetaKmsPageFlipData *page_flip_data);
void meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data, void meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data,
unsigned int sequence, unsigned int sequence,

View File

@ -29,7 +29,7 @@ struct _MetaKmsPageFlipData
{ {
int ref_count; int ref_count;
MetaKmsImpl *impl; MetaKmsImplDevice *impl_device;
MetaKmsCrtc *crtc; MetaKmsCrtc *crtc;
const MetaKmsPageFlipFeedback *feedback; const MetaKmsPageFlipFeedback *feedback;
@ -43,7 +43,7 @@ struct _MetaKmsPageFlipData
}; };
MetaKmsPageFlipData * MetaKmsPageFlipData *
meta_kms_page_flip_data_new (MetaKmsImpl *impl, meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
MetaKmsCrtc *crtc, MetaKmsCrtc *crtc,
const MetaKmsPageFlipFeedback *feedback, const MetaKmsPageFlipFeedback *feedback,
gpointer user_data) gpointer user_data)
@ -53,7 +53,7 @@ meta_kms_page_flip_data_new (MetaKmsImpl *impl,
page_flip_data = g_new0 (MetaKmsPageFlipData , 1); page_flip_data = g_new0 (MetaKmsPageFlipData , 1);
*page_flip_data = (MetaKmsPageFlipData) { *page_flip_data = (MetaKmsPageFlipData) {
.ref_count = 1, .ref_count = 1,
.impl = impl, .impl_device = impl_device,
.crtc = crtc, .crtc = crtc,
.feedback = feedback, .feedback = feedback,
.user_data = user_data, .user_data = user_data,
@ -82,10 +82,10 @@ meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data)
} }
} }
MetaKmsImpl * MetaKmsImplDevice *
meta_kms_page_flip_data_get_kms_impl (MetaKmsPageFlipData *page_flip_data) meta_kms_page_flip_data_get_impl_device (MetaKmsPageFlipData *page_flip_data)
{ {
return page_flip_data->impl; return page_flip_data->impl_device;
} }
static void static void
@ -103,13 +103,21 @@ meta_kms_page_flip_data_flipped (MetaKms *kms,
page_flip_data->user_data); page_flip_data->user_data);
} }
static MetaKms *
meta_kms_from_impl_device (MetaKmsImplDevice *impl_device)
{
MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
return meta_kms_device_get_kms (device);
}
void void
meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data, meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data,
unsigned int sequence, unsigned int sequence,
unsigned int sec, unsigned int sec,
unsigned int usec) unsigned int usec)
{ {
MetaKms *kms = meta_kms_impl_get_kms (page_flip_data->impl); MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
meta_assert_in_kms_impl (kms); meta_assert_in_kms_impl (kms);
@ -121,7 +129,7 @@ meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data
void void
meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data) meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data)
{ {
MetaKms *kms = meta_kms_impl_get_kms (page_flip_data->impl); MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
meta_assert_in_kms_impl (kms); meta_assert_in_kms_impl (kms);
@ -146,7 +154,7 @@ meta_kms_page_flip_data_mode_set_fallback (MetaKms *kms,
void void
meta_kms_page_flip_data_mode_set_fallback_in_impl (MetaKmsPageFlipData *page_flip_data) meta_kms_page_flip_data_mode_set_fallback_in_impl (MetaKmsPageFlipData *page_flip_data)
{ {
MetaKms *kms = meta_kms_impl_get_kms (page_flip_data->impl); MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
meta_assert_in_kms_impl (kms); meta_assert_in_kms_impl (kms);
@ -182,7 +190,7 @@ void
meta_kms_page_flip_data_discard_in_impl (MetaKmsPageFlipData *page_flip_data, meta_kms_page_flip_data_discard_in_impl (MetaKmsPageFlipData *page_flip_data,
const GError *error) const GError *error)
{ {
MetaKms *kms = meta_kms_impl_get_kms (page_flip_data->impl); MetaKms *kms = meta_kms_from_impl_device (page_flip_data->impl_device);
meta_assert_in_kms_impl (kms); meta_assert_in_kms_impl (kms);

View File

@ -25,7 +25,6 @@
#include "backends/native/meta-backend-native.h" #include "backends/native/meta-backend-native.h"
#include "backends/native/meta-kms-device-private.h" #include "backends/native/meta-kms-device-private.h"
#include "backends/native/meta-kms-impl.h" #include "backends/native/meta-kms-impl.h"
#include "backends/native/meta-kms-impl-simple.h"
#include "backends/native/meta-kms-update-private.h" #include "backends/native/meta-kms-update-private.h"
#include "backends/native/meta-udev.h" #include "backends/native/meta-udev.h"
#include "cogl/cogl.h" #include "cogl/cogl.h"
@ -103,15 +102,7 @@
* *
* #MetaKmsImpl: * #MetaKmsImpl:
* *
* The KMS backend implementation, running in the impl context. #MetaKmsImpl * The KMS impl context object, managing things in the impl context.
* itself is an abstract object, with potentially multiple implementations.
* Currently only #MetaKmsImplSimple exists.
*
* #MetaKmsImplSimple:
*
* A KMS backend implementation using the non-atomic drmMode* API. While it's
* interacted with using the transactional API, the #MetaKmsUpdate is processed
* non-atomically.
* *
* #MetaKmsImplDevice: * #MetaKmsImplDevice:
* *
@ -119,6 +110,9 @@
* context. It takes care of the updating of the various KMS object (CRTC, * context. It takes care of the updating of the various KMS object (CRTC,
* connector, ..) states. * connector, ..) states.
* *
* This is an abstract type, with currently #MetaKmsImplDeviceSimple,
* implementing mode setting and page flipping using legacy DRM API.
*
* #MetaKmsPageFlip: * #MetaKmsPageFlip:
* *
* A object representing a page flip. It's created when a page flip is queued, * A object representing a page flip. It's created when a page flip is queued,
@ -590,18 +584,6 @@ meta_kms_get_backend (MetaKms *kms)
return kms->backend; return kms->backend;
} }
static gpointer
notify_device_created_in_impl (MetaKmsImpl *impl,
gpointer user_data,
GError **error)
{
MetaKmsDevice *device = user_data;
meta_kms_impl_notify_device_created (impl, device);
return GINT_TO_POINTER (TRUE);
}
MetaKmsDevice * MetaKmsDevice *
meta_kms_create_device (MetaKms *kms, meta_kms_create_device (MetaKms *kms,
const char *path, const char *path,
@ -614,9 +596,6 @@ meta_kms_create_device (MetaKms *kms,
if (!device) if (!device)
return NULL; return NULL;
meta_kms_run_impl_task_sync (kms, notify_device_created_in_impl,
device, NULL);
kms->devices = g_list_append (kms->devices, device); kms->devices = g_list_append (kms->devices, device);
return device; return device;
@ -632,7 +611,7 @@ meta_kms_new (MetaBackend *backend,
kms = g_object_new (META_TYPE_KMS, NULL); kms = g_object_new (META_TYPE_KMS, NULL);
kms->backend = backend; kms->backend = backend;
kms->impl = META_KMS_IMPL (meta_kms_impl_simple_new (kms, error)); kms->impl = meta_kms_impl_new (kms);
if (!kms->impl) if (!kms->impl)
{ {
g_object_unref (kms); g_object_unref (kms);

View File

@ -678,10 +678,10 @@ if have_native_backend
'backends/native/meta-kms-device-private.h', 'backends/native/meta-kms-device-private.h',
'backends/native/meta-kms-device.c', 'backends/native/meta-kms-device.c',
'backends/native/meta-kms-device.h', 'backends/native/meta-kms-device.h',
'backends/native/meta-kms-impl-device-simple.c',
'backends/native/meta-kms-impl-device-simple.h',
'backends/native/meta-kms-impl-device.c', 'backends/native/meta-kms-impl-device.c',
'backends/native/meta-kms-impl-device.h', 'backends/native/meta-kms-impl-device.h',
'backends/native/meta-kms-impl-simple.c',
'backends/native/meta-kms-impl-simple.h',
'backends/native/meta-kms-impl.c', 'backends/native/meta-kms-impl.c',
'backends/native/meta-kms-impl.h', 'backends/native/meta-kms-impl.h',
'backends/native/meta-kms-mode.c', 'backends/native/meta-kms-mode.c',