aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/egl/main/Makefile1
-rw-r--r--src/egl/main/SConscript1
-rw-r--r--src/egl/main/eglarray.c160
-rw-r--r--src/egl/main/eglarray.h53
-rw-r--r--src/egl/main/egltypedefs.h2
5 files changed, 217 insertions, 0 deletions
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 3834a5dbfa1..41d301fc140 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -30,6 +30,7 @@ HEADERS = \
SOURCES = \
eglapi.c \
+ eglarray.c \
eglconfig.c \
eglconfigutil.c \
eglcontext.c \
diff --git a/src/egl/main/SConscript b/src/egl/main/SConscript
index 69ad873bd66..3d7ae3a8e4e 100644
--- a/src/egl/main/SConscript
+++ b/src/egl/main/SConscript
@@ -21,6 +21,7 @@ if env['platform'] != 'winddk':
egl_sources = [
'eglapi.c',
+ 'eglarray.c',
'eglconfig.c',
'eglconfigutil.c',
'eglcontext.c',
diff --git a/src/egl/main/eglarray.c b/src/egl/main/eglarray.c
new file mode 100644
index 00000000000..e4faaf4d71e
--- /dev/null
+++ b/src/egl/main/eglarray.c
@@ -0,0 +1,160 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "egllog.h"
+#include "eglarray.h"
+
+
+/**
+ * Grow the size of the array.
+ */
+static EGLBoolean
+_eglGrowArray(_EGLArray *array)
+{
+ EGLint new_size;
+ void **elems;
+
+ new_size = array->MaxSize;
+ while (new_size <= array->Size)
+ new_size *= 2;
+
+ elems = realloc(array->Elements, new_size * sizeof(array->Elements[0]));
+ if (!elems) {
+ _eglLog(_EGL_DEBUG, "failed to grow %s array to %d",
+ array->Name, new_size);
+ return EGL_FALSE;
+ }
+
+ array->Elements = elems;
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * Create an array.
+ */
+_EGLArray *
+_eglCreateArray(const char *name, EGLint init_size)
+{
+ _EGLArray *array;
+
+ array = calloc(1, sizeof(*array));
+ if (array) {
+ array->Name = name;
+ array->MaxSize = (init_size > 0) ? init_size : 1;
+ if (!_eglGrowArray(array)) {
+ free(array);
+ array = NULL;
+ }
+ }
+
+ return array;
+}
+
+
+/**
+ * Destroy an array, optionally free the data.
+ */
+void
+_eglDestroyArray(_EGLArray *array, void (*free_cb)(void *))
+{
+ if (free_cb) {
+ EGLint i;
+ for (i = 0; i < array->Size; i++)
+ free_cb(array->Elements[i]);
+ }
+ free(array->Elements);
+ free(array);
+}
+
+
+/**
+ * Append a element to an array.
+ */
+void
+_eglAppendArray(_EGLArray *array, void *elem)
+{
+ if (array->Size >= array->MaxSize && !_eglGrowArray(array))
+ return;
+
+ array->Elements[array->Size++] = elem;
+}
+
+
+/**
+ * Find in an array for the given element.
+ */
+void *
+_eglFindArray(_EGLArray *array, void *elem)
+{
+ EGLint i;
+
+ if (!array)
+ return NULL;
+
+ for (i = 0; i < array->Size; i++)
+ if (array->Elements[i] == elem)
+ return elem;
+ return NULL;
+}
+
+
+/**
+ * Filter an array and return the filtered data. The returned data pointer
+ * should be freed.
+ */
+void **
+_eglFilterArray(_EGLArray *array, EGLint *size,
+ _EGLArrayForEach filter, void *filter_data)
+{
+ void **data;
+ EGLint count = 0, i;
+
+ if (!array) {
+ *size = 0;
+ return malloc(0);
+ }
+
+ data = malloc(array->Size * sizeof(array->Elements[0]));
+ if (!data)
+ return NULL;
+
+ if (filter) {
+ for (i = 0; i < array->Size; i++) {
+ if (filter(array->Elements[i], filter_data))
+ data[count++] = array->Elements[i];
+ }
+ }
+ else {
+ memcpy(data, array->Elements, array->Size * sizeof(array->Elements[0]));
+ }
+
+ *size = count;
+
+ return data;
+}
+
+
+/**
+ * Flatten an array by converting array elements into another form and store
+ * them in a buffer.
+ */
+EGLint
+_eglFlattenArray(_EGLArray *array, void *buffer, EGLint elem_size, EGLint size,
+ _EGLArrayForEach flatten)
+{
+ EGLint i, count;
+
+ if (!array)
+ return 0;
+
+ count = (size < array->Size) ? size : array->Size;
+ if (buffer) {
+ for (i = 0; i < count; i++)
+ flatten(array->Elements[i],
+ (void *) ((char *) buffer + elem_size * i));
+ }
+
+ return count;
+}
diff --git a/src/egl/main/eglarray.h b/src/egl/main/eglarray.h
new file mode 100644
index 00000000000..80bdb0e3eef
--- /dev/null
+++ b/src/egl/main/eglarray.h
@@ -0,0 +1,53 @@
+#ifndef EGLARRAY_INCLUDED
+#define EGLARRAY_INCLUDED
+
+
+#include "egltypedefs.h"
+
+
+typedef EGLBoolean (*_EGLArrayForEach)(void *elem, void *foreach_data);
+
+
+struct _egl_array {
+ const char *Name;
+ EGLint MaxSize;
+
+ void **Elements;
+ EGLint Size;
+};
+
+
+extern _EGLArray *
+_eglCreateArray(const char *name, EGLint init_size);
+
+
+PUBLIC void
+_eglDestroyArray(_EGLArray *array, void (*free_cb)(void *));
+
+
+extern void
+_eglAppendArray(_EGLArray *array, void *elem);
+
+
+void *
+_eglFindArray(_EGLArray *array, void *elem);
+
+
+void **
+_eglFilterArray(_EGLArray *array, EGLint *size,
+ _EGLArrayForEach filter, void *filter_data);
+
+
+EGLint
+_eglFlattenArray(_EGLArray *array, void *buffer, EGLint elem_size, EGLint size,
+ _EGLArrayForEach flatten);
+
+
+static INLINE EGLint
+_eglGetArraySize(_EGLArray *array)
+{
+ return (array) ? array->Size : 0;
+}
+
+
+#endif /* EGLARRAY_INCLUDED */
diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h
index 166b133909e..0e29e9aa47e 100644
--- a/src/egl/main/egltypedefs.h
+++ b/src/egl/main/egltypedefs.h
@@ -10,6 +10,8 @@
typedef struct _egl_api _EGLAPI;
+typedef struct _egl_array _EGLArray;
+
typedef struct _egl_config _EGLConfig;
typedef struct _egl_context _EGLContext;