summaryrefslogtreecommitdiff
path: root/src/egl/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/drivers')
-rw-r--r--src/egl/drivers/dri2/Makefile19
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c951
-rw-r--r--src/egl/drivers/glx/egl_glx.c39
-rw-r--r--src/egl/drivers/xdri/Makefile28
-rw-r--r--src/egl/drivers/xdri/driinit.c85
-rw-r--r--src/egl/drivers/xdri/driinit.h9
-rw-r--r--src/egl/drivers/xdri/egl_xdri.c655
-rw-r--r--src/egl/drivers/xdri/glxinit.c682
-rw-r--r--src/egl/drivers/xdri/glxinit.h11
9 files changed, 979 insertions, 1500 deletions
diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile
new file mode 100644
index 0000000000..95f9574531
--- /dev/null
+++ b/src/egl/drivers/dri2/Makefile
@@ -0,0 +1,19 @@
+# src/egl/drivers/dri2/Makefile
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+EGL_DRIVER = egl_dri2.so
+EGL_SOURCES = egl_dri2.c
+
+EGL_INCLUDES = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/egl/main \
+ -I$(TOP)/src/mesa \
+ -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
+ $(shell pkg-config --cflags xcb-dri2 xcb-xfixes x11-xcb libdrm)
+
+EGL_CFLAGS =
+EGL_LIBS = $(shell pkg-config --libs xcb-dri2 xcb-xfixes x11-xcb libdrm)
+
+include ../Makefile.template
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
new file mode 100644
index 0000000000..d53f137530
--- /dev/null
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -0,0 +1,951 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Kristian Høgsberg <krh@bitplanet.net>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <limits.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <xf86drm.h>
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#include <xcb/xcb.h>
+#include <xcb/dri2.h>
+#include <xcb/xfixes.h>
+#include <X11/Xlib-xcb.h>
+
+#include <glapi/glapi.h>
+#include "eglconfigutil.h"
+#include "eglconfig.h"
+#include "eglcontext.h"
+#include "egldisplay.h"
+#include "egldriver.h"
+#include "eglcurrent.h"
+#include "egllog.h"
+#include "eglsurface.h"
+
+struct dri2_egl_driver
+{
+ _EGLDriver base;
+};
+
+struct dri2_egl_display
+{
+ xcb_connection_t *conn;
+ int dri2_major;
+ int dri2_minor;
+ __DRIscreen *dri_screen;
+ void *driver;
+ __DRIcoreExtension *core;
+ __DRIdri2Extension *dri2;
+ __DRI2flushExtension *flush;
+ int fd;
+
+ __DRIdri2LoaderExtension loader_extension;
+ const __DRIextension *extensions[2];
+};
+
+struct dri2_egl_context
+{
+ _EGLContext base;
+ __DRIcontext *dri_context;
+};
+
+struct dri2_egl_surface
+{
+ _EGLSurface base;
+ __DRIdrawable *dri_drawable;
+ xcb_drawable_t drawable;
+ __DRIbuffer buffers[5];
+ int buffer_count;
+ xcb_xfixes_region_t region;
+ int have_back;
+ int have_fake_front;
+ int swap_interval;
+};
+
+struct dri2_egl_config
+{
+ _EGLConfig base;
+ const __DRIconfig *dri_config;
+};
+
+/* standard typecasts */
+_EGL_DRIVER_STANDARD_TYPECASTS(dri2_egl)
+
+EGLint dri2_to_egl_attribute_map[] = {
+ 0,
+ EGL_BUFFER_SIZE, /* __DRI_ATTRIB_BUFFER_SIZE */
+ EGL_LEVEL, /* __DRI_ATTRIB_LEVEL */
+ EGL_RED_SIZE, /* __DRI_ATTRIB_RED_SIZE */
+ EGL_GREEN_SIZE, /* __DRI_ATTRIB_GREEN_SIZE */
+ EGL_BLUE_SIZE, /* __DRI_ATTRIB_BLUE_SIZE */
+ 0, /* __DRI_ATTRIB_LUMINANCE_SIZE */
+ EGL_ALPHA_SIZE, /* __DRI_ATTRIB_ALPHA_SIZE */
+ 0, /* __DRI_ATTRIB_ALPHA_MASK_SIZE */
+ EGL_DEPTH_SIZE, /* __DRI_ATTRIB_DEPTH_SIZE */
+ EGL_STENCIL_SIZE, /* __DRI_ATTRIB_STENCIL_SIZE */
+ 0, /* __DRI_ATTRIB_ACCUM_RED_SIZE */
+ 0, /* __DRI_ATTRIB_ACCUM_GREEN_SIZE */
+ 0, /* __DRI_ATTRIB_ACCUM_BLUE_SIZE */
+ 0, /* __DRI_ATTRIB_ACCUM_ALPHA_SIZE */
+ EGL_SAMPLE_BUFFERS, /* __DRI_ATTRIB_SAMPLE_BUFFERS */
+ EGL_SAMPLES, /* __DRI_ATTRIB_SAMPLES */
+ 0, /* __DRI_ATTRIB_RENDER_TYPE, */
+ 0, /* __DRI_ATTRIB_CONFIG_CAVEAT */
+ 0, /* __DRI_ATTRIB_CONFORMANT */
+ 0, /* __DRI_ATTRIB_DOUBLE_BUFFER */
+ 0, /* __DRI_ATTRIB_STEREO */
+ 0, /* __DRI_ATTRIB_AUX_BUFFERS */
+ 0, /* __DRI_ATTRIB_TRANSPARENT_TYPE */
+ 0, /* __DRI_ATTRIB_TRANSPARENT_INDEX_VALUE */
+ 0, /* __DRI_ATTRIB_TRANSPARENT_RED_VALUE */
+ 0, /* __DRI_ATTRIB_TRANSPARENT_GREEN_VALUE */
+ 0, /* __DRI_ATTRIB_TRANSPARENT_BLUE_VALUE */
+ 0, /* __DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE */
+ 0, /* __DRI_ATTRIB_FLOAT_MODE */
+ 0, /* __DRI_ATTRIB_RED_MASK */
+ 0, /* __DRI_ATTRIB_GREEN_MASK */
+ 0, /* __DRI_ATTRIB_BLUE_MASK */
+ 0, /* __DRI_ATTRIB_ALPHA_MASK */
+ EGL_MAX_PBUFFER_WIDTH, /* __DRI_ATTRIB_MAX_PBUFFER_WIDTH */
+ EGL_MAX_PBUFFER_HEIGHT, /* __DRI_ATTRIB_MAX_PBUFFER_HEIGHT */
+ EGL_MAX_PBUFFER_PIXELS, /* __DRI_ATTRIB_MAX_PBUFFER_PIXELS */
+ 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH */
+ 0, /* __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT */
+ 0, /* __DRI_ATTRIB_VISUAL_SELECT_GROUP */
+ 0, /* __DRI_ATTRIB_SWAP_METHOD */
+ EGL_MAX_SWAP_INTERVAL, /* __DRI_ATTRIB_MAX_SWAP_INTERVAL */
+ EGL_MIN_SWAP_INTERVAL, /* __DRI_ATTRIB_MIN_SWAP_INTERVAL */
+ 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGB */
+ 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */
+ 0, /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */
+ 0, /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */
+ 0, /* __DRI_ATTRIB_YINVERTED */
+};
+
+static void
+dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id)
+{
+ struct dri2_egl_config *conf;
+ struct dri2_egl_display *dri2_dpy;
+ unsigned int attrib, value, double_buffer;
+ EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
+ int i;
+
+ dri2_dpy = disp->DriverData;
+ conf = malloc(sizeof *conf);
+ if (conf == NULL)
+ return;
+
+ conf->dri_config = dri_config;
+ _eglInitConfig(&conf->base, disp, id);
+
+ i = 0;
+ while (dri2_dpy->core->indexConfigAttrib(dri_config, i++, &attrib, &value)) {
+ switch (attrib) {
+ case 0:
+ break;
+
+ case __DRI_ATTRIB_RENDER_TYPE:
+ if (value & __DRI_ATTRIB_RGBA_BIT)
+ value = EGL_RGB_BUFFER;
+ else if (value & __DRI_ATTRIB_LUMINANCE_BIT)
+ value = EGL_LUMINANCE_BUFFER;
+ else
+ /* not valid */;
+ _eglSetConfigKey(&conf->base, EGL_COLOR_BUFFER_TYPE, value);
+ break;
+
+ case __DRI_ATTRIB_CONFIG_CAVEAT:
+ if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
+ value = EGL_NON_CONFORMANT_CONFIG;
+ else if (value & __DRI_ATTRIB_SLOW_BIT)
+ value = EGL_SLOW_CONFIG;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&conf->base, EGL_CONFIG_CAVEAT, value);
+ break;
+
+ case __DRI_ATTRIB_BIND_TO_TEXTURE_RGB:
+ bind_to_texture_rgb = value;
+ break;
+
+ case __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA:
+ bind_to_texture_rgba = value;
+ break;
+
+ case __DRI_ATTRIB_DOUBLE_BUFFER:
+ double_buffer = value;
+ break;
+
+ default:
+ key = dri2_to_egl_attribute_map[attrib];
+ if (key != 0)
+ _eglSetConfigKey(&conf->base, key, value);
+ break;
+ }
+ }
+
+ /* EGL_SWAP_BEHAVIOR_PRESERVED_BIT */
+
+ if (double_buffer) {
+ /* FIXME: Figure out how to get the visual ID and types */
+ _eglSetConfigKey(&conf->base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
+ _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_ID, 0x21);
+ _eglSetConfigKey(&conf->base, EGL_NATIVE_VISUAL_TYPE,
+ XCB_VISUAL_CLASS_TRUE_COLOR);
+ } else {
+ _eglSetConfigKey(&conf->base,
+ EGL_SURFACE_TYPE, EGL_PIXMAP_BIT | EGL_PBUFFER_BIT);
+ _eglSetConfigKey(&conf->base,
+ EGL_BIND_TO_TEXTURE_RGB, bind_to_texture_rgb);
+ _eglSetConfigKey(&conf->base,
+ EGL_BIND_TO_TEXTURE_RGBA, bind_to_texture_rgba);
+ }
+
+ /* EGL_OPENGL_ES_BIT, EGL_OPENVG_BIT, EGL_OPENGL_ES2_BIT */
+ _eglSetConfigKey(&conf->base, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT);
+ _eglSetConfigKey(&conf->base, EGL_CONFORMANT, EGL_OPENGL_BIT);
+
+ if (!_eglValidateConfig(&conf->base, EGL_FALSE)) {
+ _eglLog(_EGL_DEBUG, "DRI2: failed to validate config %d", id);
+ free(conf);
+ return;
+ }
+
+ _eglAddConfig(disp, &conf->base);
+}
+
+/**
+ * Process list of buffer received from the server
+ *
+ * Processes the list of buffers received in a reply from the server to either
+ * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
+ */
+static void
+dri2_process_buffers(struct dri2_egl_surface *dri2_surf,
+ xcb_dri2_dri2_buffer_t *buffers, unsigned count)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ xcb_rectangle_t rectangle;
+ int i;
+
+ dri2_surf->buffer_count = count;
+ dri2_surf->have_fake_front = 0;
+ dri2_surf->have_back = 0;
+
+ /* This assumes the DRI2 buffer attachment tokens matches the
+ * __DRIbuffer tokens. */
+ for (i = 0; i < count; i++) {
+ dri2_surf->buffers[i].attachment = buffers[i].attachment;
+ dri2_surf->buffers[i].name = buffers[i].name;
+ dri2_surf->buffers[i].pitch = buffers[i].pitch;
+ dri2_surf->buffers[i].cpp = buffers[i].cpp;
+ dri2_surf->buffers[i].flags = buffers[i].flags;
+ if (dri2_surf->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)
+ dri2_surf->have_fake_front = 1;
+ if (dri2_surf->buffers[i].attachment == __DRI_BUFFER_BACK_LEFT)
+ dri2_surf->have_back = 1;
+ }
+
+ if (dri2_surf->region != XCB_NONE)
+ xcb_xfixes_destroy_region(dri2_dpy->conn, dri2_surf->region);
+
+ rectangle.x = 0;
+ rectangle.y = 0;
+ rectangle.width = dri2_surf->base.Width;
+ rectangle.height = dri2_surf->base.Height;
+ dri2_surf->region = xcb_generate_id(dri2_dpy->conn);
+ xcb_xfixes_create_region(dri2_dpy->conn, dri2_surf->region, 1, &rectangle);
+}
+
+static __DRIbuffer *
+dri2_get_buffers(__DRIdrawable * driDrawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *out_count, void *loaderPrivate)
+{
+ struct dri2_egl_surface *dri2_surf = loaderPrivate;
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ xcb_dri2_dri2_buffer_t *buffers;
+ xcb_dri2_get_buffers_reply_t *reply;
+ xcb_dri2_get_buffers_cookie_t cookie;
+
+ cookie = xcb_dri2_get_buffers_unchecked (dri2_dpy->conn,
+ dri2_surf->drawable,
+ count, count, attachments);
+ reply = xcb_dri2_get_buffers_reply (dri2_dpy->conn, cookie, NULL);
+ buffers = xcb_dri2_get_buffers_buffers (reply);
+ if (buffers == NULL)
+ return NULL;
+
+ *out_count = reply->count;
+ dri2_surf->base.Width = *width = reply->width;
+ dri2_surf->base.Height = *height = reply->height;
+ dri2_process_buffers(dri2_surf, buffers, *out_count);
+
+ free(reply);
+
+ return dri2_surf->buffers;
+}
+
+static void
+dri2_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
+{
+ /* FIXME: Does EGL support front buffer rendering at all? */
+
+#if 0
+ struct dri2_egl_surface *dri2_surf = loaderPrivate;
+
+ dri2WaitGL(dri2_surf);
+#endif
+}
+
+static __DRIbuffer *
+dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *out_count, void *loaderPrivate)
+{
+ struct dri2_egl_surface *dri2_surf = loaderPrivate;
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ xcb_dri2_dri2_buffer_t *buffers;
+ xcb_dri2_get_buffers_with_format_reply_t *reply;
+ xcb_dri2_get_buffers_with_format_cookie_t cookie;
+ xcb_dri2_attach_format_t *format_attachments;
+
+ format_attachments = (xcb_dri2_attach_format_t *) attachments;
+ cookie = xcb_dri2_get_buffers_with_format_unchecked (dri2_dpy->conn,
+ dri2_surf->drawable,
+ count, count,
+ format_attachments);
+
+ reply = xcb_dri2_get_buffers_with_format_reply (dri2_dpy->conn,
+ cookie, NULL);
+ if (reply == NULL)
+ return NULL;
+
+ buffers = xcb_dri2_get_buffers_with_format_buffers (reply);
+ dri2_surf->base.Width = *width = reply->width;
+ dri2_surf->base.Height = *height = reply->height;
+ *out_count = reply->count;
+ dri2_process_buffers(dri2_surf, buffers, *out_count);
+
+ free(reply);
+
+ return dri2_surf->buffers;
+}
+
+#ifdef GLX_USE_TLS
+static const char dri_driver_format[] = "%.*s/tls/%.*s_dri.so";
+#else
+static const char dri_driver_format[] = "%.*s/%.*s_dri.so";
+#endif
+
+static const char dri_driver_path[] = DEFAULT_DRIVER_DIR;
+
+/**
+ * Called via eglInitialize(), GLX_drv->API.Initialize().
+ */
+static EGLBoolean
+dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
+ EGLint *major, EGLint *minor)
+{
+ const __DRIextension **extensions;
+ const __DRIconfig **driver_configs;
+ struct dri2_egl_display *dri2_dpy;
+ char path[PATH_MAX], *search_paths, *p, *next, *end;
+ xcb_xfixes_query_version_reply_t *xfixes_query;
+ xcb_xfixes_query_version_cookie_t xfixes_query_cookie;
+ xcb_dri2_query_version_reply_t *dri2_query;
+ xcb_dri2_query_version_cookie_t dri2_query_cookie;
+ xcb_dri2_connect_reply_t *connect = NULL;
+ xcb_dri2_connect_cookie_t connect_cookie;
+ xcb_dri2_authenticate_reply_t *authenticate;
+ xcb_dri2_authenticate_cookie_t authenticate_cookie;
+ xcb_generic_error_t *error;
+ drm_magic_t magic;
+ xcb_screen_iterator_t s;
+ int i;
+
+ dri2_dpy = malloc(sizeof *dri2_dpy);
+ if (!dri2_dpy)
+ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+ disp->DriverData = (void *) dri2_dpy;
+ dri2_dpy->conn = XGetXCBConnection(disp->NativeDisplay);
+ if (!dri2_dpy->conn) {
+ dri2_dpy->conn = xcb_connect(0, 0);
+ if (!dri2_dpy->conn) {
+ _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
+ free(dri2_dpy);
+ return EGL_FALSE;
+ }
+ }
+
+ xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_xfixes_id);
+ xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri2_id);
+
+ xfixes_query_cookie = xcb_xfixes_query_version(dri2_dpy->conn,
+ XCB_XFIXES_MAJOR_VERSION,
+ XCB_XFIXES_MINOR_VERSION);
+
+ dri2_query_cookie = xcb_dri2_query_version (dri2_dpy->conn,
+ XCB_DRI2_MAJOR_VERSION,
+ XCB_DRI2_MINOR_VERSION);
+
+ s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
+ connect_cookie = xcb_dri2_connect_unchecked (dri2_dpy->conn,
+ s.data->root,
+ XCB_DRI2_DRIVER_TYPE_DRI);
+
+ xfixes_query =
+ xcb_xfixes_query_version_reply (dri2_dpy->conn,
+ xfixes_query_cookie, &error);
+ if (xfixes_query == NULL ||
+ error != NULL || xfixes_query->major_version < 2) {
+ _eglLog(_EGL_FATAL, "DRI2: failed to query xfixes version");
+ free(error);
+ goto handle_error;
+ }
+ free(xfixes_query);
+
+ dri2_query =
+ xcb_dri2_query_version_reply (dri2_dpy->conn, dri2_query_cookie, &error);
+ if (dri2_query == NULL || error != NULL) {
+ _eglLog(_EGL_FATAL, "DRI2: failed to query version");
+ free(error);
+ goto handle_error;
+ }
+ dri2_dpy->dri2_major = dri2_query->major_version;
+ dri2_dpy->dri2_minor = dri2_query->minor_version;
+ free(dri2_query);
+
+ connect = xcb_dri2_connect_reply (dri2_dpy->conn, connect_cookie, NULL);
+ if (connect->driver_name_length == 0 && connect->device_name_length == 0) {
+ _eglLog(_EGL_FATAL, "DRI2: failed to authenticate");
+ goto handle_error;
+ }
+
+ search_paths = NULL;
+ if (geteuid() == getuid()) {
+ /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
+ search_paths = getenv("LIBGL_DRIVERS_PATH");
+ }
+ if (search_paths == NULL)
+ search_paths = DEFAULT_DRIVER_DIR;
+
+ dri2_dpy->driver = NULL;
+ end = search_paths + strlen(search_paths);
+ for (p = search_paths; p < end && dri2_dpy->driver == NULL; p = next + 1) {
+ int path_len;
+
+ next = strchr(p, ':');
+ if (next == NULL)
+ next = end;
+ path_len = next - p;
+
+ snprintf(path, sizeof path,
+ dri_driver_format,
+ path_len, p,
+ xcb_dri2_connect_driver_name_length (connect),
+ xcb_dri2_connect_driver_name (connect));
+
+ dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ }
+
+ if (dri2_dpy->driver == NULL) {
+ _eglLog(_EGL_FATAL,
+ "DRI2: failed to open any driver (search paths %s)",
+ search_paths);
+ goto handle_error;
+ }
+
+ _eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path);
+ extensions = dlsym(dri2_dpy->driver, __DRI_DRIVER_EXTENSIONS);
+ if (extensions == NULL) {
+ _eglLog(_EGL_FATAL,
+ "DRI2: driver exports no extensions (%s)", dlerror());
+ goto handle_error;
+ }
+
+ for (i = 0; extensions[i]; i++) {
+ if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
+ dri2_dpy->core = (__DRIcoreExtension *) extensions[i];
+ if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
+ dri2_dpy->dri2 = (__DRIdri2Extension *) extensions[i];
+ }
+
+ if (dri2_dpy->core == NULL) {
+ _eglLog(_EGL_FATAL, "DRI2: driver has no core extension");
+ goto handle_error;
+ }
+
+ if (dri2_dpy->dri2 == NULL) {
+ _eglLog(_EGL_FATAL, "DRI2: driver has no dri2 extension");
+ goto handle_error;
+ }
+
+ snprintf(path, sizeof path, "%.*s",
+ xcb_dri2_connect_device_name_length (connect),
+ xcb_dri2_connect_device_name (connect));
+ dri2_dpy->fd = open (path, O_RDWR);
+ if (dri2_dpy->fd == -1) {
+ _eglLog(_EGL_FATAL,
+ "DRI2: could not open %s (%s)", path, strerror(errno));
+ goto handle_error;
+ }
+
+ if (drmGetMagic(dri2_dpy->fd, &magic)) {
+ _eglLog(_EGL_FATAL, "DRI2: failed to get drm magic");
+ goto handle_error;
+ }
+
+ authenticate_cookie = xcb_dri2_authenticate_unchecked (dri2_dpy->conn,
+ s.data->root, magic);
+ authenticate = xcb_dri2_authenticate_reply (dri2_dpy->conn,
+ authenticate_cookie, NULL);
+ if (authenticate == NULL || !authenticate->authenticated) {
+ _eglLog(_EGL_FATAL, "DRI2: failed to authenticate");
+ goto handle_error;
+ }
+
+ if (dri2_dpy->dri2_minor >= 1) {
+ dri2_dpy->loader_extension.base.name = __DRI_DRI2_LOADER;
+ dri2_dpy->loader_extension.base.version = 3;
+ dri2_dpy->loader_extension.getBuffers = dri2_get_buffers;
+ dri2_dpy->loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
+ dri2_dpy->loader_extension.getBuffersWithFormat =
+ dri2_get_buffers_with_format;
+ } else {
+ dri2_dpy->loader_extension.base.name = __DRI_DRI2_LOADER;
+ dri2_dpy->loader_extension.base.version = 2;
+ dri2_dpy->loader_extension.getBuffers = dri2_get_buffers;
+ dri2_dpy->loader_extension.flushFrontBuffer = dri2_flush_front_buffer;
+ dri2_dpy->loader_extension.getBuffersWithFormat = NULL;
+ }
+
+ dri2_dpy->extensions[0] = &dri2_dpy->loader_extension.base;
+ dri2_dpy->extensions[1] = NULL;
+
+ dri2_dpy->dri_screen =
+ dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
+ &driver_configs, dri2_dpy);
+
+ if (dri2_dpy->dri_screen == NULL) {
+ _eglLog(_EGL_FATAL, "DRI2: failed to create dri screen");
+ free(dri2_dpy);
+ goto handle_error;
+ }
+
+ extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
+ for (i = 0; extensions[i]; i++) {
+ _eglLog(_EGL_DEBUG, "DRI2: found extension `%s'", extensions[i]->name);
+ if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0))
+ dri2_dpy->flush = (__DRI2flushExtension *) extensions[i];
+ }
+
+ if (dri2_dpy->flush == NULL) {
+ _eglLog(_EGL_FATAL, "DRI2: driver doesn't support the flush extension");
+ free(dri2_dpy);
+ goto handle_error;
+ }
+
+ for (i = 0; driver_configs[i]; i++)
+ dri2_add_config(disp, driver_configs[i], i + 1);
+ if (!disp->NumConfigs) {
+ _eglLog(_EGL_WARNING, "DRI2: failed to create any config");
+ goto handle_error;
+ }
+
+ disp->ClientAPIsMask = EGL_OPENGL_BIT;
+
+ /* we're supporting EGL 1.4 */
+ *major = 1;
+ *minor = 4;
+
+ free (connect);
+ return EGL_TRUE;
+
+ handle_error:
+ free(connect);
+ free(dri2_dpy);
+ return EGL_FALSE;
+}
+
+/**
+ * Called via eglTerminate(), drv->API.Terminate().
+ */
+static EGLBoolean
+dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ _eglReleaseDisplayResources(drv, disp);
+ _eglCleanupDisplay(disp);
+
+ close(dri2_dpy->fd);
+ dlclose(dri2_dpy->driver);
+ free(dri2_dpy);
+
+ disp->DriverData = NULL;
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * Called via eglCreateContext(), drv->API.CreateContext().
+ */
+static _EGLContext *
+dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
+ _EGLContext *share_list, const EGLint *attrib_list)
+{
+ struct dri2_egl_context *dri2_ctx;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_context *dri2_ctx_shared = dri2_egl_context(share_list);
+ struct dri2_egl_config *dri2_config = dri2_egl_config(conf);
+
+ dri2_ctx = malloc(sizeof *dri2_ctx);
+ if (!dri2_ctx) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateContext");
+ return NULL;
+ }
+
+ if (!_eglInitContext(&dri2_ctx->base, disp, conf, attrib_list)) {
+ free(dri2_ctx);
+ return NULL;
+ }
+
+ dri2_ctx->dri_context =
+ dri2_dpy->dri2->createNewContext(dri2_dpy->dri_screen,
+ dri2_config->dri_config,
+ dri2_ctx_shared ?
+ dri2_ctx_shared->dri_context : NULL,
+ dri2_ctx);
+
+ if (!dri2_ctx->dri_context) {
+ free(dri2_ctx);
+ return NULL;
+ }
+
+ return &dri2_ctx->base;
+}
+
+static EGLBoolean
+dri2_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
+
+ if (_eglIsSurfaceBound(surf))
+ return EGL_TRUE;
+
+ (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
+
+ xcb_dri2_destroy_drawable (dri2_dpy->conn, dri2_surf->drawable);
+
+ if (surf->Type == EGL_PBUFFER_BIT)
+ xcb_free_pixmap (dri2_dpy->conn, dri2_surf->drawable);
+
+ free(surf);
+
+ return EGL_TRUE;
+}
+
+/**
+ * Called via eglMakeCurrent(), drv->API.MakeCurrent().
+ */
+static EGLBoolean
+dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
+ _EGLSurface *rsurf, _EGLContext *ctx)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_dsurf = dri2_egl_surface(dsurf);
+ struct dri2_egl_surface *dri2_rsurf = dri2_egl_surface(rsurf);
+ struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+ __DRIdrawable *ddraw, *rdraw;
+ __DRIcontext *cctx;
+
+ /* bind the new context and return the "orphaned" one */
+ if (!_eglBindContext(&ctx, &dsurf, &rsurf))
+ return EGL_FALSE;
+
+ ddraw = (dri2_dsurf) ? dri2_dsurf->dri_drawable : NULL;
+ rdraw = (dri2_rsurf) ? dri2_rsurf->dri_drawable : NULL;
+ cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL;
+
+ if ((cctx == NULL && ddraw == NULL && rdraw == NULL) ||
+ dri2_dpy->core->bindContext(cctx, ddraw, rdraw)) {
+ if (dsurf && !_eglIsSurfaceLinked(dsurf))
+ dri2_destroy_surface(drv, disp, dsurf);
+ if (rsurf && rsurf != dsurf && !_eglIsSurfaceLinked(dsurf))
+ dri2_destroy_surface(drv, disp, rsurf);
+ if (ctx != NULL && !_eglIsContextLinked(ctx))
+ dri2_dpy->core->unbindContext(dri2_egl_context(ctx)->dri_context);
+
+ return EGL_TRUE;
+ } else {
+ _eglBindContext(&ctx, &dsurf, &rsurf);
+
+ return EGL_FALSE;
+ }
+}
+
+/**
+ * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
+ */
+static _EGLSurface *
+dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
+ _EGLConfig *conf, EGLNativeWindowType window,
+ const EGLint *attrib_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
+ struct dri2_egl_surface *dri2_surf;
+ xcb_get_geometry_cookie_t cookie;
+ xcb_get_geometry_reply_t *reply;
+ xcb_screen_iterator_t s;
+ xcb_generic_error_t *error;
+
+ dri2_surf = malloc(sizeof *dri2_surf);
+ if (!dri2_surf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
+ return NULL;
+ }
+
+ if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) {
+ free(dri2_surf);
+ return NULL;
+ }
+
+ dri2_surf->region = XCB_NONE;
+ if (type == EGL_PBUFFER_BIT) {
+ dri2_surf->drawable = xcb_generate_id(dri2_dpy->conn);
+ s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
+ xcb_create_pixmap(dri2_dpy->conn,
+ _eglGetConfigKey(conf, EGL_BUFFER_SIZE),
+ dri2_surf->drawable, s.data->root,
+ dri2_surf->base.Width, dri2_surf->base.Height);
+ } else {
+ dri2_surf->drawable = window;
+ }
+
+ dri2_surf->dri_drawable =
+ (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen,
+ dri2_conf->dri_config, dri2_surf);
+ if (dri2_surf == NULL) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
+ free(dri2_surf);
+ return NULL;
+ }
+
+ xcb_dri2_create_drawable (dri2_dpy->conn, dri2_surf->drawable);
+
+ cookie = xcb_get_geometry (dri2_dpy->conn, dri2_surf->drawable);
+ reply = xcb_get_geometry_reply (dri2_dpy->conn, cookie, &error);
+ if (reply == NULL || error != NULL) {
+ _eglError(EGL_BAD_ALLOC, "xcb_get_geometry");
+ free(dri2_surf);
+ free(error);
+ return NULL;
+ }
+ dri2_surf->base.Width = reply->width;
+ dri2_surf->base.Height = reply->height;
+ free(reply);
+
+ return &dri2_surf->base;
+}
+
+/**
+ * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
+ */
+static _EGLSurface *
+dri2_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLConfig *conf, EGLNativeWindowType window,
+ const EGLint *attrib_list)
+{
+ return dri2_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
+ window, attrib_list);
+}
+
+static _EGLSurface *
+dri2_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLConfig *conf, EGLNativePixmapType pixmap,
+ const EGLint *attrib_list)
+{
+ return dri2_create_surface(drv, disp, EGL_PIXMAP_BIT, conf,
+ pixmap, attrib_list);
+}
+
+static _EGLSurface *
+dri2_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLConfig *conf, const EGLint *attrib_list)
+{
+ return dri2_create_surface(drv, disp, EGL_PBUFFER_BIT, conf,
+ XCB_WINDOW_NONE, attrib_list);
+}
+
+static EGLBoolean
+dri2_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ xcb_dri2_copy_region_cookie_t cookie;
+
+ (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
+
+#if 0
+ /* FIXME: Add support for dri swapbuffers, that'll give us swap
+ * interval and page flipping (at least for fullscreen windows) as
+ * well as the page flip event. */
+#if __DRI2_FLUSH_VERSION >= 2
+ if (pdraw->psc->f)
+ (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable);
+#endif
+#endif
+
+ if (!dri2_surf->have_back)
+ return EGL_TRUE;
+
+ cookie = xcb_dri2_copy_region_unchecked(dri2_dpy->conn,
+ dri2_surf->drawable,
+ dri2_surf->region,
+ XCB_DRI2_ATTACHMENT_BUFFER_FRONT_LEFT,
+ XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT);
+ free(xcb_dri2_copy_region_reply(dri2_dpy->conn, cookie, NULL));
+
+ return EGL_TRUE;
+}
+
+/*
+ * Called from eglGetProcAddress() via drv->API.GetProcAddress().
+ */
+static _EGLProc
+dri2_get_proc_address(_EGLDriver *drv, const char *procname)
+{
+ /* FIXME: Do we need to support lookup of EGL symbols too? */
+
+ return (_EGLProc) _glapi_get_proc_address(procname);
+}
+
+static EGLBoolean
+dri2_wait_client(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(ctx->DrawSurface);
+
+ /* FIXME: If EGL allows frontbuffer rendering for window surfaces,
+ * we need to copy fake to real here.*/
+
+ (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
+
+ return EGL_TRUE;
+}
+
+static EGLBoolean
+dri2_wait_native(_EGLDriver *drv, _EGLDisplay *disp, EGLint engine)
+{
+ if (engine != EGL_CORE_NATIVE_ENGINE)
+ return _eglError(EGL_BAD_PARAMETER, "eglWaitNative");
+ /* glXWaitX(); */
+
+ return EGL_TRUE;
+}
+
+static void
+dri2_unload(_EGLDriver *drv)
+{
+ struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
+ free(dri2_drv);
+}
+
+static EGLBoolean
+dri2_copy_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
+ EGLNativePixmapType target)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
+ xcb_gcontext_t gc;
+
+ (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable);
+
+ gc = xcb_generate_id(dri2_dpy->conn);
+ xcb_create_gc(dri2_dpy->conn, gc, target, 0, NULL);
+ xcb_copy_area(dri2_dpy->conn,
+ dri2_surf->drawable,
+ target,
+ gc,
+ 0, 0,
+ 0, 0,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height);
+ xcb_free_gc(dri2_dpy->conn, gc);
+
+ return EGL_TRUE;
+}
+
+/**
+ * This is the main entrypoint into the driver, called by libEGL.
+ * Create a new _EGLDriver object and init its dispatch table.
+ */
+_EGLDriver *
+_eglMain(const char *args)
+{
+ struct dri2_egl_driver *dri2_drv;
+
+ dri2_drv = malloc(sizeof *dri2_drv);
+ if (!dri2_drv)
+ return NULL;
+
+ _eglInitDriverFallbacks(&dri2_drv->base);
+ dri2_drv->base.API.Initialize = dri2_initialize;
+ dri2_drv->base.API.Terminate = dri2_terminate;
+ dri2_drv->base.API.CreateContext = dri2_create_context;
+ dri2_drv->base.API.MakeCurrent = dri2_make_current;
+ dri2_drv->base.API.CreateWindowSurface = dri2_create_window_surface;
+ dri2_drv->base.API.CreatePixmapSurface = dri2_create_pixmap_surface;
+ dri2_drv->base.API.CreatePbufferSurface = dri2_create_pbuffer_surface;
+ dri2_drv->base.API.DestroySurface = dri2_destroy_surface;
+ dri2_drv->base.API.SwapBuffers = dri2_swap_buffers;
+ dri2_drv->base.API.GetProcAddress = dri2_get_proc_address;
+ dri2_drv->base.API.WaitClient = dri2_wait_client;
+ dri2_drv->base.API.WaitNative = dri2_wait_native;
+ dri2_drv->base.API.CopyBuffers = dri2_copy_buffers;
+
+ dri2_drv->base.Name = "DRI2";
+ dri2_drv->base.Unload = dri2_unload;
+
+ return &dri2_drv->base;
+}
diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c
index af653b86ee..3cbfebe488 100644
--- a/src/egl/drivers/glx/egl_glx.c
+++ b/src/egl/drivers/glx/egl_glx.c
@@ -116,35 +116,14 @@ struct GLX_egl_config
int index;
};
-/** cast wrapper */
-static struct GLX_egl_driver *
-GLX_egl_driver(_EGLDriver *drv)
-{
- return (struct GLX_egl_driver *) drv;
-}
-
-static struct GLX_egl_display *
-GLX_egl_display(_EGLDisplay *dpy)
-{
- return (struct GLX_egl_display *) dpy->DriverData;
-}
-
-static struct GLX_egl_context *
-GLX_egl_context(_EGLContext *ctx)
-{
- return (struct GLX_egl_context *) ctx;
-}
-
-static struct GLX_egl_surface *
-GLX_egl_surface(_EGLSurface *surf)
-{
- return (struct GLX_egl_surface *) surf;
-}
+/* standard typecasts */
+_EGL_DRIVER_STANDARD_TYPECASTS(GLX_egl)
static int
GLX_egl_config_index(_EGLConfig *conf)
{
- return ((struct GLX_egl_config *) conf)->index;
+ struct GLX_egl_config *GLX_conf = GLX_egl_config(conf);
+ return GLX_conf->index;
}
@@ -422,7 +401,7 @@ create_configs(_EGLDisplay *dpy, struct GLX_egl_display *GLX_dpy,
EGLBoolean ok;
memset(&template, 0, sizeof(template));
- _eglInitConfig(&template.Base, id);
+ _eglInitConfig(&template.Base, dpy, id);
if (GLX_dpy->have_fbconfig)
ok = convert_fbconfig(GLX_dpy->dpy, GLX_dpy->fbconfigs[i], &template);
else
@@ -605,7 +584,7 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
- if (!_eglInitContext(drv, &GLX_ctx->Base, conf, attrib_list)) {
+ if (!_eglInitContext(&GLX_ctx->Base, disp, conf, attrib_list)) {
free(GLX_ctx);
return NULL;
}
@@ -720,7 +699,7 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp,
return NULL;
}
- if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_WINDOW_BIT,
+ if (!_eglInitSurface(&GLX_surf->Base, disp, EGL_WINDOW_BIT,
conf, attrib_list)) {
free(GLX_surf);
return NULL;
@@ -766,7 +745,7 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp,
return NULL;
}
- if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PIXMAP_BIT,
+ if (!_eglInitSurface(&GLX_surf->Base, disp, EGL_PIXMAP_BIT,
conf, attrib_list)) {
free(GLX_surf);
return NULL;
@@ -826,7 +805,7 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp,
return NULL;
}
- if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PBUFFER_BIT,
+ if (!_eglInitSurface(&GLX_surf->Base, disp, EGL_PBUFFER_BIT,
conf, attrib_list)) {
free(GLX_surf);
return NULL;
diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile
deleted file mode 100644
index 9120620dc5..0000000000
--- a/src/egl/drivers/xdri/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-# src/egl/drivers/xdri/Makefile
-
-TOP = ../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER = egl_xdri.so
-
-# steal sources from GLX
-GLX_SOURCES = dri_common.c XF86dri.c dri2.c dri2_glx.c dri_glx.c drisw_glx.c
-GLX_SOURCES := $(addprefix ../../../glx/x11/,$(GLX_SOURCES))
-GLX_INCLUDES = \
- $(shell pkg-config --cflags-only-I libdrm) \
- -I$(TOP)/include/GL/internal \
- -I$(TOP)/src/glx/x11 \
- -I$(TOP)/src/mesa/glapi \
- -I$(TOP)/src/mesa
-GLX_CFLAGS = -DGLX_DIRECT_RENDERING
-
-EGL_SOURCES = egl_xdri.c glxinit.c driinit.c $(GLX_SOURCES)
-EGL_INCLUDES = \
- -I$(TOP)/include \
- -I$(TOP)/src/egl/main \
- $(GLX_INCLUDES)
-
-EGL_CFLAGS = $(GLX_CFLAGS)
-EGL_LIBS = -lX11 -lGL
-
-include ../Makefile.template
diff --git a/src/egl/drivers/xdri/driinit.c b/src/egl/drivers/xdri/driinit.c
deleted file mode 100644
index 3e54f0bd4d..0000000000
--- a/src/egl/drivers/xdri/driinit.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * DRI initialization. The DRI loaders are defined in src/glx/x11/.
- */
-
-#include <stdlib.h>
-#include <sys/time.h>
-
-#include "glxclient.h"
-#include "driinit.h"
-
-/* for __DRI_SYSTEM_TIME extension */
-_X_HIDDEN int
-__glXGetUST(int64_t * ust)
-{
- struct timeval tv;
-
- if (ust == NULL) {
- return -EFAULT;
- }
-
- if (gettimeofday(&tv, NULL) == 0) {
- ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
- return 0;
- }
- else {
- return -errno;
- }
-}
-
-_X_HIDDEN GLboolean
-__driGetMscRateOML(__DRIdrawable * draw,
- int32_t * numerator, int32_t * denominator, void *private)
-{
- return GL_FALSE;
-}
-
-/* ignore glx extensions */
-_X_HIDDEN void
-__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name)
-{
-}
-
-_X_HIDDEN __GLXDRIdisplay *
-__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version)
-{
- __GLXDRIdisplay *driDisplay = NULL;
- int ver = 0;
- char *env;
- int force_sw;
-
- env = getenv("EGL_SOFTWARE");
- force_sw = (env && *env != '0');
-
- /* try DRI2 first */
- if (!force_sw) {
- driDisplay = dri2CreateDisplay(dpyPriv->dpy);
- if (driDisplay) {
- /* fill in the required field */
- dpyPriv->dri2Display = driDisplay;
- ver = 2;
- }
- }
-
- /* and then DRI */
- if (!force_sw && !driDisplay) {
- driDisplay = driCreateDisplay(dpyPriv->dpy);
- if (driDisplay) {
- dpyPriv->driDisplay = driDisplay;
- ver = 1;
- }
- }
-
- /* and then DRISW */
- if (!driDisplay) {
- driDisplay = driswCreateDisplay(dpyPriv->dpy);
- if (driDisplay) {
- dpyPriv->driDisplay = driDisplay;
- ver = 0;
- }
- }
-
- if (version)
- *version = ver;
- return driDisplay;
-}
diff --git a/src/egl/drivers/xdri/driinit.h b/src/egl/drivers/xdri/driinit.h
deleted file mode 100644
index 6ea05cebef..0000000000
--- a/src/egl/drivers/xdri/driinit.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef DRIINIT_INCLUDED
-#define DRIINIT_INCLUDED
-
-#include "glxclient.h"
-
-extern __GLXDRIdisplay *
-__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version);
-
-#endif /* DRIINIT_INCLUDED */
diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c
deleted file mode 100644
index 9c21576539..0000000000
--- a/src/egl/drivers/xdri/egl_xdri.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-/**
- * Code to interface a DRI driver to libEGL.
- * Note that unlike previous DRI/EGL interfaces, this one is meant to
- * be used _with_ X. Applications will use eglCreateWindowSurface()
- * to render into X-created windows.
- *
- * This is an EGL driver that, in turn, loads a regular DRI driver.
- * There are some dependencies on code in libGL, but those could be
- * removed with some effort.
- *
- * Authors: Brian Paul
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <X11/Xlib.h>
-
-#include "glxinit.h"
-#include "driinit.h"
-#include "glapi/glapi.h" /* for glapi functions */
-
-#include "eglconfig.h"
-#include "eglconfigutil.h"
-#include "eglcontext.h"
-#include "egldisplay.h"
-#include "egldriver.h"
-#include "eglcurrent.h"
-#include "egllog.h"
-#include "eglsurface.h"
-
-#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
-
-/** subclass of _EGLDriver */
-struct xdri_egl_driver
-{
- _EGLDriver Base; /**< base class */
- void (*FlushCurrentContext)(void);
-};
-
-
-/** driver data of _EGLDisplay */
-struct xdri_egl_display
-{
- Display *dpy;
- __GLXdisplayPrivate *dpyPriv;
- __GLXDRIdisplay *driDisplay;
- int driVersion;
-
- __GLXscreenConfigs *psc;
- EGLint scr;
-};
-
-
-/** subclass of _EGLContext */
-struct xdri_egl_context
-{
- _EGLContext Base; /**< base class */
-
- /* just enough info to create dri contexts */
- GLXContext dummy_gc;
-
- __GLXDRIcontext *driContext;
-};
-
-
-/** subclass of _EGLSurface */
-struct xdri_egl_surface
-{
- _EGLSurface Base; /**< base class */
-
- Drawable drawable;
- __GLXDRIdrawable *driDrawable;
-};
-
-
-/** subclass of _EGLConfig */
-struct xdri_egl_config
-{
- _EGLConfig Base; /**< base class */
-
- const __GLcontextModes *mode; /**< corresponding GLX mode */
- EGLint window_render_buffer;
-};
-
-
-
-/** cast wrapper */
-static INLINE struct xdri_egl_driver *
-xdri_egl_driver(_EGLDriver *drv)
-{
- return (struct xdri_egl_driver *) drv;
-}
-
-
-static INLINE struct xdri_egl_display *
-lookup_display(_EGLDisplay *dpy)
-{
- return (struct xdri_egl_display *) dpy->DriverData;
-}
-
-
-/** Map EGLSurface handle to xdri_egl_surface object */
-static INLINE struct xdri_egl_surface *
-lookup_surface(_EGLSurface *surface)
-{
- return (struct xdri_egl_surface *) surface;
-}
-
-
-/** Map EGLContext handle to xdri_egl_context object */
-static INLINE struct xdri_egl_context *
-lookup_context(_EGLContext *context)
-{
- return (struct xdri_egl_context *) context;
-}
-
-
-/** Map EGLConfig handle to xdri_egl_config object */
-static INLINE struct xdri_egl_config *
-lookup_config(_EGLConfig *conf)
-{
- return (struct xdri_egl_config *) conf;
-}
-
-
-/** Get size of given window */
-static Status
-get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
-{
- Window root;
- Status stat;
- int xpos, ypos;
- unsigned int w, h, bw, depth;
- stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
- *width = w;
- *height = h;
- return stat;
-}
-
-
-static EGLBoolean
-convert_config(_EGLConfig *conf, EGLint id, const __GLcontextModes *m)
-{
- EGLint val;
-
- _eglInitConfig(conf, id);
- if (!_eglConfigFromContextModesRec(conf, m, EGL_OPENGL_BIT, EGL_OPENGL_BIT))
- return EGL_FALSE;
-
- if (m->doubleBufferMode) {
- /* pixmap and pbuffer surfaces are always single-buffered */
- val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
- val &= ~(EGL_PIXMAP_BIT | EGL_PBUFFER_BIT);
- SET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE, val);
- }
- else {
- /* EGL requires OpenGL ES context to be double-buffered */
- val = GET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE);
- val &= ~(EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT);
- SET_CONFIG_ATTRIB(conf, EGL_RENDERABLE_TYPE, val);
- }
- /* skip "empty" config */
- if (!val)
- return EGL_FALSE;
-
- val = GET_CONFIG_ATTRIB(conf, EGL_SURFACE_TYPE);
- if (!(val & EGL_PBUFFER_BIT)) {
- /* bind-to-texture cannot be EGL_TRUE without pbuffer bit */
- SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGB, EGL_FALSE);
- SET_CONFIG_ATTRIB(conf, EGL_BIND_TO_TEXTURE_RGBA, EGL_FALSE);
- }
-
- /* EGL_NATIVE_RENDERABLE is a boolean */
- val = GET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE);
- if (val != EGL_TRUE)
- SET_CONFIG_ATTRIB(conf, EGL_NATIVE_RENDERABLE, EGL_FALSE);
-
- return _eglValidateConfig(conf, EGL_FALSE);
-}
-
-
-/**
- * Produce a set of EGL configs.
- */
-static EGLint
-create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id)
-{
- struct xdri_egl_display *xdri_dpy = lookup_display(disp);
- int id = first_id;
-
- for (; m; m = m->next) {
- struct xdri_egl_config *xdri_conf;
- _EGLConfig conf;
- EGLint rb;
-
- if (!convert_config(&conf, id, m))
- continue;
- if (m->doubleBufferMode) {
- rb = EGL_BACK_BUFFER;
- }
- else {
- /* ignore single-buffered mode for DRISW */
- if (xdri_dpy->driVersion == 0)
- continue;
- rb = EGL_SINGLE_BUFFER;
- }
-
- xdri_conf = CALLOC_STRUCT(xdri_egl_config);
- if (xdri_conf) {
- memcpy(&xdri_conf->Base, &conf, sizeof(conf));
- xdri_conf->mode = m;
- xdri_conf->window_render_buffer = rb;
- _eglAddConfig(disp, &xdri_conf->Base);
- id++;
- }
- }
-
- return id;
-}
-
-
-/**
- * Called via eglInitialize(), xdri_dpy->API.Initialize().
- */
-static EGLBoolean
-xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
- EGLint *minor, EGLint *major)
-{
- struct xdri_egl_display *xdri_dpy;
- __GLXdisplayPrivate *dpyPriv;
- __GLXDRIdisplay *driDisplay;
- __GLXscreenConfigs *psc;
- EGLint first_id = 1;
- int scr;
-
- xdri_dpy = CALLOC_STRUCT(xdri_egl_display);
- if (!xdri_dpy)
- return _eglError(EGL_BAD_ALLOC, "eglInitialize");
-
- xdri_dpy->dpy = (Display *) dpy->NativeDisplay;
- if (!xdri_dpy->dpy) {
- xdri_dpy->dpy = XOpenDisplay(NULL);
- if (!xdri_dpy->dpy) {
- free(xdri_dpy);
- return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
- }
- }
-
- dpyPriv = __glXInitialize(xdri_dpy->dpy);
- if (!dpyPriv) {
- _eglLog(_EGL_WARNING, "failed to create GLX display");
- free(xdri_dpy);
- return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
- }
-
- driDisplay = __driCreateDisplay(dpyPriv, &xdri_dpy->driVersion);
- if (!driDisplay) {
- _eglLog(_EGL_WARNING, "failed to create DRI display");
- free(xdri_dpy);
- return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
- }
-
- scr = DefaultScreen(xdri_dpy->dpy);
- psc = &dpyPriv->screenConfigs[scr];
-
- xdri_dpy->dpyPriv = dpyPriv;
- xdri_dpy->driDisplay = driDisplay;
- xdri_dpy->psc = psc;
- xdri_dpy->scr = scr;
-
- psc->driScreen = driDisplay->createScreen(psc, scr, dpyPriv);
- if (!psc->driScreen) {
- _eglLog(_EGL_WARNING, "failed to create DRI screen #%d", scr);
- free(xdri_dpy);
- return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
- }
-
- dpy->DriverData = xdri_dpy;
- dpy->ClientAPIsMask = EGL_OPENGL_BIT;
-
- /* add visuals and fbconfigs */
- first_id = create_configs(dpy, psc->visuals, first_id);
- create_configs(dpy, psc->configs, first_id);
-
- /* we're supporting EGL 1.4 */
- *minor = 1;
- *major = 4;
-
- return EGL_TRUE;
-}
-
-
-/**
- * Called via eglTerminate(), drv->API.Terminate().
- */
-static EGLBoolean
-xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
-{
- struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
- __GLXscreenConfigs *psc;
-
- _eglReleaseDisplayResources(drv, dpy);
- _eglCleanupDisplay(dpy);
-
- psc = xdri_dpy->psc;
- if (psc->driver_configs) {
- unsigned int i;
- for (i = 0; psc->driver_configs[i]; i++)
- free((__DRIconfig *) psc->driver_configs[i]);
- free(psc->driver_configs);
- psc->driver_configs = NULL;
- }
- if (psc->driScreen) {
- psc->driScreen->destroyScreen(psc);
- free(psc->driScreen);
- psc->driScreen = NULL;
- }
-
- xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay);
-
- free(xdri_dpy);
- dpy->DriverData = NULL;
-
- return EGL_TRUE;
-}
-
-
-/*
- * Called from eglGetProcAddress() via drv->API.GetProcAddress().
- */
-static _EGLProc
-xdri_eglGetProcAddress(_EGLDriver *drv, const char *procname)
-{
- /* the symbol is defined in libGL.so */
- return (_EGLProc) _glapi_get_proc_address(procname);
-}
-
-
-/**
- * Called via eglCreateContext(), drv->API.CreateContext().
- */
-static _EGLContext *
-xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- _EGLContext *share_list, const EGLint *attrib_list)
-{
- struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
- struct xdri_egl_config *xdri_config = lookup_config(conf);
- struct xdri_egl_context *shared = lookup_context(share_list);
- __GLXscreenConfigs *psc = xdri_dpy->psc;
- int renderType = GLX_RGBA_BIT;
- struct xdri_egl_context *xdri_ctx;
-
- xdri_ctx = CALLOC_STRUCT(xdri_egl_context);
- if (!xdri_ctx) {
- _eglError(EGL_BAD_ALLOC, "eglCreateContext");
- return NULL;
- }
-
- xdri_ctx->dummy_gc = CALLOC_STRUCT(__GLXcontextRec);
- if (!xdri_ctx->dummy_gc) {
- _eglError(EGL_BAD_ALLOC, "eglCreateContext");
- free(xdri_ctx);
- return NULL;
- }
-
- if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) {
- free(xdri_ctx->dummy_gc);
- free(xdri_ctx);
- return NULL;
- }
-
- /* the config decides the render buffer for the context */
- xdri_ctx->Base.WindowRenderBuffer = xdri_config->window_render_buffer;
-
- xdri_ctx->driContext =
- psc->driScreen->createContext(psc,
- xdri_config->mode,
- xdri_ctx->dummy_gc,
- (shared) ? shared->dummy_gc : NULL,
- renderType);
- if (!xdri_ctx->driContext) {
- free(xdri_ctx->dummy_gc);
- free(xdri_ctx);
- return NULL;
- }
-
- /* fill in the required field */
- xdri_ctx->dummy_gc->driContext = xdri_ctx->driContext;
-
- return &xdri_ctx->Base;
-}
-
-
-/**
- * Destroy a context.
- */
-static void
-destroy_context(_EGLDisplay *dpy, _EGLContext *ctx)
-{
- struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
- struct xdri_egl_context *xdri_ctx = lookup_context(ctx);
-
- /* FIXME a context might live longer than its display */
- if (!dpy->Initialized)
- _eglLog(_EGL_FATAL, "destroy a context with an unitialized display");
-
- xdri_ctx->driContext->destroyContext(xdri_ctx->driContext,
- xdri_dpy->psc, xdri_dpy->dpy);
- free(xdri_ctx->dummy_gc);
- free(xdri_ctx);
-}
-
-
-/**
- * Destroy a surface.
- */
-static void
-destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf)
-{
- struct xdri_egl_surface *xdri_surf = lookup_surface(surf);
-
- if (!dpy->Initialized)
- _eglLog(_EGL_FATAL, "destroy a surface with an unitialized display");
-
- xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable);
- free(xdri_surf);
-}
-
-
-static EGLBoolean
-xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
-{
- if (!_eglIsContextBound(ctx))
- destroy_context(dpy, ctx);
- return EGL_TRUE;
-}
-
-
-/**
- * Called via eglMakeCurrent(), drv->API.MakeCurrent().
- */
-static EGLBoolean
-xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
- _EGLSurface *r, _EGLContext *context)
-{
- struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv);
- struct xdri_egl_context *xdri_ctx = lookup_context(context);
- struct xdri_egl_surface *draw = lookup_surface(d);
- struct xdri_egl_surface *read = lookup_surface(r);
-
- /* bind the new context and return the "orphaned" one */
- if (!_eglBindContext(&context, &d, &r))
- return EGL_FALSE;
-
- /* flush before context switch */
- if (context && xdri_driver->FlushCurrentContext)
- xdri_driver->FlushCurrentContext();
-
- /* the symbol is defined in libGL.so */
- _glapi_check_multithread();
-
- if (xdri_ctx) {
- if (!xdri_ctx->driContext->bindContext(xdri_ctx->driContext,
- draw->driDrawable,
- read->driDrawable)) {
- return EGL_FALSE;
- }
- }
- else if (context) {
- xdri_ctx = lookup_context(context);
- xdri_ctx->driContext->unbindContext(xdri_ctx->driContext);
- }
-
- if (context && !_eglIsContextLinked(context))
- destroy_context(dpy, context);
- if (d && !_eglIsSurfaceLinked(d))
- destroy_surface(dpy, d);
- if (r && r != d && !_eglIsSurfaceLinked(r))
- destroy_surface(dpy, r);
-
- return EGL_TRUE;
-}
-
-
-/**
- * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
- */
-static _EGLSurface *
-xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- EGLNativeWindowType window,
- const EGLint *attrib_list)
-{
- struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
- struct xdri_egl_config *xdri_config = lookup_config(conf);
- struct xdri_egl_surface *xdri_surf;
- uint width, height;
-
- xdri_surf = CALLOC_STRUCT(xdri_egl_surface);
- if (!xdri_surf) {
- _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
- return NULL;
- }
-
- if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_WINDOW_BIT,
- &xdri_config->Base, attrib_list)) {
- free(xdri_surf);
- return NULL;
- }
-
- xdri_surf->driDrawable =
- xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc,
- (XID) window,
- (GLXDrawable) window,
- xdri_config->mode);
- if (!xdri_surf->driDrawable) {
- free(xdri_surf);
- return NULL;
- }
-
- xdri_surf->drawable = (Drawable) window;
-
- get_drawable_size(xdri_dpy->dpy, window, &width, &height);
- xdri_surf->Base.Width = width;
- xdri_surf->Base.Height = height;
-
- return &xdri_surf->Base;
-}
-
-
-/**
- * Called via eglCreatePbufferSurface(), drv->API.CreatePbufferSurface().
- */
-static _EGLSurface *
-xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
- const EGLint *attrib_list)
-{
- return NULL;
-}
-
-
-
-static EGLBoolean
-xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
-{
- if (!_eglIsSurfaceBound(surface))
- destroy_surface(dpy, surface);
- return EGL_TRUE;
-}
-
-
-static EGLBoolean
-xdri_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
- EGLint buffer)
-{
- return EGL_FALSE;
-}
-
-
-static EGLBoolean
-xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
- EGLint buffer)
-{
- return EGL_FALSE;
-}
-
-
-static EGLBoolean
-xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
-{
- struct xdri_egl_driver *xdri_driver = xdri_egl_driver(drv);
- struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
- struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
-
- /* swapBuffers does not flush commands */
- if (draw->CurrentContext && xdri_driver->FlushCurrentContext)
- xdri_driver->FlushCurrentContext();
-
- xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable, 0, 0, 0);
-
- return EGL_TRUE;
-}
-
-
-static void
-xdri_Unload(_EGLDriver *drv)
-{
- struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
- free(xdri_drv);
-}
-
-
-/**
- * This is the main entrypoint into the driver, called by libEGL.
- * Create a new _EGLDriver object and init its dispatch table.
- */
-_EGLDriver *
-_eglMain(const char *args)
-{
- struct xdri_egl_driver *xdri_drv = CALLOC_STRUCT(xdri_egl_driver);
- if (!xdri_drv)
- return NULL;
-
- _eglInitDriverFallbacks(&xdri_drv->Base);
- xdri_drv->Base.API.Initialize = xdri_eglInitialize;
- xdri_drv->Base.API.Terminate = xdri_eglTerminate;
-
- xdri_drv->Base.API.GetProcAddress = xdri_eglGetProcAddress;
-
- xdri_drv->Base.API.CreateContext = xdri_eglCreateContext;
- xdri_drv->Base.API.DestroyContext = xdri_eglDestroyContext;
- xdri_drv->Base.API.MakeCurrent = xdri_eglMakeCurrent;
- xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface;
- xdri_drv->Base.API.CreatePbufferSurface = xdri_eglCreatePbufferSurface;
- xdri_drv->Base.API.DestroySurface = xdri_eglDestroySurface;
- xdri_drv->Base.API.BindTexImage = xdri_eglBindTexImage;
- xdri_drv->Base.API.ReleaseTexImage = xdri_eglReleaseTexImage;
- xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers;
-
- xdri_drv->Base.Name = "X/DRI";
- xdri_drv->Base.Unload = xdri_Unload;
-
- /* we need a way to flush commands */
- xdri_drv->FlushCurrentContext =
- (void (*)(void)) xdri_eglGetProcAddress(&xdri_drv->Base, "glFlush");
-
- return &xdri_drv->Base;
-}
diff --git a/src/egl/drivers/xdri/glxinit.c b/src/egl/drivers/xdri/glxinit.c
deleted file mode 100644
index ba6132788a..0000000000
--- a/src/egl/drivers/xdri/glxinit.c
+++ /dev/null
@@ -1,682 +0,0 @@
-/**
- * GLX initialization. Code based on glxext.c, glx_query.c, and
- * glcontextmodes.c under src/glx/x11/. The major difference is that DRI
- * related code is stripped out.
- *
- * If the maintenance of this file takes too much time, we should consider
- * refactoring glxext.c.
- */
-
-#include <assert.h>
-#include <X11/Xlib.h>
-#include <X11/Xproto.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
-#include <sys/time.h>
-
-#include "glxinit.h"
-
-typedef struct GLXGenericGetString
-{
- CARD8 reqType;
- CARD8 glxCode;
- CARD16 length B16;
- CARD32 for_whom B32;
- CARD32 name B32;
-} xGLXGenericGetStringReq;
-
-#define sz_xGLXGenericGetStringReq 12
-#define X_GLXGenericGetString 0
-
-/* Extension required boiler plate */
-
-static char *__glXExtensionName = GLX_EXTENSION_NAME;
-static XExtensionInfo *__glXExtensionInfo = NULL;
-
-static int
-__glXCloseDisplay(Display * dpy, XExtCodes * codes)
-{
- return XextRemoveDisplay(__glXExtensionInfo, dpy);
-}
-
-static /* const */ XExtensionHooks __glXExtensionHooks = {
- NULL, /* create_gc */
- NULL, /* copy_gc */
- NULL, /* flush_gc */
- NULL, /* free_gc */
- NULL, /* create_font */
- NULL, /* free_font */
- __glXCloseDisplay, /* close_display */
- NULL, /* wire_to_event */
- NULL, /* event_to_wire */
- NULL, /* error */
- NULL, /* error_string */
-};
-
-XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
- __glXExtensionName, &__glXExtensionHooks,
- __GLX_NUMBER_EVENTS, NULL)
-
-static GLint
-_gl_convert_from_x_visual_type(int visualType)
-{
-#define NUM_VISUAL_TYPES 6
- static const int glx_visual_types[NUM_VISUAL_TYPES] = {
- GLX_STATIC_GRAY, GLX_GRAY_SCALE,
- GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
- GLX_TRUE_COLOR, GLX_DIRECT_COLOR
- };
-
- return ((unsigned) visualType < NUM_VISUAL_TYPES)
- ? glx_visual_types[visualType] : GLX_NONE;
-}
-
-static __GLcontextModes *
-_gl_context_modes_create(unsigned count, size_t minimum_size)
-{
- const size_t size = (minimum_size > sizeof(__GLcontextModes))
- ? minimum_size : sizeof(__GLcontextModes);
- __GLcontextModes *base = NULL;
- __GLcontextModes **next;
- unsigned i;
-
- next = &base;
- for (i = 0; i < count; i++) {
- *next = (__GLcontextModes *) Xmalloc(size);
- if (*next == NULL) {
- _gl_context_modes_destroy(base);
- base = NULL;
- break;
- }
-
- memset(*next, 0, size);
- (*next)->visualID = GLX_DONT_CARE;
- (*next)->visualType = GLX_DONT_CARE;
- (*next)->visualRating = GLX_NONE;
- (*next)->transparentPixel = GLX_NONE;
- (*next)->transparentRed = GLX_DONT_CARE;
- (*next)->transparentGreen = GLX_DONT_CARE;
- (*next)->transparentBlue = GLX_DONT_CARE;
- (*next)->transparentAlpha = GLX_DONT_CARE;
- (*next)->transparentIndex = GLX_DONT_CARE;
- (*next)->xRenderable = GLX_DONT_CARE;
- (*next)->fbconfigID = GLX_DONT_CARE;
- (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
- (*next)->bindToTextureRgb = GLX_DONT_CARE;
- (*next)->bindToTextureRgba = GLX_DONT_CARE;
- (*next)->bindToMipmapTexture = GLX_DONT_CARE;
- (*next)->bindToTextureTargets = GLX_DONT_CARE;
- (*next)->yInverted = GLX_DONT_CARE;
-
- next = &((*next)->next);
- }
-
- return base;
-}
-
-_X_HIDDEN void
-_gl_context_modes_destroy(__GLcontextModes * modes)
-{
- while (modes != NULL) {
- __GLcontextModes *const next = modes->next;
-
- Xfree(modes);
- modes = next;
- }
-}
-
-_X_HIDDEN char *
-__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
-{
- xGLXGenericGetStringReq *req;
- xGLXSingleReply reply;
- int length;
- int numbytes;
- char *buf;
- CARD32 for_whom = screen;
- CARD32 glxCode = X_GLXQueryServerString;
-
-
- LockDisplay(dpy);
-
-
- /* All of the GLX protocol requests for getting a string from the server
- * look the same. The exact meaning of the for_whom field is usually
- * either the screen number (for glXQueryServerString) or the context tag
- * (for GLXSingle).
- */
-
- GetReq(GLXGenericGetString, req);
- req->reqType = opcode;
- req->glxCode = glxCode;
- req->for_whom = for_whom;
- req->name = name;
-
- _XReply(dpy, (xReply *) & reply, 0, False);
-
- length = reply.length * 4;
- numbytes = reply.size;
-
- buf = (char *) Xmalloc(numbytes);
- if (buf != NULL) {
- _XRead(dpy, buf, numbytes);
- length -= numbytes;
- }
-
- _XEatData(dpy, length);
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- return buf;
-}
-
-/************************************************************************/
-/*
-** Free the per screen configs data as well as the array of
-** __glXScreenConfigs.
-*/
-static void
-FreeScreenConfigs(__GLXdisplayPrivate * priv)
-{
- __GLXscreenConfigs *psc;
- GLint i, screens;
-
- /* Free screen configuration information */
- psc = priv->screenConfigs;
- screens = ScreenCount(priv->dpy);
- for (i = 0; i < screens; i++, psc++) {
- if (psc->configs) {
- _gl_context_modes_destroy(psc->configs);
- psc->configs = NULL; /* NOTE: just for paranoia */
- }
- if (psc->visuals) {
- _gl_context_modes_destroy(psc->visuals);
- psc->visuals = NULL; /* NOTE: just for paranoia */
- }
- Xfree((char *) psc->serverGLXexts);
- }
- XFree((char *) priv->screenConfigs);
- priv->screenConfigs = NULL;
-}
-
-/*
-** Release the private memory referred to in a display private
-** structure. The caller will free the extension structure.
-*/
-static int
-__glXFreeDisplayPrivate(XExtData * extension)
-{
- __GLXdisplayPrivate *priv;
-
- priv = (__GLXdisplayPrivate *) extension->private_data;
- FreeScreenConfigs(priv);
- if (priv->serverGLXvendor) {
- Xfree((char *) priv->serverGLXvendor);
- priv->serverGLXvendor = 0x0; /* to protect against double free's */
- }
- if (priv->serverGLXversion) {
- Xfree((char *) priv->serverGLXversion);
- priv->serverGLXversion = 0x0; /* to protect against double free's */
- }
-
- Xfree((char *) priv);
- return 0;
-}
-
-/************************************************************************/
-
-/*
-** Query the version of the GLX extension. This procedure works even if
-** the client extension is not completely set up.
-*/
-static Bool
-QueryVersion(Display * dpy, int opcode, int *major, int *minor)
-{
- xGLXQueryVersionReq *req;
- xGLXQueryVersionReply reply;
-
- /* Send the glXQueryVersion request */
- LockDisplay(dpy);
- GetReq(GLXQueryVersion, req);
- req->reqType = opcode;
- req->glxCode = X_GLXQueryVersion;
- req->majorVersion = GLX_MAJOR_VERSION;
- req->minorVersion = GLX_MINOR_VERSION;
- _XReply(dpy, (xReply *) & reply, 0, False);
- UnlockDisplay(dpy);
- SyncHandle();
-
- if (reply.majorVersion != GLX_MAJOR_VERSION) {
- /*
- ** The server does not support the same major release as this
- ** client.
- */
- return GL_FALSE;
- }
- *major = reply.majorVersion;
- *minor = min(reply.minorVersion, GLX_MINOR_VERSION);
- return GL_TRUE;
-}
-
-_X_HIDDEN void
-__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
- const INT32 * bp, Bool tagged_only,
- Bool fbconfig_style_tags)
-{
- int i;
-
- if (!tagged_only) {
- /* Copy in the first set of properties */
- config->visualID = *bp++;
-
- config->visualType = _gl_convert_from_x_visual_type(*bp++);
-
- config->rgbMode = *bp++;
-
- config->redBits = *bp++;
- config->greenBits = *bp++;
- config->blueBits = *bp++;
- config->alphaBits = *bp++;
- config->accumRedBits = *bp++;
- config->accumGreenBits = *bp++;
- config->accumBlueBits = *bp++;
- config->accumAlphaBits = *bp++;
-
- config->doubleBufferMode = *bp++;
- config->stereoMode = *bp++;
-
- config->rgbBits = *bp++;
- config->depthBits = *bp++;
- config->stencilBits = *bp++;
- config->numAuxBuffers = *bp++;
- config->level = *bp++;
-
- count -= __GLX_MIN_CONFIG_PROPS;
- }
-
- /*
- ** Additional properties may be in a list at the end
- ** of the reply. They are in pairs of property type
- ** and property value.
- */
-
-#define FETCH_OR_SET(tag) \
- config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
-
- for (i = 0; i < count; i += 2) {
- switch (*bp++) {
- case GLX_RGBA:
- FETCH_OR_SET(rgbMode);
- break;
- case GLX_BUFFER_SIZE:
- config->rgbBits = *bp++;
- break;
- case GLX_LEVEL:
- config->level = *bp++;
- break;
- case GLX_DOUBLEBUFFER:
- FETCH_OR_SET(doubleBufferMode);
- break;
- case GLX_STEREO:
- FETCH_OR_SET(stereoMode);
- break;
- case GLX_AUX_BUFFERS:
- config->numAuxBuffers = *bp++;
- break;
- case GLX_RED_SIZE:
- config->redBits = *bp++;
- break;
- case GLX_GREEN_SIZE:
- config->greenBits = *bp++;
- break;
- case GLX_BLUE_SIZE:
- config->blueBits = *bp++;
- break;
- case GLX_ALPHA_SIZE:
- config->alphaBits = *bp++;
- break;
- case GLX_DEPTH_SIZE:
- config->depthBits = *bp++;
- break;
- case GLX_STENCIL_SIZE:
- config->stencilBits = *bp++;
- break;
- case GLX_ACCUM_RED_SIZE:
- config->accumRedBits = *bp++;
- break;
- case GLX_ACCUM_GREEN_SIZE:
- config->accumGreenBits = *bp++;
- break;
- case GLX_ACCUM_BLUE_SIZE:
- config->accumBlueBits = *bp++;
- break;
- case GLX_ACCUM_ALPHA_SIZE:
- config->accumAlphaBits = *bp++;
- break;
- case GLX_VISUAL_CAVEAT_EXT:
- config->visualRating = *bp++;
- break;
- case GLX_X_VISUAL_TYPE:
- config->visualType = *bp++;
- break;
- case GLX_TRANSPARENT_TYPE:
- config->transparentPixel = *bp++;
- break;
- case GLX_TRANSPARENT_INDEX_VALUE:
- config->transparentIndex = *bp++;
- break;
- case GLX_TRANSPARENT_RED_VALUE:
- config->transparentRed = *bp++;
- break;
- case GLX_TRANSPARENT_GREEN_VALUE:
- config->transparentGreen = *bp++;
- break;
- case GLX_TRANSPARENT_BLUE_VALUE:
- config->transparentBlue = *bp++;
- break;
- case GLX_TRANSPARENT_ALPHA_VALUE:
- config->transparentAlpha = *bp++;
- break;
- case GLX_VISUAL_ID:
- config->visualID = *bp++;
- break;
- case GLX_DRAWABLE_TYPE:
- config->drawableType = *bp++;
- break;
- case GLX_RENDER_TYPE:
- config->renderType = *bp++;
- break;
- case GLX_X_RENDERABLE:
- config->xRenderable = *bp++;
- break;
- case GLX_FBCONFIG_ID:
- config->fbconfigID = *bp++;
- break;
- case GLX_MAX_PBUFFER_WIDTH:
- config->maxPbufferWidth = *bp++;
- break;
- case GLX_MAX_PBUFFER_HEIGHT:
- config->maxPbufferHeight = *bp++;
- break;
- case GLX_MAX_PBUFFER_PIXELS:
- config->maxPbufferPixels = *bp++;
- break;
- case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
- config->optimalPbufferWidth = *bp++;
- break;
- case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
- config->optimalPbufferHeight = *bp++;
- break;
- case GLX_VISUAL_SELECT_GROUP_SGIX:
- config->visualSelectGroup = *bp++;
- break;
- case GLX_SWAP_METHOD_OML:
- config->swapMethod = *bp++;
- break;
- case GLX_SAMPLE_BUFFERS_SGIS:
- config->sampleBuffers = *bp++;
- break;
- case GLX_SAMPLES_SGIS:
- config->samples = *bp++;
- break;
- case GLX_BIND_TO_TEXTURE_RGB_EXT:
- config->bindToTextureRgb = *bp++;
- break;
- case GLX_BIND_TO_TEXTURE_RGBA_EXT:
- config->bindToTextureRgba = *bp++;
- break;
- case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
- config->bindToMipmapTexture = *bp++;
- break;
- case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
- config->bindToTextureTargets = *bp++;
- break;
- case GLX_Y_INVERTED_EXT:
- config->yInverted = *bp++;
- break;
- case None:
- i = count;
- break;
- default:
- break;
- }
- }
-
- config->renderType =
- (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
-
- config->haveAccumBuffer = ((config->accumRedBits +
- config->accumGreenBits +
- config->accumBlueBits +
- config->accumAlphaBits) > 0);
- config->haveDepthBuffer = (config->depthBits > 0);
- config->haveStencilBuffer = (config->stencilBits > 0);
-}
-
-static __GLcontextModes *
-createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
- int screen, GLboolean tagged_only)
-{
- INT32 buf[__GLX_TOTAL_CONFIG], *props;
- unsigned prop_size;
- __GLcontextModes *modes, *m;
- int i;
-
- if (nprops == 0)
- return NULL;
-
- /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
-
- /* Check number of properties */
- if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
- return NULL;
-
- /* Allocate memory for our config structure */
- modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
- if (!modes)
- return NULL;
-
- prop_size = nprops * __GLX_SIZE_INT32;
- if (prop_size <= sizeof(buf))
- props = buf;
- else
- props = Xmalloc(prop_size);
-
- /* Read each config structure and convert it into our format */
- m = modes;
- for (i = 0; i < nvisuals; i++) {
- _XRead(dpy, (char *) props, prop_size);
- /* Older X servers don't send this so we default it here. */
- m->drawableType = GLX_WINDOW_BIT;
- __glXInitializeVisualConfigFromTags(m, nprops, props,
- tagged_only, GL_TRUE);
- m->screen = screen;
- m = m->next;
- }
-
- if (props != buf)
- Xfree(props);
-
- return modes;
-}
-
-static GLboolean
-getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
-{
- xGLXGetVisualConfigsReq *req;
- __GLXscreenConfigs *psc;
- xGLXGetVisualConfigsReply reply;
-
- LockDisplay(dpy);
-
- psc = priv->screenConfigs + screen;
- psc->visuals = NULL;
- GetReq(GLXGetVisualConfigs, req);
- req->reqType = priv->majorOpcode;
- req->glxCode = X_GLXGetVisualConfigs;
- req->screen = screen;
-
- if (!_XReply(dpy, (xReply *) & reply, 0, False))
- goto out;
-
- psc->visuals = createConfigsFromProperties(dpy,
- reply.numVisuals,
- reply.numProps,
- screen, GL_FALSE);
-
- out:
- UnlockDisplay(dpy);
- return psc->visuals != NULL;
-}
-
-static GLboolean
-getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
-{
- xGLXGetFBConfigsReq *fb_req;
- xGLXGetFBConfigsSGIXReq *sgi_req;
- xGLXVendorPrivateWithReplyReq *vpreq;
- xGLXGetFBConfigsReply reply;
- __GLXscreenConfigs *psc;
-
- psc = priv->screenConfigs + screen;
- psc->serverGLXexts =
- __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
-
- LockDisplay(dpy);
-
- psc->configs = NULL;
- if (atof(priv->serverGLXversion) >= 1.3) {
- GetReq(GLXGetFBConfigs, fb_req);
- fb_req->reqType = priv->majorOpcode;
- fb_req->glxCode = X_GLXGetFBConfigs;
- fb_req->screen = screen;
- }
- else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
- GetReqExtra(GLXVendorPrivateWithReply,
- sz_xGLXGetFBConfigsSGIXReq +
- sz_xGLXVendorPrivateWithReplyReq, vpreq);
- sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
- sgi_req->reqType = priv->majorOpcode;
- sgi_req->glxCode = X_GLXVendorPrivateWithReply;
- sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
- sgi_req->screen = screen;
- }
- else
- goto out;
-
- if (!_XReply(dpy, (xReply *) & reply, 0, False))
- goto out;
-
- psc->configs = createConfigsFromProperties(dpy,
- reply.numFBConfigs,
- reply.numAttribs * 2,
- screen, GL_TRUE);
-
- out:
- UnlockDisplay(dpy);
- return psc->configs != NULL;
-}
-
-static GLboolean
-AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
-{
- __GLXscreenConfigs *psc;
- GLint i, screens;
-
- /*
- ** First allocate memory for the array of per screen configs.
- */
- screens = ScreenCount(dpy);
- psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs));
- if (!psc) {
- return GL_FALSE;
- }
- memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
- priv->screenConfigs = psc;
-
- priv->serverGLXversion =
- __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
- if (priv->serverGLXversion == NULL) {
- FreeScreenConfigs(priv);
- return GL_FALSE;
- }
-
- for (i = 0; i < screens; i++, psc++) {
- getFBConfigs(dpy, priv, i);
- getVisualConfigs(dpy, priv, i);
- psc->scr = i;
- psc->dpy = dpy;
- }
-
- SyncHandle();
-
- return GL_TRUE;
-}
-
-_X_HIDDEN __GLXdisplayPrivate *
-__glXInitialize(Display * dpy)
-{
- XExtDisplayInfo *info = __glXFindDisplay(dpy);
- XExtData **privList, *private, *found;
- __GLXdisplayPrivate *dpyPriv;
- XEDataObject dataObj;
- int major, minor;
-
- if (!XextHasExtension(info))
- return NULL;
-
- /* See if a display private already exists. If so, return it */
- dataObj.display = dpy;
- privList = XEHeadOfExtensionList(dataObj);
- found = XFindOnExtensionList(privList, info->codes->extension);
- if (found)
- return (__GLXdisplayPrivate *) found->private_data;
-
- /* See if the versions are compatible */
- if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor))
- return NULL;
-
- /*
- ** Allocate memory for all the pieces needed for this buffer.
- */
- private = (XExtData *) Xmalloc(sizeof(XExtData));
- if (!private)
- return NULL;
- dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
- if (!dpyPriv) {
- Xfree(private);
- return NULL;
- }
-
- /*
- ** Init the display private and then read in the screen config
- ** structures from the server.
- */
- dpyPriv->majorOpcode = info->codes->major_opcode;
- dpyPriv->majorVersion = major;
- dpyPriv->minorVersion = minor;
- dpyPriv->dpy = dpy;
-
- dpyPriv->serverGLXvendor = NULL;
- dpyPriv->serverGLXversion = NULL;
-
- if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
- Xfree(dpyPriv);
- Xfree(private);
- return NULL;
- }
-
- /*
- ** Fill in the private structure. This is the actual structure that
- ** hangs off of the Display structure. Our private structure is
- ** referred to by this structure. Got that?
- */
- private->number = info->codes->extension;
- private->next = 0;
- private->free_private = __glXFreeDisplayPrivate;
- private->private_data = (char *) dpyPriv;
- XAddToExtensionList(privList, private);
-
- return dpyPriv;
-}
diff --git a/src/egl/drivers/xdri/glxinit.h b/src/egl/drivers/xdri/glxinit.h
deleted file mode 100644
index 1cc7c460fe..0000000000
--- a/src/egl/drivers/xdri/glxinit.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef GLXINIT_INCLUDED
-#define GLXINIT_INCLUDED
-
-#include <X11/Xlib.h>
-#include "glxclient.h"
-
-/* this is used by DRI loaders */
-extern void
-_gl_context_modes_destroy(__GLcontextModes * modes);
-
-#endif /* GLXINIT_INCLUDED */