[mutter] output-xrandr: Add support for the "max bpc" KMS connector property



commit 99d84ae1cc8f027a35c32d266cef48758daaff6d
Author: Daniel van Vugt <daniel van vugt canonical com>
Date:   Fri Jun 10 16:34:40 2022 +0800

    output-xrandr: Add support for the "max bpc" KMS connector property
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2412>

 src/backends/x11/meta-output-xrandr.c | 88 +++++++++++++++++++++++++++++++++++
 1 file changed, 88 insertions(+)
---
diff --git a/src/backends/x11/meta-output-xrandr.c b/src/backends/x11/meta-output-xrandr.c
index 6fde5667e4..37a377e48c 100644
--- a/src/backends/x11/meta-output-xrandr.c
+++ b/src/backends/x11/meta-output-xrandr.c
@@ -145,11 +145,28 @@ output_set_underscanning_xrandr (MetaOutput *output,
     }
 }
 
+static void
+output_set_max_bpc_xrandr (MetaOutput   *output,
+                           unsigned int  max_bpc)
+{
+  Display *xdisplay = xdisplay_from_output (output);
+  Atom prop = XInternAtom (xdisplay, "max bpc", False);
+  uint32_t value = max_bpc;
+
+  xcb_randr_change_output_property (XGetXCBConnection (xdisplay),
+                                    (XID) meta_output_get_id (output),
+                                    prop, XCB_ATOM_INTEGER, 32,
+                                    XCB_PROP_MODE_REPLACE,
+                                    1, &value);
+}
+
 void
 meta_output_xrandr_apply_mode (MetaOutputXrandr *output_xrandr)
 {
   MetaOutput *output = META_OUTPUT (output_xrandr);
   Display *xdisplay = xdisplay_from_output (output);
+  const MetaOutputInfo *output_info = meta_output_get_info (output);
+  unsigned int max_bpc;
 
   if (meta_output_is_primary (output))
     {
@@ -164,6 +181,13 @@ meta_output_xrandr_apply_mode (MetaOutputXrandr *output_xrandr)
       output_set_underscanning_xrandr (output,
                                        meta_output_is_underscanning (output));
     }
+
+  if (meta_output_get_max_bpc (output, &max_bpc) &&
+      max_bpc >= output_info->max_bpc_min &&
+      max_bpc <= output_info->max_bpc_max)
+    {
+      output_set_max_bpc_xrandr (output, max_bpc);
+    }
 }
 
 static int
@@ -347,6 +371,33 @@ output_get_underscanning_xrandr (MetaOutput *output)
   return (strcmp (str, "on") == 0);
 }
 
+static gboolean
+output_get_max_bpc_xrandr (MetaOutput   *output,
+                           unsigned int *max_bpc)
+{
+  Display *xdisplay = xdisplay_from_output (output);
+  Atom atom, actual_type;
+  int actual_format;
+  unsigned long nitems, bytes_after;
+  g_autofree unsigned char *buffer = NULL;
+
+  atom = XInternAtom (xdisplay, "max bpc", False);
+  XRRGetOutputProperty (xdisplay,
+                        (XID) meta_output_get_id (output),
+                        atom,
+                        0, G_MAXLONG, False, False, XCB_ATOM_INTEGER,
+                        &actual_type, &actual_format,
+                        &nitems, &bytes_after, &buffer);
+
+  if (actual_type != XCB_ATOM_INTEGER || actual_format != 32 || nitems < 1)
+    return FALSE;
+
+  if (max_bpc)
+    *max_bpc = *((uint32_t*) buffer);
+
+  return TRUE;
+}
+
 static gboolean
 output_get_supports_underscanning_xrandr (Display  *xdisplay,
                                           RROutput  output_id)
@@ -392,6 +443,36 @@ output_get_supports_underscanning_xrandr (Display  *xdisplay,
   return supports_underscanning;
 }
 
+static gboolean
+output_get_max_bpc_range_xrandr (Display      *xdisplay,
+                                 RROutput      output_id,
+                                 unsigned int *min,
+                                 unsigned int *max)
+{
+  Atom atom;
+  XRRPropertyInfo *property_info;
+  long *values;
+
+  atom = XInternAtom (xdisplay, "max bpc", False);
+
+  meta_clutter_x11_trap_x_errors ();
+  property_info = XRRQueryOutputProperty (xdisplay,
+                                          (XID) output_id,
+                                          atom);
+  meta_clutter_x11_untrap_x_errors ();
+
+  if (!property_info || property_info->num_values != 2)
+    return FALSE;
+
+  values = (long *) property_info->values;
+  if (min)
+    *min = values[0];
+  if (max)
+    *max = values[1];
+
+  return TRUE;
+}
+
 static gboolean
 output_get_supports_color_transform_xrandr (Display  *xdisplay,
                                             RROutput  output_id)
@@ -934,6 +1015,10 @@ meta_output_xrandr_new (MetaGpuXrandr *gpu_xrandr,
 
   output_info->supports_underscanning =
     output_get_supports_underscanning_xrandr (xdisplay, output_id);
+  output_get_max_bpc_range_xrandr (xdisplay,
+                                   output_id,
+                                   &output_info->max_bpc_min,
+                                   &output_info->max_bpc_max);
   output_info->supports_color_transform =
     output_get_supports_color_transform_xrandr (xdisplay, output_id);
   output_info_init_backlight_limits_xrandr (output_info, xdisplay, output_id);
@@ -954,6 +1039,9 @@ meta_output_xrandr_new (MetaGpuXrandr *gpu_xrandr,
         .is_presentation = output_get_presentation_xrandr (output),
         .is_underscanning = output_get_underscanning_xrandr (output),
       };
+      output_assignment.has_max_bpc =
+        output_get_max_bpc_xrandr (output, &output_assignment.max_bpc);
+
       meta_output_assign_crtc (output, assigned_crtc, &output_assignment);
     }
   else


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]