OSDN Git Service

minigbm: introduce drv_array
authorGurchetan Singh <gurchetansingh@chromium.org>
Thu, 2 Nov 2017 23:42:49 +0000 (16:42 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Thu, 9 Nov 2017 08:38:12 +0000 (00:38 -0800)
We want to allow multiple mappings of a single buffer with different
map flags. To do this, we'll need some sort of linked list or dynamic
array of mappings. We already use dynamic arrays in minigbm, so let's
centralize that functionality and use it.

BUG=chromium:764871
TEST=emerge-kevin {minigbm, arc-cros-gralloc}

Change-Id: I2b391d6e8e690eac6368b1404a806b2bfbbcdf44
Reviewed-on: https://chromium-review.googlesource.com/758145
Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
helpers.h
helpers_array.c [new file with mode: 0644]
helpers_array.h [new file with mode: 0644]

index cbd8f18..5de7225 100644 (file)
--- a/helpers.h
+++ b/helpers.h
@@ -8,6 +8,7 @@
 #define HELPERS_H
 
 #include "drv.h"
+#include "helpers_array.h"
 
 uint32_t drv_stride_from_format(uint32_t format, uint32_t width, size_t plane);
 uint32_t drv_size_from_format(uint32_t format, uint32_t stride, uint32_t height, size_t plane);
@@ -35,5 +36,4 @@ struct kms_item *drv_query_kms(struct driver *drv, uint32_t *num_items);
 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);
-
 #endif
diff --git a/helpers_array.c b/helpers_array.c
new file mode 100644 (file)
index 0000000..20b43e2
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+struct drv_array {
+       void **items;
+       uint32_t size;
+       uint32_t item_size;
+       uint32_t allocations;
+};
+
+struct drv_array *drv_array_init(uint32_t item_size)
+{
+       struct drv_array *array;
+
+       array = calloc(1, sizeof(*array));
+
+       /* Start with a power of 2 number of allocations. */
+       array->allocations = 2;
+       array->items = calloc(array->allocations, sizeof(*array->items));
+       array->item_size = item_size;
+       return array;
+}
+
+void *drv_array_append(struct drv_array *array, void *data)
+{
+       void *item;
+
+       if (array->size >= array->allocations) {
+               void **new_items = NULL;
+               array->allocations *= 2;
+               new_items = realloc(array->items, array->allocations * sizeof(*array->items));
+               assert(new_items);
+               array->items = new_items;
+       }
+
+       item = calloc(1, array->item_size);
+       memcpy(item, data, array->item_size);
+       array->items[array->size] = item;
+       array->size++;
+       return item;
+}
+
+void drv_array_remove(struct drv_array *array, uint32_t idx)
+{
+       uint32_t i;
+
+       assert(array);
+       assert(idx < array->size);
+
+       free(array->items[idx]);
+       array->items[idx] = NULL;
+
+       for (i = idx + 1; i < array->size; i++)
+               array->items[i - 1] = array->items[i];
+
+       array->size--;
+       if ((DIV_ROUND_UP(array->allocations, 2) > array->size) && array->allocations > 2) {
+               void **new_items = NULL;
+               array->allocations = DIV_ROUND_UP(array->allocations, 2);
+               new_items = realloc(array->items, array->allocations * sizeof(*array->items));
+               assert(new_items);
+               array->items = new_items;
+       }
+}
+
+void *drv_array_at_idx(struct drv_array *array, uint32_t idx)
+{
+       assert(idx < array->size);
+       return array->items[idx];
+}
+
+uint32_t drv_array_size(struct drv_array *array)
+{
+       return array->size;
+}
+
+void drv_array_destroy(struct drv_array *array)
+{
+       uint32_t i;
+
+       for (i = 0; i < array->size; i++)
+               free(array->items[i]);
+
+       free(array->items);
+       free(array);
+}
diff --git a/helpers_array.h b/helpers_array.h
new file mode 100644 (file)
index 0000000..2893976
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+struct drv_array;
+
+struct drv_array *drv_array_init(uint32_t item_size);
+
+/* The data will be copied and appended to the array. */
+void *drv_array_append(struct drv_array *array, void *data);
+
+/* The data at the specified index will be freed -- the array will shrink. */
+void drv_array_remove(struct drv_array *array, uint32_t idx);
+
+void *drv_array_at_idx(struct drv_array *array, uint32_t idx);
+
+uint32_t drv_array_size(struct drv_array *array);
+
+/* The array and all associated data will be freed. */
+void drv_array_destroy(struct drv_array *array);