mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-23 21:35:34 +00:00
add epoxy for glew replacement
This commit is contained in:
parent
25e8cf4711
commit
1ceed22049
19 changed files with 162337 additions and 0 deletions
642
Engine/lib/epoxy/src/dispatch_common.c
Normal file
642
Engine/lib/epoxy/src/dispatch_common.c
Normal file
|
|
@ -0,0 +1,642 @@
|
|||
/*
|
||||
* Copyright © 2013-2014 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>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#include <err.h>
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dispatch_common.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define GLX_LIB "/opt/X11/lib/libGL.1.dylib"
|
||||
#elif defined(ANDROID)
|
||||
#define GLX_LIB "libGLESv2.so"
|
||||
#else
|
||||
#define GLX_LIB "libGL.so.1"
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
#define EGL_LIB "libEGL.so"
|
||||
#define GLES1_LIB "libGLESv1_CM.so"
|
||||
#define GLES2_LIB "libGLESv2.so"
|
||||
#elif defined _WIN32
|
||||
#define EGL_LIB "libEGL.dll"
|
||||
#define GLES1_LIB "libGLES_CM.dll"
|
||||
#define GLES2_LIB "libGLESv2.dll"
|
||||
#else
|
||||
#define EGL_LIB "libEGL.so.1"
|
||||
#define GLES1_LIB "libGLESv1_CM.so.1"
|
||||
#define GLES2_LIB "libGLESv2.so.2"
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define CONSTRUCT(_func) static void _func (void) __attribute__((constructor));
|
||||
#define DESTRUCT(_func) static void _func (void) __attribute__((destructor));
|
||||
#elif defined (_MSC_VER) && (_MSC_VER >= 1500)
|
||||
#define CONSTRUCT(_func) \
|
||||
static void _func(void); \
|
||||
static int _func ## _wrapper(void) { _func(); return 0; } \
|
||||
__pragma(section(".CRT$XCU",read)) \
|
||||
__declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _wrapper;
|
||||
|
||||
#define DESTRUCT(_func) \
|
||||
static void _func(void); \
|
||||
static int _func ## _constructor(void) { atexit (_func); return 0; } \
|
||||
__pragma(section(".CRT$XCU",read)) \
|
||||
__declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor;
|
||||
|
||||
#else
|
||||
#error "You will need constructor support for your compiler"
|
||||
#endif
|
||||
|
||||
struct api {
|
||||
#ifndef _WIN32
|
||||
/**
|
||||
* Locking for making sure we don't double-dlopen().
|
||||
*/
|
||||
pthread_mutex_t mutex;
|
||||
#endif
|
||||
|
||||
/** dlopen() return value for libGL.so.1. */
|
||||
void *glx_handle;
|
||||
|
||||
/**
|
||||
* dlopen() return value for OS X's GL library.
|
||||
*
|
||||
* On linux, glx_handle is used instead.
|
||||
*/
|
||||
void *gl_handle;
|
||||
|
||||
/** dlopen() return value for libEGL.so.1 */
|
||||
void *egl_handle;
|
||||
|
||||
/** dlopen() return value for libGLESv1_CM.so.1 */
|
||||
void *gles1_handle;
|
||||
|
||||
/** dlopen() return value for libGLESv2.so.2 */
|
||||
void *gles2_handle;
|
||||
|
||||
/**
|
||||
* This value gets incremented when any thread is in
|
||||
* glBegin()/glEnd() called through epoxy.
|
||||
*
|
||||
* We're not guaranteed to be called through our wrapper, so the
|
||||
* conservative paths also try to handle the failure cases they'll
|
||||
* see if begin_count didn't reflect reality. It's also a bit of
|
||||
* a bug that the conservative paths might return success because
|
||||
* some other thread was in epoxy glBegin/glEnd while our thread
|
||||
* is trying to resolve, but given that it's basically just for
|
||||
* informative error messages, we shouldn't need to care.
|
||||
*/
|
||||
long begin_count;
|
||||
};
|
||||
|
||||
static struct api api = {
|
||||
#ifndef _WIN32
|
||||
.mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
};
|
||||
|
||||
static bool library_initialized;
|
||||
|
||||
#ifdef BUILD_EGL
|
||||
static EGLenum
|
||||
epoxy_egl_get_current_gl_context_api(void);
|
||||
#endif
|
||||
|
||||
CONSTRUCT (library_init)
|
||||
static void
|
||||
library_init(void)
|
||||
{
|
||||
library_initialized = true;
|
||||
}
|
||||
|
||||
static bool
|
||||
get_dlopen_handle(void **handle, const char *lib_name, bool exit_on_fail)
|
||||
{
|
||||
if (*handle)
|
||||
return true;
|
||||
|
||||
if (!library_initialized) {
|
||||
fprintf(stderr,
|
||||
"Attempting to dlopen() while in the dynamic linker.\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
*handle = LoadLibraryA(lib_name);
|
||||
#else
|
||||
pthread_mutex_lock(&api.mutex);
|
||||
if (!*handle) {
|
||||
*handle = dlopen(lib_name, RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!*handle) {
|
||||
if (exit_on_fail) {
|
||||
fprintf(stderr, "Couldn't open %s: %s\n", lib_name, dlerror());
|
||||
exit(1);
|
||||
} else {
|
||||
(void)dlerror();
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&api.mutex);
|
||||
#endif
|
||||
|
||||
return *handle != NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
do_dlsym(void **handle, const char *lib_name, const char *name,
|
||||
bool exit_on_fail)
|
||||
{
|
||||
void *result;
|
||||
const char *error = "";
|
||||
|
||||
if (!get_dlopen_handle(handle, lib_name, exit_on_fail))
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
result = GetProcAddress(*handle, name);
|
||||
#else
|
||||
result = dlsym(*handle, name);
|
||||
if (!result)
|
||||
error = dlerror();
|
||||
#endif
|
||||
if (!result && exit_on_fail) {
|
||||
fprintf(stderr,"%s() not found in %s: %s\n", name, lib_name, error);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PUBLIC bool
|
||||
epoxy_is_desktop_gl(void)
|
||||
{
|
||||
const char *es_prefix = "OpenGL ES";
|
||||
const char *version;
|
||||
|
||||
#ifdef BUILD_EGL
|
||||
/* PowerVR's OpenGL ES implementation (and perhaps other) don't
|
||||
* comply with the standard, which states that
|
||||
* "glGetString(GL_VERSION)" should return a string starting with
|
||||
* "OpenGL ES". Therefore, to distinguish desktop OpenGL from
|
||||
* OpenGL ES, we must also check the context type through EGL (we
|
||||
* can do that as PowerVR is only usable through EGL).
|
||||
*/
|
||||
if (epoxy_current_context_is_egl()) {
|
||||
switch (epoxy_egl_get_current_gl_context_api()) {
|
||||
case EGL_OPENGL_API: return true;
|
||||
case EGL_OPENGL_ES_API: return false;
|
||||
case EGL_NONE:
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (api.begin_count)
|
||||
return true;
|
||||
|
||||
version = (const char *)glGetString(GL_VERSION);
|
||||
|
||||
/* If we didn't get a version back, there are only two things that
|
||||
* could have happened: either malloc failure (which basically
|
||||
* doesn't exist), or we were called within a glBegin()/glEnd().
|
||||
* Assume the second, which only exists for desktop GL.
|
||||
*/
|
||||
if (!version)
|
||||
return true;
|
||||
|
||||
return strncmp(es_prefix, version, strlen(es_prefix));
|
||||
}
|
||||
|
||||
static int
|
||||
epoxy_internal_gl_version(int error_version)
|
||||
{
|
||||
const char *version = (const char *)glGetString(GL_VERSION);
|
||||
GLint major, minor;
|
||||
int scanf_count;
|
||||
|
||||
if (!version)
|
||||
return error_version;
|
||||
|
||||
/* skip to version number */
|
||||
while (!isdigit(*version) && *version != '\0')
|
||||
version++;
|
||||
|
||||
/* Interpret version number */
|
||||
scanf_count = sscanf(version, "%i.%i", &major, &minor);
|
||||
if (scanf_count != 2) {
|
||||
fprintf(stderr, "Unable to interpret GL_VERSION string: %s\n",
|
||||
version);
|
||||
exit(1);
|
||||
}
|
||||
return 10 * major + minor;
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
epoxy_gl_version(void)
|
||||
{
|
||||
return epoxy_internal_gl_version(0);
|
||||
}
|
||||
|
||||
int
|
||||
epoxy_conservative_gl_version(void)
|
||||
{
|
||||
if (api.begin_count)
|
||||
return 100;
|
||||
|
||||
return epoxy_internal_gl_version(100);
|
||||
}
|
||||
|
||||
bool
|
||||
epoxy_extension_in_string(const char *extension_list, const char *ext)
|
||||
{
|
||||
const char *ptr = extension_list;
|
||||
size_t len = strlen(ext);
|
||||
|
||||
/* Make sure that don't just find an extension with our name as a prefix. */
|
||||
while (true) {
|
||||
ptr = strstr(ptr, ext);
|
||||
if (!ptr)
|
||||
return false;
|
||||
|
||||
if (ptr[len] == ' ' || ptr[len] == 0)
|
||||
return true;
|
||||
ptr += len;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
epoxy_internal_has_gl_extension(const char *ext, bool invalid_op_mode)
|
||||
{
|
||||
if (epoxy_gl_version() < 30) {
|
||||
const char *exts = (const char *)glGetString(GL_EXTENSIONS);
|
||||
if (!exts)
|
||||
return invalid_op_mode;
|
||||
return epoxy_extension_in_string(exts, ext);
|
||||
} else {
|
||||
int num_extensions;
|
||||
int i;
|
||||
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
|
||||
if (num_extensions == 0)
|
||||
return invalid_op_mode;
|
||||
|
||||
for (i = 0; i < num_extensions; i++) {
|
||||
const char *gl_ext = (const char *)glGetStringi(GL_EXTENSIONS, i);
|
||||
if (strcmp(ext, gl_ext) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the currently bound context is EGL or GLX, trying to
|
||||
* avoid loading libraries unless necessary.
|
||||
*/
|
||||
EPOXY_IMPORTEXPORT bool
|
||||
epoxy_current_context_is_egl(void)
|
||||
{
|
||||
#ifdef BUILD_EGL
|
||||
if (get_dlopen_handle(&api.egl_handle, EGL_LIB, false) && epoxy_egl_get_current_gl_context_api() != EGL_NONE)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given GL extension is supported in the current context.
|
||||
*
|
||||
* Note that this function can't be called from within glBegin()/glEnd().
|
||||
*
|
||||
* \sa epoxy_has_egl_extension()
|
||||
* \sa epoxy_has_glx_extension()
|
||||
*/
|
||||
PUBLIC bool
|
||||
epoxy_has_gl_extension(const char *ext)
|
||||
{
|
||||
return epoxy_internal_has_gl_extension(ext, false);
|
||||
}
|
||||
|
||||
bool
|
||||
epoxy_conservative_has_gl_extension(const char *ext)
|
||||
{
|
||||
if (api.begin_count)
|
||||
return true;
|
||||
|
||||
return epoxy_internal_has_gl_extension(ext, true);
|
||||
}
|
||||
|
||||
void *
|
||||
epoxy_egl_dlsym(const char *name)
|
||||
{
|
||||
return do_dlsym(&api.egl_handle, EGL_LIB, name, true);
|
||||
}
|
||||
|
||||
void *
|
||||
epoxy_glx_dlsym(const char *name)
|
||||
{
|
||||
return do_dlsym(&api.glx_handle, GLX_LIB, name, true);
|
||||
}
|
||||
|
||||
void *
|
||||
epoxy_gl_dlsym(const char *name)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return do_dlsym(&api.gl_handle, "OPENGL32", name, true);
|
||||
#elif defined(__APPLE__)
|
||||
return do_dlsym(&api.gl_handle,
|
||||
"/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL",
|
||||
name, true);
|
||||
#else
|
||||
/* There's no library for desktop GL support independent of GLX. */
|
||||
return epoxy_glx_dlsym(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *
|
||||
epoxy_gles1_dlsym(const char *name)
|
||||
{
|
||||
if (!epoxy_current_context_is_egl()) {
|
||||
return epoxy_get_proc_address(name);
|
||||
} else {
|
||||
return do_dlsym(&api.gles1_handle, GLES1_LIB, name, true);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
epoxy_gles2_dlsym(const char *name)
|
||||
{
|
||||
if (!epoxy_current_context_is_egl()) {
|
||||
return epoxy_get_proc_address(name);
|
||||
} else {
|
||||
return do_dlsym(&api.gles2_handle, GLES2_LIB, name, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the appropriate dlsym() or eglGetProcAddress() for GLES3
|
||||
* functions.
|
||||
*
|
||||
* Mesa interpreted GLES as intending that the GLES3 functions were
|
||||
* available only through eglGetProcAddress() and not dlsym(), while
|
||||
* ARM's Mali drivers interpreted GLES as intending that GLES3
|
||||
* functions were available only through dlsym() and not
|
||||
* eglGetProcAddress(). Thanks, Khronos.
|
||||
*/
|
||||
void *
|
||||
epoxy_gles3_dlsym(const char *name)
|
||||
{
|
||||
if (!epoxy_current_context_is_egl()) {
|
||||
return epoxy_get_proc_address(name);
|
||||
} else {
|
||||
void *func = do_dlsym(&api.gles2_handle, GLES2_LIB, name, false);
|
||||
|
||||
if (func)
|
||||
return func;
|
||||
|
||||
return epoxy_get_proc_address(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs either the dlsym or glXGetProcAddress()-equivalent for
|
||||
* core functions in desktop GL.
|
||||
*/
|
||||
void *
|
||||
epoxy_get_core_proc_address(const char *name, int core_version)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int core_symbol_support = 11;
|
||||
#elif defined(ANDROID)
|
||||
/**
|
||||
* All symbols must be resolved through eglGetProcAddress
|
||||
* on Android
|
||||
*/
|
||||
int core_symbol_support = 0;
|
||||
#else
|
||||
int core_symbol_support = 12;
|
||||
#endif
|
||||
|
||||
if (core_version <= core_symbol_support) {
|
||||
return epoxy_gl_dlsym(name);
|
||||
} else {
|
||||
return epoxy_get_proc_address(name);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BUILD_EGL
|
||||
static EGLenum
|
||||
epoxy_egl_get_current_gl_context_api(void)
|
||||
{
|
||||
EGLDisplay eglDisplay = eglGetCurrentDisplay();
|
||||
EGLContext eglContext = eglGetCurrentContext();
|
||||
EGLint eglContextClientType = EGL_NONE;
|
||||
return eglQueryContext(eglDisplay, eglContext, EGL_CONTEXT_CLIENT_TYPE,
|
||||
&eglContextClientType) == EGL_TRUE
|
||||
? (EGLenum)eglContextClientType
|
||||
: EGL_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Performs the dlsym() for the core GL 1.0 functions that we use for
|
||||
* determining version and extension support for deciding on dlsym
|
||||
* versus glXGetProcAddress() for all other functions.
|
||||
*
|
||||
* This needs to succeed on implementations without GLX (since
|
||||
* glGetString() and glGetIntegerv() are both in GLES1/2 as well, and
|
||||
* at call time we don't know for sure what API they're trying to use
|
||||
* without inspecting contexts ourselves).
|
||||
*/
|
||||
void *
|
||||
epoxy_get_bootstrap_proc_address(const char *name)
|
||||
{
|
||||
/* If we already have a library that links to libglapi loaded,
|
||||
* use that.
|
||||
*/
|
||||
#ifdef BUILD_GLX
|
||||
if (api.glx_handle && glXGetCurrentContext())
|
||||
return epoxy_gl_dlsym(name);
|
||||
#endif
|
||||
|
||||
/* If epoxy hasn't loaded any API-specific library yet, try to
|
||||
* figure out what API the context is using and use that library,
|
||||
* since future calls will also use that API (this prevents a
|
||||
* non-X11 ES2 context from loading a bunch of X11 junk).
|
||||
*/
|
||||
#ifdef BUILD_EGL
|
||||
get_dlopen_handle(&api.egl_handle, EGL_LIB, false);
|
||||
if (api.egl_handle) {
|
||||
switch (epoxy_egl_get_current_gl_context_api()) {
|
||||
case EGL_OPENGL_API:
|
||||
return epoxy_gl_dlsym(name);
|
||||
case EGL_OPENGL_ES_API: {
|
||||
EGLDisplay eglDisplay = eglGetCurrentDisplay();
|
||||
EGLContext eglContext = eglGetCurrentContext();
|
||||
EGLint glesVer = -1;
|
||||
if (eglDisplay != EGL_NO_DISPLAY
|
||||
&& eglContext != EGL_NO_CONTEXT
|
||||
&& eglQueryContext(eglDisplay, eglContext,
|
||||
EGL_CONTEXT_CLIENT_VERSION, &glesVer) == EGL_TRUE)
|
||||
return glesVer >= 2 ? epoxy_gles2_dlsym(name) : epoxy_gles1_dlsym(name);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fall back to GLX */
|
||||
return epoxy_gl_dlsym(name);
|
||||
}
|
||||
|
||||
void *
|
||||
epoxy_get_proc_address(const char *name)
|
||||
{
|
||||
#if defined(BUILD_EGL)
|
||||
if (epoxy_current_context_is_egl())
|
||||
return eglGetProcAddress(name);
|
||||
#endif
|
||||
#if defined(BUILD_WGL)
|
||||
void *func = wglGetProcAddress(name);
|
||||
return func ? func : epoxy_gl_dlsym(name);
|
||||
#elif defined(__APPLE__)
|
||||
return epoxy_gl_dlsym(name);
|
||||
#elif defined(BUILD_GLX)
|
||||
return glXGetProcAddressARB((const GLubyte *)name);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
WRAPPER_VISIBILITY (void)
|
||||
WRAPPER(epoxy_glBegin)(GLenum primtype)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
InterlockedIncrement(&api.begin_count);
|
||||
#else
|
||||
pthread_mutex_lock(&api.mutex);
|
||||
api.begin_count++;
|
||||
pthread_mutex_unlock(&api.mutex);
|
||||
#endif
|
||||
|
||||
epoxy_glBegin_unwrapped(primtype);
|
||||
}
|
||||
|
||||
WRAPPER_VISIBILITY (void)
|
||||
WRAPPER(epoxy_glEnd)(void)
|
||||
{
|
||||
epoxy_glEnd_unwrapped();
|
||||
|
||||
#ifdef _WIN32
|
||||
InterlockedDecrement(&api.begin_count);
|
||||
#else
|
||||
pthread_mutex_lock(&api.mutex);
|
||||
api.begin_count--;
|
||||
pthread_mutex_unlock(&api.mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
PUBLIC PFNGLBEGINPROC epoxy_glBegin = epoxy_glBegin_wrapped;
|
||||
PUBLIC PFNGLENDPROC epoxy_glEnd = epoxy_glEnd_wrapped;
|
||||
188
Engine/lib/epoxy/src/dispatch_common.h
Normal file
188
Engine/lib/epoxy/src/dispatch_common.h
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN 1
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef EPOXY_DLL
|
||||
# define EPOXY_IMPORTEXPORT __declspec(dllexport)
|
||||
# endif
|
||||
#else
|
||||
# ifdef EPOXY_DLL
|
||||
# define EPOXY_IMPORTEXPORT __attribute__((visibility("default")))
|
||||
# endif
|
||||
#endif
|
||||
#ifndef EPOXY_IMPORTEXPORT
|
||||
# define EPOXY_IMPORTEXPORT
|
||||
#endif
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
#ifdef BUILD_GLX
|
||||
# include <epoxy/glx.h>
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_EGL
|
||||
# include <epoxy/egl.h>
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_WGL
|
||||
# include <epoxy/wgl.h>
|
||||
#endif
|
||||
|
||||
#ifndef PUBLIC
|
||||
# define PUBLIC EPOXY_IMPORTEXPORT
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define PACKED __attribute__((__packed__))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
/* On win32, we're going to need to keep a per-thread dispatch table,
|
||||
* since the function pointers depend on the device and pixel format
|
||||
* of the current context.
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
#define USING_DISPATCH_TABLE 1
|
||||
#else
|
||||
#define USING_DISPATCH_TABLE 0
|
||||
#endif
|
||||
|
||||
#define UNWRAPPED_PROTO(x) (GLAPIENTRY *x)
|
||||
#define WRAPPER_VISIBILITY(type) static type GLAPIENTRY
|
||||
#define WRAPPER(x) x ## _wrapped
|
||||
|
||||
#define GEN_GLOBAL_REWRITE_PTR(name, args, passthrough) \
|
||||
static void EPOXY_CALLSPEC \
|
||||
name##_global_rewrite_ptr args \
|
||||
{ \
|
||||
name = (void *)name##_resolver(); \
|
||||
name passthrough; \
|
||||
}
|
||||
|
||||
#define GEN_GLOBAL_REWRITE_PTR_RET(ret, name, args, passthrough) \
|
||||
static ret EPOXY_CALLSPEC \
|
||||
name##_global_rewrite_ptr args \
|
||||
{ \
|
||||
name = (void *)name##_resolver(); \
|
||||
return name passthrough; \
|
||||
}
|
||||
|
||||
#if USING_DISPATCH_TABLE
|
||||
#define GEN_DISPATCH_TABLE_REWRITE_PTR(name, args, passthrough) \
|
||||
static void EPOXY_CALLSPEC \
|
||||
name##_dispatch_table_rewrite_ptr args \
|
||||
{ \
|
||||
struct dispatch_table *dispatch_table = get_dispatch_table(); \
|
||||
\
|
||||
dispatch_table->name = (void *)name##_resolver(); \
|
||||
dispatch_table->name passthrough; \
|
||||
}
|
||||
|
||||
#define GEN_DISPATCH_TABLE_REWRITE_PTR_RET(ret, name, args, passthrough) \
|
||||
static ret EPOXY_CALLSPEC \
|
||||
name##_dispatch_table_rewrite_ptr args \
|
||||
{ \
|
||||
struct dispatch_table *dispatch_table = get_dispatch_table(); \
|
||||
\
|
||||
dispatch_table->name = (void *)name##_resolver(); \
|
||||
return dispatch_table->name passthrough; \
|
||||
}
|
||||
|
||||
#define GEN_DISPATCH_TABLE_THUNK(name, args, passthrough) \
|
||||
static void EPOXY_CALLSPEC \
|
||||
name##_dispatch_table_thunk args \
|
||||
{ \
|
||||
get_dispatch_table()->name passthrough; \
|
||||
}
|
||||
|
||||
#define GEN_DISPATCH_TABLE_THUNK_RET(ret, name, args, passthrough) \
|
||||
static ret EPOXY_CALLSPEC \
|
||||
name##_dispatch_table_thunk args \
|
||||
{ \
|
||||
return get_dispatch_table()->name passthrough; \
|
||||
}
|
||||
|
||||
#else
|
||||
#define GEN_DISPATCH_TABLE_REWRITE_PTR(name, args, passthrough)
|
||||
#define GEN_DISPATCH_TABLE_REWRITE_PTR_RET(ret, name, args, passthrough)
|
||||
#define GEN_DISPATCH_TABLE_THUNK(name, args, passthrough)
|
||||
#define GEN_DISPATCH_TABLE_THUNK_RET(ret, name, args, passthrough)
|
||||
#endif
|
||||
|
||||
#define GEN_THUNKS(name, args, passthrough) \
|
||||
GEN_GLOBAL_REWRITE_PTR(name, args, passthrough) \
|
||||
GEN_DISPATCH_TABLE_REWRITE_PTR(name, args, passthrough) \
|
||||
GEN_DISPATCH_TABLE_THUNK(name, args, passthrough)
|
||||
|
||||
#define GEN_THUNKS_RET(ret, name, args, passthrough) \
|
||||
GEN_GLOBAL_REWRITE_PTR_RET(ret, name, args, passthrough) \
|
||||
GEN_DISPATCH_TABLE_REWRITE_PTR_RET(ret, name, args, passthrough) \
|
||||
GEN_DISPATCH_TABLE_THUNK_RET(ret, name, args, passthrough)
|
||||
|
||||
void *epoxy_egl_dlsym(const char *name);
|
||||
void *epoxy_glx_dlsym(const char *name);
|
||||
void *epoxy_gl_dlsym(const char *name);
|
||||
void *epoxy_gles1_dlsym(const char *name);
|
||||
void *epoxy_gles2_dlsym(const char *name);
|
||||
void *epoxy_gles3_dlsym(const char *name);
|
||||
void *epoxy_get_proc_address(const char *name);
|
||||
void *epoxy_get_core_proc_address(const char *name, int core_version);
|
||||
void *epoxy_get_bootstrap_proc_address(const char *name);
|
||||
|
||||
int epoxy_conservative_gl_version(void);
|
||||
bool epoxy_conservative_has_gl_extension(const char *name);
|
||||
int epoxy_conservative_glx_version(void);
|
||||
bool epoxy_conservative_has_glx_extension(const char *name);
|
||||
int epoxy_conservative_egl_version(void);
|
||||
bool epoxy_conservative_has_egl_extension(const char *name);
|
||||
bool epoxy_conservative_has_wgl_extension(const char *name);
|
||||
|
||||
bool epoxy_extension_in_string(const char *extension_list, const char *ext);
|
||||
|
||||
#define glBegin_unwrapped epoxy_glBegin_unwrapped
|
||||
#define glEnd_unwrapped epoxy_glEnd_unwrapped
|
||||
extern void UNWRAPPED_PROTO(glBegin_unwrapped)(GLenum primtype);
|
||||
extern void UNWRAPPED_PROTO(glEnd_unwrapped)(void);
|
||||
|
||||
#if USING_DISPATCH_TABLE
|
||||
void gl_init_dispatch_table(void);
|
||||
void gl_switch_to_dispatch_table(void);
|
||||
void wgl_init_dispatch_table(void);
|
||||
void wgl_switch_to_dispatch_table(void);
|
||||
extern uint32_t gl_tls_index, gl_tls_size;
|
||||
extern uint32_t wgl_tls_index, wgl_tls_size;
|
||||
|
||||
#define wglMakeCurrent_unwrapped epoxy_wglMakeCurrent_unwrapped
|
||||
#define wglMakeContextCurrentARB_unwrapped epoxy_wglMakeContextCurrentARB_unwrapped
|
||||
#define wglMakeContextCurrentEXT_unwrapped epoxy_wglMakeContextCurrentEXT_unwrapped
|
||||
#define wglMakeAssociatedContextCurrentAMD_unwrapped epoxy_wglMakeAssociatedContextCurrentAMD_unwrapped
|
||||
extern BOOL UNWRAPPED_PROTO(wglMakeCurrent_unwrapped)(HDC hdc, HGLRC hglrc);
|
||||
extern BOOL UNWRAPPED_PROTO(wglMakeContextCurrentARB_unwrapped)(HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
|
||||
extern BOOL UNWRAPPED_PROTO(wglMakeContextCurrentEXT_unwrapped)(HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
|
||||
extern BOOL UNWRAPPED_PROTO(wglMakeAssociatedContextCurrentAMD_unwrapped)(HGLRC hglrc);
|
||||
#endif /* _WIN32_ */
|
||||
69
Engine/lib/epoxy/src/egl/dispatch_egl.c
Normal file
69
Engine/lib/epoxy/src/egl/dispatch_egl.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dispatch_common.h"
|
||||
|
||||
int
|
||||
epoxy_conservative_egl_version(void)
|
||||
{
|
||||
EGLDisplay dpy = eglGetCurrentDisplay();
|
||||
|
||||
if (!dpy)
|
||||
return 14;
|
||||
|
||||
return epoxy_egl_version(dpy);
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
epoxy_egl_version(EGLDisplay dpy)
|
||||
{
|
||||
int major, minor;
|
||||
const char *version_string;
|
||||
int ret;
|
||||
|
||||
version_string = eglQueryString(dpy, EGL_VERSION);
|
||||
ret = sscanf(version_string, "%d.%d", &major, &minor);
|
||||
assert(ret == 2);
|
||||
return major * 10 + minor;
|
||||
}
|
||||
|
||||
bool
|
||||
epoxy_conservative_has_egl_extension(const char *ext)
|
||||
{
|
||||
EGLDisplay dpy = eglGetCurrentDisplay();
|
||||
|
||||
if (!dpy)
|
||||
return true;
|
||||
|
||||
return epoxy_has_egl_extension(dpy, ext);
|
||||
}
|
||||
|
||||
PUBLIC bool
|
||||
epoxy_has_egl_extension(EGLDisplay dpy, const char *ext)
|
||||
{
|
||||
return epoxy_extension_in_string(eglQueryString(dpy, EGL_EXTENSIONS), ext);
|
||||
}
|
||||
4206
Engine/lib/epoxy/src/egl/egl_generated_dispatch.c
Normal file
4206
Engine/lib/epoxy/src/egl/egl_generated_dispatch.c
Normal file
File diff suppressed because it is too large
Load diff
124424
Engine/lib/epoxy/src/egl/gl_generated_dispatch.c
Normal file
124424
Engine/lib/epoxy/src/egl/gl_generated_dispatch.c
Normal file
File diff suppressed because it is too large
Load diff
106
Engine/lib/epoxy/src/glx/dispatch_glx.c
Normal file
106
Engine/lib/epoxy/src/glx/dispatch_glx.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dispatch_common.h"
|
||||
|
||||
/**
|
||||
* If we can determine the GLX version from the current context, then
|
||||
* return that, otherwise return a version that will just send us on
|
||||
* to dlsym() or get_proc_address().
|
||||
*/
|
||||
int
|
||||
epoxy_conservative_glx_version(void)
|
||||
{
|
||||
Display *dpy = glXGetCurrentDisplay();
|
||||
GLXContext ctx = glXGetCurrentContext();
|
||||
int screen;
|
||||
|
||||
if (!dpy || !ctx)
|
||||
return 14;
|
||||
|
||||
glXQueryContext(dpy, ctx, GLX_SCREEN, &screen);
|
||||
|
||||
return epoxy_glx_version(dpy, screen);
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
epoxy_glx_version(Display *dpy, int screen)
|
||||
{
|
||||
int server_major, server_minor;
|
||||
int client_major, client_minor;
|
||||
int server, client;
|
||||
const char *version_string;
|
||||
int ret=0, sscanf_ret;
|
||||
|
||||
if ((version_string = glXQueryServerString(dpy, screen, GLX_VERSION)))
|
||||
{
|
||||
sscanf_ret = sscanf(version_string, "%d.%d", &server_major, &server_minor);
|
||||
assert(sscanf_ret == 2);
|
||||
server = server_major * 10 + server_minor;
|
||||
if ((version_string = glXGetClientString(dpy, GLX_VERSION)))
|
||||
{
|
||||
sscanf_ret = sscanf(version_string, "%d.%d", &client_major, &client_minor);
|
||||
assert(sscanf_ret == 2);
|
||||
client = client_major * 10 + client_minor;
|
||||
ret = client <= server ? client : server;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* If we can determine the GLX extension support from the current
|
||||
* context, then return that, otherwise give the answer that will just
|
||||
* send us on to get_proc_address().
|
||||
*/
|
||||
bool
|
||||
epoxy_conservative_has_glx_extension(const char *ext)
|
||||
{
|
||||
Display *dpy = glXGetCurrentDisplay();
|
||||
GLXContext ctx = glXGetCurrentContext();
|
||||
int screen;
|
||||
|
||||
if (!dpy || !ctx)
|
||||
return true;
|
||||
|
||||
glXQueryContext(dpy, ctx, GLX_SCREEN, &screen);
|
||||
|
||||
return epoxy_has_glx_extension(dpy, screen, ext);
|
||||
}
|
||||
|
||||
PUBLIC bool
|
||||
epoxy_has_glx_extension(Display *dpy, int screen, const char *ext)
|
||||
{
|
||||
/* 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() is what gives you the intersection
|
||||
* of the two.
|
||||
*/
|
||||
return epoxy_extension_in_string(glXQueryExtensionsString(dpy, screen), ext);
|
||||
}
|
||||
4812
Engine/lib/epoxy/src/glx/glx_generated_dispatch.c
Normal file
4812
Engine/lib/epoxy/src/glx/glx_generated_dispatch.c
Normal file
File diff suppressed because it is too large
Load diff
217
Engine/lib/epoxy/src/wgl/dispatch_wgl.c
Normal file
217
Engine/lib/epoxy/src/wgl/dispatch_wgl.c
Normal file
|
|
@ -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.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "dispatch_common.h"
|
||||
|
||||
static bool first_context_current = false;
|
||||
static bool already_switched_to_dispatch_table = false;
|
||||
|
||||
/**
|
||||
* If we can determine the WGL extension support from the current
|
||||
* context, then return that, otherwise give the answer that will just
|
||||
* send us on to get_proc_address().
|
||||
*/
|
||||
bool
|
||||
epoxy_conservative_has_wgl_extension(const char *ext)
|
||||
{
|
||||
HDC hdc = wglGetCurrentDC();
|
||||
|
||||
if (!hdc)
|
||||
return true;
|
||||
|
||||
return epoxy_has_wgl_extension(hdc, ext);
|
||||
}
|
||||
|
||||
PUBLIC bool
|
||||
epoxy_has_wgl_extension(HDC hdc, const char *ext)
|
||||
{
|
||||
PFNWGLGETEXTENSIONSSTRINGARBPROC getext;
|
||||
|
||||
getext = (void *)wglGetProcAddress("wglGetExtensionsStringARB");
|
||||
if (!getext) {
|
||||
fprintf(stderr,
|
||||
"Implementation unexpectedly missing "
|
||||
"WGL_ARB_extensions_string. Probably a libepoxy bug.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return epoxy_extension_in_string(getext(hdc), ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the work necessary to update the win32 per-thread dispatch
|
||||
* tables when wglMakeCurrent() is called.
|
||||
*
|
||||
* Right now, we use global function pointers until the second
|
||||
* MakeCurrent occurs, at which point we switch to dispatch tables.
|
||||
* This could be improved in the future to track a resolved dispatch
|
||||
* table per context and reuse it when the context is made current
|
||||
* again.
|
||||
*/
|
||||
PUBLIC void
|
||||
epoxy_handle_external_wglMakeCurrent(void)
|
||||
{
|
||||
if (!first_context_current) {
|
||||
first_context_current = true;
|
||||
} else {
|
||||
if (!already_switched_to_dispatch_table) {
|
||||
already_switched_to_dispatch_table = true;
|
||||
gl_switch_to_dispatch_table();
|
||||
wgl_switch_to_dispatch_table();
|
||||
}
|
||||
|
||||
gl_init_dispatch_table();
|
||||
wgl_init_dispatch_table();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This global symbol is apparently looked up by Windows when loading
|
||||
* a DLL, but it doesn't declare the prototype.
|
||||
*/
|
||||
BOOL WINAPI
|
||||
DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved);
|
||||
|
||||
BOOL WINAPI
|
||||
DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved)
|
||||
{
|
||||
void *data;
|
||||
|
||||
switch (reason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
gl_tls_index = TlsAlloc();
|
||||
if (gl_tls_index == TLS_OUT_OF_INDEXES)
|
||||
return FALSE;
|
||||
wgl_tls_index = TlsAlloc();
|
||||
if (wgl_tls_index == TLS_OUT_OF_INDEXES)
|
||||
return FALSE;
|
||||
|
||||
first_context_current = false;
|
||||
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
data = LocalAlloc(LPTR, gl_tls_size);
|
||||
TlsSetValue(gl_tls_index, data);
|
||||
|
||||
data = LocalAlloc(LPTR, wgl_tls_size);
|
||||
TlsSetValue(wgl_tls_index, data);
|
||||
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
data = TlsGetValue(gl_tls_index);
|
||||
LocalFree(data);
|
||||
|
||||
data = TlsGetValue(wgl_tls_index);
|
||||
LocalFree(data);
|
||||
|
||||
if (reason == DLL_PROCESS_DETACH) {
|
||||
TlsFree(gl_tls_index);
|
||||
TlsFree(wgl_tls_index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifndef EPOXY_DLL
|
||||
#ifdef __GNUC__
|
||||
PIMAGE_TLS_CALLBACK dllmain_callback __attribute__((section(".CRT$XLB"))) = (PIMAGE_TLS_CALLBACK)DllMain;
|
||||
#else
|
||||
# ifdef _WIN64
|
||||
# pragma comment(linker, "/INCLUDE:_tls_used")
|
||||
# pragma comment(linker, "/INCLUDE:dllmain_callback")
|
||||
# pragma const_seg(".CRT$XLB")
|
||||
extern const PIMAGE_TLS_CALLBACK dllmain_callback;
|
||||
const PIMAGE_TLS_CALLBACK dllmain_callback = DllMain;
|
||||
# pragma const_seg()
|
||||
# else
|
||||
# pragma comment(linker, "/INCLUDE:__tls_used")
|
||||
# pragma comment(linker, "/INCLUDE:_dllmain_callback")
|
||||
# pragma data_seg(".CRT$XLB")
|
||||
PIMAGE_TLS_CALLBACK dllmain_callback = DllMain;
|
||||
# pragma data_seg()
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
WRAPPER_VISIBILITY (BOOL)
|
||||
WRAPPER(epoxy_wglMakeCurrent)(HDC hdc, HGLRC hglrc)
|
||||
{
|
||||
BOOL ret = epoxy_wglMakeCurrent_unwrapped(hdc, hglrc);
|
||||
|
||||
epoxy_handle_external_wglMakeCurrent();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
WRAPPER_VISIBILITY (BOOL)
|
||||
WRAPPER(epoxy_wglMakeContextCurrentARB)(HDC hDrawDC,
|
||||
HDC hReadDC,
|
||||
HGLRC hglrc)
|
||||
{
|
||||
BOOL ret = epoxy_wglMakeContextCurrentARB_unwrapped(hDrawDC, hReadDC,
|
||||
hglrc);
|
||||
|
||||
epoxy_handle_external_wglMakeCurrent();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
WRAPPER_VISIBILITY (BOOL)
|
||||
WRAPPER(epoxy_wglMakeContextCurrentEXT)(HDC hDrawDC,
|
||||
HDC hReadDC,
|
||||
HGLRC hglrc)
|
||||
{
|
||||
BOOL ret = epoxy_wglMakeContextCurrentEXT_unwrapped(hDrawDC, hReadDC,
|
||||
hglrc);
|
||||
|
||||
epoxy_handle_external_wglMakeCurrent();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
WRAPPER_VISIBILITY (BOOL)
|
||||
WRAPPER(epoxy_wglMakeAssociatedContextCurrentAMD)(HGLRC hglrc)
|
||||
{
|
||||
BOOL ret = epoxy_wglMakeAssociatedContextCurrentAMD_unwrapped(hglrc);
|
||||
|
||||
epoxy_handle_external_wglMakeCurrent();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
PUBLIC PFNWGLMAKECURRENTPROC epoxy_wglMakeCurrent = epoxy_wglMakeCurrent_wrapped;
|
||||
PUBLIC PFNWGLMAKECONTEXTCURRENTEXTPROC epoxy_wglMakeContextCurrentEXT = epoxy_wglMakeContextCurrentEXT_wrapped;
|
||||
PUBLIC PFNWGLMAKECONTEXTCURRENTARBPROC epoxy_wglMakeContextCurrentARB = epoxy_wglMakeContextCurrentARB_wrapped;
|
||||
PUBLIC PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC epoxy_wglMakeAssociatedContextCurrentEXT = epoxy_wglMakeAssociatedContextCurrentAMD_wrapped;
|
||||
5250
Engine/lib/epoxy/src/wgl/wgl_generated_dispatch.c
Normal file
5250
Engine/lib/epoxy/src/wgl/wgl_generated_dispatch.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue