onscreen/native: Track GAMMA_LUT invalidations here

We only know if changing the GAMMA_LUT has happened if we sent away a
KMS update that succeeded. Concentrate this state tracking to the
onscreen.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2814>
This commit is contained in:
Jonas Ådahl 2022-12-20 12:12:10 +01:00
parent beb6903397
commit 24bdafa220
8 changed files with 101 additions and 64 deletions

View File

@ -298,6 +298,7 @@ void
meta_renderer_resume (MetaRenderer *renderer)
{
MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer);
MetaRendererClass *klass = META_RENDERER_GET_CLASS (renderer);
GList *l;
g_return_if_fail (priv->is_paused);
@ -311,6 +312,9 @@ meta_renderer_resume (MetaRenderer *renderer)
clutter_frame_clock_uninhibit (frame_clock);
}
if (klass->resume)
klass->resume (renderer);
}
gboolean

View File

@ -46,6 +46,7 @@ struct _MetaRendererClass
MetaOutput *output,
MetaCrtc *crtc);
void (* rebuild_views) (MetaRenderer *renderer);
void (* resume) (MetaRenderer *renderer);
GList * (* get_views_for_monitor) (MetaRenderer *renderer,
MetaMonitor *monitor);
};

View File

@ -36,6 +36,15 @@
#include "backends/native/meta-kms.h"
#include "backends/native/meta-monitor-manager-native.h"
enum
{
GAMMA_LUT_CHANGED,
N_SIGNALS
};
static guint signals[N_SIGNALS];
#define ALL_TRANSFORMS_MASK ((1 << META_MONITOR_N_TRANSFORMS) - 1)
struct _MetaCrtcKms
@ -97,6 +106,16 @@ meta_crtc_kms_get_gamma_lut_size (MetaCrtc *crtc)
return crtc_state->gamma.size;
}
const MetaKmsCrtcGamma *
meta_crtc_kms_peek_gamma_lut (MetaCrtcKms *crtc_kms)
{
MetaMonitorManagerNative *monitor_manager_native =
monitor_manager_from_crtc (META_CRTC (crtc_kms));
return meta_monitor_manager_native_get_cached_crtc_gamma (monitor_manager_native,
crtc_kms);
}
static MetaGammaLut *
meta_crtc_kms_get_gamma_lut (MetaCrtc *crtc)
{
@ -238,7 +257,7 @@ meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc,
crtc_kms,
crtc_gamma);
meta_crtc_kms_invalidate_gamma (crtc_kms);
g_signal_emit (crtc_kms, signals[GAMMA_LUT_CHANGED], 0);
clutter_stage_schedule_update (CLUTTER_STAGE (stage));
}
@ -374,36 +393,6 @@ meta_crtc_kms_is_gamma_invalid (MetaCrtcKms *crtc_kms)
return !crtc_kms->is_gamma_valid;
}
void
meta_crtc_kms_set_gamma (MetaCrtcKms *crtc_kms,
MetaKmsUpdate *kms_update)
{
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);
MetaMonitorManagerNative *monitor_manager_native =
META_MONITOR_MANAGER_NATIVE (monitor_manager);
MetaKmsCrtcGamma *gamma;
MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
g_return_if_fail (!crtc_kms->is_gamma_valid);
g_return_if_fail (meta_kms_crtc_has_gamma (kms_crtc));
gamma = meta_monitor_manager_native_get_cached_crtc_gamma (monitor_manager_native,
crtc_kms);
g_return_if_fail (gamma);
meta_kms_update_set_crtc_gamma (kms_update,
kms_crtc,
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)
@ -498,12 +487,6 @@ 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)
{
@ -574,4 +557,12 @@ meta_crtc_kms_class_init (MetaCrtcKmsClass *klass)
crtc_native_class->is_transform_handled = meta_crtc_kms_is_transform_handled;
crtc_native_class->is_hw_cursor_supported = meta_crtc_kms_is_hw_cursor_supported;
signals[GAMMA_LUT_CHANGED] =
g_signal_new ("gamma-lut-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL, NULL,
G_TYPE_NONE, 0);
}

View File

@ -72,12 +72,9 @@ gboolean
meta_crtc_kms_supports_format (MetaCrtcKms *crtc_kms,
uint32_t drm_format);
void meta_crtc_kms_invalidate_gamma (MetaCrtcKms *crtc_kms);
gboolean meta_crtc_kms_is_gamma_invalid (MetaCrtcKms *crtc_kms);
void meta_crtc_kms_set_gamma (MetaCrtcKms *crtc_kms,
MetaKmsUpdate *kms_update);
const MetaKmsCrtcGamma * meta_crtc_kms_peek_gamma_lut (MetaCrtcKms *crtc_kms);
MetaCrtcKms * meta_crtc_kms_from_kms_crtc (MetaKmsCrtc *kms_crtc);

View File

@ -158,12 +158,7 @@ meta_monitor_manager_native_set_power_save_mode (MetaMonitorManager *manager,
{
case META_POWER_SAVE_ON:
case META_POWER_SAVE_UNSUPPORTED:
{
g_list_foreach (meta_gpu_get_crtcs (META_GPU (gpu_kms)),
(GFunc) meta_crtc_kms_invalidate_gamma,
NULL);
break;
}
break;
case META_POWER_SAVE_STANDBY:
case META_POWER_SAVE_SUSPEND:
case META_POWER_SAVE_OFF:
@ -452,20 +447,7 @@ meta_monitor_manager_native_pause (MetaMonitorManagerNative *manager_native)
void
meta_monitor_manager_native_resume (MetaMonitorManagerNative *manager_native)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_native);
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
GList *l;
meta_monitor_manager_native_connect_hotplug_handler (manager_native);
for (l = meta_backend_get_gpus (backend); l; l = l->next)
{
MetaGpu *gpu = l->data;
g_list_foreach (meta_gpu_get_crtcs (gpu),
(GFunc) meta_crtc_kms_invalidate_gamma,
NULL);
}
}
static gboolean

View File

@ -107,6 +107,8 @@ struct _MetaOnscreenNative
#endif
MetaRendererView *view;
gboolean is_gamma_lut_invalid;
};
G_DEFINE_TYPE (MetaOnscreenNative, meta_onscreen_native,
@ -223,6 +225,7 @@ notify_view_crtc_presented (MetaRendererView *view,
CoglFramebuffer *framebuffer =
clutter_stage_view_get_onscreen (stage_view);
CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
CoglFrameInfo *frame_info;
MetaCrtc *crtc;
@ -230,6 +233,8 @@ notify_view_crtc_presented (MetaRendererView *view,
g_return_if_fail (frame_info != NULL);
onscreen_native->is_gamma_lut_invalid = FALSE;
crtc = META_CRTC (meta_crtc_kms_from_kms_crtc (kms_crtc));
maybe_update_frame_info (crtc, frame_info, time_us, flags, sequence);
@ -1397,12 +1402,23 @@ meta_onscreen_native_prepare_frame (CoglOnscreen *onscreen,
MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
MetaKms *kms = meta_kms_device_get_kms (kms_device);
if (meta_crtc_kms_is_gamma_invalid (crtc_kms))
if (onscreen_native->is_gamma_lut_invalid)
{
MetaKmsUpdate *kms_update;
const MetaKmsCrtcGamma *gamma;
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
meta_crtc_kms_set_gamma (crtc_kms, kms_update);
gamma = meta_crtc_kms_peek_gamma_lut (crtc_kms);
if (gamma)
{
MetaKmsUpdate *kms_update;
kms_update = meta_kms_ensure_pending_update (kms, kms_device);
meta_kms_update_set_crtc_gamma (kms_update,
kms_crtc,
gamma->size,
gamma->red,
gamma->green,
gamma->blue);
}
}
if (meta_output_kms_is_privacy_screen_invalid (output_kms))
@ -2135,6 +2151,23 @@ init_secondary_gpu_state (MetaRendererNative *renderer_native,
return TRUE;
}
void
meta_onscreen_native_invalidate (MetaOnscreenNative *onscreen_native)
{
if (meta_crtc_get_gamma_lut_size (onscreen_native->crtc) > 0)
onscreen_native->is_gamma_lut_invalid = TRUE;
}
static void
on_gamma_lut_changed (MetaCrtc *crtc,
MetaOnscreenNative *onscreen_native)
{
ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (onscreen_native->view);
onscreen_native->is_gamma_lut_invalid = TRUE;
clutter_stage_view_schedule_update (stage_view);
}
MetaOnscreenNative *
meta_onscreen_native_new (MetaRendererNative *renderer_native,
MetaGpuKms *render_gpu,
@ -2162,6 +2195,14 @@ meta_onscreen_native_new (MetaRendererNative *renderer_native,
onscreen_native->output = output;
onscreen_native->crtc = crtc;
if (meta_crtc_get_gamma_lut_size (crtc) > 0)
{
onscreen_native->is_gamma_lut_invalid = TRUE;
g_signal_connect_object (crtc, "gamma-lut-changed",
G_CALLBACK (on_gamma_lut_changed),
onscreen_native, G_CONNECT_DEFAULT);
}
return onscreen_native;
}

View File

@ -62,4 +62,6 @@ MetaOnscreenNative * meta_onscreen_native_new (MetaRendererNative *renderer_nati
META_EXPORT_TEST
MetaCrtc * meta_onscreen_native_get_crtc (MetaOnscreenNative *onscreen_native);
void meta_onscreen_native_invalidate (MetaOnscreenNative *onscreen_native);
#endif /* META_ONSCREEN_NATIVE_H */

View File

@ -1452,6 +1452,24 @@ meta_renderer_native_rebuild_views (MetaRenderer *renderer)
meta_renderer_native_queue_modes_reset (META_RENDERER_NATIVE (renderer));
}
static void
meta_renderer_native_resume (MetaRenderer *renderer)
{
GList *l;
for (l = meta_renderer_get_views (renderer); l; l = l->next)
{
ClutterStageView *stage_view = l->data;
CoglFramebuffer *framebuffer;
framebuffer = clutter_stage_view_get_onscreen (stage_view);
if (!META_IS_ONSCREEN_NATIVE (framebuffer))
continue;
meta_onscreen_native_invalidate (META_ONSCREEN_NATIVE (framebuffer));
}
}
void
meta_renderer_native_prepare_frame (MetaRendererNative *renderer_native,
MetaRendererView *view,
@ -2173,6 +2191,7 @@ meta_renderer_native_class_init (MetaRendererNativeClass *klass)
renderer_class->create_cogl_renderer = meta_renderer_native_create_cogl_renderer;
renderer_class->create_view = meta_renderer_native_create_view;
renderer_class->rebuild_views = meta_renderer_native_rebuild_views;
renderer_class->resume = meta_renderer_native_resume;
}
MetaRendererNative *