egl: _eglFilterArray should not allocate.
authorChia-I Wu <olv@lunarg.com>
Mon, 6 Dec 2010 06:38:23 +0000 (14:38 +0800)
committerChia-I Wu <olv@lunarg.com>
Mon, 6 Dec 2010 07:40:37 +0000 (15:40 +0800)
Otherwise, when it is called from within a driver, the caller cannot
free the returned data (on Windows).

src/egl/main/eglarray.c
src/egl/main/eglarray.h
src/egl/main/eglconfig.c
src/gallium/state_trackers/egl/common/egl_g3d_api.c

index d686fa162d5ecdbc3766bd176aea17f47efe4ca4..fe2f1a7f32fcd4988896d1dbf62b5f451f3d013d 100644 (file)
@@ -118,38 +118,39 @@ _eglFindArray(_EGLArray *array, void *elem)
 
 
 /**
- * Filter an array and return the filtered data.  The returned data pointer
- * should be freed.
+ * Filter an array and return the number of filtered elements.
  */
-void **
-_eglFilterArray(_EGLArray *array, EGLint *size,
+EGLint
+_eglFilterArray(_EGLArray *array, void **data, 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 (!array)
+      return 0;
 
    if (filter) {
       for (i = 0; i < array->Size; i++) {
-         if (filter(array->Elements[i], filter_data))
-            data[count++] = array->Elements[i];
+         if (filter(array->Elements[i], filter_data)) {
+            if (data && count < size)
+               data[count] = array->Elements[i];
+            count++;
+         }
+         if (data && count >= size)
+            break;
       }
    }
    else {
-      memcpy(data, array->Elements, array->Size * sizeof(array->Elements[0]));
+      if (data) {
+         count = (size < array->Size) ? size : array->Size;
+         memcpy(data, array->Elements, count * sizeof(array->Elements[0]));
+      }
+      else {
+         count = array->Size;
+      }
    }
 
-   *size = count;
-
-   return data;
+   return count;
 }
 
 
index c8309fb066a760be3e0554ff01002382d4a31ae4..a88189a62524e921e0020ed4a36c8d66baf33aaa 100644 (file)
@@ -37,8 +37,8 @@ void *
 _eglFindArray(_EGLArray *array, void *elem);
 
 
-PUBLIC void **
-_eglFilterArray(_EGLArray *array, EGLint *size,
+PUBLIC EGLint
+_eglFilterArray(_EGLArray *array, void **data, EGLint size,
                 _EGLArrayForEach filter, void *filter_data);
 
 
index fec94fb20cd52f70086e39f27fa65d99961aa260..5b377b7f610d68be9a70654414a178079a47cb44 100644 (file)
@@ -697,11 +697,22 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
    if (!_eglParseConfigAttribList(&criteria, disp, attrib_list))
       return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
 
-   configList = (_EGLConfig **) _eglFilterArray(disp->Configs, &count,
+   /* get the number of matched configs */
+   count = _eglFilterArray(disp->Configs, NULL, 0,
          (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria);
+   if (!count) {
+      *num_configs = count;
+      return EGL_TRUE;
+   }
+
+   configList = malloc(sizeof(*configList) * count);
    if (!configList)
       return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");
 
+   /* get the matched configs */
+   _eglFilterArray(disp->Configs, (void **) configList, count,
+         (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria);
+
    /* perform sorting of configs */
    if (configs && count) {
       _eglSortConfigs((const _EGLConfig **) configList, count,
index f505220222ec4dfcb4f69eb1d83d68e1eacfafa7..8e53e1dccbaecba3a450471f7b84aee67f0e79b5 100644 (file)
@@ -141,11 +141,22 @@ egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
    if (!_eglParseConfigAttribList(&criteria, dpy, attribs))
       return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
 
-   tmp_configs = (_EGLConfig **) _eglFilterArray(dpy->Configs, &tmp_size,
+   /* get the number of matched configs */
+   tmp_size = _eglFilterArray(dpy->Configs, NULL, 0,
          (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
+   if (!tmp_size) {
+      *num_configs = tmp_size;
+      return EGL_TRUE;
+   }
+
+   tmp_configs = MALLOC(sizeof(tmp_configs[0]) * tmp_size);
    if (!tmp_configs)
       return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");
 
+   /* get the matched configs */
+   _eglFilterArray(dpy->Configs, (void **) tmp_configs, tmp_size,
+         (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria);
+
    /* perform sorting of configs */
    if (tmp_configs && tmp_size) {
       _eglSortConfigs((const _EGLConfig **) tmp_configs, tmp_size,
@@ -155,7 +166,7 @@ egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs,
          configs[i] = _eglGetConfigHandle(tmp_configs[i]);
    }
 
-   free(tmp_configs);
+   FREE(tmp_configs);
 
    *num_configs = size;