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:
Jonas Ådahl 2020-07-16 23:38:10 +02:00 committed by Marge Bot
parent a7a1391de7
commit 37fe30c515
10 changed files with 221 additions and 114 deletions

View File

@ -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)

View File

@ -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)
{

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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 MetaKmsFeedback *
combine_feedbacks (MetaKmsFeedback *feedback,
MetaKmsFeedback *other_feedback)
{
GList *failed_planes;
MetaKmsFeedback *new_feedback;
const GError *error;
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_update_in_impl (MetaKmsImpl *impl,
meta_kms_process_updates_in_impl (MetaKmsImpl *impl,
gpointer user_data,
GError **error)
{
g_autoptr (MetaKmsUpdate) update = user_data;
MetaKmsFeedback *feedback;
GList *updates = user_data;
MetaKmsFeedback *feedback = NULL;
GList *l;
feedback = meta_kms_impl_process_update (impl, update);
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

View File

@ -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);

View File

@ -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",

View File

@ -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);
}
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 *