[RFC xserver 09/16] modesetting: Add helper functions to retrieve DRM properties

Daniel Stone daniels at collabora.com
Thu Jun 8 18:43:35 UTC 2017


From: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>

These functions have been borrowed from Weston and will be used
in following patches.

Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 hw/xfree86/drivers/modesetting/drmmode_display.c | 171 +++++++++++++++++++++++
 hw/xfree86/drivers/modesetting/drmmode_display.h |  13 ++
 2 files changed, 184 insertions(+)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index aa6baae09..2ae870537 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -87,6 +87,177 @@ drmmode_zaphod_string_matches(ScrnInfoPtr scrn, const char *s, char *output_name
     return FALSE;
 }
 
+static uint64_t
+drmmode_prop_get_value(drmmode_prop_info_ptr info,
+                       drmModeObjectPropertiesPtr props,
+                       uint64_t def)
+{
+    unsigned int i;
+
+    if (info->prop_id == 0)
+        return def;
+
+    for (i = 0; i < props->count_props; i++) {
+        unsigned int j;
+
+        if (props->props[i] != info->prop_id)
+            continue;
+
+        /* Simple (non-enum) types can return the value directly */
+        if (info->num_enum_values == 0)
+            return props->prop_values[i];
+
+        /* Map from raw value to enum value */
+        for (j = 0; j < info->num_enum_values; j++) {
+            if (!info->enum_values[j].valid)
+                continue;
+            if (info->enum_values[j].value != props->prop_values[i])
+                continue;
+
+            return j;
+        }
+    }
+
+    return def;
+}
+
+static uint32_t
+drmmode_prop_info_update(drmmode_ptr drmmode,
+                         drmmode_prop_info_ptr info,
+                         unsigned int num_infos,
+                         drmModeObjectProperties *props)
+{
+    drmModePropertyRes *prop;
+    uint32_t valid_mask = 0;
+    unsigned i, j;
+
+    assert(num_infos <= 32 && "update return type");
+
+    for (i = 0; i < props->count_props; i++) {
+        Bool props_incomplete = FALSE;
+        unsigned int k;
+
+        for (j = 0; j < num_infos; j++) {
+            if (info[j].prop_id == props->props[i])
+                break;
+            if (!info[j].prop_id)
+                props_incomplete = TRUE;
+        }
+
+        /* We've already discovered this property. */
+        if (j != num_infos)
+            continue;
+
+        /* We haven't found this property ID, but as we've already
+         * found all known properties, we don't need to look any
+         * further. */
+        if (!props_incomplete)
+            break;
+
+        prop = drmModeGetProperty(drmmode->fd, props->props[i]);
+        if (!prop)
+            continue;
+
+        for (j = 0; j < num_infos; j++) {
+            if (!strcmp(prop->name, info[j].name))
+                break;
+        }
+
+        /* We don't know/care about this property. */
+        if (j == num_infos) {
+            drmModeFreeProperty(prop);
+            continue;
+        }
+
+        info[j].prop_id = props->props[i];
+        valid_mask |= 1U << j;
+
+        if (info[j].num_enum_values == 0) {
+            drmModeFreeProperty(prop);
+            continue;
+        }
+
+        if (!(prop->flags & DRM_MODE_PROP_ENUM)) {
+            xf86DrvMsg(drmmode->scrn->scrnIndex, X_WARNING,
+                       "expected property %s to be an enum,"
+                       " but it is not; ignoring\n", prop->name);
+            drmModeFreeProperty(prop);
+            continue;
+        }
+
+        for (k = 0; k < info[j].num_enum_values; k++) {
+            int l;
+
+            if (info[j].enum_values[k].valid)
+                continue;
+
+            for (l = 0; l < prop->count_enums; l++) {
+                if (!strcmp(prop->enums[l].name,
+                            info[j].enum_values[k].name))
+                    break;
+            }
+
+            if (l == prop->count_enums)
+                continue;
+
+            info[j].enum_values[k].valid = TRUE;
+            info[j].enum_values[k].value = prop->enums[l].value;
+        }
+
+        drmModeFreeProperty(prop);
+    }
+
+    return valid_mask;
+}
+
+static Bool
+drmmode_prop_info_copy(drmmode_prop_info_ptr dst,
+		       const drmmode_prop_info_rec *src,
+		       unsigned int num_props)
+{
+    unsigned int i;
+
+    memcpy(dst, src, num_props * sizeof(*dst));
+
+    for (i = 0; i < num_props; i++) {
+        unsigned int j;
+
+        dst[i].prop_id = 0;
+
+        if (src[i].num_enum_values == 0)
+            continue;
+
+        dst[i].enum_values =
+            malloc(src[i].num_enum_values *
+                    sizeof(*dst[i].enum_values));
+        if (!dst[i].enum_values)
+            goto err;
+
+        memcpy(dst[i].enum_values, src[i].enum_values,
+                src[i].num_enum_values * sizeof(*dst[i].enum_values));
+
+        for (j = 0; j < dst[i].num_enum_values; j++)
+            dst[i].enum_values[j].valid = FALSE;
+    }
+
+    return TRUE;
+
+err:
+    while (i--)
+        free(dst[i].enum_values);
+    free(dst);
+    return FALSE;
+}
+
+static void
+drmmode_prop_info_free(drmmode_prop_info_ptr info, int num_props)
+{
+    int i;
+
+    for (i = 0; i < num_props; i++)
+        free(info[i].enum_values);
+}
+
 int
 drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
 {
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index f774250ef..a2cd9d0ae 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -86,6 +86,19 @@ typedef struct {
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
+    const char *name;
+    Bool valid;
+    uint64_t value;
+} drmmode_prop_enum_info_rec, *drmmode_prop_enum_info_ptr;
+
+typedef struct {
+    const char *name;
+    uint32_t prop_id;
+    unsigned int num_enum_values;
+    drmmode_prop_enum_info_rec *enum_values;
+} drmmode_prop_info_rec, *drmmode_prop_info_ptr;
+
+typedef struct {
     drmmode_ptr drmmode;
     drmModeCrtcPtr mode_crtc;
     uint32_t vblank_pipe;
-- 
2.13.0



More information about the xorg-devel mailing list