summaryrefslogtreecommitdiff
path: root/src/egl/glitz_egl_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/glitz_egl_config.c')
-rw-r--r--src/egl/glitz_egl_config.c221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/egl/glitz_egl_config.c b/src/egl/glitz_egl_config.c
new file mode 100644
index 0000000..671c6d9
--- /dev/null
+++ b/src/egl/glitz_egl_config.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright © 2004 David Reveman
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * David Reveman not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * David Reveman makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "../config.h"
+#endif
+
+#include "glitz_eglint.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+static int
+_glitz_egl_format_compare (const void *elem1,
+ const void *elem2)
+{
+ int i, score[2];
+ glitz_drawable_format_t *format[2];
+
+ format[0] = (glitz_drawable_format_t *) elem1;
+ format[1] = (glitz_drawable_format_t *) elem2;
+ i = score[0] = score[1] = 0;
+
+ for (; i < 2; i++) {
+ if (format[i]->color.red_size) {
+ if (format[i]->color.red_size == 8)
+ score[i] += 5;
+ score[i] += 10;
+ }
+
+ if (format[i]->color.green_size) {
+ if (format[i]->color.green_size == 8)
+ score[i] += 5;
+ score[i] += 10;
+ }
+
+ if (format[i]->color.alpha_size) {
+ if (format[i]->color.alpha_size == 8)
+ score[i] += 5;
+ score[i] += 10;
+ }
+
+ if (format[i]->stencil_size)
+ score[i] += 5;
+
+ if (format[i]->depth_size)
+ score[i] += 5;
+
+ if (format[i]->doublebuffer)
+ score[i] += 10;
+
+ if (format[i]->types.window)
+ score[i] += 10;
+
+ if (format[i]->types.pbuffer)
+ score[i] += 10;
+
+ if (format[i]->samples > 1)
+ score[i] -= (20 - format[i]->samples);
+ }
+
+ return score[1] - score[0];
+}
+
+static void
+_glitz_add_format (glitz_egl_screen_info_t *screen_info,
+ glitz_drawable_format_t *format,
+ EGLConfig egl_id)
+{
+ if (!glitz_drawable_format_find (screen_info->formats,
+ screen_info->n_formats,
+ GLITZ_DRAWABLE_FORMAT_ALL_EXCEPT_ID_MASK,
+ format, 0)) {
+ int n = screen_info->n_formats;
+
+ screen_info->formats =
+ realloc (screen_info->formats,
+ sizeof (glitz_drawable_format_t) * (n + 1));
+ screen_info->egl_config_ids =
+ realloc (screen_info->egl_config_ids, sizeof (EGLConfig) * (n + 1));
+
+ if (screen_info->formats && screen_info->egl_config_ids) {
+ screen_info->formats[n] = *format;
+ screen_info->formats[n].id = n;
+ screen_info->egl_config_ids[n] = egl_id;
+ screen_info->n_formats++;
+ }
+ }
+}
+
+static glitz_status_t
+_glitz_egl_query_configs (glitz_egl_screen_info_t *screen_info)
+{
+ EGLDisplay egl_display;
+ glitz_drawable_format_t format;
+ EGLConfig *egl_configs;
+ int i, num_configs;
+ EGLConfig egl_id;
+
+ egl_display = screen_info->display_info->egl_display;
+
+ eglGetConfigs(egl_display, NULL, 0, &num_configs);
+ egl_configs = malloc(sizeof(*egl_configs) * num_configs);
+ eglGetConfigs(egl_display, egl_configs, num_configs, &num_configs);
+
+ for (i = 0; i < num_configs; i++) {
+ int value;
+
+ eglGetConfigAttrib(egl_display, egl_configs[i],
+ EGL_SURFACE_TYPE, &value);
+ if (!((value & EGL_WINDOW_BIT) || (value & EGL_PBUFFER_BIT)))
+ continue;
+
+ format.types.window = (value & EGL_WINDOW_BIT)? 1: 0;
+ format.types.pbuffer = (value & EGL_PBUFFER_BIT)? 1: 0;
+ format.id = 0;
+
+ eglGetConfigAttrib(egl_display, egl_configs[i], EGL_CONFIG_ID, &value);
+ egl_id = (EGLConfig) value;
+
+ eglGetConfigAttrib(egl_display, egl_configs[i], EGL_RED_SIZE, &value);
+ format.color.red_size = (unsigned short) value;
+ eglGetConfigAttrib(egl_display, egl_configs[i], EGL_GREEN_SIZE, &value);
+ format.color.green_size = (unsigned short) value;
+ eglGetConfigAttrib(egl_display, egl_configs[i], EGL_BLUE_SIZE, &value);
+ format.color.blue_size = (unsigned short) value;
+ eglGetConfigAttrib(egl_display, egl_configs[i], EGL_ALPHA_SIZE, &value);
+ format.color.alpha_size = (unsigned short) value;
+ eglGetConfigAttrib(egl_display, egl_configs[i], EGL_DEPTH_SIZE, &value);
+ format.depth_size = (unsigned short) value;
+ eglGetConfigAttrib(egl_display, egl_configs[i], EGL_STENCIL_SIZE, &value);
+ format.stencil_size = (unsigned short) value;
+
+ format.doublebuffer = 1;
+
+ eglGetConfigAttrib(egl_display, egl_configs[i], EGL_SAMPLE_BUFFERS, &value);
+ if (value) {
+ eglGetConfigAttrib(egl_display, egl_configs[i], EGL_SAMPLES, &value);
+ format.samples = (unsigned short) (value > 1)? value: 1;
+ if (format.samples > 1)
+ format.types.pbuffer = 0;
+ } else
+ format.samples = 1;
+
+ _glitz_add_format (screen_info, &format, egl_id);
+ }
+
+ free(egl_configs);
+
+ return GLITZ_STATUS_SUCCESS;
+}
+
+void
+glitz_egl_query_configs (glitz_egl_screen_info_t *screen_info)
+{
+ EGLConfig *egl_new_ids;
+ int i;
+
+ _glitz_egl_query_configs (screen_info);
+
+ if (!screen_info->n_formats)
+ return;
+
+ qsort (screen_info->formats, screen_info->n_formats,
+ sizeof (glitz_drawable_format_t), _glitz_egl_format_compare);
+
+ /*
+ * Update XID list so that it matches the sorted format list.
+ */
+ egl_new_ids = malloc (sizeof (EGLConfig) * screen_info->n_formats);
+ if (!egl_new_ids) {
+ screen_info->n_formats = 0;
+ return;
+ }
+
+ for (i = 0; i < screen_info->n_formats; i++) {
+ egl_new_ids[i] = screen_info->egl_config_ids[screen_info->formats[i].id];
+ screen_info->formats[i].id = i;
+ }
+
+ free (screen_info->egl_config_ids);
+ screen_info->egl_config_ids = egl_new_ids;
+}
+
+glitz_drawable_format_t *
+glitz_egl_find_config (EGLDisplay egl_display,
+ EGLScreenMESA egl_screen,
+ unsigned long mask,
+ const glitz_drawable_format_t *templ,
+ int count)
+{
+ glitz_egl_screen_info_t *screen_info =
+ glitz_egl_screen_info_get (egl_display, egl_screen);
+
+ return glitz_drawable_format_find (screen_info->formats,
+ screen_info->n_formats,
+ mask, templ, count);
+}
+slim_hidden_def(glitz_egl_find_config);