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

View File

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

View File

@ -33,9 +33,8 @@ struct _MetaKmsImplClass
{
GObjectClass parent_class;
gboolean (* process_update) (MetaKmsImpl *impl,
MetaKmsUpdate *update,
GError **error);
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);
@ -44,9 +43,8 @@ struct _MetaKmsImplClass
MetaKms * meta_kms_impl_get_kms (MetaKmsImpl *impl);
gboolean meta_kms_impl_process_update (MetaKmsImpl *impl,
MetaKmsUpdate *update,
GError **error);
MetaKmsFeedback * meta_kms_impl_process_update (MetaKmsImpl *impl,
MetaKmsUpdate *update);
void meta_kms_impl_handle_page_flip_callback (MetaKmsImpl *impl,
MetaKmsPageFlipData *page_flip_data);

View File

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

View File

@ -26,6 +26,13 @@
#include "backends/native/meta-kms-types.h"
#include "backends/native/meta-kms-update.h"
typedef struct _MetaKmsFeedback
{
MetaKmsFeedbackResult result;
GError *error;
} MetaKmsFeedback;
typedef struct _MetaKmsProperty
{
uint32_t prop_id;
@ -78,6 +85,10 @@ typedef struct _MetaKmsPageFlip
gpointer custom_page_flip_user_data;
} MetaKmsPageFlip;
MetaKmsFeedback * meta_kms_feedback_new_passed (void);
MetaKmsFeedback * meta_kms_feedback_new_failed (GError *error);
void meta_kms_update_seal (MetaKmsUpdate *update);
gboolean meta_kms_update_is_sealed (MetaKmsUpdate *update);

View File

@ -37,6 +37,52 @@ struct _MetaKmsUpdate
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 *
meta_kms_property_new (uint32_t prop_id,
uint64_t value)

View File

@ -29,6 +29,12 @@
#include "backends/native/meta-kms-types.h"
#include "meta/boxes.h"
typedef enum _MetaKmsFeedbackResult
{
META_KMS_FEEDBACK_PASSED,
META_KMS_FEEDBACK_FAILED,
} MetaKmsFeedbackResult;
typedef enum _MetaKmsAssignPlaneFlag
{
META_KMS_ASSIGN_PLANE_FLAG_NONE = 0,
@ -53,6 +59,12 @@ struct _MetaKmsPageFlipFeedback
typedef int (* MetaKmsCustomPageFlipFunc) (gpointer custom_page_flip_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);
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)
#endif /* META_KMS_UPDATE_H */

View File

@ -207,41 +207,34 @@ meta_kms_process_update_in_impl (MetaKmsImpl *impl,
GError **error)
{
g_autoptr (MetaKmsUpdate) update = user_data;
gboolean ret;
ret = meta_kms_impl_process_update (impl, update, error);
MetaKmsFeedback *feedback;
feedback = meta_kms_impl_process_update (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,
MetaKmsUpdate *update,
GError **error)
MetaKmsUpdate *update)
{
gpointer ret;
meta_kms_update_seal (update);
COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync,
"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,
update,
error);
return GPOINTER_TO_INT (ret);
NULL);
}
gboolean
meta_kms_post_pending_update_sync (MetaKms *kms,
GError **error)
MetaKmsFeedback *
meta_kms_post_pending_update_sync (MetaKms *kms)
{
return meta_kms_post_update_sync (kms,
g_steal_pointer (&kms->pending_update),
error);
g_steal_pointer (&kms->pending_update));
}
static gpointer

View File

@ -32,8 +32,7 @@ MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms *kms);
MetaKmsUpdate * meta_kms_get_pending_update (MetaKms *kms);
gboolean meta_kms_post_pending_update_sync (MetaKms *kms,
GError **error);
MetaKmsFeedback * meta_kms_post_pending_update_sync (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);
MetaKms *kms = meta_backend_native_get_kms (backend_native);
MetaKmsUpdate *kms_update;
g_autoptr (GError) error = NULL;
uint64_t state;
GList *l;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
switch (mode) {
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);
}
if (!meta_kms_post_pending_update_sync (kms, &error))
g_warning ("Failed to DPMS: %s", error->message);
kms_feedback = meta_kms_post_pending_update_sync (kms);
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
@ -455,7 +459,7 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
MetaKmsCrtc *kms_crtc;
g_autofree char *gamma_ramp_string = NULL;
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);
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,
size, red, green, blue);
if (!meta_kms_post_pending_update_sync (kms, &error))
g_warning ("Failed to CRTC gamma: %s", error->message);
kms_feedback = meta_kms_post_pending_update_sync (kms);
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

View File

@ -2280,6 +2280,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
MetaPowerSave power_save_mode;
g_autoptr (GError) error = NULL;
MetaDrmBufferGbm *buffer_gbm;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
"Onscreen (swap-buffers)");
@ -2361,8 +2362,11 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
COGL_TRACE_BEGIN (MetaRendererNativePostKmsUpdate,
"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))
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);
MetaKms *kms = meta_backend_native_get_kms (backend_native);
MetaKmsUpdate *kms_update = NULL;
GError *error = NULL;
renderer_native->frame_counter++;
@ -3461,11 +3464,15 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
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))
g_warning ("Failed to post KMS update: %s", error->message);
g_error_free (error);
}
}
}