# Copyright (c) 2001, Stanford University
# All rights reserved.
#
# See the file LICENSE.txt for information on redistributing this software.
import sys
import apiutil
keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
apiutil.CopyrightC()
print """
/* DO NOT EDIT - THIS FILE GENERATED BY THE glloader.py SCRIPT */
#include "cr_error.h"
#include "cr_dll.h"
#include "cr_spu.h"
#include "cr_string.h"
#include "cr_error.h"
#include "cr_environment.h"
#include <stdio.h>
#if defined(WINDOWS)
#include <windows.h>
#include <process.h>
#include <direct.h>
#define SYSTEM_GL "opengl32.dll"
#elif defined (DARWIN)
#define SYSTEM_GL "libGL.dylib"
#define SYSTEM_CGL "OpenGL"
# ifndef VBOX_WITH_COCOA_QT
# define SYSTEM_AGL "AGL"
# endif
#include <string.h> /* VBOX */
#elif defined(IRIX) || defined(IRIX64) || defined(Linux) || defined(FreeBSD) || defined(AIX) || defined(SunOS) || defined(OSF1)
#include <string.h>
#if defined(AIX)
#define SYSTEM_GL "libGL.o"
#else
#define SYSTEM_GL "libGL.so.1"
#endif
typedef void (*glxfuncptr)();
extern glxfuncptr glxGetProcAddressARB( const GLubyte *name );
#else
#error I don't know where your system's GL lives. Too bad.
#endif
static CRDLL *glDll = NULL;
#ifdef DARWIN
#define SYSTEM_GL_LIB_DIR "/System/Library/Frameworks/OpenGL.framework/Libraries"
#define SYSTEM_CGL_DIR "/System/Library/Frameworks/OpenGL.framework"
static CRDLL *cglDll = NULL;
# ifndef VBOX_WITH_COCOA_QT
# define SYSTEM_AGL_DIR "/System/Library/Frameworks/AGL.framework"
static CRDLL *aglDll = NULL;
# endif
#endif
#if defined(WINDOWS)
#define GLLOADER_APIENTRY __stdcall
#else
#define GLLOADER_APIENTRY
#endif
/*
* Add an entry to the SPUNamedFunctionTable
*/
static int
fillin( SPUNamedFunctionTable *entry, const char *funcName, SPUGenericFunction funcPtr )
{
if (funcPtr) {
entry->name = crStrdup( funcName );
entry->fn = funcPtr;
return 1;
}
return 0;
}
#ifndef WINDOWS
static int FileExists(char *directory, char *filename)
{
FILE *f;
char fullFilename[8096];
crStrcpy(fullFilename, directory);
crStrcat(fullFilename, "/");
crStrcat(fullFilename, filename);
f = fopen(fullFilename, "r");
if (f) {
fclose(f);
return 1;
}
else {
return 0;
}
}
#endif
/*
* Locate the native OpenGL library, open it and return shared library
* handle.
*/
static CRDLL *
__findSystemLib( const char *provided_system_path, char *lib )
{
CRDLL *dll;
char system_path[8096];
memset(system_path, 0, sizeof(system_path));
if (provided_system_path && (crStrlen(provided_system_path) > 0) )
{
crStrcpy( system_path, provided_system_path );
}
else
{
#if defined(WINDOWS)
GetSystemDirectory(system_path, MAX_PATH);
#elif defined(IRIX) || defined(IRIX64)
#ifdef IRIX_64BIT
crStrcpy( system_path, "/usr/lib64" );
#else
crStrcpy( system_path, "/usr/lib32" );
#endif
#elif defined(PLAYSTATION2)
crStrcpy( system_path, "/usr/X11R6/lib" );
#else
/* On RedHat 9, the correct default system directory
* is /usr/lib/tls/ (and if /usr/lib/ is used,
* the dynamic loader will generate a floating point
* exception SIGFPE). On other systems, including
* earlier versions of RedHat, the OpenGL library
* lives in /usr/lib. We'll use the /usr/lib/tls/
* version if it exists; otherwise, we'll use /usr/lib.
*/
/*crStrcpy(system_path, "/usr/lib");*/
#if defined(__linux__) && defined(__amd64__)
/*if (sizeof(void *) == 8 && FileExists("/usr/lib64", lib)) {
crStrcat(system_path, "64");
}*/
#endif
/*if (FileExists("/usr/lib/tls", lib) ||
FileExists("/usr/lib64/tls", lib)) {
crStrcat(system_path, "/tls");
}*/
#endif
}
#if !defined(__linux__) && !defined(SunOS) && !defined(__FreeBSD__)
crStrcat( system_path, "/" );
#endif
#if !defined(CR_NO_GL_SYSTEM_PATH)
crStrcat( system_path, lib );
dll = crDLLOpen(system_path, 1 /*resolveGlobal*/);
#else
dll = crDLLOpen(lib, 1 /*resolveGlobal*/);
#endif
return dll;
}
static CRDLL *
#ifdef DARWIN
__findSystemGL( const char *provided_system_path, const char *default_system_path, char *provided_lib_name )
#else
__findSystemGL( const char *provided_system_path )
#endif
{
#ifdef DARWIN
const char *the_path = (provided_system_path && crStrlen(provided_system_path) > 0) ? provided_system_path : default_system_path;
/* Fallback for loading frameworks */
if( !provided_lib_name )
return crDLLOpen( the_path, 1 );
else
return __findSystemLib( the_path, provided_lib_name );
#else
return __findSystemLib( provided_system_path, SYSTEM_GL );
#endif
}
static SPUGenericFunction
findExtFunction( const crOpenGLInterface *interface, const char *funcName )
{
#ifdef WINDOWS
if (interface->wglGetProcAddress)
return (SPUGenericFunction) interface->wglGetProcAddress( funcName );
else
return (SPUGenericFunction) NULL;
#else
/* XXX for some reason, the NVIDIA glXGetProcAddressARB() function
* returns pointers that cause Chromium to crash. If we use the
* pointer returned by crDLLGetNoError() instead, we're OK.
*/
SPUGenericFunction f = crDLLGetNoError(glDll, funcName);
if (f)
return f;
#if !defined(DARWIN)
else if (interface->glXGetProcAddressARB)
return interface->glXGetProcAddressARB( (const GLubyte *) funcName );
#endif
else
return NULL;
#endif
}
"""
def IsExtensionFunc(func_name):
"""Determine if the named function is a core function, or extension."""
cat = apiutil.Category(func_name)
if cat == "1.0" or cat == "1.1" or cat == "1.2" or cat == "1.3":
return 0
else:
return 1
#
# Generate a no-op function.
#
def GenerateNop(func_name):
return_type = apiutil.ReturnType(func_name);
params = apiutil.Parameters(func_name)
print 'static %s GLLOADER_APIENTRY Nop%s(%s)' % (return_type, func_name, apiutil.MakeDeclarationString(params))
print '{'
for (name, type, vecSize) in params:
if name != "":
print '\t(void) %s;' % name
if apiutil.ReturnType(func_name) != 'void':
print '\treturn 0;'
print '}'
print ''
#
# Make no-op funcs for all OpenGL extension functions
#
for func_name in keys:
if IsExtensionFunc(func_name):
GenerateNop(func_name)
#
# Generate the crLoadOpenGL() function
#
print """
void
crUnloadOpenGL( void )
{
crDLLClose( glDll );
glDll = NULL;
#ifdef DARWIN
crDLLClose( cglDll );
cglDll = NULL;
# ifndef VBOX_WITH_COCOA_QT
crDLLClose( aglDll );
aglDll = NULL;
# endif
#endif
}
/*
* Initialize the 'interface' structure with the WGL or GLX window system
* interface functions.
* Then, fill in the table with (name, pointer) pairs for all the core
* OpenGL entrypoint functions. But only if table is not NULL
* Return: number of entries placed in table[], or 0 if error.
*/
int
crLoadOpenGL( crOpenGLInterface *interface, SPUNamedFunctionTable table[] )
{
static const char *coreFunctions[] = {
"""
for func_name in keys:
if not IsExtensionFunc(func_name):
print '\t\t"gl%s",' % func_name
print """
NULL
};
SPUNamedFunctionTable *entry = table;
int i;
const char *env_syspath = crGetenv( "CR_SYSTEM_GL_PATH" );
#ifdef DARWIN
const char *env_cgl_syspath = crGetenv( "CR_SYSTEM_CGL_PATH" );
# ifndef VBOX_WITH_COCOA_QT
const char *env_agl_syspath = crGetenv( "CR_SYSTEM_AGL_PATH" );
# endif
#endif
crDebug( "Looking for the system's OpenGL library..." );
#ifdef DARWIN
glDll = __findSystemGL( env_syspath, SYSTEM_GL_LIB_DIR, SYSTEM_GL );
#else
glDll = __findSystemGL( env_syspath );
#endif
if (!glDll)
{
crError("Unable to find system OpenGL!");
return 0;
}
crDebug( "Found it in %s.", !env_syspath ? "default path" : env_syspath );
#ifdef DARWIN
crDebug( "Looking for the system's CGL library..." );
cglDll = __findSystemGL( env_cgl_syspath, SYSTEM_CGL_DIR, SYSTEM_CGL );
if (!cglDll)
{
crError("Unable to find system CGL!");
return 0;
}
crDebug( "Found it in %s.", !env_cgl_syspath ? "default path" : env_cgl_syspath );
# ifndef VBOX_WITH_COCOA_QT
crDebug( "Looking for the system's AGL library..." );
aglDll = __findSystemGL( env_agl_syspath, SYSTEM_AGL_DIR, SYSTEM_AGL );
if (!aglDll)
{
crError("Unable to find system AGL!");
return 0;
}
crDebug( "Found it in %s.", !env_agl_syspath ? "default path" : env_agl_syspath );
# endif
#endif
"""
useful_wgl_functions = [
"wglGetProcAddress",
"wglMakeCurrent",
"wglSwapBuffers",
"wglCreateContext",
"wglDeleteContext",
"wglShareLists",
"wglGetCurrentContext",
"wglChoosePixelFormat",
"wglDescribePixelFormat",
"wglSetPixelFormat",
"wglChoosePixelFormatEXT",
"wglGetPixelFormatAttribivEXT",
"wglGetPixelFormatAttribfvEXT",
"glGetString"
]
useful_agl_functions = [
"aglCreateContext",
"aglDestroyContext",
"aglSetCurrentContext",
"aglSwapBuffers",
"aglChoosePixelFormat",
"aglDestroyPixelFormat",
"aglDescribePixelFormat",
"aglGetCurrentContext",
"aglSetDrawable",
"aglGetDrawable",
"aglSetFullScreen",
"aglUpdateContext",
"aglUseFont",
"aglSetInteger",
"aglGetInteger",
"aglGetError",
"aglEnable",
"aglDisable"
]
in_gl_functions = [
"CGLGetCurrentContext",
"CGLSetCurrentContext"
]
useful_cgl_functions = [
"CGLChoosePixelFormat",
"CGLDestroyPixelFormat",
"CGLDescribePixelFormat",
"CGLQueryRendererInfo",
"CGLDestroyRendererInfo",
"CGLDescribeRenderer",
"CGLCreateContext",
"CGLDestroyContext",
"CGLCopyContext",
"CGLCreatePBuffer",
"CGLDestroyPBuffer",
"CGLDescribePBuffer",
"CGLTexImagePBuffer",
"CGLSetOffScreen",
"CGLGetOffScreen",
"CGLSetFullScreen",
"CGLSetPBuffer",
"CGLGetPBuffer",
"CGLClearDrawable",
"CGLFlushDrawable",
"CGLEnable",
"CGLDisable",
"CGLIsEnabled",
"CGLSetParameter",
"CGLGetParameter",
"CGLSetVirtualScreen",
"CGLGetVirtualScreen",
"CGLSetOption",
"CGLGetOption",
"CGLGetVersion",
"CGLErrorString",
"CGLSetSurface",
"CGLGetSurface",
"CGLUpdateContext",
"glGetString"
]
useful_glx_functions = [
"glXGetConfig",
"glXQueryExtension",
"glXQueryVersion",
"glXQueryExtensionsString",
"glXChooseVisual",
"glXCreateContext",
"glXDestroyContext",
"glXUseXFont",
"glXIsDirect",
"glXMakeCurrent",
"glGetString",
"glXSwapBuffers",
"glXGetCurrentDisplay",
"glXGetCurrentContext",
"glXGetClientString",
"glXWaitGL",
"glXWaitX",
"glXCopyContext"
]
possibly_useful_glx_functions = [
"glXGetProcAddressARB",
"glXJoinSwapGroupNV",
"glXBindSwapBarrierNV",
"glXQuerySwapGroupNV",
"glXQueryMaxSwapGroupsNV",
"glXQueryFrameCountNV",
"glXResetFrameCountNV",
"glXChooseFBConfig",
"glXGetFBConfigs",
"glXGetFBConfigAttrib",
"glXGetVisualFromFBConfig",
"glXCreateNewContext",
"glXCreatePbuffer",
"glXDestroyPbuffer",
"glXQueryContext",
"glXQueryDrawable",
"glXMakeContextCurrent",
"glXCreateWindow",
"glXGetVisualFromFBConfig",
]
print '#ifdef WINDOWS'
for fun in useful_wgl_functions:
print '\tinterface->%s = (%sFunc_t) crDLLGetNoError( glDll, "%s" );' % (fun,fun,fun)
print '#elif defined(DARWIN)'
print '# ifndef VBOX_WITH_COCOA_QT'
for fun in useful_agl_functions:
print '\tinterface->%s = (%sFunc_t) crDLLGetNoError( aglDll, "%s" );' % (fun,fun,fun)
print '# endif'
for fun in useful_cgl_functions:
print '\tinterface->%s = (%sFunc_t) crDLLGetNoError( cglDll, "%s" );' % (fun, fun,fun)
for fun in in_gl_functions:
print '\tinterface->%s = (%sFunc_t) crDLLGetNoError( glDll, "%s" );' % (fun, fun,fun)
print '#else'
print '\t/* GLX */'
# XXX merge these loops?
for fun in useful_glx_functions:
print '\tinterface->%s = (%sFunc_t) crDLLGetNoError( glDll, "%s" );' % (fun, fun, fun)
for fun in possibly_useful_glx_functions:
print '\tinterface->%s = (%sFunc_t) crDLLGetNoError( glDll, "%s" );' % (fun, fun, fun)
print '#endif'
print """
if (!entry)
return 1; /* token value */
for (i = 0; coreFunctions[i]; i++) {
const char *name = coreFunctions[i];
if (fillin(entry, name + 2, crDLLGetNoError(glDll, name)))
entry++;
else
crDebug("glLoader: NULL function %s", name);
}
/* end of table markers */
entry->name = NULL;
entry->fn = NULL;
return entry - table; /* number of entries filled */
}
/*
* Fill in table[] with all the OpenGL extension functions that we're
* interested in.
*/
int
crLoadOpenGLExtensions( const crOpenGLInterface *interface, SPUNamedFunctionTable table[] )
{
struct extfunc {
const char *funcName;
const char *aliasName;
SPUGenericFunction nopFunction;
};
static const struct extfunc functions[] = {
"""
for func_name in keys:
if IsExtensionFunc(func_name):
if apiutil.Category(func_name) == "Chromium":
prefix = "cr"
else:
prefix = "gl"
s = '\t\t{ "' + prefix + func_name + '", '
a = apiutil.ReverseAlias(func_name)
if a:
s += '"' + prefix + a + '", '
else:
s += 'NULL, '
s += '(SPUGenericFunction) Nop' + func_name + ' },'
print s
print """
{ NULL, NULL, NULL}
};
const struct extfunc *func;
SPUNamedFunctionTable *entry = table;
#ifdef WINDOWS
if (interface->wglGetProcAddress == NULL)
crWarning("Unable to find wglGetProcAddress() in system GL library");
#elif !defined(DARWIN)
if (interface->glXGetProcAddressARB == NULL)
crWarning("Unable to find glXGetProcAddressARB() in system GL library");
#endif
for (func = functions; func->funcName; func++) {
SPUGenericFunction f = findExtFunction(interface, func->funcName);
if (!f && func->aliasName) {
f = findExtFunction(interface, func->aliasName);
}
if (!f) {
f = func->nopFunction;
}
(void) fillin(entry, func->funcName + 2 , f); /* +2 to skip "gl" */
entry++;
}
/* end of list */
entry->name = NULL;
entry->fn = NULL;
return entry - table; /* number of entries filled */
}
"""
print """
#ifdef USE_OSMESA
int crLoadOSMesa( OSMesaContext (**createContext)( GLenum format, OSMesaContext sharelist ),
GLboolean (**makeCurrent)( OSMesaContext ctx, GLubyte *buffer,
GLenum type, GLsizei width, GLsizei height ),
void (**destroyContext)( OSMesaContext ctx ))
{
static CRDLL *osMesaDll = NULL;
const char *env_syspath = crGetenv( "CR_SYSTEM_GL_PATH" );
crDebug( "Looking for the system's OSMesa library..." );
osMesaDll = __findSystemLib( env_syspath, "libOSMesa.so" );
if (!osMesaDll)
{
crError("Unable to find system OSMesa!");
return 0;
}
crDebug( "Found it in %s.", !env_syspath ? "default path" : env_syspath );
*createContext = (OSMesaContext (*) ( GLenum format, OSMesaContext sharelist ))
crDLLGetNoError( osMesaDll, "OSMesaCreateContext" );
*makeCurrent = (GLboolean (*) ( OSMesaContext ctx, GLubyte *buffer,
GLenum type, GLsizei width, GLsizei height ))
crDLLGetNoError( osMesaDll, "OSMesaMakeCurrent" );
*destroyContext = (void (*) ( OSMesaContext ctx))
crDLLGetNoError( osMesaDll, "OSMesaDestroyContext" );
return 1;
}
#endif
"""