summaryrefslogtreecommitdiff
path: root/src/dispatch_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dispatch_common.c')
-rw-r--r--src/dispatch_common.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/src/dispatch_common.c b/src/dispatch_common.c
new file mode 100644
index 0000000..1b45389
--- /dev/null
+++ b/src/dispatch_common.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright © 2013 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.
+ */
+
+/**
+ * @file dispatch_common.c
+ *
+ * Implements common code shared by the generated GL/EGL/GLX dispatch code.
+ *
+ * A collection of some important specs on getting GL function pointers.
+ *
+ * From the linux GL ABI (http://www.opengl.org/registry/ABI/):
+ *
+ * "3.4. The libraries must export all OpenGL 1.2, GLU 1.3, GLX 1.3, and
+ * ARB_multitexture entry points statically.
+ *
+ * 3.5. Because non-ARB extensions vary so widely and are constantly
+ * increasing in number, it's infeasible to require that they all be
+ * supported, and extensions can always be added to hardware drivers
+ * after the base link libraries are released. These drivers are
+ * dynamically loaded by libGL, so extensions not in the base
+ * library must also be obtained dynamically.
+ *
+ * 3.6. To perform the dynamic query, libGL also must export an entry
+ * point called
+ *
+ * void (*glXGetProcAddressARB(const GLubyte *))();
+ *
+ * The full specification of this function is available separately. It
+ * takes the string name of a GL or GLX entry point and returns a pointer
+ * to a function implementing that entry point. It is functionally
+ * identical to the wglGetProcAddress query defined by the Windows OpenGL
+ * library, except that the function pointers returned are context
+ * independent, unlike the WGL query."
+ *
+ * From the EGL 1.4 spec:
+ *
+ * "Client API function pointers returned by eglGetProcAddress are
+ * independent of the display and the currently bound client API context,
+ * and may be used by any client API context which supports the extension.
+ *
+ * eglGetProcAddress may be queried for all of the following functions:
+ *
+ * • All EGL and client API extension functions supported by the
+ * implementation (whether those extensions are supported by the current
+ * client API context or not). This includes any mandatory OpenGL ES
+ * extensions.
+ *
+ * eglGetProcAddress may not be queried for core (non-extension) functions
+ * in EGL or client APIs 20 .
+ *
+ * For functions that are queryable with eglGetProcAddress,
+ * implementations may choose to also export those functions statically
+ * from the object libraries im- plementing those functions. However,
+ * portable clients cannot rely on this behavior.
+ *
+ * From the GLX 1.4 spec:
+ *
+ * "glXGetProcAddress may be queried for all of the following functions:
+ *
+ * • All GL and GLX extension functions supported by the implementation
+ * (whether those extensions are supported by the current context or
+ * not).
+ *
+ * • All core (non-extension) functions in GL and GLX from version 1.0 up
+ * to and including the versions of those specifications supported by
+ * the implementation, as determined by glGetString(GL VERSION) and
+ * glXQueryVersion queries."
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <stdio.h>
+#include "epoxy/gl.h"
+#include "epoxy/glx.h"
+#include "dispatch_common.h"
+
+/* XXX: Make this thread local */
+struct api local_api;
+
+struct api *api = &local_api;
+
+bool
+epoxy_is_desktop_gl(void)
+{
+ const char *es_prefix = "OpenGL ES ";
+ const char *version = (const char *)glGetString(GL_VERSION);
+
+ printf("VERSION %s\n", version);
+ return !strncmp(es_prefix, version, strlen(es_prefix));
+}
+
+PUBLIC int
+epoxy_gl_version(void)
+{
+ GLint major, minor;
+
+ glGetIntegerv(GL_MAJOR_VERSION, &major);
+ glGetIntegerv(GL_MAJOR_VERSION, &minor);
+
+ return major * 10 + minor;
+}
+
+bool
+epoxy_is_glx(void)
+{
+ return true; /* XXX */
+}
+
+int
+epoxy_glx_version(void)
+{
+ return 14; /* XXX */
+}
+
+static bool
+epoxy_extension_in_string(const char *extension_list, const char *ext)
+{
+ const char *ptr = extension_list;
+ int len = strlen(ext);
+
+ /* Make sure that don't just find an extension with our name as a prefix. */
+ do {
+ ptr = strstr(ptr, ext);
+ } while (ptr && (ptr[len] != ' ' && ptr[len] != 0));
+
+ return ptr != NULL;
+}
+
+PUBLIC bool
+epoxy_has_gl_extension(const char *ext)
+{
+ return epoxy_extension_in_string((const char *)glGetString(GL_EXTENSIONS),
+ ext);
+}
+
+#if 0
+PUBLIC bool
+epoxy_has_egl_extension(const char *ext)
+{
+ return epoxy_extension_in_string(eglQueryString(EGL_EXTENSIONS), ext);
+}
+#endif
+
+PUBLIC bool
+epoxy_has_glx_extension(const char *ext)
+{
+ Display *dpy = glXGetCurrentDisplay();
+ int screen = 0;
+
+ if (!dpy) {
+ fprintf(stderr, "waffle needs a display!"); /* XXX */
+ return false;
+ }
+
+ /* No, you can't just use glXGetClientString or glXGetServerString() here.
+ * Those each tell you about one half of what's needed for an extension to
+ * be supported, and glXQueryExtensionsString().
+ */
+ return epoxy_extension_in_string(glXQueryExtensionsString(dpy, screen), ext);
+}
+
+void *
+epoxy_dlsym(const char *name)
+{
+ assert(api->gl_handle);
+ return dlsym(api->gl_handle, name);
+}
+
+void *
+epoxy_get_proc_address(const char *name)
+{
+ return glXGetProcAddress((const GLubyte *)name);
+}
+
+void
+epoxy_glx_autoinit(void)
+{
+ if (api->gl_handle)
+ return;
+
+ api->gl_handle = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
+ if (!api->gl_handle) {
+ fprintf(stderr, "Couldn't open libGL.so.1: %s", dlerror());
+ exit(1);
+ }
+
+ api->winsys_handle = api->gl_handle;
+}
+
+void
+epoxy_platform_autoinit(void)
+{
+ epoxy_glx_autoinit();
+}
+