kms: Add way to preserve failed update
When we e.g. try to post an direct client buffer scanout update, it might arbitrarily fail; when this happen we still will want to post the rest of the update when we try again after having composited the primary plane. To do this, add a way to preserve the metadata of an update if it failed, only dropping the failed plane assignments. This involves unlocking a previously locked MetaKmsUpdate, so that e.g. a new primary plane can be assigned. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
parent
8876b217af
commit
3bad37482d
@ -1079,9 +1079,13 @@ meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
|
||||
for (l = meta_kms_get_devices (kms); l; l = l->next)
|
||||
{
|
||||
MetaKmsDevice *kms_device = l->data;
|
||||
MetaKmsUpdateFlag flags;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
|
||||
flags = META_KMS_UPDATE_FLAG_NONE;
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms,
|
||||
kms_device,
|
||||
flags);
|
||||
on_kms_update_result (kms_feedback, renderer);
|
||||
}
|
||||
}
|
||||
|
@ -112,6 +112,8 @@ MetaKmsFeedback * meta_kms_feedback_new_failed (GList *failed_planes,
|
||||
|
||||
void meta_kms_update_lock (MetaKmsUpdate *update);
|
||||
|
||||
void meta_kms_update_unlock (MetaKmsUpdate *update);
|
||||
|
||||
gboolean meta_kms_update_is_locked (MetaKmsUpdate *update);
|
||||
|
||||
MetaKmsDevice * meta_kms_update_get_device (MetaKmsUpdate *update);
|
||||
@ -136,6 +138,9 @@ void meta_kms_update_get_custom_page_flip_func (MetaKmsUpdate *updat
|
||||
MetaKmsCustomPageFlipFunc *custom_page_flip_func,
|
||||
gpointer *custom_page_flip_user_data);
|
||||
|
||||
void meta_kms_update_drop_plane_assignment (MetaKmsUpdate *update,
|
||||
MetaKmsPlane *plane);
|
||||
|
||||
GList * meta_kms_update_take_result_listeners (MetaKmsUpdate *update);
|
||||
|
||||
void meta_kms_result_listener_notify (MetaKmsResultListener *listener,
|
||||
|
@ -141,6 +141,26 @@ meta_kms_mode_set_free (MetaKmsModeSet *mode_set)
|
||||
g_free (mode_set);
|
||||
}
|
||||
|
||||
void
|
||||
meta_kms_update_drop_plane_assignment (MetaKmsUpdate *update,
|
||||
MetaKmsPlane *plane)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = update->plane_assignments; l; l = l->next)
|
||||
{
|
||||
MetaKmsPlaneAssignment *plane_assignment = l->data;
|
||||
|
||||
if (plane_assignment->plane == plane)
|
||||
{
|
||||
update->plane_assignments =
|
||||
g_list_delete_link (update->plane_assignments, l);
|
||||
meta_kms_plane_assignment_free (plane_assignment);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MetaKmsPlaneAssignment *
|
||||
meta_kms_update_assign_plane (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc,
|
||||
@ -469,6 +489,12 @@ meta_kms_update_lock (MetaKmsUpdate *update)
|
||||
update->is_locked = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_kms_update_unlock (MetaKmsUpdate *update)
|
||||
{
|
||||
update->is_locked = FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_kms_update_is_locked (MetaKmsUpdate *update)
|
||||
{
|
||||
|
@ -177,6 +177,13 @@ struct _MetaKms
|
||||
|
||||
G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
meta_kms_add_pending_update (MetaKms *kms,
|
||||
MetaKmsUpdate *update)
|
||||
{
|
||||
kms->pending_updates = g_list_prepend (kms->pending_updates, update);
|
||||
}
|
||||
|
||||
MetaKmsUpdate *
|
||||
meta_kms_ensure_pending_update (MetaKms *kms,
|
||||
MetaKmsDevice *device)
|
||||
@ -188,7 +195,7 @@ meta_kms_ensure_pending_update (MetaKms *kms,
|
||||
return update;
|
||||
|
||||
update = meta_kms_update_new (device);
|
||||
kms->pending_updates = g_list_prepend (kms->pending_updates, update);
|
||||
meta_kms_add_pending_update (kms, update);
|
||||
|
||||
return update;
|
||||
}
|
||||
@ -246,8 +253,9 @@ meta_kms_process_update_in_impl (MetaKmsImpl *impl,
|
||||
}
|
||||
|
||||
MetaKmsFeedback *
|
||||
meta_kms_post_pending_update_sync (MetaKms *kms,
|
||||
MetaKmsDevice *device)
|
||||
meta_kms_post_pending_update_sync (MetaKms *kms,
|
||||
MetaKmsDevice *device,
|
||||
MetaKmsUpdateFlag flags)
|
||||
{
|
||||
MetaKmsUpdate *update;
|
||||
MetaKmsFeedback *feedback;
|
||||
@ -270,6 +278,27 @@ meta_kms_post_pending_update_sync (MetaKms *kms,
|
||||
|
||||
result_listeners = meta_kms_update_take_result_listeners (update);
|
||||
|
||||
if (feedback->error &&
|
||||
flags & META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
meta_kms_update_unlock (update);
|
||||
|
||||
for (l = feedback->failed_planes; l; l = l->next)
|
||||
{
|
||||
MetaKmsPlane *plane = l->data;
|
||||
|
||||
meta_kms_update_drop_plane_assignment (update, plane);
|
||||
}
|
||||
|
||||
meta_kms_add_pending_update (kms, update);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_kms_update_free (update);
|
||||
}
|
||||
|
||||
for (l = result_listeners; l; l = l->next)
|
||||
{
|
||||
MetaKmsResultListener *listener = l->data;
|
||||
@ -279,8 +308,6 @@ meta_kms_post_pending_update_sync (MetaKms *kms,
|
||||
}
|
||||
g_list_free (result_listeners);
|
||||
|
||||
meta_kms_update_free (update);
|
||||
|
||||
return feedback;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,12 @@
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/native/meta-kms-types.h"
|
||||
|
||||
typedef enum _MetaKmsUpdateFlag
|
||||
{
|
||||
META_KMS_UPDATE_FLAG_NONE = 0,
|
||||
META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR = 1 << 0,
|
||||
} MetaKmsUpdateFlag;
|
||||
|
||||
#define META_TYPE_KMS (meta_kms_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaKms, meta_kms, META, KMS, GObject)
|
||||
|
||||
@ -34,8 +40,9 @@ MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms *kms,
|
||||
MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms,
|
||||
MetaKmsDevice *device);
|
||||
|
||||
MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms *kms,
|
||||
MetaKmsDevice *device);
|
||||
MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms *kms,
|
||||
MetaKmsDevice *device,
|
||||
MetaKmsUpdateFlag flags);
|
||||
|
||||
void meta_kms_discard_pending_page_flips (MetaKms *kms);
|
||||
|
||||
|
@ -145,12 +145,16 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
|
||||
MetaGpuKms *gpu_kms = l->data;
|
||||
MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
|
||||
MetaKmsUpdate *kms_update;
|
||||
MetaKmsUpdateFlag flags;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
|
||||
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_device);
|
||||
flags = META_KMS_UPDATE_FLAG_NONE;
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms,
|
||||
kms_device,
|
||||
flags);
|
||||
if (meta_kms_feedback_get_result (kms_feedback) !=
|
||||
META_KMS_FEEDBACK_PASSED)
|
||||
{
|
||||
@ -423,6 +427,7 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaKmsUpdate *kms_update;
|
||||
g_autofree char *gamma_ramp_string = NULL;
|
||||
MetaKmsUpdateFlag flags;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
||||
@ -434,7 +439,8 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
g_debug ("Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s",
|
||||
meta_crtc_get_id (crtc), gamma_ramp_string);
|
||||
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
|
||||
flags = META_KMS_UPDATE_FLAG_NONE;
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device, flags);
|
||||
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
|
||||
{
|
||||
g_warning ("Failed to set CRTC gamma: %s",
|
||||
|
@ -1877,6 +1877,7 @@ unset_disabled_crtcs (MetaBackend *backend,
|
||||
meta_gpu_kms_get_kms_device (META_GPU_KMS (gpu));
|
||||
GList *k;
|
||||
gboolean did_mode_set = FALSE;
|
||||
MetaKmsUpdateFlag flags;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
|
||||
for (k = meta_gpu_get_crtcs (gpu); k; k = k->next)
|
||||
@ -1896,7 +1897,10 @@ unset_disabled_crtcs (MetaBackend *backend,
|
||||
if (!did_mode_set)
|
||||
continue;
|
||||
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
|
||||
flags = META_KMS_UPDATE_FLAG_NONE;
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms,
|
||||
kms_device,
|
||||
flags);
|
||||
if (meta_kms_feedback_get_result (kms_feedback) !=
|
||||
META_KMS_FEEDBACK_PASSED)
|
||||
{
|
||||
@ -1938,6 +1942,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaKmsUpdateFlag flags;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
|
||||
@ -2006,7 +2011,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
"Onscreen (post pending update)");
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc));
|
||||
kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
|
||||
|
||||
flags = META_KMS_UPDATE_FLAG_NONE;
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device, flags);
|
||||
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
|
||||
{
|
||||
const GError *error = meta_kms_feedback_get_error (kms_feedback);
|
||||
@ -2176,6 +2183,7 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
||||
MetaPowerSave power_save_mode;
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaKmsUpdateFlag flags;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
|
||||
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
|
||||
@ -2199,7 +2207,9 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
||||
|
||||
kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc));
|
||||
kms_device = meta_kms_crtc_get_device (kms_crtc);
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
|
||||
|
||||
flags = META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR;
|
||||
kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device, flags);
|
||||
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
|
||||
{
|
||||
const GError *feedback_error = meta_kms_feedback_get_error (kms_feedback);
|
||||
|
Loading…
x
Reference in New Issue
Block a user