mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
backend/native: Set CRTC gamma once per frame
Before we received new gamma updates via D-Bus and posted the update to KMS directly. This won't be possible with atomic KMS, since one can only update the state of a CRTC once per cycle. Thus, to handle this, when configured by D-Bus, only cache the value, and mark it as invalid. The next frame, the native renderer will pick up the newly cached gamma value and configure the CRTCs accordingly. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
parent
7d8dd6cc75
commit
3ec5418104
@ -33,6 +33,7 @@
|
||||
#include "backends/native/meta-kms-mode.h"
|
||||
#include "backends/native/meta-kms-plane.h"
|
||||
#include "backends/native/meta-kms-update.h"
|
||||
#include "backends/native/meta-kms.h"
|
||||
#include "backends/native/meta-monitor-manager-kms.h"
|
||||
|
||||
#define ALL_TRANSFORMS_MASK ((1 << META_MONITOR_N_TRANSFORMS) - 1)
|
||||
@ -47,6 +48,8 @@ struct _MetaCrtcKms
|
||||
|
||||
gpointer cursor_renderer_private;
|
||||
GDestroyNotify cursor_renderer_private_destroy_notify;
|
||||
|
||||
gboolean is_gamma_valid;
|
||||
};
|
||||
|
||||
static GQuark kms_crtc_crtc_kms_quark;
|
||||
@ -176,6 +179,39 @@ generate_crtc_connector_list (MetaGpu *gpu,
|
||||
return connectors;
|
||||
}
|
||||
|
||||
void
|
||||
meta_crtc_kms_maybe_set_gamma (MetaCrtcKms *crtc_kms,
|
||||
MetaKmsDevice *kms_device)
|
||||
{
|
||||
MetaGpu *gpu = meta_crtc_get_gpu (META_CRTC (crtc_kms));
|
||||
MetaBackend *backend = meta_gpu_get_backend (gpu);
|
||||
MetaMonitorManager *monitor_manager =
|
||||
meta_backend_get_monitor_manager (backend);
|
||||
MetaMonitorManagerKms *monitor_manager_kms =
|
||||
META_MONITOR_MANAGER_KMS (monitor_manager);
|
||||
MetaKms *kms = meta_kms_device_get_kms (kms_device);
|
||||
MetaKmsUpdate *kms_update;
|
||||
MetaKmsCrtcGamma *gamma;
|
||||
|
||||
if (crtc_kms->is_gamma_valid)
|
||||
return;
|
||||
|
||||
gamma = meta_monitor_manager_kms_get_cached_crtc_gamma (monitor_manager_kms,
|
||||
crtc_kms);
|
||||
if (!gamma)
|
||||
return;
|
||||
|
||||
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
|
||||
meta_kms_update_set_crtc_gamma (kms_update,
|
||||
meta_crtc_kms_get_kms_crtc (crtc_kms),
|
||||
gamma->size,
|
||||
gamma->red,
|
||||
gamma->green,
|
||||
gamma->blue);
|
||||
|
||||
crtc_kms->is_gamma_valid = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
meta_crtc_kms_set_mode (MetaCrtcKms *crtc_kms,
|
||||
MetaKmsUpdate *kms_update)
|
||||
@ -287,6 +323,12 @@ meta_crtc_kms_supports_format (MetaCrtcKms *crtc_kms,
|
||||
drm_format);
|
||||
}
|
||||
|
||||
void
|
||||
meta_crtc_kms_invalidate_gamma (MetaCrtcKms *crtc_kms)
|
||||
{
|
||||
crtc_kms->is_gamma_valid = FALSE;
|
||||
}
|
||||
|
||||
MetaCrtcKms *
|
||||
meta_crtc_kms_from_kms_crtc (MetaKmsCrtc *kms_crtc)
|
||||
{
|
||||
|
@ -72,6 +72,11 @@ gboolean
|
||||
meta_crtc_kms_supports_format (MetaCrtcKms *crtc_kms,
|
||||
uint32_t drm_format);
|
||||
|
||||
void meta_crtc_kms_invalidate_gamma (MetaCrtcKms *crtc_kms);
|
||||
|
||||
void meta_crtc_kms_maybe_set_gamma (MetaCrtcKms *crtc_kms,
|
||||
MetaKmsDevice *kms_device);
|
||||
|
||||
MetaCrtcKms * meta_crtc_kms_from_kms_crtc (MetaKmsCrtc *kms_crtc);
|
||||
|
||||
MetaCrtcKms * meta_crtc_kms_new (MetaGpuKms *gpu_kms,
|
||||
|
@ -76,6 +76,8 @@ struct _MetaMonitorManagerKms
|
||||
MetaMonitorManager parent_instance;
|
||||
|
||||
gulong kms_resources_changed_handler_id;
|
||||
|
||||
GHashTable *crtc_gamma_cache;
|
||||
};
|
||||
|
||||
struct _MetaMonitorManagerKmsClass
|
||||
@ -430,6 +432,17 @@ generate_gamma_ramp_string (size_t size,
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
MetaKmsCrtcGamma *
|
||||
meta_monitor_manager_kms_get_cached_crtc_gamma (MetaMonitorManagerKms *manager_kms,
|
||||
MetaCrtcKms *crtc_kms)
|
||||
{
|
||||
uint64_t crtc_id;
|
||||
|
||||
crtc_id = meta_crtc_get_id (META_CRTC (crtc_kms));
|
||||
return g_hash_table_lookup (manager_kms->crtc_gamma_cache,
|
||||
GUINT_TO_POINTER (crtc_id));
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
MetaCrtc *crtc,
|
||||
@ -438,32 +451,24 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
|
||||
unsigned short *green,
|
||||
unsigned short *blue)
|
||||
{
|
||||
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
|
||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||
MetaKmsCrtc *kms_crtc;
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaKmsUpdate *kms_update;
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
||||
g_autofree char *gamma_ramp_string = NULL;
|
||||
MetaKmsUpdateFlag flags;
|
||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
|
||||
ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
|
||||
|
||||
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);
|
||||
g_hash_table_replace (manager_kms->crtc_gamma_cache,
|
||||
GUINT_TO_POINTER (meta_crtc_get_id (crtc)),
|
||||
meta_kms_crtc_gamma_new (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);
|
||||
|
||||
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",
|
||||
meta_kms_feedback_get_error (kms_feedback)->message);
|
||||
}
|
||||
meta_crtc_kms_invalidate_gamma (crtc_kms);
|
||||
clutter_stage_schedule_update (stage);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -595,6 +600,17 @@ meta_monitor_manager_kms_get_default_layout_mode (MetaMonitorManager *manager)
|
||||
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_monitor_manager_kms_dispose (GObject *object)
|
||||
{
|
||||
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
|
||||
|
||||
g_clear_pointer (&manager_kms->crtc_gamma_cache,
|
||||
g_hash_table_unref);
|
||||
|
||||
G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_monitor_manager_kms_initable_init (GInitable *initable,
|
||||
GCancellable *cancellable,
|
||||
@ -626,6 +642,11 @@ meta_monitor_manager_kms_initable_init (GInitable *initable,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
manager_kms->crtc_gamma_cache =
|
||||
g_hash_table_new_full (NULL, NULL,
|
||||
NULL,
|
||||
(GDestroyNotify) meta_kms_crtc_gamma_free);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -643,8 +664,11 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
|
||||
static void
|
||||
meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass);
|
||||
|
||||
object_class->dispose = meta_monitor_manager_kms_dispose;
|
||||
|
||||
manager_class->read_edid = meta_monitor_manager_kms_read_edid;
|
||||
manager_class->read_current_state = meta_monitor_manager_kms_read_current_state;
|
||||
manager_class->ensure_initial_config = meta_monitor_manager_kms_ensure_initial_config;
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#include "backends/meta-monitor-manager-private.h"
|
||||
#include "backends/native/meta-crtc-kms.h"
|
||||
#include "backends/native/meta-kms-crtc.h"
|
||||
|
||||
typedef struct _MetaGpuKms MetaGpuKms;
|
||||
|
||||
@ -41,4 +43,7 @@ void meta_monitor_manager_kms_resume (MetaMonitorManagerKms *manager_kms);
|
||||
|
||||
uint64_t meta_power_save_to_dpms_state (MetaPowerSave power_save);
|
||||
|
||||
MetaKmsCrtcGamma * meta_monitor_manager_kms_get_cached_crtc_gamma (MetaMonitorManagerKms *manager_kms,
|
||||
MetaCrtcKms *crtc_kms);
|
||||
|
||||
#endif /* META_MONITOR_MANAGER_KMS_H */
|
||||
|
@ -3283,6 +3283,19 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer)
|
||||
meta_renderer_native_queue_modes_reset (META_RENDERER_NATIVE (renderer));
|
||||
}
|
||||
|
||||
void
|
||||
meta_renderer_native_prepare_frame (MetaRendererNative *renderer_native,
|
||||
MetaRendererView *view,
|
||||
ClutterFrame *frame)
|
||||
{
|
||||
MetaCrtc *crtc = meta_renderer_view_get_crtc (view);
|
||||
MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
|
||||
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
|
||||
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);;
|
||||
|
||||
meta_crtc_kms_maybe_set_gamma (crtc_kms, kms_device);
|
||||
}
|
||||
|
||||
static void
|
||||
add_onscreen_frame_info (MetaCrtc *crtc)
|
||||
{
|
||||
|
@ -53,6 +53,10 @@ struct gbm_device * meta_gbm_device_from_gpu (MetaGpuKms *gpu_kms);
|
||||
|
||||
MetaGpuKms * meta_renderer_native_get_primary_gpu (MetaRendererNative *renderer_native);
|
||||
|
||||
void meta_renderer_native_prepare_frame (MetaRendererNative *renderer_native,
|
||||
MetaRendererView *view,
|
||||
ClutterFrame *frame);
|
||||
|
||||
void meta_renderer_native_finish_frame (MetaRendererNative *renderer_native,
|
||||
MetaRendererView *view,
|
||||
ClutterFrame *frame);
|
||||
|
@ -112,11 +112,16 @@ meta_stage_native_prepare_frame (ClutterStageWindow *stage_window,
|
||||
ClutterFrame *frame)
|
||||
{
|
||||
MetaBackend *backend = meta_get_backend ();
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
||||
MetaCursorRenderer *cursor_renderer =
|
||||
meta_backend_get_cursor_renderer (backend);
|
||||
MetaCursorRendererNative *cursor_renderer_native =
|
||||
META_CURSOR_RENDERER_NATIVE (cursor_renderer);
|
||||
|
||||
meta_renderer_native_prepare_frame (renderer_native,
|
||||
META_RENDERER_VIEW (stage_view),
|
||||
frame);
|
||||
meta_cursor_renderer_native_prepare_frame (cursor_renderer_native,
|
||||
META_RENDERER_VIEW (stage_view));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user