summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Reveman <davidr@novell.com>2005-05-19 13:30:49 +0000
committerDavid Reveman <davidr@novell.com>2005-05-19 13:30:49 +0000
commit43dcd2317802a79eee54eee7b1ae74bd1ccc5d69 (patch)
tree6ed2c396435fd1ecfa32b53a39805f99f948b5eb /src
parent65f551e0bb453a6d98225686485914f242296cfb (diff)
Add EGL backend
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/egl/.cvsignore7
-rw-r--r--src/egl/Makefile.am40
-rw-r--r--src/egl/glitz-egl.h78
-rw-r--r--src/egl/glitz-egl.man27
-rw-r--r--src/egl/glitz-egl.pc.in11
-rw-r--r--src/egl/glitz_egl_config.c221
-rw-r--r--src/egl/glitz_egl_context.c357
-rw-r--r--src/egl/glitz_egl_extension.c74
-rw-r--r--src/egl/glitz_egl_info.c432
-rw-r--r--src/egl/glitz_egl_pbuffer.c67
-rw-r--r--src/egl/glitz_egl_surface.c203
-rw-r--r--src/egl/glitz_eglext.h56
-rw-r--r--src/egl/glitz_eglint.h171
14 files changed, 1745 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ffa75d7..43e1470 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = . glx agl
+SUBDIRS = . glx agl egl
lib_LTLIBRARIES = libglitz.la
include_HEADERS = glitz.h
diff --git a/src/egl/.cvsignore b/src/egl/.cvsignore
new file mode 100644
index 0000000..6829f0d
--- /dev/null
+++ b/src/egl/.cvsignore
@@ -0,0 +1,7 @@
+Makefile
+Makefile.in
+*.la
+*.lo
+*.loT
+.libs
+.deps
diff --git a/src/egl/Makefile.am b/src/egl/Makefile.am
new file mode 100644
index 0000000..547bb84
--- /dev/null
+++ b/src/egl/Makefile.am
@@ -0,0 +1,40 @@
+if GLITZ_BUILD_EGL_BACKEND
+
+INCLUDES = \
+ $(GLITZ_INC) \
+ $(EGL_CFLAGS)
+
+lib_LTLIBRARIES = libglitz-egl.la
+include_HEADERS = glitz-egl.h
+
+libglitz_egl_la_SOURCES = \
+ glitz-egl.h \
+ glitz_egl_surface.c \
+ glitz_egl_config.c \
+ glitz_egl_info.c \
+ glitz_egl_extension.c \
+ glitz_egl_context.c \
+ glitz_egl_pbuffer.c \
+ glitz_eglext.h \
+ glitz_eglint.h
+
+libglitz_egl_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined
+libglitz_egl_la_LIBADD = $(GLITZ_LIB) $(EGL_LIBS)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = glitz-egl.pc
+
+endif
+
+EXTRA_DIST = \
+ glitz-egl.h \
+ glitz_egl_surface.c \
+ glitz_egl_config.c \
+ glitz_egl_info.c \
+ glitz_egl_extension.c \
+ glitz_egl_context.c \
+ glitz_egl_pbuffer.c \
+ glitz_eglext.h \
+ glitz_eglint.h \
+ glitz-egl.pc.in \
+ glitz-egl.man
diff --git a/src/egl/glitz-egl.h b/src/egl/glitz-egl.h
new file mode 100644
index 0000000..005732a
--- /dev/null
+++ b/src/egl/glitz-egl.h
@@ -0,0 +1,78 @@
+/*
+ * 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>
+ */
+
+#ifndef GLITZ_EGL_H_INCLUDED
+#define GLITZ_EGL_H_INCLUDED
+
+#include <GL/gl.h>
+#include <GLES/egl.h>
+
+#include <glitz.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* glitz_egl_info.c */
+
+void
+glitz_egl_init (const char *gl_library);
+
+void
+glitz_egl_fini (void);
+
+
+/* glitz_egl_config.c */
+
+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_drawable.c */
+
+glitz_drawable_t *
+glitz_egl_create_window_surface (EGLDisplay display,
+ EGLScreenMESA screen,
+ glitz_drawable_format_t *format,
+ NativeWindowType window,
+ unsigned int width,
+ unsigned int height);
+
+glitz_drawable_t *
+glitz_egl_create_pbuffer_surface (EGLDisplay display,
+ EGLScreenMESA screen,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height);
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* GLITZ_EGL_H_INCLUDED */
diff --git a/src/egl/glitz-egl.man b/src/egl/glitz-egl.man
new file mode 100644
index 0000000..1387f41
--- /dev/null
+++ b/src/egl/glitz-egl.man
@@ -0,0 +1,27 @@
+.\"
+.\"
+.de TQ
+.br
+.ns
+.TP
+\\$1
+..
+.TH GLITZ-EGL 3 "Version 1.0"
+
+.SH NAME
+GLITZ-EGL \- EGL interface to glitz
+
+.SH SYNOPSIS
+.nf
+.B #include <glitz-egl.h>
+.fi
+.SH DESCRIPTION
+
+EGL interface to glitz.
+
+.SH AUTHOR
+David Reveman
+Jon Smirl
+
+.SH "SEE ALSO"
+.BR GLITZ (3)
diff --git a/src/egl/glitz-egl.pc.in b/src/egl/glitz-egl.pc.in
new file mode 100644
index 0000000..6182874
--- /dev/null
+++ b/src/egl/glitz-egl.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libglitz-egl
+Description: OpenGL compositing library (EGL backend)
+Version: @VERSION@
+Requires: glitz
+Libs: -L${libdir} -lglitz-egl @EGL_LIBS@
+Cflags: -I${includedir} @EGL_CFLAGS@
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);
diff --git a/src/egl/glitz_egl_context.c b/src/egl/glitz_egl_context.c
new file mode 100644
index 0000000..89d77d3
--- /dev/null
+++ b/src/egl/glitz_egl_context.c
@@ -0,0 +1,357 @@
+/*
+ * 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>
+
+extern glitz_gl_proc_address_list_t _glitz_egl_gl_proc_address;
+
+static void
+_glitz_egl_context_create (glitz_egl_screen_info_t *screen_info,
+ EGLConfig egl_config,
+ EGLContext egl_share_list,
+ glitz_egl_context_t *context)
+{
+ context->id = egl_config;
+ context->egl_context = eglCreateContext (screen_info->display_info->egl_display,
+ egl_config, egl_share_list, NULL);
+}
+
+static glitz_context_t *
+_glitz_egl_create_context (void *abstract_drawable,
+ glitz_drawable_format_t *format)
+{
+ glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable;
+ glitz_egl_screen_info_t *screen_info = drawable->screen_info;
+ int format_id = screen_info->egl_config_ids[format->id];
+ glitz_egl_context_t *context;
+
+ context = malloc (sizeof (glitz_egl_context_t));
+ if (!context)
+ return NULL;
+
+ _glitz_context_init (&context->base, &drawable->base);
+
+ _glitz_egl_context_create (screen_info,
+ format_id,
+ screen_info->egl_root_context,
+ context);
+
+ return (glitz_context_t *) context;
+}
+
+static void
+_glitz_egl_context_destroy (void *abstract_context)
+{
+ glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context;
+ glitz_egl_surface_t *drawable = (glitz_egl_surface_t *)
+ context->base.drawable;
+
+ if (drawable->screen_info->display_info->thread_info->cctx == &context->base)
+ {
+ eglMakeCurrent (drawable->screen_info->display_info->egl_display,
+ EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ drawable->screen_info->display_info->thread_info->cctx = NULL;
+ }
+
+ eglDestroyContext (drawable->screen_info->display_info->egl_display,
+ context->egl_context);
+
+ _glitz_context_fini (&context->base);
+
+ free (context);
+}
+
+static void
+_glitz_egl_copy_context (void *abstract_src,
+ void *abstract_dst,
+ unsigned long mask)
+{
+ glitz_egl_context_t *src = (glitz_egl_context_t *) abstract_src;
+ glitz_egl_context_t *dst = (glitz_egl_context_t *) abstract_dst;
+ glitz_egl_surface_t *drawable = (glitz_egl_surface_t *)
+ src->base.drawable;
+
+ eglCopyContextMESA (drawable->screen_info->display_info->egl_display,
+ src->egl_context, dst->egl_context, mask);
+}
+
+static void
+_glitz_egl_make_current (void *abstract_context,
+ void *abstract_drawable)
+{
+ glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context;
+ glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable;
+ glitz_egl_display_info_t *display_info = drawable->screen_info->display_info;
+
+ if ((eglGetCurrentContext () != context->egl_context) ||
+ (eglGetCurrentSurface ( 0 ) != drawable->egl_surface))
+ eglMakeCurrent (display_info->egl_display, drawable->egl_surface,
+ drawable->egl_surface, context->egl_context);
+
+ display_info->thread_info->cctx = &context->base;
+}
+
+static glitz_function_pointer_t
+_glitz_egl_context_get_proc_address (void *abstract_context,
+ const char *name)
+{
+ glitz_egl_context_t *context = (glitz_egl_context_t *) abstract_context;
+ glitz_egl_surface_t *drawable = (glitz_egl_surface_t *)
+ context->base.drawable;
+
+ _glitz_egl_make_current (context, drawable);
+
+ return glitz_egl_get_proc_address (name, drawable->screen_info);
+}
+
+glitz_egl_context_t *
+glitz_egl_context_get (glitz_egl_screen_info_t *screen_info,
+ glitz_drawable_format_t *format)
+{
+ glitz_egl_context_t *context;
+ glitz_egl_context_t **contexts = screen_info->contexts;
+ int index, n_contexts = screen_info->n_contexts;
+ EGLConfig egl_config_id;
+
+ for (; n_contexts; n_contexts--, contexts++)
+ if ((*contexts)->id == screen_info->egl_config_ids[format->id])
+ return *contexts;
+
+ index = screen_info->n_contexts++;
+
+ screen_info->contexts =
+ realloc (screen_info->contexts,
+ sizeof (glitz_egl_context_t *) * screen_info->n_contexts);
+ if (!screen_info->contexts)
+ return NULL;
+
+ context = malloc (sizeof (glitz_egl_context_t));
+ if (!context)
+ return NULL;
+
+ screen_info->contexts[index] = context;
+
+ egl_config_id = screen_info->egl_config_ids[format->id];
+
+ _glitz_egl_context_create (screen_info,
+ egl_config_id,
+ screen_info->egl_root_context,
+ context);
+
+ if (!screen_info->egl_root_context)
+ screen_info->egl_root_context = context->egl_context;
+
+ memcpy (&context->backend.gl,
+ &_glitz_egl_gl_proc_address,
+ sizeof (glitz_gl_proc_address_list_t));
+
+ context->backend.create_pbuffer = glitz_egl_create_pbuffer;
+ context->backend.destroy = glitz_egl_destroy;
+ context->backend.push_current = glitz_egl_push_current;
+ context->backend.pop_current = glitz_egl_pop_current;
+ context->backend.swap_buffers = glitz_egl_swap_buffers;
+
+ context->backend.create_context = _glitz_egl_create_context;
+ context->backend.destroy_context = _glitz_egl_context_destroy;
+ context->backend.copy_context = _glitz_egl_copy_context;
+ context->backend.make_current = _glitz_egl_make_current;
+ context->backend.get_proc_address = _glitz_egl_context_get_proc_address;
+
+ context->backend.drawable_formats = screen_info->formats;
+ context->backend.n_drawable_formats = screen_info->n_formats;
+
+ context->backend.texture_formats = NULL;
+ context->backend.formats = NULL;
+ context->backend.n_formats = 0;
+
+ context->backend.program_map = &screen_info->program_map;
+ context->backend.feature_mask = 0;
+
+ context->initialized = 0;
+
+ return context;
+}
+
+void
+glitz_egl_context_destroy (glitz_egl_screen_info_t *screen_info,
+ glitz_egl_context_t *context)
+{
+ if (context->backend.formats)
+ free (context->backend.formats);
+
+ if (context->backend.texture_formats)
+ free (context->backend.texture_formats);
+
+ eglDestroyContext (screen_info->display_info->egl_display,
+ context->egl_context);
+ free (context);
+}
+
+static void
+_glitz_egl_context_initialize (glitz_egl_screen_info_t *screen_info,
+ glitz_egl_context_t *context)
+{
+ const char *version;
+
+ glitz_backend_init (&context->backend,
+ glitz_egl_get_proc_address,
+ (void *) screen_info);
+
+ context->backend.gl.get_integer_v (GLITZ_GL_MAX_VIEWPORT_DIMS,
+ context->max_viewport_dims);
+
+ glitz_initiate_state (&_glitz_egl_gl_proc_address);
+
+ version = (const char *) context->backend.gl.get_string (GLITZ_GL_VERSION);
+ if (version)
+ {
+ /* Having trouble with TexSubImage2D to NPOT GL_TEXTURE_2D textures when
+ using nvidia's binary driver. Seems like a driver issue, but I'm not
+ sure yet. Turning of NPOT GL_TEXTURE_2D textures until this have been
+ solved. */
+ if (strstr (version, "NVIDIA 61.11") ||
+ strstr (version, "NVIDIA 66.29"))
+ {
+ context->backend.feature_mask &=
+ ~GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK;
+ }
+ }
+
+ context->initialized = 1;
+}
+
+static void
+_glitz_egl_context_make_current (glitz_egl_surface_t *drawable,
+ glitz_bool_t finish)
+{
+ glitz_egl_display_info_t *display_info = drawable->screen_info->display_info;
+
+ if (finish)
+ glFinish ();
+
+ if (display_info->thread_info->cctx)
+ {
+ glitz_context_t *ctx = display_info->thread_info->cctx;
+
+ if (ctx->lose_current)
+ ctx->lose_current (ctx->closure);
+
+ display_info->thread_info->cctx = NULL;
+ }
+
+ eglMakeCurrent (display_info->egl_display,
+ drawable->egl_surface, drawable->egl_surface,
+ drawable->context->egl_context);
+
+ drawable->base.update_all = 1;
+
+ if (!drawable->context->initialized)
+ _glitz_egl_context_initialize (drawable->screen_info, drawable->context);
+}
+
+static void
+_glitz_egl_context_update (glitz_egl_surface_t *drawable,
+ glitz_constraint_t constraint)
+{
+ EGLContext egl_context;
+
+ switch (constraint) {
+ case GLITZ_NONE:
+ break;
+ case GLITZ_ANY_CONTEXT_CURRENT: {
+ glitz_egl_display_info_t *dinfo = drawable->screen_info->display_info;
+
+ if (dinfo->thread_info->cctx)
+ {
+ _glitz_egl_context_make_current (drawable, 0);
+ }
+ else
+ {
+ egl_context = eglGetCurrentContext ();
+ if (egl_context == (EGLContext) 0)
+ _glitz_egl_context_make_current (drawable, 0);
+ }
+ } break;
+ case GLITZ_CONTEXT_CURRENT:
+ egl_context = eglGetCurrentContext ();
+ if (egl_context != drawable->context->egl_context)
+ _glitz_egl_context_make_current (drawable, (egl_context)? 1: 0);
+ break;
+ case GLITZ_DRAWABLE_CURRENT:
+ egl_context = eglGetCurrentContext ();
+ if ((egl_context != drawable->context->egl_context) ||
+ (eglGetCurrentSurface ( 0 ) != drawable->egl_surface))
+ _glitz_egl_context_make_current (drawable, (egl_context)? 1: 0);
+ break;
+ }
+}
+
+void
+glitz_egl_push_current (void *abstract_drawable,
+ glitz_surface_t *surface,
+ glitz_constraint_t constraint)
+{
+ glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable;
+ glitz_egl_context_info_t *context_info;
+ int index;
+
+ index = drawable->screen_info->context_stack_size++;
+
+ context_info = &drawable->screen_info->context_stack[index];
+ context_info->drawable = drawable;
+ context_info->surface = surface;
+ context_info->constraint = constraint;
+
+ _glitz_egl_context_update (context_info->drawable, constraint);
+}
+
+glitz_surface_t *
+glitz_egl_pop_current (void *abstract_drawable)
+{
+ glitz_egl_surface_t *drawable = (glitz_egl_surface_t *) abstract_drawable;
+ glitz_egl_context_info_t *context_info = NULL;
+ int index;
+
+ drawable->screen_info->context_stack_size--;
+ index = drawable->screen_info->context_stack_size - 1;
+
+ context_info = &drawable->screen_info->context_stack[index];
+
+ if (context_info->drawable)
+ _glitz_egl_context_update (context_info->drawable,
+ context_info->constraint);
+
+ if (context_info->constraint == GLITZ_DRAWABLE_CURRENT)
+ return context_info->surface;
+
+ return NULL;
+}
diff --git a/src/egl/glitz_egl_extension.c b/src/egl/glitz_egl_extension.c
new file mode 100644
index 0000000..67ae1c0
--- /dev/null
+++ b/src/egl/glitz_egl_extension.c
@@ -0,0 +1,74 @@
+/*
+ * 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"
+
+#if 0
+static glitz_extension_map egl_extensions[] = {
+ { 0.0, "EGL_SGIX_fbconfig", GLITZ_EGL_FEATURE_FBCONFIG_MASK },
+ { 0.0, "EGL_SGIX_pbuffer", GLITZ_EGL_FEATURE_PBUFFER_MASK },
+ { 0.0, "EGL_SGI_make_current_read",
+ GLITZ_EGL_FEATURE_MAKE_CURRENT_READ_MASK },
+ { 0.0, "EGL_ARB_multisample", GLITZ_EGL_FEATURE_MULTISAMPLE_MASK },
+ { 0.0, NULL, 0 }
+};
+#endif
+
+void
+glitz_egl_query_extensions (glitz_egl_screen_info_t *screen_info,
+ glitz_gl_float_t egl_version)
+{
+#if 0
+ const char *egl_extensions_string;
+
+ egl_extensions_string =
+ eglQueryExtensionsString (screen_info->display_info->display,
+ screen_info->screen);
+
+ screen_info->egl_feature_mask =
+ glitz_extensions_query (egl_version,
+ egl_extensions_string,
+ egl_extensions);
+
+ if (screen_info->egl_feature_mask & GLITZ_EGL_FEATURE_MULTISAMPLE_MASK) {
+ const char *vendor;
+
+ vendor = eglGetClientString (screen_info->display_info->display,
+ EGL_VENDOR);
+
+ if (vendor) {
+
+ /* NVIDIA's driver seem to support multisample with pbuffers */
+ if (!strncmp ("NVIDIA", vendor, 6))
+ screen_info->egl_feature_mask |=
+ GLITZ_EGL_FEATURE_PBUFFER_MULTISAMPLE_MASK;
+ }
+ }
+#endif
+}
diff --git a/src/egl/glitz_egl_info.c b/src/egl/glitz_egl_info.c
new file mode 100644
index 0000000..514de5c
--- /dev/null
+++ b/src/egl/glitz_egl_info.c
@@ -0,0 +1,432 @@
+/*
+ * 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 <pthread.h>
+#include <string.h>
+#include <dlfcn.h>
+
+glitz_gl_proc_address_list_t _glitz_egl_gl_proc_address = {
+
+ /* core */
+ (glitz_gl_enable_t) glEnable,
+ (glitz_gl_disable_t) glDisable,
+ (glitz_gl_get_error_t) glGetError,
+ (glitz_gl_get_string_t) glGetString,
+ (glitz_gl_enable_client_state_t) glEnableClientState,
+ (glitz_gl_disable_client_state_t) glDisableClientState,
+ (glitz_gl_vertex_pointer_t) glVertexPointer,
+ (glitz_gl_tex_coord_pointer_t) glTexCoordPointer,
+ (glitz_gl_draw_arrays_t) glDrawArrays,
+ (glitz_gl_tex_env_f_t) glTexEnvf,
+ (glitz_gl_tex_env_fv_t) glTexEnvfv,
+ (glitz_gl_tex_gen_i_t) glTexGeni,
+ (glitz_gl_tex_gen_fv_t) glTexGenfv,
+ (glitz_gl_color_4us_t) glColor4us,
+ (glitz_gl_color_4f_t) glColor4f,
+ (glitz_gl_scissor_t) glScissor,
+ (glitz_gl_blend_func_t) glBlendFunc,
+ (glitz_gl_clear_t) glClear,
+ (glitz_gl_clear_color_t) glClearColor,
+ (glitz_gl_clear_stencil_t) glClearStencil,
+ (glitz_gl_stencil_func_t) glStencilFunc,
+ (glitz_gl_stencil_op_t) glStencilOp,
+ (glitz_gl_push_attrib_t) glPushAttrib,
+ (glitz_gl_pop_attrib_t) glPopAttrib,
+ (glitz_gl_matrix_mode_t) glMatrixMode,
+ (glitz_gl_push_matrix_t) glPushMatrix,
+ (glitz_gl_pop_matrix_t) glPopMatrix,
+ (glitz_gl_load_identity_t) glLoadIdentity,
+ (glitz_gl_load_matrix_f_t) glLoadMatrixf,
+ (glitz_gl_depth_range_t) glDepthRange,
+ (glitz_gl_viewport_t) glViewport,
+ (glitz_gl_raster_pos_2f_t) glRasterPos2f,
+ (glitz_gl_bitmap_t) glBitmap,
+ (glitz_gl_read_buffer_t) glReadBuffer,
+ (glitz_gl_draw_buffer_t) glDrawBuffer,
+ (glitz_gl_copy_pixels_t) glCopyPixels,
+ (glitz_gl_flush_t) glFlush,
+ (glitz_gl_finish_t) glFinish,
+ (glitz_gl_pixel_store_i_t) glPixelStorei,
+ (glitz_gl_ortho_t) glOrtho,
+ (glitz_gl_scale_f_t) glScalef,
+ (glitz_gl_translate_f_t) glTranslatef,
+ (glitz_gl_hint_t) glHint,
+ (glitz_gl_depth_mask_t) glDepthMask,
+ (glitz_gl_polygon_mode_t) glPolygonMode,
+ (glitz_gl_shade_model_t) glShadeModel,
+ (glitz_gl_color_mask_t) glColorMask,
+ (glitz_gl_read_pixels_t) glReadPixels,
+ (glitz_gl_get_tex_image_t) glGetTexImage,
+ (glitz_gl_tex_sub_image_2d_t) glTexSubImage2D,
+ (glitz_gl_gen_textures_t) glGenTextures,
+ (glitz_gl_delete_textures_t) glDeleteTextures,
+ (glitz_gl_bind_texture_t) glBindTexture,
+ (glitz_gl_tex_image_2d_t) glTexImage2D,
+ (glitz_gl_tex_parameter_i_t) glTexParameteri,
+ (glitz_gl_get_tex_level_parameter_iv_t) glGetTexLevelParameteriv,
+ (glitz_gl_copy_tex_sub_image_2d_t) glCopyTexSubImage2D,
+ (glitz_gl_get_integer_v_t) glGetIntegerv,
+
+ /* extensions */
+ (glitz_gl_blend_color_t) 0,
+ (glitz_gl_active_texture_t) 0,
+ (glitz_gl_client_active_texture_t) 0,
+ (glitz_gl_multi_draw_arrays_t) 0,
+ (glitz_gl_gen_programs_t) 0,
+ (glitz_gl_delete_programs_t) 0,
+ (glitz_gl_program_string_t) 0,
+ (glitz_gl_bind_program_t) 0,
+ (glitz_gl_program_local_param_4fv_t) 0,
+ (glitz_gl_get_program_iv_t) 0,
+ (glitz_gl_gen_buffers_t) 0,
+ (glitz_gl_delete_buffers_t) 0,
+ (glitz_gl_bind_buffer_t) 0,
+ (glitz_gl_buffer_data_t) 0,
+ (glitz_gl_buffer_sub_data_t) 0,
+ (glitz_gl_get_buffer_sub_data_t) 0,
+ (glitz_gl_map_buffer_t) 0,
+ (glitz_gl_unmap_buffer_t) 0
+};
+
+glitz_function_pointer_t
+glitz_egl_get_proc_address (const char *name,
+ void *closure)
+{
+ glitz_egl_screen_info_t *screen_info = (glitz_egl_screen_info_t *) closure;
+ glitz_egl_thread_info_t *info = screen_info->display_info->thread_info;
+ glitz_function_pointer_t address = NULL;
+
+ if (screen_info->egl_feature_mask & GLITZ_EGL_FEATURE_GET_PROC_ADDRESS_MASK)
+ address = eglGetProcAddress ((glitz_gl_ubyte_t *) name);
+
+ if (!address) {
+ if (!info->dlhand)
+ info->dlhand = dlopen (info->gl_library, RTLD_LAZY);
+
+ if (info->dlhand) {
+ dlerror ();
+ address = (glitz_function_pointer_t) dlsym (info->dlhand, name);
+ if (dlerror () != NULL)
+ address = NULL;
+ }
+ }
+
+ return address;
+}
+
+static void
+_glitz_egl_display_destroy (glitz_egl_display_info_t *display_info);
+
+static void
+_glitz_egl_screen_destroy (glitz_egl_screen_info_t *screen_info);
+
+static void
+_glitz_egl_thread_info_fini (glitz_egl_thread_info_t *thread_info)
+{
+ int i;
+
+ for (i = 0; i < thread_info->n_displays; i++)
+ _glitz_egl_display_destroy (thread_info->displays[i]);
+
+ free (thread_info->displays);
+
+ thread_info->displays = NULL;
+ thread_info->n_displays = 0;
+
+ if (thread_info->gl_library) {
+ free (thread_info->gl_library);
+ thread_info->gl_library = NULL;
+ }
+
+ if (thread_info->dlhand) {
+ dlclose (thread_info->dlhand);
+ thread_info->dlhand = NULL;
+ }
+
+ thread_info->cctx = NULL;
+}
+#define PTHREADS
+#ifdef PTHREADS
+
+/* thread safe */
+static int tsd_initialized = 0;
+static pthread_key_t info_tsd;
+
+static void
+_glitz_egl_thread_info_init (glitz_egl_thread_info_t *thread_info)
+{
+ thread_info->displays = NULL;
+ thread_info->n_displays = 0;
+ thread_info->gl_library = NULL;
+ thread_info->dlhand = NULL;
+ thread_info->cctx = NULL;
+}
+
+static void
+_glitz_egl_thread_info_destroy (glitz_egl_thread_info_t *thread_info)
+{
+ pthread_setspecific (info_tsd, NULL);
+
+ if (thread_info) {
+ _glitz_egl_thread_info_fini (thread_info);
+ free (thread_info);
+ }
+}
+
+static void
+_tsd_destroy (void *p)
+{
+ if (p) {
+ _glitz_egl_thread_info_fini ((glitz_egl_thread_info_t *) p);
+ free (p);
+ }
+}
+
+static glitz_egl_thread_info_t *
+_glitz_egl_thread_info_get (const char *gl_library)
+{
+ glitz_egl_thread_info_t *thread_info;
+ void *p;
+
+ if (!tsd_initialized) {
+ pthread_key_create (&info_tsd, _tsd_destroy);
+ tsd_initialized = 1;
+ }
+
+ p = pthread_getspecific (info_tsd);
+
+ if (p == NULL) {
+ thread_info = malloc (sizeof (glitz_egl_thread_info_t));
+ _glitz_egl_thread_info_init (thread_info);
+
+ pthread_setspecific (info_tsd, thread_info);
+ } else
+ thread_info = (glitz_egl_thread_info_t *) p;
+
+ if (gl_library) {
+ int len = strlen (gl_library);
+
+ if (thread_info->gl_library) {
+ free (thread_info->gl_library);
+ thread_info->gl_library = NULL;
+ }
+
+ thread_info->gl_library = malloc (len + 1);
+ if (thread_info->gl_library) {
+ memcpy (thread_info->gl_library, gl_library, len);
+ thread_info->gl_library[len] = '\0';
+ }
+ }
+
+ return thread_info;
+}
+
+#else
+
+/* not thread safe */
+static glitz_egl_thread_info_t thread_info = {
+ NULL,
+ 0,
+ NULL,
+ NULL
+};
+
+static void
+_glitz_egl_thread_info_destroy (glitz_egl_thread_info_t *thread_info)
+{
+ if (thread_info)
+ _glitz_egl_thread_info_fini (thread_info);
+}
+
+static glitz_egl_thread_info_t *
+_glitz_egl_thread_info_get (const char *gl_library)
+{
+ if (gl_library) {
+ int len = strlen (gl_library);
+
+ if (thread_info.gl_library) {
+ free (thread_info.gl_library);
+ thread_info.gl_library = NULL;
+ }
+
+ thread_info.gl_library = malloc (len + 1);
+ if (thread_info.gl_library) {
+ memcpy (thread_info.gl_library, gl_library, len);
+ thread_info.gl_library[len] = '\0';
+ }
+ }
+
+ return &thread_info;
+}
+
+#endif
+
+static glitz_egl_display_info_t *
+_glitz_egl_display_info_get (EGLDisplay egl_display)
+{
+ glitz_egl_display_info_t *display_info;
+ glitz_egl_thread_info_t *thread_info = _glitz_egl_thread_info_get (NULL);
+ glitz_egl_display_info_t **displays = thread_info->displays;
+ int index, n_displays = thread_info->n_displays;
+
+ for (; n_displays; n_displays--, displays++)
+ if ((*displays)->egl_display == egl_display)
+ return *displays;
+
+ index = thread_info->n_displays++;
+
+ thread_info->displays =
+ realloc (thread_info->displays,
+ sizeof (glitz_egl_display_info_t *) * thread_info->n_displays);
+
+ display_info = malloc (sizeof (glitz_egl_display_info_t));
+ thread_info->displays[index] = display_info;
+
+ display_info->thread_info = thread_info;
+ display_info->egl_display = egl_display;
+ display_info->screens = NULL;
+ display_info->n_screens = 0;
+
+ return display_info;
+}
+
+static void
+_glitz_egl_display_destroy (glitz_egl_display_info_t *display_info)
+{
+ int i;
+
+ for (i = 0; i < display_info->n_screens; i++)
+ _glitz_egl_screen_destroy (display_info->screens[i]);
+
+ if (display_info->screens)
+ free (display_info->screens);
+
+ free (display_info);
+}
+
+glitz_egl_screen_info_t *
+glitz_egl_screen_info_get (EGLDisplay display,
+ EGLScreenMESA screen)
+{
+ glitz_egl_screen_info_t *screen_info;
+ glitz_egl_display_info_t *display_info =
+ _glitz_egl_display_info_get (display);
+ glitz_egl_screen_info_t **screens = display_info->screens;
+ int index, n_screens = display_info->n_screens;
+#if 0
+ int error_base, event_base;
+#endif
+
+ for (; n_screens; n_screens--, screens++)
+ if ((*screens)->screen == screen)
+ return *screens;
+
+ index = display_info->n_screens++;
+
+ display_info->screens =
+ realloc (display_info->screens,
+ sizeof (glitz_egl_screen_info_t *) * display_info->n_screens);
+
+ screen_info = malloc (sizeof (glitz_egl_screen_info_t));
+ display_info->screens[index] = screen_info;
+
+ screen_info->display_info = display_info;
+ screen_info->screen = screen;
+ screen_info->drawables = 0;
+ screen_info->formats = NULL;
+ screen_info->egl_config_ids = NULL;
+ screen_info->n_formats = 0;
+
+ screen_info->contexts = NULL;
+ screen_info->n_contexts = 0;
+
+ glitz_program_map_init (&screen_info->program_map);
+
+ screen_info->egl_root_context = (EGLContext) 0;
+ screen_info->egl_feature_mask = 0;
+#if 0
+ if (eglQueryExtension (display, &error_base, &event_base)) {
+ int major, minor;
+
+ if (eglQueryVersion (display, &major, &minor)) {
+ screen_info->egl_version = major + minor / 10.0f;
+ if (major > 1 || (major > 0 || minor >= 2)) {
+ glitz_egl_query_extensions (screen_info, screen_info->egl_version);
+ _glitz_egl_proc_address_lookup (screen_info);
+ glitz_egl_query_formats (screen_info);
+ }
+ }
+ }
+#endif
+ glitz_egl_query_extensions (screen_info, screen_info->egl_version);
+ glitz_egl_query_configs (screen_info);
+
+ screen_info->context_stack_size = 1;
+ screen_info->context_stack->drawable = NULL;
+ screen_info->context_stack->surface = NULL;
+ screen_info->context_stack->constraint = GLITZ_NONE;
+
+ return screen_info;
+}
+
+static void
+_glitz_egl_screen_destroy (glitz_egl_screen_info_t *screen_info)
+{
+ EGLDisplay egl_display = screen_info->display_info->egl_display;
+ int i;
+
+ if (screen_info->egl_root_context)
+ eglMakeCurrent (egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ for (i = 0; i < screen_info->n_contexts; i++)
+ glitz_egl_context_destroy (screen_info, screen_info->contexts[i]);
+
+ free (screen_info->contexts);
+ free (screen_info->formats);
+ free (screen_info->egl_config_ids);
+ free (screen_info);
+}
+
+void
+glitz_egl_init (const char *gl_library)
+{
+ _glitz_egl_thread_info_get (gl_library);
+}
+slim_hidden_def(glitz_egl_init);
+
+void
+glitz_egl_fini (void)
+{
+ glitz_egl_thread_info_t *info = _glitz_egl_thread_info_get (NULL);
+
+ _glitz_egl_thread_info_destroy (info);
+}
+slim_hidden_def(glitz_egl_fini);
diff --git a/src/egl/glitz_egl_pbuffer.c b/src/egl/glitz_egl_pbuffer.c
new file mode 100644
index 0000000..cfe147a
--- /dev/null
+++ b/src/egl/glitz_egl_pbuffer.c
@@ -0,0 +1,67 @@
+/*
+ * 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"
+
+EGLSurface
+glitz_egl_pbuffer_create (glitz_egl_screen_info_t *screen_info,
+ EGLConfig egl_config,
+ int width,
+ int height)
+{
+ if (egl_config) {
+ int attributes[9];
+
+ attributes[0] = EGL_WIDTH;
+ attributes[1] = width;
+
+ attributes[2] = EGL_HEIGHT;
+ attributes[3] = height;
+#if 0
+ attributes[4] = EGL_LARGEST_PBUFFER;
+ attributes[5] = 0;
+
+ attributes[6] = EGL_PRESERVED_CONTENTS;
+ attributes[7] = 1;
+ attributes[8] = 0;
+#endif
+ return
+ eglCreatePbufferSurface(screen_info->display_info->egl_display,
+ egl_config, attributes);
+ } else
+ return (EGLSurface) 0;
+}
+
+void
+glitz_egl_pbuffer_destroy (glitz_egl_screen_info_t *screen_info,
+ EGLSurface egl_pbuffer)
+{
+ eglDestroySurface(screen_info->display_info->egl_display,
+ egl_pbuffer);
+}
diff --git a/src/egl/glitz_egl_surface.c b/src/egl/glitz_egl_surface.c
new file mode 100644
index 0000000..4afdd7a
--- /dev/null
+++ b/src/egl/glitz_egl_surface.c
@@ -0,0 +1,203 @@
+/*
+ * 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"
+
+static glitz_egl_surface_t *
+_glitz_egl_create_surface (glitz_egl_screen_info_t *screen_info,
+ glitz_egl_context_t *context,
+ glitz_drawable_format_t *format,
+ EGLSurface egl_surface,
+ int width,
+ int height)
+{
+ glitz_egl_surface_t *surface;
+
+ if (width <= 0 || height <= 0)
+ return NULL;
+
+ surface = (glitz_egl_surface_t *) malloc (sizeof (glitz_egl_surface_t));
+ if (surface == NULL)
+ return NULL;
+
+ surface->base.ref_count = 1;
+ surface->screen_info = screen_info;
+ surface->context = context;
+ surface->egl_surface = egl_surface;
+ surface->base.format = format;
+ surface->base.backend = &context->backend;
+
+ glitz_drawable_update_size (&surface->base, width, height);
+
+ if (!context->initialized) {
+ glitz_egl_push_current (surface, NULL, GLITZ_CONTEXT_CURRENT);
+ glitz_egl_pop_current (surface);
+ }
+
+ if (width > context->max_viewport_dims[0] ||
+ height > context->max_viewport_dims[1]) {
+ free (surface);
+ return NULL;
+ }
+
+ screen_info->drawables++;
+
+ return surface;
+}
+
+static glitz_drawable_t *
+_glitz_egl_create_pbuffer_surface (glitz_egl_screen_info_t *screen_info,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height)
+{
+ glitz_egl_surface_t *surface;
+ glitz_egl_context_t *context;
+ EGLSurface egl_pbuffer;
+
+ if (!format->types.pbuffer)
+ return NULL;
+
+ context = glitz_egl_context_get (screen_info, format);
+ if (!context)
+ return NULL;
+
+ egl_pbuffer = glitz_egl_pbuffer_create (screen_info, context->egl_config,
+ (int) width, (int) height);
+ if (!egl_pbuffer)
+ return NULL;
+
+ surface = _glitz_egl_create_surface (screen_info, context, format,
+ egl_pbuffer,
+ width, height);
+ if (!surface) {
+ glitz_egl_pbuffer_destroy (screen_info, egl_pbuffer);
+ return NULL;
+ }
+
+ return &surface->base;
+}
+
+glitz_drawable_t *
+glitz_egl_create_pbuffer (void *abstract_templ,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height)
+{
+ glitz_egl_surface_t *templ = (glitz_egl_surface_t *) abstract_templ;
+
+ return _glitz_egl_create_pbuffer_surface (templ->screen_info, format,
+ width, height);
+}
+
+glitz_drawable_t *
+glitz_egl_create_window_surface (EGLDisplay display,
+ EGLScreenMESA screen,
+ glitz_drawable_format_t *format,
+ NativeWindowType window,
+ unsigned int width,
+ unsigned int height)
+{
+ glitz_egl_surface_t *surface;
+ glitz_egl_screen_info_t *screen_info;
+ glitz_egl_context_t *context;
+
+ screen_info = glitz_egl_screen_info_get (display, screen);
+ if (!screen_info)
+ return NULL;
+
+ context = glitz_egl_context_get (screen_info, format);
+ if (!context)
+ return NULL;
+
+ surface = _glitz_egl_create_surface (screen_info, context, format,
+ window,
+ width, height);
+ if (!surface)
+ return NULL;
+
+ return &surface->base;
+}
+slim_hidden_def(glitz_egl_create_window_surface);
+
+glitz_drawable_t *
+glitz_egl_create_pbuffer_surface (EGLDisplay display,
+ EGLScreenMESA screen,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height)
+{
+ glitz_egl_screen_info_t *screen_info;
+
+ screen_info = glitz_egl_screen_info_get (display, screen);
+ if (!screen_info)
+ return NULL;
+
+ return _glitz_egl_create_pbuffer_surface (screen_info, format,
+ width, height);
+}
+slim_hidden_def(glitz_egl_create_pbuffer_surface);
+
+void
+glitz_egl_destroy (void *abstract_drawable)
+{
+ EGLint value;
+ glitz_egl_surface_t *surface = (glitz_egl_surface_t *) abstract_drawable;
+
+ surface->screen_info->drawables--;
+ if (surface->screen_info->drawables == 0) {
+ /*
+ * Last drawable? We have to destroy all fragment programs as this may
+ * be our last chance to have a context current.
+ */
+ glitz_egl_push_current (abstract_drawable, NULL, GLITZ_CONTEXT_CURRENT);
+ glitz_program_map_fini (&surface->base.backend->gl,
+ &surface->screen_info->program_map);
+ glitz_egl_pop_current (abstract_drawable);
+ }
+
+ if (eglGetCurrentSurface ( 0 ) == surface->egl_surface)
+ eglMakeCurrent (surface->screen_info->display_info->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ eglQuerySurface (surface->screen_info->display_info->egl_display, surface->egl_surface,
+ EGL_SURFACE_TYPE, &value);
+ if (value == EGL_PBUFFER_BIT)
+ glitz_egl_pbuffer_destroy (surface->screen_info, surface->egl_surface);
+
+ free (surface);
+}
+
+void
+glitz_egl_swap_buffers (void *abstract_drawable)
+{
+ glitz_egl_surface_t *surface = (glitz_egl_surface_t *) abstract_drawable;
+
+ eglSwapBuffers (surface->screen_info->display_info->egl_display,
+ surface->egl_surface);
+}
diff --git a/src/egl/glitz_eglext.h b/src/egl/glitz_eglext.h
new file mode 100644
index 0000000..49c2721
--- /dev/null
+++ b/src/egl/glitz_eglext.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2004 David Reveman, Peter Nilsson
+ *
+ * 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 names of
+ * David Reveman and Peter Nilsson not be used in advertising or
+ * publicity pertaining to distribution of the software without
+ * specific, written prior permission. David Reveman and Peter Nilsson
+ * makes no representations about the suitability of this software for
+ * any purpose. It is provided "as is" without express or implied warranty.
+ *
+ * DAVID REVEMAN AND PETER NILSSON DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DAVID REVEMAN AND
+ * PETER NILSSON 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.
+ *
+ * Authors: David Reveman <davidr@novell.com>
+ * Peter Nilsson <c99pnn@cs.umu.se>
+ */
+
+#ifndef GLITZ_EGLEXT_H_INCLUDED
+#define GLITZ_EGLEXT_H_INCLUDED
+
+
+typedef glitz_function_pointer_t (* glitz_egl_get_proc_address_t)
+ (const glitz_gl_ubyte_t *);
+typedef EGLConfig *(* glitz_egl_get_configs_t)
+ (EGLDisplay egl_display, EGLScreenMESA egl_screen, int *n_elements);
+typedef int (* glitz_egl_get_config_attrib_t)
+ (EGLDisplay egl_display, EGLConfig egl_config, int attribute, int *value);
+typedef EGLSurface (* glitz_egl_create_pbuffer_t)
+ (EGLDisplay egl_display, EGLConfig egl_config, const int *attrib_list);
+typedef void (* glitz_egl_destroy_pbuffer_t)
+ (EGLDisplay egl_display, EGLSurface egl_pbuffer);
+typedef void (* glitz_egl_query_drawable_t)
+ (EGLDisplay egl_display, EGLSurface egl_surface,
+ int attribute, unsigned int *value);
+typedef EGLBoolean (* glitz_egl_make_context_current_t)
+ (EGLDisplay egl_display, EGLSurface egl_draw, EGLSurface egl_read, EGLContext egl_ctx);
+typedef EGLContext (* glitz_egl_create_new_context_t)
+ (EGLDisplay egl_display, EGLConfig egl_config, int render_type,
+ EGLContext egl_share_list, EGLBoolean direct);
+
+typedef EGLBoolean *(* glitz_egl_bind_tex_image_t)
+ (EGLDisplay egl_display, EGLSurface egl_pbuffer, int buffer);
+typedef EGLBoolean (* glitz_egl_release_tex_image_t)
+ (EGLDisplay egl_display, EGLSurface egl_pbuffer, int buffer);
+
+#endif /* GLITZ_EGLEXT_H_INCLUDED */
diff --git a/src/egl/glitz_eglint.h b/src/egl/glitz_eglint.h
new file mode 100644
index 0000000..7a61488
--- /dev/null
+++ b/src/egl/glitz_eglint.h
@@ -0,0 +1,171 @@
+/*
+ * 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>
+ */
+
+#ifndef GLITZ_EGLINT_H_INCLUDED
+#define GLITZ_EGLINT_H_INCLUDED
+
+#include "glitz.h"
+#include "glitzint.h"
+
+#include "glitz-egl.h"
+
+#include "glitz_eglext.h"
+
+#define GLITZ_EGL_FEATURE_MAKE_CURRENT_READ_MASK (1L << 2)
+#define GLITZ_EGL_FEATURE_GET_PROC_ADDRESS_MASK (1L << 3)
+#define GLITZ_EGL_FEATURE_MULTISAMPLE_MASK (1L << 4)
+#define GLITZ_EGL_FEATURE_PBUFFER_MULTISAMPLE_MASK (1L << 5)
+
+typedef struct _glitz_egl_surface glitz_egl_surface_t;
+typedef struct _glitz_egl_screen_info_t glitz_egl_screen_info_t;
+typedef struct _glitz_egl_display_info_t glitz_egl_display_info_t;
+
+typedef struct _glitz_egl_thread_info_t {
+ glitz_egl_display_info_t **displays;
+ int n_displays;
+ char *gl_library;
+ void *dlhand;
+ glitz_context_t *cctx;
+} glitz_egl_thread_info_t;
+
+struct _glitz_egl_display_info_t {
+ glitz_egl_thread_info_t *thread_info;
+ EGLDisplay egl_display;
+ glitz_egl_screen_info_t **screens;
+ int n_screens;
+};
+
+typedef struct _glitz_egl_context_info_t {
+ glitz_egl_surface_t *drawable;
+ glitz_surface_t *surface;
+ glitz_constraint_t constraint;
+} glitz_egl_context_info_t;
+
+typedef struct _glitz_egl_context_t {
+ glitz_context_t base;
+ EGLContext egl_context;
+ glitz_format_id_t id;
+ EGLConfig egl_config;
+ glitz_backend_t backend;
+ glitz_gl_int_t max_viewport_dims[2];
+ glitz_gl_int_t max_texture_2d_size;
+ glitz_gl_int_t max_texture_rect_size;
+ glitz_bool_t initialized;
+} glitz_egl_context_t;
+
+struct _glitz_egl_screen_info_t {
+ glitz_egl_display_info_t *display_info;
+ int screen;
+ int drawables;
+ glitz_drawable_format_t *formats;
+ EGLConfig *egl_config_ids;
+ int n_formats;
+ glitz_egl_context_t **contexts;
+ int n_contexts;
+ glitz_egl_context_info_t context_stack[GLITZ_CONTEXT_STACK_SIZE];
+ int context_stack_size;
+ EGLContext egl_root_context;
+ unsigned long egl_feature_mask;
+ glitz_gl_float_t egl_version;
+ glitz_program_map_t program_map;
+};
+
+struct _glitz_egl_surface {
+ glitz_drawable_t base;
+
+ glitz_egl_screen_info_t *screen_info;
+ glitz_egl_context_t *context;
+ EGLSurface egl_surface;
+};
+
+extern void __internal_linkage
+glitz_egl_query_extensions (glitz_egl_screen_info_t *screen_info,
+ glitz_gl_float_t egl_version);
+
+extern glitz_egl_screen_info_t __internal_linkage *
+glitz_egl_screen_info_get (EGLDisplay egl_display,
+ EGLScreenMESA egl_screen);
+
+extern glitz_function_pointer_t __internal_linkage
+glitz_egl_get_proc_address (const char *name,
+ void *closure);
+
+extern glitz_egl_context_t __internal_linkage *
+glitz_egl_context_get (glitz_egl_screen_info_t *screen_info,
+ glitz_drawable_format_t *format);
+
+extern void __internal_linkage
+glitz_egl_context_destroy (glitz_egl_screen_info_t *screen_info,
+ glitz_egl_context_t *context);
+
+extern void __internal_linkage
+glitz_egl_query_configs (glitz_egl_screen_info_t *screen_info);
+
+extern EGLSurface __internal_linkage
+glitz_egl_pbuffer_create (glitz_egl_screen_info_t *screen_info,
+ EGLConfig egl_config,
+ int width,
+ int height);
+
+extern void __internal_linkage
+glitz_egl_pbuffer_destroy (glitz_egl_screen_info_t *screen_info,
+ EGLSurface egl_pbuffer);
+
+extern glitz_drawable_t __internal_linkage *
+glitz_egl_create_pbuffer (void *abstract_templ,
+ glitz_drawable_format_t *format,
+ unsigned int width,
+ unsigned int height);
+
+extern void __internal_linkage
+glitz_egl_push_current (void *abstract_drawable,
+ glitz_surface_t *surface,
+ glitz_constraint_t constraint);
+
+extern glitz_surface_t __internal_linkage *
+glitz_egl_pop_current (void *abstract_drawable);
+
+void
+glitz_egl_make_current (void *abstract_drawable,
+ glitz_constraint_t constraint);
+
+extern glitz_status_t __internal_linkage
+glitz_egl_make_current_read (void *abstract_surface);
+
+extern void __internal_linkage
+glitz_egl_destroy (void *abstract_drawable);
+
+extern void __internal_linkage
+glitz_egl_swap_buffers (void *abstract_drawable);
+
+/* Avoid unnecessary PLT entries. */
+
+slim_hidden_proto(glitz_egl_init)
+slim_hidden_proto(glitz_egl_fini)
+slim_hidden_proto(glitz_egl_find_config)
+slim_hidden_proto(glitz_egl_create_window_surface)
+slim_hidden_proto(glitz_egl_create_pbuffer_surface)
+
+#endif /* GLITZ_EGLINT_H_INCLUDED */