Mesa (master): egl: Add dynamic array.

Chia-I Wu olv at kemper.freedesktop.org
Wed Jun 30 03:33:26 PDT 2010


Module: Mesa
Branch: master
Commit: 106466783f986f532d3ee7af3a70f693c610ea04
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=106466783f986f532d3ee7af3a70f693c610ea04

Author: Chia-I Wu <olv at lunarg.com>
Date:   Wed Jun 30 16:08:52 2010 +0800

egl: Add dynamic array.

Dynamic arrays will be used to store configs and screens of a display.

---

 src/egl/main/Makefile      |    1 +
 src/egl/main/SConscript    |    1 +
 src/egl/main/eglarray.c    |  160 ++++++++++++++++++++++++++++++++++++++++++++
 src/egl/main/eglarray.h    |   53 +++++++++++++++
 src/egl/main/egltypedefs.h |    2 +
 5 files changed, 217 insertions(+), 0 deletions(-)

diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 3834a5d..41d301f 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 69ad873..3d7ae3a 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 0000000..e4faaf4
--- /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 0000000..80bdb0e
--- /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 166b133..0e29e9a 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;



More information about the mesa-commit mailing list