[mutter] kms/crtc: Read gamma state when prediction failed
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] kms/crtc: Read gamma state when prediction failed
- Date: Thu, 10 Oct 2019 14:57:59 +0000 (UTC)
commit 1b4709794ea3602f5573fee164c880a14f049d3b
Author: Jonas Ådahl <jadahl gmail com>
Date: Thu Oct 10 10:47:05 2019 +0200
kms/crtc: Read gamma state when prediction failed
If we did a mode set, the gamma may have been changed by the kernel, and
if we didn't also update the gamma in the same transaction, we have no
way to predict the current gamma ramp state. In this case, read the
gamma state directly from KMS.
This should be relatively harmless regarding the race conditions the
state prediction was meant to solve, as the worst case is we get none or
out of date gamma ramps; and since this is for when gamma ramps are not
updated at mode setting time, we'd get intermediate gamma state to begin
with, so it's not worse than what we currently do anyway.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/851
https://gitlab.gnome.org/GNOME/mutter/merge_requests/840
src/backends/native/meta-kms-crtc.c | 46 ++++++++++++++++++++++++++++++++++---
1 file changed, 43 insertions(+), 3 deletions(-)
---
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index 3610df903..da99a58cd 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
@@ -143,14 +143,26 @@ meta_kms_crtc_update_state (MetaKmsCrtc *crtc)
drmModeFreeCrtc (drm_crtc);
}
+static void
+clear_gamma_state (MetaKmsCrtc *crtc)
+{
+ crtc->current_state.gamma.size = 0;
+ g_clear_pointer (&crtc->current_state.gamma.red, g_free);
+ g_clear_pointer (&crtc->current_state.gamma.green, g_free);
+ g_clear_pointer (&crtc->current_state.gamma.blue, g_free);
+}
+
void
meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
MetaKmsUpdate *update)
{
+ gboolean is_gamma_valid;
GList *mode_sets;
GList *crtc_gammas;
GList *l;
+ is_gamma_valid = TRUE;
+
mode_sets = meta_kms_update_get_mode_sets (update);
for (l = mode_sets; l; l = l->next)
{
@@ -178,6 +190,8 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
crtc->current_state.drm_mode = (drmModeModeInfo) { 0 };
}
+ is_gamma_valid = FALSE;
+
break;
}
@@ -196,8 +210,36 @@ meta_kms_crtc_predict_state (MetaKmsCrtc *crtc,
g_memdup (gamma->green, gamma->size * sizeof (uint16_t));
crtc->current_state.gamma.blue =
g_memdup (gamma->blue, gamma->size * sizeof (uint16_t));
+
+ is_gamma_valid = TRUE;
break;
}
+
+ if (!is_gamma_valid)
+ {
+ if (crtc->current_state.is_drm_mode_valid)
+ {
+ MetaKmsImplDevice *impl_device;
+ drmModeCrtc *drm_crtc;
+
+ impl_device = meta_kms_device_get_impl_device (crtc->device);
+ drm_crtc = drmModeGetCrtc (meta_kms_impl_device_get_fd (impl_device),
+ crtc->id);
+ if (drm_crtc)
+ {
+ read_gamma_state (crtc, impl_device, drm_crtc);
+ drmModeFreeCrtc (drm_crtc);
+ }
+ else
+ {
+ clear_gamma_state (crtc);
+ }
+ }
+ else
+ {
+ clear_gamma_state (crtc);
+ }
+ }
}
MetaKmsCrtc *
@@ -220,9 +262,7 @@ meta_kms_crtc_finalize (GObject *object)
{
MetaKmsCrtc *crtc = META_KMS_CRTC (object);
- g_clear_pointer (&crtc->current_state.gamma.red, g_free);
- g_clear_pointer (&crtc->current_state.gamma.green, g_free);
- g_clear_pointer (&crtc->current_state.gamma.blue, g_free);
+ clear_gamma_state (crtc);
G_OBJECT_CLASS (meta_kms_crtc_parent_class)->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]