Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2010 LunarG, Inc.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  21.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  23.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24.  * DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28.  
  29. #include <stdlib.h>
  30. #include <string.h>
  31.  
  32. #define EGL_EGLEXT_PROTOTYPES
  33. #include <EGL/egl.h>
  34. #include <EGL/eglext.h>
  35.  
  36. #include "egllog.h"
  37. #include "eglarray.h"
  38.  
  39.  
  40. /**
  41.  * Grow the size of the array.
  42.  */
  43. static EGLBoolean
  44. _eglGrowArray(_EGLArray *array)
  45. {
  46.    EGLint new_size;
  47.    void **elems;
  48.  
  49.    new_size = array->MaxSize;
  50.    while (new_size <= array->Size)
  51.       new_size *= 2;
  52.  
  53.    elems = realloc(array->Elements, new_size * sizeof(array->Elements[0]));
  54.    if (!elems) {
  55.       _eglLog(_EGL_DEBUG, "failed to grow %s array to %d",
  56.             array->Name, new_size);
  57.       return EGL_FALSE;
  58.    }
  59.  
  60.    array->Elements = elems;
  61.    array->MaxSize = new_size;
  62.  
  63.    return EGL_TRUE;
  64. }
  65.  
  66.  
  67. /**
  68.  * Create an array.
  69.  */
  70. _EGLArray *
  71. _eglCreateArray(const char *name, EGLint init_size)
  72. {
  73.    _EGLArray *array;
  74.  
  75.    array = calloc(1, sizeof(*array));
  76.    if (array) {
  77.       array->Name = name;
  78.       array->MaxSize = (init_size > 0) ? init_size : 1;
  79.       if (!_eglGrowArray(array)) {
  80.          free(array);
  81.          array = NULL;
  82.       }
  83.    }
  84.  
  85.    return array;
  86. }
  87.  
  88.  
  89. /**
  90.  * Destroy an array, optionally free the data.
  91.  */
  92. void
  93. _eglDestroyArray(_EGLArray *array, void (*free_cb)(void *))
  94. {
  95.    if (free_cb) {
  96.       EGLint i;
  97.       for (i = 0; i < array->Size; i++)
  98.          free_cb(array->Elements[i]);
  99.    }
  100.    free(array->Elements);
  101.    free(array);
  102. }
  103.  
  104.  
  105. /**
  106.  * Append a element to an array.
  107.  */
  108. void
  109. _eglAppendArray(_EGLArray *array, void *elem)
  110. {
  111.    if (array->Size >= array->MaxSize && !_eglGrowArray(array))
  112.       return;
  113.  
  114.    array->Elements[array->Size++] = elem;
  115. }
  116.  
  117.  
  118. /**
  119.  * Erase an element from an array.
  120.  */
  121. void
  122. _eglEraseArray(_EGLArray *array, EGLint i, void (*free_cb)(void *))
  123. {
  124.    if (free_cb)
  125.       free_cb(array->Elements[i]);
  126.    if (i < array->Size - 1) {
  127.       memmove(&array->Elements[i], &array->Elements[i + 1],
  128.             (array->Size - i - 1) * sizeof(array->Elements[0]));
  129.    }
  130.    array->Size--;
  131. }
  132.  
  133.  
  134. /**
  135.  * Find in an array for the given element.
  136.  */
  137. void *
  138. _eglFindArray(_EGLArray *array, void *elem)
  139. {
  140.    EGLint i;
  141.  
  142.    if (!array)
  143.       return NULL;
  144.  
  145.    for (i = 0; i < array->Size; i++)
  146.       if (array->Elements[i] == elem)
  147.          return elem;
  148.    return NULL;
  149. }
  150.  
  151.  
  152. /**
  153.  * Filter an array and return the number of filtered elements.
  154.  */
  155. EGLint
  156. _eglFilterArray(_EGLArray *array, void **data, EGLint size,
  157.                 _EGLArrayForEach filter, void *filter_data)
  158. {
  159.    EGLint count = 0, i;
  160.  
  161.    if (!array)
  162.       return 0;
  163.  
  164.    if (filter) {
  165.       for (i = 0; i < array->Size; i++) {
  166.          if (filter(array->Elements[i], filter_data)) {
  167.             if (data && count < size)
  168.                data[count] = array->Elements[i];
  169.             count++;
  170.          }
  171.          if (data && count >= size)
  172.             break;
  173.       }
  174.    }
  175.    else {
  176.       if (data) {
  177.          count = (size < array->Size) ? size : array->Size;
  178.          memcpy(data, array->Elements, count * sizeof(array->Elements[0]));
  179.       }
  180.       else {
  181.          count = array->Size;
  182.       }
  183.    }
  184.  
  185.    return count;
  186. }
  187.  
  188.  
  189. /**
  190.  * Flatten an array by converting array elements into another form and store
  191.  * them in a buffer.
  192.  */
  193. EGLint
  194. _eglFlattenArray(_EGLArray *array, void *buffer, EGLint elem_size, EGLint size,
  195.                  _EGLArrayForEach flatten)
  196. {
  197.    EGLint i, count;
  198.  
  199.    if (!array)
  200.       return 0;
  201.  
  202.    count = array->Size;
  203.    if (buffer) {
  204.       /* do not exceed buffer size */
  205.       if (count > size)
  206.          count = size;
  207.       for (i = 0; i < count; i++)
  208.          flatten(array->Elements[i],
  209.                (void *) ((char *) buffer + elem_size * i));
  210.    }
  211.  
  212.    return count;
  213. }
  214.