mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 01:50:42 -05:00
kms/update: Make each MetaKmsUpdate update a single device
For now feedbacks from an update are combined, meaning we might lose error information. The feedback API may have to be reconsidered and redesigned when planes gets a more front seat position. This means we need to avoid trying to post updates if we're in power save mode, as it may be empty. Note that this is an intermediate state during refactoring that aims to introduce atomic mode setting support, and we'll stop combining feedbacks completely in the future. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
parent
a7a1391de7
commit
37fe30c515
@ -383,7 +383,6 @@ typedef struct
|
||||
MetaLogicalMonitor *in_logical_monitor;
|
||||
graphene_rect_t in_local_cursor_rect;
|
||||
MetaCursorSprite *in_cursor_sprite;
|
||||
MetaKmsUpdate *in_kms_update;
|
||||
|
||||
gboolean out_painted;
|
||||
} UpdateCrtcCursorData;
|
||||
@ -401,6 +400,10 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
MetaCursorRendererNativePrivate *priv =
|
||||
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
|
||||
MetaCrtc *crtc;
|
||||
MetaGpuKms *gpu_kms;
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaKms *kms;
|
||||
MetaKmsUpdate *kms_update;
|
||||
MetaMonitorTransform transform;
|
||||
const MetaCrtcModeInfo *crtc_mode_info;
|
||||
graphene_rect_t scaled_crtc_rect;
|
||||
@ -446,6 +449,10 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
};
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (monitor_crtc_mode->output);
|
||||
gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
|
||||
kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
|
||||
kms = meta_kms_device_get_kms (kms_device);
|
||||
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
|
||||
|
||||
if (priv->has_hw_cursor &&
|
||||
graphene_rect_intersection (&scaled_crtc_rect,
|
||||
@ -487,7 +494,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
&cursor_rect);
|
||||
|
||||
set_crtc_cursor (data->in_cursor_renderer_native,
|
||||
data->in_kms_update,
|
||||
kms_update,
|
||||
META_CRTC_KMS (crtc),
|
||||
cursor_rect.x,
|
||||
cursor_rect.y,
|
||||
@ -498,7 +505,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
|
||||
else
|
||||
{
|
||||
unset_crtc_cursor (data->in_cursor_renderer_native,
|
||||
data->in_kms_update,
|
||||
kms_update,
|
||||
META_CRTC_KMS (crtc));
|
||||
}
|
||||
|
||||
@ -533,15 +540,12 @@ update_hw_cursor (MetaCursorRendererNative *native,
|
||||
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaKmsUpdate *kms_update;
|
||||
GList *logical_monitors;
|
||||
GList *l;
|
||||
graphene_rect_t rect;
|
||||
gboolean painted = FALSE;
|
||||
g_autoptr (MetaKmsFeedback) feedback = NULL;
|
||||
|
||||
kms_update = meta_kms_ensure_pending_update (kms);
|
||||
|
||||
if (cursor_sprite)
|
||||
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
|
||||
else
|
||||
@ -567,7 +571,6 @@ update_hw_cursor (MetaCursorRendererNative *native,
|
||||
.size = rect.size
|
||||
},
|
||||
.in_cursor_sprite = cursor_sprite,
|
||||
.in_kms_update = kms_update,
|
||||
};
|
||||
|
||||
monitors = meta_logical_monitor_get_monitors (logical_monitor);
|
||||
@ -586,7 +589,7 @@ update_hw_cursor (MetaCursorRendererNative *native,
|
||||
painted = painted || data.out_painted;
|
||||
}
|
||||
|
||||
feedback = meta_kms_post_pending_update_sync (kms);
|
||||
feedback = meta_kms_post_pending_updates_sync (kms);
|
||||
if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED)
|
||||
{
|
||||
for (l = meta_kms_feedback_get_failed_planes (feedback); l; l = l->next)
|
||||
|
@ -55,6 +55,12 @@ struct _MetaKmsDevice
|
||||
|
||||
G_DEFINE_TYPE (MetaKmsDevice, meta_kms_device, G_TYPE_OBJECT);
|
||||
|
||||
MetaKms *
|
||||
meta_kms_device_get_kms (MetaKmsDevice *device)
|
||||
{
|
||||
return device->kms;
|
||||
}
|
||||
|
||||
MetaKmsImplDevice *
|
||||
meta_kms_device_get_impl_device (MetaKmsDevice *device)
|
||||
{
|
||||
|
@ -29,6 +29,8 @@ G_DECLARE_FINAL_TYPE (MetaKmsDevice, meta_kms_device,
|
||||
META, KMS_DEVICE,
|
||||
GObject)
|
||||
|
||||
MetaKms * meta_kms_device_get_kms (MetaKmsDevice *device);
|
||||
|
||||
int meta_kms_device_leak_fd (MetaKmsDevice *device);
|
||||
|
||||
const char * meta_kms_device_get_path (MetaKmsDevice *device);
|
||||
|
@ -111,6 +111,8 @@ void meta_kms_update_seal (MetaKmsUpdate *update);
|
||||
|
||||
gboolean meta_kms_update_is_sealed (MetaKmsUpdate *update);
|
||||
|
||||
MetaKmsDevice * meta_kms_update_get_device (MetaKmsUpdate *update);
|
||||
|
||||
void meta_kms_plane_assignment_set_rotation (MetaKmsPlaneAssignment *plane_assignment,
|
||||
uint64_t rotation);
|
||||
|
||||
|
@ -23,11 +23,15 @@
|
||||
#include "backends/native/meta-kms-update-private.h"
|
||||
|
||||
#include "backends/meta-display-config-shared.h"
|
||||
#include "backends/native/meta-kms-crtc.h"
|
||||
#include "backends/native/meta-kms-connector.h"
|
||||
#include "backends/native/meta-kms-mode-private.h"
|
||||
#include "backends/native/meta-kms-plane.h"
|
||||
|
||||
struct _MetaKmsUpdate
|
||||
{
|
||||
MetaKmsDevice *device;
|
||||
|
||||
gboolean is_sealed;
|
||||
|
||||
MetaPowerSave power_save;
|
||||
@ -143,6 +147,8 @@ meta_kms_update_assign_plane (MetaKmsUpdate *update,
|
||||
MetaKmsPlaneAssignment *plane_assignment;
|
||||
|
||||
g_assert (!meta_kms_update_is_sealed (update));
|
||||
g_assert (meta_kms_crtc_get_device (crtc) == update->device);
|
||||
g_assert (meta_kms_plane_get_device (plane) == update->device);
|
||||
|
||||
plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1);
|
||||
*plane_assignment = (MetaKmsPlaneAssignment) {
|
||||
@ -169,6 +175,8 @@ meta_kms_update_unassign_plane (MetaKmsUpdate *update,
|
||||
MetaKmsPlaneAssignment *plane_assignment;
|
||||
|
||||
g_assert (!meta_kms_update_is_sealed (update));
|
||||
g_assert (meta_kms_crtc_get_device (crtc) == update->device);
|
||||
g_assert (meta_kms_plane_get_device (plane) == update->device);
|
||||
|
||||
plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1);
|
||||
*plane_assignment = (MetaKmsPlaneAssignment) {
|
||||
@ -193,6 +201,7 @@ meta_kms_update_mode_set (MetaKmsUpdate *update,
|
||||
MetaKmsModeSet *mode_set;
|
||||
|
||||
g_assert (!meta_kms_update_is_sealed (update));
|
||||
g_assert (meta_kms_crtc_get_device (crtc) == update->device);
|
||||
|
||||
mode_set = g_new0 (MetaKmsModeSet, 1);
|
||||
*mode_set = (MetaKmsModeSet) {
|
||||
@ -237,6 +246,7 @@ meta_kms_update_set_underscanning (MetaKmsUpdate *update,
|
||||
MetaKmsConnectorUpdate *connector_update;
|
||||
|
||||
g_assert (!meta_kms_update_is_sealed (update));
|
||||
g_assert (meta_kms_connector_get_device (connector) == update->device);
|
||||
|
||||
connector_update = ensure_connector_update (update, connector);
|
||||
connector_update->underscanning.has_update = TRUE;
|
||||
@ -252,6 +262,7 @@ meta_kms_update_unset_underscanning (MetaKmsUpdate *update,
|
||||
MetaKmsConnectorUpdate *connector_update;
|
||||
|
||||
g_assert (!meta_kms_update_is_sealed (update));
|
||||
g_assert (meta_kms_connector_get_device (connector) == update->device);
|
||||
|
||||
connector_update = ensure_connector_update (update, connector);
|
||||
connector_update->underscanning.has_update = TRUE;
|
||||
@ -266,6 +277,7 @@ meta_kms_update_set_dpms_state (MetaKmsUpdate *update,
|
||||
MetaKmsConnectorUpdate *connector_update;
|
||||
|
||||
g_assert (!meta_kms_update_is_sealed (update));
|
||||
g_assert (meta_kms_connector_get_device (connector) == update->device);
|
||||
|
||||
connector_update = ensure_connector_update (update, connector);
|
||||
connector_update->dpms.has_update = TRUE;
|
||||
@ -292,6 +304,7 @@ meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
|
||||
MetaKmsCrtcGamma *gamma;
|
||||
|
||||
g_assert (!meta_kms_update_is_sealed (update));
|
||||
g_assert (meta_kms_crtc_get_device (crtc) == update->device);
|
||||
|
||||
gamma = g_new0 (MetaKmsCrtcGamma, 1);
|
||||
*gamma = (MetaKmsCrtcGamma) {
|
||||
@ -315,6 +328,7 @@ meta_kms_update_page_flip (MetaKmsUpdate *update,
|
||||
MetaKmsPageFlip *page_flip;
|
||||
|
||||
g_assert (!meta_kms_update_is_sealed (update));
|
||||
g_assert (meta_kms_crtc_get_device (crtc) == update->device);
|
||||
|
||||
page_flip = g_new0 (MetaKmsPageFlip, 1);
|
||||
*page_flip = (MetaKmsPageFlip) {
|
||||
@ -338,6 +352,7 @@ meta_kms_update_custom_page_flip (MetaKmsUpdate *update,
|
||||
MetaKmsPageFlip *page_flip;
|
||||
|
||||
g_assert (!meta_kms_update_is_sealed (update));
|
||||
g_assert (meta_kms_crtc_get_device (crtc) == update->device);
|
||||
|
||||
page_flip = g_new0 (MetaKmsPageFlip, 1);
|
||||
*page_flip = (MetaKmsPageFlip) {
|
||||
@ -430,10 +445,21 @@ meta_kms_update_is_sealed (MetaKmsUpdate *update)
|
||||
return update->is_sealed;
|
||||
}
|
||||
|
||||
MetaKmsUpdate *
|
||||
meta_kms_update_new (void)
|
||||
MetaKmsDevice *
|
||||
meta_kms_update_get_device (MetaKmsUpdate *update)
|
||||
{
|
||||
return g_new0 (MetaKmsUpdate, 1);
|
||||
return update->device;
|
||||
}
|
||||
|
||||
MetaKmsUpdate *
|
||||
meta_kms_update_new (MetaKmsDevice *device)
|
||||
{
|
||||
MetaKmsUpdate *update;
|
||||
|
||||
update = g_new0 (MetaKmsUpdate, 1);
|
||||
update->device = device;
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -81,7 +81,7 @@ GList * meta_kms_feedback_get_failed_planes (MetaKmsFeedback *feedback);
|
||||
|
||||
const GError * meta_kms_feedback_get_error (MetaKmsFeedback *feedback);
|
||||
|
||||
MetaKmsUpdate * meta_kms_update_new (void);
|
||||
MetaKmsUpdate * meta_kms_update_new (MetaKmsDevice *device);
|
||||
|
||||
void meta_kms_update_free (MetaKmsUpdate *update);
|
||||
|
||||
|
@ -95,7 +95,8 @@
|
||||
* posted. An update consists of plane assignments, mode sets and KMS object
|
||||
* property entries. The user adds updates to the object, and then posts it via
|
||||
* MetaKms. It will then be processed by the MetaKms backend (See
|
||||
* #MetaKmsImpl), potentially atomically.
|
||||
* #MetaKmsImpl), potentially atomically. Each #MetaKmsUpdate deals with
|
||||
* updating a single device.
|
||||
*
|
||||
*
|
||||
* There are also these private objects, without public facing API:
|
||||
@ -174,7 +175,7 @@ struct _MetaKms
|
||||
|
||||
GList *devices;
|
||||
|
||||
MetaKmsUpdate *pending_update;
|
||||
GList *pending_updates;
|
||||
|
||||
GList *pending_callbacks;
|
||||
guint callback_source_id;
|
||||
@ -183,18 +184,36 @@ struct _MetaKms
|
||||
G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT)
|
||||
|
||||
MetaKmsUpdate *
|
||||
meta_kms_ensure_pending_update (MetaKms *kms)
|
||||
meta_kms_ensure_pending_update (MetaKms *kms,
|
||||
MetaKmsDevice *device)
|
||||
{
|
||||
if (!kms->pending_update)
|
||||
kms->pending_update = meta_kms_update_new ();
|
||||
MetaKmsUpdate *update;
|
||||
|
||||
return meta_kms_get_pending_update (kms);
|
||||
update = meta_kms_get_pending_update (kms, device);
|
||||
if (update)
|
||||
return update;
|
||||
|
||||
update = meta_kms_update_new (device);
|
||||
kms->pending_updates = g_list_prepend (kms->pending_updates, update);
|
||||
|
||||
return update;
|
||||
}
|
||||
|
||||
MetaKmsUpdate *
|
||||
meta_kms_get_pending_update (MetaKms *kms)
|
||||
meta_kms_get_pending_update (MetaKms *kms,
|
||||
MetaKmsDevice *device)
|
||||
{
|
||||
return kms->pending_update;
|
||||
GList *l;
|
||||
|
||||
for (l = kms->pending_updates; l; l = l->next)
|
||||
{
|
||||
MetaKmsUpdate *update = l->data;
|
||||
|
||||
if (meta_kms_update_get_device (update) == device)
|
||||
return update;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -208,40 +227,84 @@ meta_kms_predict_states_in_impl (MetaKms *kms,
|
||||
update);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
meta_kms_process_update_in_impl (MetaKmsImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
static MetaKmsFeedback *
|
||||
combine_feedbacks (MetaKmsFeedback *feedback,
|
||||
MetaKmsFeedback *other_feedback)
|
||||
{
|
||||
g_autoptr (MetaKmsUpdate) update = user_data;
|
||||
MetaKmsFeedback *feedback;
|
||||
GList *failed_planes;
|
||||
MetaKmsFeedback *new_feedback;
|
||||
const GError *error;
|
||||
|
||||
feedback = meta_kms_impl_process_update (impl, update);
|
||||
meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update);
|
||||
if (!feedback)
|
||||
return other_feedback;
|
||||
|
||||
failed_planes =
|
||||
g_list_concat (meta_kms_feedback_get_failed_planes (feedback),
|
||||
meta_kms_feedback_get_failed_planes (other_feedback));
|
||||
error = meta_kms_feedback_get_error (feedback);
|
||||
if (!error)
|
||||
error = meta_kms_feedback_get_error (other_feedback);
|
||||
|
||||
if (error)
|
||||
{
|
||||
new_feedback = meta_kms_feedback_new_failed (failed_planes,
|
||||
g_error_copy (error));
|
||||
}
|
||||
else
|
||||
{
|
||||
new_feedback = meta_kms_feedback_new_passed ();
|
||||
}
|
||||
|
||||
meta_kms_feedback_free (feedback);
|
||||
meta_kms_feedback_free (other_feedback);
|
||||
|
||||
return new_feedback;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
meta_kms_process_updates_in_impl (MetaKmsImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
GList *updates = user_data;
|
||||
MetaKmsFeedback *feedback = NULL;
|
||||
GList *l;
|
||||
|
||||
for (l = updates; l; l = l->next)
|
||||
{
|
||||
MetaKmsUpdate *update = l->data;
|
||||
MetaKmsFeedback *device_feedback;
|
||||
|
||||
device_feedback = meta_kms_impl_process_update (impl, update);
|
||||
feedback = combine_feedbacks (feedback, device_feedback);
|
||||
meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update);
|
||||
}
|
||||
|
||||
g_list_free_full (updates, (GDestroyNotify) meta_kms_update_free);
|
||||
|
||||
return feedback;
|
||||
}
|
||||
|
||||
static MetaKmsFeedback *
|
||||
meta_kms_post_update_sync (MetaKms *kms,
|
||||
MetaKmsUpdate *update)
|
||||
meta_kms_post_updates_sync (MetaKms *kms,
|
||||
GList *updates)
|
||||
{
|
||||
meta_kms_update_seal (update);
|
||||
g_list_foreach (updates, (GFunc) meta_kms_update_seal, NULL);
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync,
|
||||
"KMS (post update)");
|
||||
|
||||
return meta_kms_run_impl_task_sync (kms,
|
||||
meta_kms_process_update_in_impl,
|
||||
update,
|
||||
meta_kms_process_updates_in_impl,
|
||||
updates,
|
||||
NULL);
|
||||
}
|
||||
|
||||
MetaKmsFeedback *
|
||||
meta_kms_post_pending_update_sync (MetaKms *kms)
|
||||
meta_kms_post_pending_updates_sync (MetaKms *kms)
|
||||
{
|
||||
return meta_kms_post_update_sync (kms,
|
||||
g_steal_pointer (&kms->pending_update));
|
||||
return meta_kms_post_updates_sync (kms,
|
||||
g_steal_pointer (&kms->pending_updates));
|
||||
}
|
||||
|
||||
static gpointer
|
||||
|
@ -28,11 +28,13 @@
|
||||
#define META_TYPE_KMS (meta_kms_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaKms, meta_kms, META, KMS, GObject)
|
||||
|
||||
MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms *kms);
|
||||
MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms *kms,
|
||||
MetaKmsDevice *device);
|
||||
|
||||
MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms);
|
||||
MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms,
|
||||
MetaKmsDevice *device);
|
||||
|
||||
MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms *kms);
|
||||
MetaKmsFeedback * meta_kms_post_pending_updates_sync (MetaKms *kms);
|
||||
|
||||
void meta_kms_discard_pending_page_flips (MetaKms *kms);
|
||||
|
||||
|
@ -120,7 +120,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||
MetaKmsUpdate *kms_update;
|
||||
uint64_t state;
|
||||
GList *l;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
@ -142,15 +141,17 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
return;
|
||||
}
|
||||
|
||||
kms_update = meta_kms_ensure_pending_update (kms);
|
||||
for (l = meta_backend_get_gpus (backend); l; l = l->next)
|
||||
{
|
||||
MetaGpuKms *gpu_kms = l->data;
|
||||
MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
|
||||
MetaKmsUpdate *kms_update;
|
||||
|
||||
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
|
||||
meta_gpu_kms_set_power_save_mode (gpu_kms, state, kms_update);
|
||||
}
|
||||
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms);
|
||||
kms_feedback = meta_kms_post_pending_updates_sync (kms);
|
||||
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
|
||||
{
|
||||
g_warning ("Failed to set DPMS: %s",
|
||||
@ -418,20 +419,21 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
g_autofree char *gamma_ramp_string = NULL;
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaKmsUpdate *kms_update;
|
||||
g_autofree char *gamma_ramp_string = NULL;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
||||
kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
|
||||
meta_kms_update_set_crtc_gamma (kms_update, kms_crtc, size, red, green, blue);
|
||||
|
||||
gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
|
||||
g_debug ("Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s",
|
||||
meta_crtc_get_id (crtc), gamma_ramp_string);
|
||||
|
||||
kms_update = meta_kms_ensure_pending_update (kms);
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
||||
meta_kms_update_set_crtc_gamma (kms_update, kms_crtc, size, red, green, blue);
|
||||
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms);
|
||||
kms_feedback = meta_kms_post_pending_updates_sync (kms);
|
||||
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
|
||||
{
|
||||
g_warning ("Failed to set CRTC gamma: %s",
|
||||
|
@ -1285,8 +1285,7 @@ static void
|
||||
meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
||||
MetaRendererView *view,
|
||||
MetaCrtc *crtc,
|
||||
MetaKmsPageFlipFlag flags,
|
||||
MetaKmsUpdate *kms_update)
|
||||
MetaKmsPageFlipFlag flags)
|
||||
{
|
||||
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||
@ -1295,10 +1294,16 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
|
||||
MetaRendererNativeGpuData *renderer_gpu_data;
|
||||
MetaGpuKms *gpu_kms;
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaKms *kms;
|
||||
MetaKmsUpdate *kms_update;
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state = NULL;
|
||||
uint32_t fb_id;
|
||||
|
||||
gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
|
||||
kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
|
||||
kms = meta_kms_device_get_kms (kms_device);
|
||||
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
|
||||
|
||||
g_assert (meta_gpu_kms_is_crtc_active (gpu_kms, crtc));
|
||||
|
||||
@ -1340,16 +1345,21 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
|
||||
|
||||
static void
|
||||
meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen,
|
||||
MetaRendererNativeGpuData *renderer_gpu_data,
|
||||
MetaKmsUpdate *kms_update)
|
||||
MetaRendererNativeGpuData *renderer_gpu_data)
|
||||
{
|
||||
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
|
||||
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
MetaKms *kms = meta_kms_device_get_kms (kms_device);
|
||||
MetaKmsUpdate *kms_update;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeSetCrtcModes,
|
||||
"Onscreen (set CRTC modes)");
|
||||
|
||||
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
|
||||
|
||||
switch (renderer_gpu_data->mode)
|
||||
{
|
||||
case META_RENDERER_NATIVE_MODE_GBM:
|
||||
@ -1374,32 +1384,17 @@ meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen,
|
||||
|
||||
static void
|
||||
meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen,
|
||||
MetaKmsPageFlipFlag flags,
|
||||
MetaKmsUpdate *kms_update)
|
||||
MetaKmsPageFlipFlag flags)
|
||||
{
|
||||
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||
MetaRendererView *view = onscreen_native->view;
|
||||
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
|
||||
MetaRenderer *renderer = META_RENDERER (renderer_native);
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (meta_renderer_get_backend (renderer));
|
||||
MetaPowerSave power_save_mode;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs,
|
||||
"Onscreen (flip CRTCs)");
|
||||
|
||||
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
|
||||
if (power_save_mode == META_POWER_SAVE_ON)
|
||||
{
|
||||
meta_onscreen_native_flip_crtc (onscreen, view, onscreen_native->crtc,
|
||||
flags,
|
||||
kms_update);
|
||||
}
|
||||
else
|
||||
{
|
||||
queue_dummy_power_save_page_flip (onscreen);
|
||||
}
|
||||
meta_onscreen_native_flip_crtc (onscreen, view, onscreen_native->crtc,
|
||||
flags);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -1864,8 +1859,7 @@ retry:
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_crtc_modes (CoglOnscreen *onscreen,
|
||||
MetaKmsUpdate *kms_update)
|
||||
ensure_crtc_modes (CoglOnscreen *onscreen)
|
||||
{
|
||||
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||
@ -1874,29 +1868,19 @@ ensure_crtc_modes (CoglOnscreen *onscreen,
|
||||
CoglRenderer *cogl_renderer = cogl_context->display->renderer;
|
||||
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
|
||||
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
|
||||
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
||||
MetaRenderer *renderer = META_RENDERER (renderer_native);
|
||||
MetaBackend *backend = meta_renderer_get_backend (renderer);
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaPowerSave power_save_mode;
|
||||
|
||||
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
|
||||
if (onscreen_native->pending_set_crtc &&
|
||||
power_save_mode == META_POWER_SAVE_ON)
|
||||
if (onscreen_native->pending_set_crtc)
|
||||
{
|
||||
meta_onscreen_native_set_crtc_mode (onscreen,
|
||||
renderer_gpu_data,
|
||||
kms_update);
|
||||
meta_onscreen_native_set_crtc_mode (onscreen, renderer_gpu_data);
|
||||
onscreen_native->pending_set_crtc = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static MetaKmsUpdate *
|
||||
static gboolean
|
||||
unset_disabled_crtcs (MetaBackend *backend,
|
||||
MetaKms *kms)
|
||||
{
|
||||
MetaKmsUpdate *kms_update = NULL;
|
||||
gboolean did_mode_set = FALSE;
|
||||
GList *l;
|
||||
|
||||
for (l = meta_backend_get_gpus (backend); l; l = l->next)
|
||||
@ -1907,24 +1891,30 @@ unset_disabled_crtcs (MetaBackend *backend,
|
||||
for (k = meta_gpu_get_crtcs (gpu); k; k = k->next)
|
||||
{
|
||||
MetaCrtc *crtc = k->data;
|
||||
MetaKmsCrtc *kms_crtc =
|
||||
meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
||||
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
MetaKmsUpdate *kms_update;
|
||||
|
||||
if (meta_crtc_get_config (crtc))
|
||||
continue;
|
||||
|
||||
kms_update = meta_kms_ensure_pending_update (kms);
|
||||
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
|
||||
meta_crtc_kms_set_mode (META_CRTC_KMS (crtc), kms_update);
|
||||
|
||||
did_mode_set = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return kms_update;
|
||||
return did_mode_set;
|
||||
}
|
||||
|
||||
static void
|
||||
post_pending_update (MetaKms *kms)
|
||||
post_pending_updates (MetaKms *kms)
|
||||
{
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms);
|
||||
kms_feedback = meta_kms_post_pending_updates_sync (kms);
|
||||
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
|
||||
{
|
||||
const GError *error = meta_kms_feedback_get_error (kms_feedback);
|
||||
@ -1950,12 +1940,14 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
MetaRenderer *renderer = META_RENDERER (renderer_native);
|
||||
MetaBackend *backend = meta_renderer_get_backend (renderer);
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
|
||||
gboolean egl_context_changed = FALSE;
|
||||
MetaKmsUpdate *kms_update;
|
||||
MetaPowerSave power_save_mode;
|
||||
g_autoptr (GError) error = NULL;
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
@ -1963,8 +1955,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
|
||||
"Onscreen (swap-buffers)");
|
||||
|
||||
kms_update = meta_kms_ensure_pending_update (kms);
|
||||
|
||||
update_secondary_gpu_state_pre_swap_buffers (onscreen);
|
||||
|
||||
parent_vtable->onscreen_swap_buffers_with_damage (onscreen,
|
||||
@ -2003,10 +1993,17 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
|
||||
update_secondary_gpu_state_post_swap_buffers (onscreen, &egl_context_changed);
|
||||
|
||||
ensure_crtc_modes (onscreen, kms_update);
|
||||
meta_onscreen_native_flip_crtcs (onscreen,
|
||||
META_KMS_PAGE_FLIP_FLAG_NONE,
|
||||
kms_update);
|
||||
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
|
||||
if (power_save_mode == META_POWER_SAVE_ON)
|
||||
{
|
||||
ensure_crtc_modes (onscreen);
|
||||
meta_onscreen_native_flip_crtcs (onscreen, META_KMS_PAGE_FLIP_FLAG_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
queue_dummy_power_save_page_flip (onscreen);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we changed EGL context, cogl will have the wrong idea about what is
|
||||
@ -2019,7 +2016,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
|
||||
COGL_TRACE_BEGIN (MetaRendererNativePostKmsUpdate,
|
||||
"Onscreen (post pending update)");
|
||||
post_pending_update (kms);
|
||||
post_pending_updates (kms);
|
||||
COGL_TRACE_END (MetaRendererNativePostKmsUpdate);
|
||||
}
|
||||
|
||||
@ -2165,10 +2162,18 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
||||
MetaBackend *backend = meta_renderer_get_backend (renderer);
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||
MetaKmsUpdate *kms_update;
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaPowerSave power_save_mode;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
|
||||
kms_update = meta_kms_ensure_pending_update (kms);
|
||||
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
|
||||
if (power_save_mode != META_POWER_SAVE_ON)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"Can't scanout directly while power saving");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
|
||||
render_gpu);
|
||||
@ -2178,12 +2183,11 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
||||
|
||||
g_set_object (&onscreen_native->gbm.next_fb, META_DRM_BUFFER (scanout));
|
||||
|
||||
ensure_crtc_modes (onscreen, kms_update);
|
||||
ensure_crtc_modes (onscreen);
|
||||
meta_onscreen_native_flip_crtcs (onscreen,
|
||||
META_KMS_PAGE_FLIP_FLAG_NO_DISCARD_FEEDBACK,
|
||||
kms_update);
|
||||
META_KMS_PAGE_FLIP_FLAG_NO_DISCARD_FEEDBACK);
|
||||
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms);
|
||||
kms_feedback = meta_kms_post_pending_updates_sync (kms);
|
||||
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
|
||||
{
|
||||
const GError *feedback_error = meta_kms_feedback_get_error (kms_feedback);
|
||||
@ -3159,16 +3163,16 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
|
||||
MetaBackend *backend = meta_renderer_get_backend (renderer);
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||
MetaKmsUpdate *kms_update = NULL;
|
||||
gboolean did_mode_set = FALSE;
|
||||
|
||||
if (renderer_native->pending_unset_disabled_crtcs)
|
||||
{
|
||||
kms_update = unset_disabled_crtcs (backend, kms);
|
||||
did_mode_set = unset_disabled_crtcs (backend, kms);
|
||||
renderer_native->pending_unset_disabled_crtcs = FALSE;
|
||||
}
|
||||
|
||||
if (kms_update)
|
||||
post_pending_update (kms);
|
||||
if (did_mode_set)
|
||||
post_pending_updates (kms);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -3751,12 +3755,9 @@ meta_renderer_native_reset_modes (MetaRendererNative *renderer_native)
|
||||
MetaBackend *backend = meta_renderer_get_backend (renderer);
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||
MetaKmsUpdate *kms_update;
|
||||
|
||||
kms_update = unset_disabled_crtcs (backend, kms);
|
||||
|
||||
if (kms_update)
|
||||
post_pending_update (kms);
|
||||
if (unset_disabled_crtcs (backend, kms))
|
||||
post_pending_updates (kms);
|
||||
}
|
||||
|
||||
static MetaGpuKms *
|
||||
|
Loading…
Reference in New Issue
Block a user