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; MetaLogicalMonitor *in_logical_monitor;
graphene_rect_t in_local_cursor_rect; graphene_rect_t in_local_cursor_rect;
MetaCursorSprite *in_cursor_sprite; MetaCursorSprite *in_cursor_sprite;
MetaKmsUpdate *in_kms_update;
gboolean out_painted; gboolean out_painted;
} UpdateCrtcCursorData; } UpdateCrtcCursorData;
@ -401,6 +400,10 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
MetaCursorRendererNativePrivate *priv = MetaCursorRendererNativePrivate *priv =
meta_cursor_renderer_native_get_instance_private (cursor_renderer_native); meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
MetaCrtc *crtc; MetaCrtc *crtc;
MetaGpuKms *gpu_kms;
MetaKmsDevice *kms_device;
MetaKms *kms;
MetaKmsUpdate *kms_update;
MetaMonitorTransform transform; MetaMonitorTransform transform;
const MetaCrtcModeInfo *crtc_mode_info; const MetaCrtcModeInfo *crtc_mode_info;
graphene_rect_t scaled_crtc_rect; 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); 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 && if (priv->has_hw_cursor &&
graphene_rect_intersection (&scaled_crtc_rect, graphene_rect_intersection (&scaled_crtc_rect,
@ -487,7 +494,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
&cursor_rect); &cursor_rect);
set_crtc_cursor (data->in_cursor_renderer_native, set_crtc_cursor (data->in_cursor_renderer_native,
data->in_kms_update, kms_update,
META_CRTC_KMS (crtc), META_CRTC_KMS (crtc),
cursor_rect.x, cursor_rect.x,
cursor_rect.y, cursor_rect.y,
@ -498,7 +505,7 @@ update_monitor_crtc_cursor (MetaMonitor *monitor,
else else
{ {
unset_crtc_cursor (data->in_cursor_renderer_native, unset_crtc_cursor (data->in_cursor_renderer_native,
data->in_kms_update, kms_update,
META_CRTC_KMS (crtc)); META_CRTC_KMS (crtc));
} }
@ -533,15 +540,12 @@ update_hw_cursor (MetaCursorRendererNative *native,
MetaKms *kms = meta_backend_native_get_kms (backend_native); MetaKms *kms = meta_backend_native_get_kms (backend_native);
MetaMonitorManager *monitor_manager = MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend); meta_backend_get_monitor_manager (backend);
MetaKmsUpdate *kms_update;
GList *logical_monitors; GList *logical_monitors;
GList *l; GList *l;
graphene_rect_t rect; graphene_rect_t rect;
gboolean painted = FALSE; gboolean painted = FALSE;
g_autoptr (MetaKmsFeedback) feedback = NULL; g_autoptr (MetaKmsFeedback) feedback = NULL;
kms_update = meta_kms_ensure_pending_update (kms);
if (cursor_sprite) if (cursor_sprite)
rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite); rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
else else
@ -567,7 +571,6 @@ update_hw_cursor (MetaCursorRendererNative *native,
.size = rect.size .size = rect.size
}, },
.in_cursor_sprite = cursor_sprite, .in_cursor_sprite = cursor_sprite,
.in_kms_update = kms_update,
}; };
monitors = meta_logical_monitor_get_monitors (logical_monitor); monitors = meta_logical_monitor_get_monitors (logical_monitor);
@ -586,7 +589,7 @@ update_hw_cursor (MetaCursorRendererNative *native,
painted = painted || data.out_painted; 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) if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED)
{ {
for (l = meta_kms_feedback_get_failed_planes (feedback); l; l = l->next) 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); G_DEFINE_TYPE (MetaKmsDevice, meta_kms_device, G_TYPE_OBJECT);
MetaKms *
meta_kms_device_get_kms (MetaKmsDevice *device)
{
return device->kms;
}
MetaKmsImplDevice * MetaKmsImplDevice *
meta_kms_device_get_impl_device (MetaKmsDevice *device) 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, META, KMS_DEVICE,
GObject) GObject)
MetaKms * meta_kms_device_get_kms (MetaKmsDevice *device);
int meta_kms_device_leak_fd (MetaKmsDevice *device); int meta_kms_device_leak_fd (MetaKmsDevice *device);
const char * meta_kms_device_get_path (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); 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, void meta_kms_plane_assignment_set_rotation (MetaKmsPlaneAssignment *plane_assignment,
uint64_t rotation); uint64_t rotation);

View File

@ -23,11 +23,15 @@
#include "backends/native/meta-kms-update-private.h" #include "backends/native/meta-kms-update-private.h"
#include "backends/meta-display-config-shared.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-mode-private.h"
#include "backends/native/meta-kms-plane.h" #include "backends/native/meta-kms-plane.h"
struct _MetaKmsUpdate struct _MetaKmsUpdate
{ {
MetaKmsDevice *device;
gboolean is_sealed; gboolean is_sealed;
MetaPowerSave power_save; MetaPowerSave power_save;
@ -143,6 +147,8 @@ meta_kms_update_assign_plane (MetaKmsUpdate *update,
MetaKmsPlaneAssignment *plane_assignment; MetaKmsPlaneAssignment *plane_assignment;
g_assert (!meta_kms_update_is_sealed (update)); 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 = g_new0 (MetaKmsPlaneAssignment, 1);
*plane_assignment = (MetaKmsPlaneAssignment) { *plane_assignment = (MetaKmsPlaneAssignment) {
@ -169,6 +175,8 @@ meta_kms_update_unassign_plane (MetaKmsUpdate *update,
MetaKmsPlaneAssignment *plane_assignment; MetaKmsPlaneAssignment *plane_assignment;
g_assert (!meta_kms_update_is_sealed (update)); 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 = g_new0 (MetaKmsPlaneAssignment, 1);
*plane_assignment = (MetaKmsPlaneAssignment) { *plane_assignment = (MetaKmsPlaneAssignment) {
@ -193,6 +201,7 @@ meta_kms_update_mode_set (MetaKmsUpdate *update,
MetaKmsModeSet *mode_set; MetaKmsModeSet *mode_set;
g_assert (!meta_kms_update_is_sealed (update)); 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 = g_new0 (MetaKmsModeSet, 1);
*mode_set = (MetaKmsModeSet) { *mode_set = (MetaKmsModeSet) {
@ -237,6 +246,7 @@ meta_kms_update_set_underscanning (MetaKmsUpdate *update,
MetaKmsConnectorUpdate *connector_update; MetaKmsConnectorUpdate *connector_update;
g_assert (!meta_kms_update_is_sealed (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 = ensure_connector_update (update, connector);
connector_update->underscanning.has_update = TRUE; connector_update->underscanning.has_update = TRUE;
@ -252,6 +262,7 @@ meta_kms_update_unset_underscanning (MetaKmsUpdate *update,
MetaKmsConnectorUpdate *connector_update; MetaKmsConnectorUpdate *connector_update;
g_assert (!meta_kms_update_is_sealed (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 = ensure_connector_update (update, connector);
connector_update->underscanning.has_update = TRUE; connector_update->underscanning.has_update = TRUE;
@ -266,6 +277,7 @@ meta_kms_update_set_dpms_state (MetaKmsUpdate *update,
MetaKmsConnectorUpdate *connector_update; MetaKmsConnectorUpdate *connector_update;
g_assert (!meta_kms_update_is_sealed (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 = ensure_connector_update (update, connector);
connector_update->dpms.has_update = TRUE; connector_update->dpms.has_update = TRUE;
@ -292,6 +304,7 @@ meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
MetaKmsCrtcGamma *gamma; MetaKmsCrtcGamma *gamma;
g_assert (!meta_kms_update_is_sealed (update)); g_assert (!meta_kms_update_is_sealed (update));
g_assert (meta_kms_crtc_get_device (crtc) == update->device);
gamma = g_new0 (MetaKmsCrtcGamma, 1); gamma = g_new0 (MetaKmsCrtcGamma, 1);
*gamma = (MetaKmsCrtcGamma) { *gamma = (MetaKmsCrtcGamma) {
@ -315,6 +328,7 @@ meta_kms_update_page_flip (MetaKmsUpdate *update,
MetaKmsPageFlip *page_flip; MetaKmsPageFlip *page_flip;
g_assert (!meta_kms_update_is_sealed (update)); 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 = g_new0 (MetaKmsPageFlip, 1);
*page_flip = (MetaKmsPageFlip) { *page_flip = (MetaKmsPageFlip) {
@ -338,6 +352,7 @@ meta_kms_update_custom_page_flip (MetaKmsUpdate *update,
MetaKmsPageFlip *page_flip; MetaKmsPageFlip *page_flip;
g_assert (!meta_kms_update_is_sealed (update)); 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 = g_new0 (MetaKmsPageFlip, 1);
*page_flip = (MetaKmsPageFlip) { *page_flip = (MetaKmsPageFlip) {
@ -430,10 +445,21 @@ meta_kms_update_is_sealed (MetaKmsUpdate *update)
return update->is_sealed; return update->is_sealed;
} }
MetaKmsUpdate * MetaKmsDevice *
meta_kms_update_new (void) 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 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); 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); 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 * 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 * 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 * 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: * There are also these private objects, without public facing API:
@ -174,7 +175,7 @@ struct _MetaKms
GList *devices; GList *devices;
MetaKmsUpdate *pending_update; GList *pending_updates;
GList *pending_callbacks; GList *pending_callbacks;
guint callback_source_id; guint callback_source_id;
@ -183,18 +184,36 @@ struct _MetaKms
G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT) G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT)
MetaKmsUpdate * MetaKmsUpdate *
meta_kms_ensure_pending_update (MetaKms *kms) meta_kms_ensure_pending_update (MetaKms *kms,
MetaKmsDevice *device)
{ {
if (!kms->pending_update) MetaKmsUpdate *update;
kms->pending_update = meta_kms_update_new ();
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 * 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 static void
@ -208,40 +227,84 @@ meta_kms_predict_states_in_impl (MetaKms *kms,
update); 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 static gpointer
meta_kms_process_update_in_impl (MetaKmsImpl *impl, meta_kms_process_updates_in_impl (MetaKmsImpl *impl,
gpointer user_data, gpointer user_data,
GError **error) GError **error)
{ {
g_autoptr (MetaKmsUpdate) update = user_data; GList *updates = user_data;
MetaKmsFeedback *feedback; 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); 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; return feedback;
} }
static MetaKmsFeedback * static MetaKmsFeedback *
meta_kms_post_update_sync (MetaKms *kms, meta_kms_post_updates_sync (MetaKms *kms,
MetaKmsUpdate *update) GList *updates)
{ {
meta_kms_update_seal (update); g_list_foreach (updates, (GFunc) meta_kms_update_seal, NULL);
COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync, COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync,
"KMS (post update)"); "KMS (post update)");
return meta_kms_run_impl_task_sync (kms, return meta_kms_run_impl_task_sync (kms,
meta_kms_process_update_in_impl, meta_kms_process_updates_in_impl,
update, updates,
NULL); NULL);
} }
MetaKmsFeedback * MetaKmsFeedback *
meta_kms_post_pending_update_sync (MetaKms *kms) meta_kms_post_pending_updates_sync (MetaKms *kms)
{ {
return meta_kms_post_update_sync (kms, return meta_kms_post_updates_sync (kms,
g_steal_pointer (&kms->pending_update)); g_steal_pointer (&kms->pending_updates));
} }
static gpointer static gpointer

View File

@ -28,11 +28,13 @@
#define META_TYPE_KMS (meta_kms_get_type ()) #define META_TYPE_KMS (meta_kms_get_type ())
G_DECLARE_FINAL_TYPE (MetaKms, meta_kms, META, KMS, GObject) 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); 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); MetaBackend *backend = meta_monitor_manager_get_backend (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;
uint64_t state; uint64_t state;
GList *l; GList *l;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL; g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
@ -142,15 +141,17 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
return; return;
} }
kms_update = meta_kms_ensure_pending_update (kms);
for (l = meta_backend_get_gpus (backend); l; l = l->next) for (l = meta_backend_get_gpus (backend); l; l = l->next)
{ {
MetaGpuKms *gpu_kms = l->data; 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); 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) if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{ {
g_warning ("Failed to set DPMS: %s", 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); 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);
MetaKmsCrtc *kms_crtc; MetaKmsCrtc *kms_crtc;
g_autofree char *gamma_ramp_string = NULL; MetaKmsDevice *kms_device;
MetaKmsUpdate *kms_update; MetaKmsUpdate *kms_update;
g_autofree char *gamma_ramp_string = NULL;
g_autoptr (MetaKmsFeedback) kms_feedback = 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); gamma_ramp_string = generate_gamma_ramp_string (size, red, green, blue);
g_debug ("Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s", g_debug ("Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s",
meta_crtc_get_id (crtc), gamma_ramp_string); meta_crtc_get_id (crtc), gamma_ramp_string);
kms_update = meta_kms_ensure_pending_update (kms); kms_feedback = meta_kms_post_pending_updates_sync (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);
if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED) if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{ {
g_warning ("Failed to set CRTC gamma: %s", g_warning ("Failed to set CRTC gamma: %s",

View File

@ -1285,8 +1285,7 @@ static void
meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
MetaRendererView *view, MetaRendererView *view,
MetaCrtc *crtc, MetaCrtc *crtc,
MetaKmsPageFlipFlag flags, MetaKmsPageFlipFlag flags)
MetaKmsUpdate *kms_update)
{ {
CoglOnscreenEGL *onscreen_egl = onscreen->winsys; CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
@ -1295,10 +1294,16 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc); MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
MetaRendererNativeGpuData *renderer_gpu_data; MetaRendererNativeGpuData *renderer_gpu_data;
MetaGpuKms *gpu_kms; MetaGpuKms *gpu_kms;
MetaKmsDevice *kms_device;
MetaKms *kms;
MetaKmsUpdate *kms_update;
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state = NULL; MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state = NULL;
uint32_t fb_id; uint32_t fb_id;
gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); 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)); g_assert (meta_gpu_kms_is_crtc_active (gpu_kms, crtc));
@ -1340,16 +1345,21 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
static void static void
meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen, meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen,
MetaRendererNativeGpuData *renderer_gpu_data, MetaRendererNativeGpuData *renderer_gpu_data)
MetaKmsUpdate *kms_update)
{ {
CoglOnscreenEGL *onscreen_egl = onscreen->winsys; CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
MetaCrtcKms *crtc_kms = META_CRTC_KMS (onscreen_native->crtc); 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, COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeSetCrtcModes,
"Onscreen (set CRTC modes)"); "Onscreen (set CRTC modes)");
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
switch (renderer_gpu_data->mode) switch (renderer_gpu_data->mode)
{ {
case META_RENDERER_NATIVE_MODE_GBM: case META_RENDERER_NATIVE_MODE_GBM:
@ -1374,32 +1384,17 @@ meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen,
static void static void
meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen, meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen,
MetaKmsPageFlipFlag flags, MetaKmsPageFlipFlag flags)
MetaKmsUpdate *kms_update)
{ {
CoglOnscreenEGL *onscreen_egl = onscreen->winsys; CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
MetaRendererView *view = onscreen_native->view; 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, COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs,
"Onscreen (flip CRTCs)"); "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, meta_onscreen_native_flip_crtc (onscreen, view, onscreen_native->crtc,
flags, flags);
kms_update);
}
else
{
queue_dummy_power_save_page_flip (onscreen);
}
} }
static gboolean static gboolean
@ -1864,8 +1859,7 @@ retry:
} }
static void static void
ensure_crtc_modes (CoglOnscreen *onscreen, ensure_crtc_modes (CoglOnscreen *onscreen)
MetaKmsUpdate *kms_update)
{ {
CoglOnscreenEGL *onscreen_egl = onscreen->winsys; CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
@ -1874,29 +1868,19 @@ ensure_crtc_modes (CoglOnscreen *onscreen,
CoglRenderer *cogl_renderer = cogl_context->display->renderer; CoglRenderer *cogl_renderer = cogl_context->display->renderer;
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; 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)
if (onscreen_native->pending_set_crtc &&
power_save_mode == META_POWER_SAVE_ON)
{ {
meta_onscreen_native_set_crtc_mode (onscreen, meta_onscreen_native_set_crtc_mode (onscreen, renderer_gpu_data);
renderer_gpu_data,
kms_update);
onscreen_native->pending_set_crtc = FALSE; onscreen_native->pending_set_crtc = FALSE;
} }
} }
static MetaKmsUpdate * static gboolean
unset_disabled_crtcs (MetaBackend *backend, unset_disabled_crtcs (MetaBackend *backend,
MetaKms *kms) MetaKms *kms)
{ {
MetaKmsUpdate *kms_update = NULL; gboolean did_mode_set = FALSE;
GList *l; GList *l;
for (l = meta_backend_get_gpus (backend); l; l = l->next) 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) for (k = meta_gpu_get_crtcs (gpu); k; k = k->next)
{ {
MetaCrtc *crtc = k->data; 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)) if (meta_crtc_get_config (crtc))
continue; 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); meta_crtc_kms_set_mode (META_CRTC_KMS (crtc), kms_update);
did_mode_set = TRUE;
} }
} }
return kms_update; return did_mode_set;
} }
static void static void
post_pending_update (MetaKms *kms) post_pending_updates (MetaKms *kms)
{ {
g_autoptr (MetaKmsFeedback) kms_feedback = NULL; 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) if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{ {
const GError *error = meta_kms_feedback_get_error (kms_feedback); 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); MetaRenderer *renderer = META_RENDERER (renderer_native);
MetaBackend *backend = meta_renderer_get_backend (renderer); MetaBackend *backend = meta_renderer_get_backend (renderer);
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); 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); MetaKms *kms = meta_backend_native_get_kms (backend_native);
CoglOnscreenEGL *onscreen_egl = onscreen->winsys; CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
MetaGpuKms *render_gpu = onscreen_native->render_gpu; MetaGpuKms *render_gpu = onscreen_native->render_gpu;
gboolean egl_context_changed = FALSE; gboolean egl_context_changed = FALSE;
MetaKmsUpdate *kms_update; 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; g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
@ -1963,8 +1955,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers, COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
"Onscreen (swap-buffers)"); "Onscreen (swap-buffers)");
kms_update = meta_kms_ensure_pending_update (kms);
update_secondary_gpu_state_pre_swap_buffers (onscreen); update_secondary_gpu_state_pre_swap_buffers (onscreen);
parent_vtable->onscreen_swap_buffers_with_damage (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); update_secondary_gpu_state_post_swap_buffers (onscreen, &egl_context_changed);
ensure_crtc_modes (onscreen, kms_update); power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
meta_onscreen_native_flip_crtcs (onscreen, if (power_save_mode == META_POWER_SAVE_ON)
META_KMS_PAGE_FLIP_FLAG_NONE, {
kms_update); 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 * 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, COGL_TRACE_BEGIN (MetaRendererNativePostKmsUpdate,
"Onscreen (post pending update)"); "Onscreen (post pending update)");
post_pending_update (kms); post_pending_updates (kms);
COGL_TRACE_END (MetaRendererNativePostKmsUpdate); COGL_TRACE_END (MetaRendererNativePostKmsUpdate);
} }
@ -2165,10 +2162,18 @@ meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
MetaBackend *backend = meta_renderer_get_backend (renderer); MetaBackend *backend = meta_renderer_get_backend (renderer);
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; MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaPowerSave power_save_mode;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL; 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, renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
render_gpu); 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)); 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_onscreen_native_flip_crtcs (onscreen,
META_KMS_PAGE_FLIP_FLAG_NO_DISCARD_FEEDBACK, META_KMS_PAGE_FLIP_FLAG_NO_DISCARD_FEEDBACK);
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) if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
{ {
const GError *feedback_error = meta_kms_feedback_get_error (kms_feedback); 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); MetaBackend *backend = meta_renderer_get_backend (renderer);
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; gboolean did_mode_set = FALSE;
if (renderer_native->pending_unset_disabled_crtcs) 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; renderer_native->pending_unset_disabled_crtcs = FALSE;
} }
if (kms_update) if (did_mode_set)
post_pending_update (kms); post_pending_updates (kms);
} }
static gboolean static gboolean
@ -3751,12 +3755,9 @@ meta_renderer_native_reset_modes (MetaRendererNative *renderer_native)
MetaBackend *backend = meta_renderer_get_backend (renderer); MetaBackend *backend = meta_renderer_get_backend (renderer);
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;
kms_update = unset_disabled_crtcs (backend, kms); if (unset_disabled_crtcs (backend, kms))
post_pending_updates (kms);
if (kms_update)
post_pending_update (kms);
} }
static MetaGpuKms * static MetaGpuKms *