kms: Make update processing return direct feedback

The current API as all synchronous, so they can be made to return
feedback immediately. This will be needed for the cursor renderer which
needs to know whether it should fall back to OpenGL cursor rendering.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
This commit is contained in:
Jonas Ådahl 2019-11-09 00:14:36 +01:00
parent 3ace2b9a28
commit 73dcb9fa22
11 changed files with 129 additions and 53 deletions

View File

@ -747,11 +747,11 @@ process_entries (MetaKmsImpl *impl,
return TRUE; return TRUE;
} }
static gboolean static MetaKmsFeedback *
meta_kms_impl_simple_process_update (MetaKmsImpl *impl, meta_kms_impl_simple_process_update (MetaKmsImpl *impl,
MetaKmsUpdate *update, MetaKmsUpdate *update)
GError **error)
{ {
GError *error = NULL;
GList *l; GList *l;
meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl)); meta_assert_in_kms_impl (meta_kms_impl_get_kms (impl));
@ -760,31 +760,31 @@ meta_kms_impl_simple_process_update (MetaKmsImpl *impl,
update, update,
meta_kms_update_get_connector_properties (update), meta_kms_update_get_connector_properties (update),
process_connector_property, process_connector_property,
error)) &error))
goto discard_page_flips; goto discard_page_flips;
if (!process_entries (impl, if (!process_entries (impl,
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 discard_page_flips; goto discard_page_flips;
if (!process_entries (impl, if (!process_entries (impl,
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 discard_page_flips; goto discard_page_flips;
if (!process_entries (impl, if (!process_entries (impl,
update, update,
meta_kms_update_get_page_flips (update), meta_kms_update_get_page_flips (update),
process_page_flip, process_page_flip,
error)) &error))
goto discard_page_flips; goto discard_page_flips;
return TRUE; return meta_kms_feedback_new_passed ();
discard_page_flips: discard_page_flips:
for (l = meta_kms_update_get_page_flips (update); l; l = l->next) for (l = meta_kms_update_get_page_flips (update); l; l = l->next)
@ -794,7 +794,7 @@ discard_page_flips:
discard_page_flip (impl, update, page_flip); discard_page_flip (impl, update, page_flip);
} }
return FALSE; return meta_kms_feedback_new_failed (error);
} }
static void static void

View File

@ -44,12 +44,11 @@ meta_kms_impl_get_kms (MetaKmsImpl *impl)
return priv->kms; return priv->kms;
} }
gboolean MetaKmsFeedback *
meta_kms_impl_process_update (MetaKmsImpl *impl, meta_kms_impl_process_update (MetaKmsImpl *impl,
MetaKmsUpdate *update, MetaKmsUpdate *update)
GError **error)
{ {
return META_KMS_IMPL_GET_CLASS (impl)->process_update (impl, update, error); return META_KMS_IMPL_GET_CLASS (impl)->process_update (impl, update);
} }
void void

View File

@ -33,9 +33,8 @@ struct _MetaKmsImplClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
gboolean (* process_update) (MetaKmsImpl *impl, MetaKmsFeedback * (* process_update) (MetaKmsImpl *impl,
MetaKmsUpdate *update, MetaKmsUpdate *update);
GError **error);
void (* handle_page_flip_callback) (MetaKmsImpl *impl, void (* handle_page_flip_callback) (MetaKmsImpl *impl,
MetaKmsPageFlipData *page_flip_data); MetaKmsPageFlipData *page_flip_data);
void (* discard_pending_page_flips) (MetaKmsImpl *impl); void (* discard_pending_page_flips) (MetaKmsImpl *impl);
@ -44,9 +43,8 @@ struct _MetaKmsImplClass
MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl); MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl);
gboolean meta_kms_impl_process_update (MetaKmsImpl *impl, MetaKmsFeedback * meta_kms_impl_process_update (MetaKmsImpl *impl,
MetaKmsUpdate *update, MetaKmsUpdate *update);
GError **error);
void meta_kms_impl_handle_page_flip_callback (MetaKmsImpl *impl, void meta_kms_impl_handle_page_flip_callback (MetaKmsImpl *impl,
MetaKmsPageFlipData *page_flip_data); MetaKmsPageFlipData *page_flip_data);

View File

@ -33,6 +33,8 @@ typedef struct _MetaKmsUpdate MetaKmsUpdate;
typedef struct _MetaKmsPlaneAssignment MetaKmsPlaneAssignment; typedef struct _MetaKmsPlaneAssignment MetaKmsPlaneAssignment;
typedef struct _MetaKmsModeSet MetaKmsModeSet; typedef struct _MetaKmsModeSet MetaKmsModeSet;
typedef struct _MetaKmsFeedback MetaKmsFeedback;
typedef struct _MetaKmsPageFlipFeedback MetaKmsPageFlipFeedback; typedef struct _MetaKmsPageFlipFeedback MetaKmsPageFlipFeedback;
typedef struct _MetaKmsImpl MetaKmsImpl; typedef struct _MetaKmsImpl MetaKmsImpl;

View File

@ -26,6 +26,13 @@
#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"
typedef struct _MetaKmsFeedback
{
MetaKmsFeedbackResult result;
GError *error;
} MetaKmsFeedback;
typedef struct _MetaKmsProperty typedef struct _MetaKmsProperty
{ {
uint32_t prop_id; uint32_t prop_id;
@ -78,6 +85,10 @@ typedef struct _MetaKmsPageFlip
gpointer custom_page_flip_user_data; gpointer custom_page_flip_user_data;
} MetaKmsPageFlip; } MetaKmsPageFlip;
MetaKmsFeedback * meta_kms_feedback_new_passed (void);
MetaKmsFeedback * meta_kms_feedback_new_failed (GError *error);
void meta_kms_update_seal (MetaKmsUpdate *update); void meta_kms_update_seal (MetaKmsUpdate *update);
gboolean meta_kms_update_is_sealed (MetaKmsUpdate *update); gboolean meta_kms_update_is_sealed (MetaKmsUpdate *update);

View File

@ -37,6 +37,52 @@ struct _MetaKmsUpdate
GList *crtc_gammas; GList *crtc_gammas;
}; };
MetaKmsFeedback *
meta_kms_feedback_new_passed (void)
{
MetaKmsFeedback *feedback;
feedback = g_new0 (MetaKmsFeedback, 1);
*feedback = (MetaKmsFeedback) {
.result = META_KMS_FEEDBACK_PASSED,
};
return feedback;
}
MetaKmsFeedback *
meta_kms_feedback_new_failed (GError *error)
{
MetaKmsFeedback *feedback;
feedback = g_new0 (MetaKmsFeedback, 1);
*feedback = (MetaKmsFeedback) {
.result = META_KMS_FEEDBACK_FAILED,
.error = error,
};
return feedback;
}
void
meta_kms_feedback_free (MetaKmsFeedback *feedback)
{
g_clear_error (&feedback->error);
g_free (feedback);
}
MetaKmsFeedbackResult
meta_kms_feedback_get_result (MetaKmsFeedback *feedback)
{
return feedback->result;
}
const GError *
meta_kms_feedback_get_error (MetaKmsFeedback *feedback)
{
return feedback->error;
}
static MetaKmsProperty * static MetaKmsProperty *
meta_kms_property_new (uint32_t prop_id, meta_kms_property_new (uint32_t prop_id,
uint64_t value) uint64_t value)

View File

@ -29,6 +29,12 @@
#include "backends/native/meta-kms-types.h" #include "backends/native/meta-kms-types.h"
#include "meta/boxes.h" #include "meta/boxes.h"
typedef enum _MetaKmsFeedbackResult
{
META_KMS_FEEDBACK_PASSED,
META_KMS_FEEDBACK_FAILED,
} MetaKmsFeedbackResult;
typedef enum _MetaKmsAssignPlaneFlag typedef enum _MetaKmsAssignPlaneFlag
{ {
META_KMS_ASSIGN_PLANE_FLAG_NONE = 0, META_KMS_ASSIGN_PLANE_FLAG_NONE = 0,
@ -53,6 +59,12 @@ struct _MetaKmsPageFlipFeedback
typedef int (* MetaKmsCustomPageFlipFunc) (gpointer custom_page_flip_data, typedef int (* MetaKmsCustomPageFlipFunc) (gpointer custom_page_flip_data,
gpointer user_data); gpointer user_data);
void meta_kms_feedback_free (MetaKmsFeedback *feedback);
MetaKmsFeedbackResult meta_kms_feedback_get_result (MetaKmsFeedback *feedback);
const GError * meta_kms_feedback_get_error (MetaKmsFeedback *feedback);
MetaKmsUpdate * meta_kms_update_new (void); MetaKmsUpdate * meta_kms_update_new (void);
void meta_kms_update_free (MetaKmsUpdate *update); void meta_kms_update_free (MetaKmsUpdate *update);
@ -109,6 +121,7 @@ meta_fixed_16_rectangle_to_rectangle (MetaFixed16Rectangle fixed_rect)
}; };
} }
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsFeedback, meta_kms_feedback_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsUpdate, meta_kms_update_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsUpdate, meta_kms_update_free)
#endif /* META_KMS_UPDATE_H */ #endif /* META_KMS_UPDATE_H */

View File

@ -207,41 +207,34 @@ meta_kms_process_update_in_impl (MetaKmsImpl *impl,
GError **error) GError **error)
{ {
g_autoptr (MetaKmsUpdate) update = user_data; g_autoptr (MetaKmsUpdate) update = user_data;
gboolean ret; MetaKmsFeedback *feedback;
ret = meta_kms_impl_process_update (impl, update, error);
feedback = meta_kms_impl_process_update (impl, update);
meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update); meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update);
return GINT_TO_POINTER (ret); return feedback;
} }
static gboolean static MetaKmsFeedback *
meta_kms_post_update_sync (MetaKms *kms, meta_kms_post_update_sync (MetaKms *kms,
MetaKmsUpdate *update, MetaKmsUpdate *update)
GError **error)
{ {
gpointer ret;
meta_kms_update_seal (update); meta_kms_update_seal (update);
COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync, COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync,
"KMS (post update)"); "KMS (post update)");
ret = meta_kms_run_impl_task_sync (kms, return meta_kms_run_impl_task_sync (kms,
meta_kms_process_update_in_impl, meta_kms_process_update_in_impl,
update, update,
error); NULL);
return GPOINTER_TO_INT (ret);
} }
gboolean MetaKmsFeedback *
meta_kms_post_pending_update_sync (MetaKms *kms, meta_kms_post_pending_update_sync (MetaKms *kms)
GError **error)
{ {
return meta_kms_post_update_sync (kms, return meta_kms_post_update_sync (kms,
g_steal_pointer (&kms->pending_update), g_steal_pointer (&kms->pending_update));
error);
} }
static gpointer static gpointer

View File

@ -32,8 +32,7 @@ MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms *kms);
MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms); MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms);
gboolean meta_kms_post_pending_update_sync (MetaKms *kms, MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms *kms);
GError **error);
void meta_kms_discard_pending_page_flips (MetaKms *kms); void meta_kms_discard_pending_page_flips (MetaKms *kms);

View File

@ -121,9 +121,9 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
MetaKms *kms = meta_backend_native_get_kms (backend_native); MetaKms *kms = meta_backend_native_get_kms (backend_native);
MetaKmsUpdate *kms_update; MetaKmsUpdate *kms_update;
g_autoptr (GError) error = NULL;
uint64_t state; uint64_t state;
GList *l; GList *l;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
switch (mode) { switch (mode) {
case META_POWER_SAVE_ON: case META_POWER_SAVE_ON:
@ -150,8 +150,12 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
meta_gpu_kms_set_power_save_mode (gpu_kms, state, kms_update); meta_gpu_kms_set_power_save_mode (gpu_kms, state, kms_update);
} }
if (!meta_kms_post_pending_update_sync (kms, &error)) kms_feedback = meta_kms_post_pending_update_sync (kms);
g_warning ("Failed to DPMS: %s", error->message); if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{
g_warning ("Failed to set DPMS: %s",
meta_kms_feedback_get_error (kms_feedback)->message);
}
} }
static void static void
@ -455,7 +459,7 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
MetaKmsCrtc *kms_crtc; MetaKmsCrtc *kms_crtc;
g_autofree char *gamma_ramp_string = NULL; g_autofree char *gamma_ramp_string = NULL;
MetaKmsUpdate *kms_update; MetaKmsUpdate *kms_update;
g_autoptr (GError) error = NULL; g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue); gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
g_debug ("Setting CRTC (%ld) gamma to %s", crtc->crtc_id, gamma_ramp_string); g_debug ("Setting CRTC (%ld) gamma to %s", crtc->crtc_id, gamma_ramp_string);
@ -466,8 +470,12 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
meta_kms_crtc_set_gamma (kms_crtc, kms_update, meta_kms_crtc_set_gamma (kms_crtc, kms_update,
size, red, green, blue); size, red, green, blue);
if (!meta_kms_post_pending_update_sync (kms, &error)) kms_feedback = meta_kms_post_pending_update_sync (kms);
g_warning ("Failed to CRTC gamma: %s", error->message); if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{
g_warning ("Failed to set CRTC gamma: %s",
meta_kms_feedback_get_error (kms_feedback)->message);
}
} }
static void static void

View File

@ -2280,6 +2280,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
MetaPowerSave power_save_mode; MetaPowerSave power_save_mode;
g_autoptr (GError) error = NULL; g_autoptr (GError) error = NULL;
MetaDrmBufferGbm *buffer_gbm; MetaDrmBufferGbm *buffer_gbm;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers, COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
"Onscreen (swap-buffers)"); "Onscreen (swap-buffers)");
@ -2361,8 +2362,11 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
COGL_TRACE_BEGIN (MetaRendererNativePostKmsUpdate, COGL_TRACE_BEGIN (MetaRendererNativePostKmsUpdate,
"Onscreen (post pending update)"); "Onscreen (post pending update)");
if (!meta_kms_post_pending_update_sync (kms, &error)) kms_feedback = meta_kms_post_pending_update_sync (kms);
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{ {
const GError *error = meta_kms_feedback_get_error (kms_feedback);
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
g_warning ("Failed to post KMS update: %s", error->message); g_warning ("Failed to post KMS update: %s", error->message);
} }
@ -3431,7 +3435,6 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
MetaKms *kms = meta_backend_native_get_kms (backend_native); MetaKms *kms = meta_backend_native_get_kms (backend_native);
MetaKmsUpdate *kms_update = NULL; MetaKmsUpdate *kms_update = NULL;
GError *error = NULL;
renderer_native->frame_counter++; renderer_native->frame_counter++;
@ -3461,11 +3464,15 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
if (kms_update) if (kms_update)
{ {
if (!meta_kms_post_pending_update_sync (kms, &error)) g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
kms_feedback = meta_kms_post_pending_update_sync (kms);
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{ {
const GError *error = meta_kms_feedback_get_error (kms_feedback);
if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED)) if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
g_warning ("Failed to post KMS update: %s", error->message); g_warning ("Failed to post KMS update: %s", error->message);
g_error_free (error);
} }
} }
} }