minigbm: use drv_array for combinations and kms_items

This de-deuplicates the various dynamic arrays we use.

BUG=chromium:764871
TEST=gbmtest passes

Change-Id: I94c8cf7c71fdb98b931aab00c5381853e2ae0d3f
Reviewed-on: https://chromium-review.googlesource.com/758149
Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
diff --git a/drv.c b/drv.c
index a1be245..5b6a116 100644
--- a/drv.c
+++ b/drv.c
@@ -136,18 +136,14 @@
 	if (!drv->mappings)
 		goto free_buffer_table;
 
-	/* Start with a power of 2 number of allocations. */
-	drv->combos.allocations = 2;
-	drv->combos.size = 0;
-
-	drv->combos.data = calloc(drv->combos.allocations, sizeof(struct combination));
-	if (!drv->combos.data)
+	drv->combos = drv_array_init(sizeof(struct combination));
+	if (!drv->combos)
 		goto free_mappings;
 
 	if (drv->backend->init) {
 		ret = drv->backend->init(drv);
 		if (ret) {
-			free(drv->combos.data);
+			drv_array_destroy(drv->combos);
 			goto free_mappings;
 		}
 	}
@@ -174,8 +170,7 @@
 
 	drmHashDestroy(drv->buffer_table);
 	drv_array_destroy(drv->mappings);
-
-	free(drv->combos.data);
+	drv_array_destroy(drv->combos);
 
 	pthread_mutex_unlock(&drv->driver_lock);
 	pthread_mutex_destroy(&drv->driver_lock);
@@ -202,8 +197,8 @@
 
 	best = NULL;
 	uint32_t i;
-	for (i = 0; i < drv->combos.size; i++) {
-		curr = &drv->combos.data[i];
+	for (i = 0; i < drv_array_size(drv->combos); i++) {
+		curr = drv_array_at_idx(drv->combos, i);
 		if ((format == curr->format) && use_flags == (curr->use_flags & use_flags))
 			if (!best || best->metadata.priority < curr->metadata.priority)
 				best = curr;
diff --git a/drv_priv.h b/drv_priv.h
index 048b9a3..18a289c 100644
--- a/drv_priv.h
+++ b/drv_priv.h
@@ -49,19 +49,13 @@
 	uint64_t use_flags;
 };
 
-struct combinations {
-	struct combination *data;
-	uint32_t size;
-	uint32_t allocations;
-};
-
 struct driver {
 	int fd;
 	const struct backend *backend;
 	void *priv;
 	void *buffer_table;
 	struct drv_array *mappings;
-	struct combinations combos;
+	struct drv_array *combos;
 	pthread_mutex_t driver_lock;
 };
 
diff --git a/helpers.c b/helpers.c
index 0eba698..ef653ed 100644
--- a/helpers.c
+++ b/helpers.c
@@ -421,35 +421,18 @@
 	return ret;
 }
 
-int drv_add_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata,
-			uint64_t use_flags)
-{
-	struct combinations *combos = &drv->combos;
-	if (combos->size >= combos->allocations) {
-		struct combination *new_data;
-		combos->allocations *= 2;
-		new_data = realloc(combos->data, combos->allocations * sizeof(*combos->data));
-		if (!new_data)
-			return -ENOMEM;
-
-		combos->data = new_data;
-	}
-
-	combos->data[combos->size].format = format;
-	combos->data[combos->size].metadata.priority = metadata->priority;
-	combos->data[combos->size].metadata.tiling = metadata->tiling;
-	combos->data[combos->size].metadata.modifier = metadata->modifier;
-	combos->data[combos->size].use_flags = use_flags;
-	combos->size++;
-	return 0;
-}
-
 void drv_add_combinations(struct driver *drv, const uint32_t *formats, uint32_t num_formats,
 			  struct format_metadata *metadata, uint64_t use_flags)
 {
 	uint32_t i;
-	for (i = 0; i < num_formats; i++)
-		drv_add_combination(drv, formats[i], metadata, use_flags);
+
+	for (i = 0; i < num_formats; i++) {
+		struct combination combo = { .format = formats[i],
+					     .metadata = *metadata,
+					     .use_flags = use_flags };
+
+		drv_array_append(drv->combos, &combo);
+	}
 }
 
 void drv_modify_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata,
@@ -458,30 +441,27 @@
 	uint32_t i;
 	struct combination *combo;
 	/* Attempts to add the specified flags to an existing combination. */
-	for (i = 0; i < drv->combos.size; i++) {
-		combo = &drv->combos.data[i];
+	for (i = 0; i < drv_array_size(drv->combos); i++) {
+		combo = (struct combination *)drv_array_at_idx(drv->combos, i);
 		if (combo->format == format && combo->metadata.tiling == metadata->tiling &&
 		    combo->metadata.modifier == metadata->modifier)
 			combo->use_flags |= use_flags;
 	}
 }
 
-struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items)
+struct drv_array *drv_query_kms(struct driver *drv)
 {
-	struct kms_item *items;
+	struct drv_array *kms_items;
 	uint64_t plane_type, use_flag;
-	uint32_t i, j, k, allocations, item_size;
+	uint32_t i, j, k;
 
 	drmModePlanePtr plane;
 	drmModePropertyPtr prop;
 	drmModePlaneResPtr resources;
 	drmModeObjectPropertiesPtr props;
 
-	/* Start with a power of 2 number of allocations. */
-	allocations = 2;
-	item_size = 0;
-	items = calloc(allocations, sizeof(*items));
-	if (!items)
+	kms_items = drv_array_init(sizeof(struct kms_item));
+	if (!kms_items)
 		goto out;
 
 	/*
@@ -532,32 +512,22 @@
 
 		for (j = 0; j < plane->count_formats; j++) {
 			bool found = false;
-			for (k = 0; k < item_size; k++) {
-				if (items[k].format == plane->formats[j] &&
-				    items[k].modifier == DRM_FORMAT_MOD_INVALID) {
-					items[k].use_flags |= use_flag;
+			for (k = 0; k < drv_array_size(kms_items); k++) {
+				struct kms_item *item = drv_array_at_idx(kms_items, k);
+				if (item->format == plane->formats[j] &&
+				    item->modifier == DRM_FORMAT_MOD_INVALID) {
+					item->use_flags |= use_flag;
 					found = true;
 					break;
 				}
 			}
 
-			if (!found && item_size >= allocations) {
-				struct kms_item *new_data = NULL;
-				allocations *= 2;
-				new_data = realloc(items, allocations * sizeof(*items));
-				if (!new_data) {
-					item_size = 0;
-					goto out;
-				}
-
-				items = new_data;
-			}
-
 			if (!found) {
-				items[item_size].format = plane->formats[j];
-				items[item_size].modifier = DRM_FORMAT_MOD_INVALID;
-				items[item_size].use_flags = use_flag;
-				item_size++;
+				struct kms_item item = { .format = plane->formats[j],
+							 .modifier = DRM_FORMAT_MOD_INVALID,
+							 .use_flags = use_flag };
+
+				drv_array_append(kms_items, &item);
 			}
 		}
 
@@ -567,20 +537,20 @@
 
 	drmModeFreePlaneResources(resources);
 out:
-	if (items && item_size == 0) {
-		free(items);
-		items = NULL;
+	if (kms_items && !drv_array_size(kms_items)) {
+		drv_array_destroy(kms_items);
+		return NULL;
 	}
 
-	*num_items = item_size;
-	return items;
+	return kms_items;
 }
 
 int drv_modify_linear_combinations(struct driver *drv)
 {
-	uint32_t i, j, num_items;
-	struct kms_item *items;
+	uint32_t i, j;
+	struct kms_item *item;
 	struct combination *combo;
+	struct drv_array *kms_items;
 
 	/*
 	 * All current drivers can scanout linear XRGB8888/ARGB8888 as a primary
@@ -594,19 +564,20 @@
 	drv_modify_combination(drv, DRM_FORMAT_ARGB8888, &LINEAR_METADATA,
 			       BO_USE_CURSOR | BO_USE_SCANOUT);
 
-	items = drv_query_kms(drv, &num_items);
-	if (!items || !num_items)
+	kms_items = drv_query_kms(drv);
+	if (!kms_items)
 		return 0;
 
-	for (i = 0; i < num_items; i++) {
-		for (j = 0; j < drv->combos.size; j++) {
-			combo = &drv->combos.data[j];
-			if (items[i].format == combo->format)
+	for (i = 0; i < drv_array_size(kms_items); i++) {
+		item = (struct kms_item *)drv_array_at_idx(kms_items, i);
+		for (j = 0; j < drv_array_size(drv->combos); j++) {
+			combo = drv_array_at_idx(drv->combos, j);
+			if (item->format == combo->format)
 				combo->use_flags |= BO_USE_SCANOUT;
 		}
 	}
 
-	free(items);
+	drv_array_destroy(kms_items);
 	return 0;
 }
 
diff --git a/helpers.h b/helpers.h
index b0fbdee..6b8818d 100644
--- a/helpers.h
+++ b/helpers.h
@@ -31,7 +31,7 @@
 			  struct format_metadata *metadata, uint64_t usage);
 void drv_modify_combination(struct driver *drv, uint32_t format, struct format_metadata *metadata,
 			    uint64_t usage);
-struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items);
+struct drv_array *drv_query_kms(struct driver *drv);
 int drv_modify_linear_combinations(struct driver *drv);
 uint64_t drv_pick_modifier(const uint64_t *modifiers, uint32_t count,
 			   const uint64_t *modifier_order, uint32_t order_count);
diff --git a/i915.c b/i915.c
index d4f2ece..9b7a6fe 100644
--- a/i915.c
+++ b/i915.c
@@ -58,8 +58,8 @@
 	 * Older hardware can't scanout Y-tiled formats. Newer devices can, and
 	 * report this functionality via format modifiers.
 	 */
-	for (i = 0; i < drv->combos.size; i++) {
-		combo = &drv->combos.data[i];
+	for (i = 0; i < drv_array_size(drv->combos); i++) {
+		combo = (struct combination *)drv_array_at_idx(drv->combos, i);
 		if (combo->format != item->format)
 			continue;
 
@@ -84,8 +84,8 @@
 static int i915_add_combinations(struct driver *drv)
 {
 	int ret;
-	uint32_t i, num_items;
-	struct kms_item *items;
+	uint32_t i;
+	struct drv_array *kms_items;
 	struct format_metadata metadata;
 	uint64_t render_use_flags, texture_use_flags;
 
@@ -151,19 +151,19 @@
 			     ARRAY_SIZE(tileable_texture_source_formats), &metadata,
 			     texture_use_flags);
 
-	items = drv_query_kms(drv, &num_items);
-	if (!items || !num_items)
+	kms_items = drv_query_kms(drv);
+	if (!kms_items)
 		return 0;
 
-	for (i = 0; i < num_items; i++) {
-		ret = i915_add_kms_item(drv, &items[i]);
+	for (i = 0; i < drv_array_size(kms_items); i++) {
+		ret = i915_add_kms_item(drv, (struct kms_item *)drv_array_at_idx(kms_items, i));
 		if (ret) {
-			free(items);
+			drv_array_destroy(kms_items);
 			return ret;
 		}
 	}
 
-	free(items);
+	drv_array_destroy(kms_items);
 	return 0;
 }
 
diff --git a/rockchip.c b/rockchip.c
index 7964676..7cecf3b 100644
--- a/rockchip.c
+++ b/rockchip.c
@@ -76,14 +76,13 @@
 
 static int rockchip_add_kms_item(struct driver *drv, const struct kms_item *item)
 {
-	int ret;
 	uint32_t i, j;
 	uint64_t use_flags;
 	struct combination *combo;
 	struct format_metadata metadata;
 
-	for (i = 0; i < drv->combos.size; i++) {
-		combo = &drv->combos.data[i];
+	for (i = 0; i < drv_array_size(drv->combos); i++) {
+		combo = (struct combination *)drv_array_at_idx(drv->combos, i);
 		if (combo->format == item->format) {
 			if (item->modifier == DRM_FORMAT_MOD_CHROMEOS_ROCKCHIP_AFBC) {
 				use_flags = BO_USE_RENDERING | BO_USE_SCANOUT | BO_USE_TEXTURE;
@@ -96,10 +95,7 @@
 						use_flags &= ~BO_USE_RENDERING;
 				}
 
-				ret =
-				    drv_add_combination(drv, item[i].format, &metadata, use_flags);
-				if (ret)
-					return ret;
+				drv_add_combinations(drv, &item->format, 1, &metadata, use_flags);
 			} else {
 				combo->use_flags |= item->use_flags;
 			}
@@ -112,8 +108,8 @@
 static int rockchip_init(struct driver *drv)
 {
 	int ret;
-	uint32_t i, num_items;
-	struct kms_item *items;
+	uint32_t i;
+	struct drv_array *kms_items;
 	struct format_metadata metadata;
 
 	metadata.tiling = 0;
@@ -139,19 +135,19 @@
 	drv_modify_combination(drv, DRM_FORMAT_R8, &metadata,
 			       BO_USE_CAMERA_READ | BO_USE_CAMERA_WRITE);
 
-	items = drv_query_kms(drv, &num_items);
-	if (!items || !num_items)
+	kms_items = drv_query_kms(drv);
+	if (!kms_items)
 		return 0;
 
-	for (i = 0; i < num_items; i++) {
-		ret = rockchip_add_kms_item(drv, &items[i]);
+	for (i = 0; i < drv_array_size(kms_items); i++) {
+		ret = rockchip_add_kms_item(drv, (struct kms_item *)drv_array_at_idx(kms_items, i));
 		if (ret) {
-			free(items);
+			drv_array_destroy(kms_items);
 			return ret;
 		}
 	}
 
-	free(items);
+	drv_array_destroy(kms_items);
 	return 0;
 }