From: Chia-I Wu Date: Wed, 30 Jun 2010 08:08:52 +0000 (+0800) Subject: egl: Add dynamic array. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=106466783f986f532d3ee7af3a70f693c610ea04;p=mesa.git egl: Add dynamic array. Dynamic arrays will be used to store configs and screens of a display. --- 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 +#include + +#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;