diff options
Diffstat (limited to 'src/dispatch_common.c')
-rw-r--r-- | src/dispatch_common.c | 217 |
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(); +} + |