[RFC v2 07/13] modesetting: Add helper functions to retrieve DRM properties
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Fri Jul 14 04:47:54 UTC 2017
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>
---
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