egl: Add dynamic array.
authorChia-I Wu <olv@lunarg.com>
Wed, 30 Jun 2010 08:08:52 +0000 (16:08 +0800)
committerChia-I Wu <olv@lunarg.com>
Wed, 30 Jun 2010 10:32:48 +0000 (18:32 +0800)
Dynamic arrays will be used to store configs and screens of a display.

src/egl/main/Makefile
src/egl/main/SConscript
src/egl/main/eglarray.c [new file with mode: 0644]
src/egl/main/eglarray.h [new file with mode: 0644]
src/egl/main/egltypedefs.h

index 3834a5dbfa187bec47d4e433d2909edc13985472..41d301fc14056b6b3a02f659b354308a1b0f060d 100644 (file)
@@ -30,6 +30,7 @@ HEADERS = \
 
 SOURCES = \
        eglapi.c \
+       eglarray.c \
        eglconfig.c \
        eglconfigutil.c \
        eglcontext.c \
index 69ad873bd6698b345fca8542925bb08b62424f13..3d7ae3a8e4ebe8c355694538d5aa6cd25e205e8f 100644 (file)
@@ -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 (file)
index 0000000..e4faaf4
--- /dev/null
@@ -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 (file)
index 0000000..80bdb0e
--- /dev/null
@@ -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 */
index 166b133909e3b699f6dab58009508bf8f554f2f2..0e29e9aa47e9148a152a17228112cb99446d64ad 100644 (file)
@@ -10,6 +10,8 @@
 
 typedef struct _egl_api _EGLAPI;
 
+typedef struct _egl_array _EGLArray;
+
 typedef struct _egl_config _EGLConfig;
 
 typedef struct _egl_context _EGLContext;