From: José Fonseca Date: Sat, 14 Apr 2012 17:13:25 +0000 (+0100) Subject: Move dispatch to its own subdirectory. X-Git-Url: https://git.cworth.org/git?p=apitrace;a=commitdiff_plain;h=4f242f43bf4b3c8f5daadc4496c0e84ae55117b3 Move dispatch to its own subdirectory. --- diff --git a/.gitignore b/.gitignore index 93f029e..1e6d570 100644 --- a/.gitignore +++ b/.gitignore @@ -32,7 +32,6 @@ apitrace build dxsdk eglretrace -glproc.hpp glretrace install_manifest.txt qapitrace diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d5c99f..f817701 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,17 +237,6 @@ include_directories ( ${CMAKE_CURRENT_SOURCE_DIR}/common ) -add_custom_command ( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glproc.py > ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp - DEPENDS glproc.py dispatch.py specs/wglapi.py specs/glxapi.py specs/cglapi.py specs/eglapi.py specs/glesapi.py specs/glapi.py specs/gltypes.py specs/stdapi.py -) - -# Wrap glproc.hpp as a target to prevent the command from being executed -# multiple times simulatenously, when the targets that depend on it are built -# in parallel. -add_custom_target (glproc DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp) - if (WIN32) set (os os_win32.cpp) set (glws_os glws_wgl.cpp) @@ -296,14 +285,10 @@ endif () ############################################################################## -# API tracers +# Sub-directories +add_subdirectory (dispatch) add_subdirectory (wrappers) - - -############################################################################## -# API retracers - add_subdirectory (retrace) diff --git a/dispatch.py b/dispatch.py deleted file mode 100644 index 95bc36d..0000000 --- a/dispatch.py +++ /dev/null @@ -1,115 +0,0 @@ -########################################################################## -# -# Copyright 2010 VMware, Inc. -# 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, 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 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. -# -##########################################################################/ - - -"""Generate DLL/SO dispatching functions. -""" - - -import specs.stdapi as stdapi - - -def function_pointer_type(function): - return '__PFN' + function.name.upper() - - -def function_pointer_value(function): - return '__' + function.name + '_ptr' - - -class Dispatcher: - - def header(self): - # Must be implemented by derived classes, which should define, declare, - # or implement something like: - # - # typedef void (*__PROC)(void); - # - # static __PROC __getPublicProcAddress(const char *name); - # static __PROC __getPrivateProcAddress(const char *name); - # - raise NotImplementedError - - def dispatch_api(self, api): - for function in api.functions: - self.invokeFunction(function) - - # define standard name aliases for convenience, but only when not - # tracing, as that would cause symbol clashing with the tracing - # functions - print '#ifdef RETRACE' - for function in api.functions: - print '#define %s __%s' % (function.name, function.name) - print '#endif /* RETRACE */' - print - - def invokeFunction(self, function): - ptype = function_pointer_type(function) - pvalue = function_pointer_value(function) - print 'typedef ' + function.prototype('* %s' % ptype) + ';' - print 'static %s %s = NULL;' % (ptype, pvalue) - print - print 'static inline ' + function.prototype('__' + function.name) + ' {' - print ' const char *__name = "%s";' % function.name - if function.type is stdapi.Void: - ret = '' - else: - ret = 'return ' - self.get_true_pointer(function) - print ' %s%s(%s);' % (ret, pvalue, ', '.join([str(arg.name) for arg in function.args])) - print '}' - print - - def isFunctionPublic(self, function): - return True - - def get_true_pointer(self, function): - ptype = function_pointer_type(function) - pvalue = function_pointer_value(function) - if self.isFunctionPublic(function): - get_proc_address = '__getPublicProcAddress' - else: - get_proc_address = '__getPrivateProcAddress' - print ' if (!%s) {' % (pvalue,) - print ' %s = (%s)%s(__name);' % (pvalue, ptype, get_proc_address) - print ' if (!%s) {' % (pvalue,) - self.failFunction(function) - print ' }' - print ' }' - - def failFunction(self, function): - if function.type is stdapi.Void or function.fail is not None: - print r' os::log("warning: ignoring call to unavailable function %s\n", __name);' - if function.type is stdapi.Void: - assert function.fail is None - print ' return;' - else: - assert function.fail is not None - print ' return %s;' % function.fail - else: - print r' os::log("error: unavailable function %s\n", __name);' - print r' os::abort();' - - diff --git a/dispatch/.gitignore b/dispatch/.gitignore new file mode 100644 index 0000000..213c471 --- /dev/null +++ b/dispatch/.gitignore @@ -0,0 +1 @@ +glproc.hpp diff --git a/dispatch/CMakeLists.txt b/dispatch/CMakeLists.txt new file mode 100644 index 0000000..0dad67f --- /dev/null +++ b/dispatch/CMakeLists.txt @@ -0,0 +1,55 @@ +############################################################################## +# Dispatch + +include_directories ( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_custom_command ( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glproc.py > ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp + DEPENDS + glproc.py + dispatch.py + ${CMAKE_SOURCE_DIR}/specs/wglapi.py + ${CMAKE_SOURCE_DIR}/specs/glxapi.py + ${CMAKE_SOURCE_DIR}/specs/cglapi.py + ${CMAKE_SOURCE_DIR}/specs/eglapi.py + ${CMAKE_SOURCE_DIR}/specs/glesapi.py + ${CMAKE_SOURCE_DIR}/specs/glapi.py + ${CMAKE_SOURCE_DIR}/specs/gltypes.py + ${CMAKE_SOURCE_DIR}/specs/stdapi.py +) + + +# Wrap glproc.hpp as a target to prevent the command from being executed +# multiple times simulatenously, when the targets that depend on it are built +# in parallel. +add_custom_target (glproc DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp) + + +add_library (glproc_gl STATIC EXCLUDE_FROM_ALL + glproc_gl.cpp +) + +add_dependencies (glproc_gl glproc) + +set_target_properties (glproc_gl PROPERTIES + # Ensure it can be statically linked in shared libraries + COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}" +) + +if (ENABLE_EGL) + add_library (glproc_egl STATIC EXCLUDE_FROM_ALL + glproc_egl.cpp + ) + + add_dependencies (glproc_egl glproc) + + set_target_properties (glproc_egl PROPERTIES + # Ensure it can be statically linked in shared libraries + COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}" + ) +endif () + diff --git a/dispatch/__init__.py b/dispatch/__init__.py new file mode 100644 index 0000000..b872135 --- /dev/null +++ b/dispatch/__init__.py @@ -0,0 +1 @@ +from dispatch import * diff --git a/dispatch/dispatch.py b/dispatch/dispatch.py new file mode 100644 index 0000000..491db91 --- /dev/null +++ b/dispatch/dispatch.py @@ -0,0 +1,121 @@ +########################################################################## +# +# Copyright 2010 VMware, Inc. +# 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, 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 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. +# +##########################################################################/ + + +"""Generate DLL/SO dispatching functions. +""" + + +# Adjust path +import os.path +import sys +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) + + +import specs.stdapi as stdapi + + +def function_pointer_type(function): + return '__PFN' + function.name.upper() + + +def function_pointer_value(function): + return '__' + function.name + '_ptr' + + +class Dispatcher: + + def header(self): + # Must be implemented by derived classes, which should define, declare, + # or implement something like: + # + # typedef void (*__PROC)(void); + # + # static __PROC __getPublicProcAddress(const char *name); + # static __PROC __getPrivateProcAddress(const char *name); + # + raise NotImplementedError + + def dispatch_api(self, api): + for function in api.functions: + self.invokeFunction(function) + + # define standard name aliases for convenience, but only when not + # tracing, as that would cause symbol clashing with the tracing + # functions + print '#ifdef RETRACE' + for function in api.functions: + print '#define %s __%s' % (function.name, function.name) + print '#endif /* RETRACE */' + print + + def invokeFunction(self, function): + ptype = function_pointer_type(function) + pvalue = function_pointer_value(function) + print 'typedef ' + function.prototype('* %s' % ptype) + ';' + print 'static %s %s = NULL;' % (ptype, pvalue) + print + print 'static inline ' + function.prototype('__' + function.name) + ' {' + print ' const char *__name = "%s";' % function.name + if function.type is stdapi.Void: + ret = '' + else: + ret = 'return ' + self.get_true_pointer(function) + print ' %s%s(%s);' % (ret, pvalue, ', '.join([str(arg.name) for arg in function.args])) + print '}' + print + + def isFunctionPublic(self, function): + return True + + def get_true_pointer(self, function): + ptype = function_pointer_type(function) + pvalue = function_pointer_value(function) + if self.isFunctionPublic(function): + get_proc_address = '__getPublicProcAddress' + else: + get_proc_address = '__getPrivateProcAddress' + print ' if (!%s) {' % (pvalue,) + print ' %s = (%s)%s(__name);' % (pvalue, ptype, get_proc_address) + print ' if (!%s) {' % (pvalue,) + self.failFunction(function) + print ' }' + print ' }' + + def failFunction(self, function): + if function.type is stdapi.Void or function.fail is not None: + print r' os::log("warning: ignoring call to unavailable function %s\n", __name);' + if function.type is stdapi.Void: + assert function.fail is None + print ' return;' + else: + assert function.fail is not None + print ' return %s;' % function.fail + else: + print r' os::log("error: unavailable function %s\n", __name);' + print r' os::abort();' + + diff --git a/dispatch/glproc.py b/dispatch/glproc.py new file mode 100644 index 0000000..35ccf61 --- /dev/null +++ b/dispatch/glproc.py @@ -0,0 +1,544 @@ +########################################################################## +# +# Copyright 2010 VMware, Inc. +# 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, 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 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. +# +##########################################################################/ + + +"""Generated an header, glproc.hpp, which does pretty much what GLEW does, but +covers all the functions we support. +""" + + +from dispatch import Dispatcher +import specs.stdapi as stdapi +from specs.glapi import glapi +from specs.glxapi import glxapi +from specs.wglapi import wglapi +from specs.cglapi import cglapi +from specs.eglapi import eglapi +from specs.glesapi import glesapi + + +# See http://www.opengl.org/registry/ABI/ +public_symbols = set([ + # GL 1.2 and ARB_multitexture + "glAccum", + "glAlphaFunc", + "glAreTexturesResident", + "glArrayElement", + "glBegin", + "glBindTexture", + "glBitmap", + "glBlendFunc", + "glCallList", + "glCallLists", + "glClear", + "glClearAccum", + "glClearColor", + "glClearDepth", + "glClearIndex", + "glClearStencil", + "glClipPlane", + "glColor3b", + "glColor3bv", + "glColor3d", + "glColor3dv", + "glColor3f", + "glColor3fv", + "glColor3i", + "glColor3iv", + "glColor3s", + "glColor3sv", + "glColor3ub", + "glColor3ubv", + "glColor3ui", + "glColor3uiv", + "glColor3us", + "glColor3usv", + "glColor4b", + "glColor4bv", + "glColor4d", + "glColor4dv", + "glColor4f", + "glColor4fv", + "glColor4i", + "glColor4iv", + "glColor4s", + "glColor4sv", + "glColor4ub", + "glColor4ubv", + "glColor4ui", + "glColor4uiv", + "glColor4us", + "glColor4usv", + "glColorMask", + "glColorMaterial", + "glColorPointer", + "glCopyPixels", + "glCopyTexImage1D", + "glCopyTexImage2D", + "glCopyTexSubImage1D", + "glCopyTexSubImage2D", + "glCullFace", + "glDeleteLists", + "glDeleteTextures", + "glDepthFunc", + "glDepthMask", + "glDepthRange", + "glDisable", + "glDisableClientState", + "glDrawArrays", + "glDrawBuffer", + "glDrawElements", + "glDrawPixels", + "glEdgeFlag", + "glEdgeFlagPointer", + "glEdgeFlagv", + "glEnable", + "glEnableClientState", + "glEnd", + "glEndList", + "glEvalCoord1d", + "glEvalCoord1dv", + "glEvalCoord1f", + "glEvalCoord1fv", + "glEvalCoord2d", + "glEvalCoord2dv", + "glEvalCoord2f", + "glEvalCoord2fv", + "glEvalMesh1", + "glEvalMesh2", + "glEvalPoint1", + "glEvalPoint2", + "glFeedbackBuffer", + "glFinish", + "glFlush", + "glFogf", + "glFogfv", + "glFogi", + "glFogiv", + "glFrontFace", + "glFrustum", + "glGenLists", + "glGenTextures", + "glGetBooleanv", + "glGetClipPlane", + "glGetDoublev", + "glGetError", + "glGetFloatv", + "glGetIntegerv", + "glGetLightfv", + "glGetLightiv", + "glGetMapdv", + "glGetMapfv", + "glGetMapiv", + "glGetMaterialfv", + "glGetMaterialiv", + "glGetPixelMapfv", + "glGetPixelMapuiv", + "glGetPixelMapusv", + "glGetPointerv", + "glGetPolygonStipple", + "glGetString", + "glGetTexEnvfv", + "glGetTexEnviv", + "glGetTexGendv", + "glGetTexGenfv", + "glGetTexGeniv", + "glGetTexImage", + "glGetTexLevelParameterfv", + "glGetTexLevelParameteriv", + "glGetTexParameterfv", + "glGetTexParameteriv", + "glHint", + "glIndexMask", + "glIndexPointer", + "glIndexd", + "glIndexdv", + "glIndexf", + "glIndexfv", + "glIndexi", + "glIndexiv", + "glIndexs", + "glIndexsv", + "glIndexub", + "glIndexubv", + "glInitNames", + "glInterleavedArrays", + "glIsEnabled", + "glIsList", + "glIsTexture", + "glLightModelf", + "glLightModelfv", + "glLightModeli", + "glLightModeliv", + "glLightf", + "glLightfv", + "glLighti", + "glLightiv", + "glLineStipple", + "glLineWidth", + "glListBase", + "glLoadIdentity", + "glLoadMatrixd", + "glLoadMatrixf", + "glLoadName", + "glLogicOp", + "glMap1d", + "glMap1f", + "glMap2d", + "glMap2f", + "glMapGrid1d", + "glMapGrid1f", + "glMapGrid2d", + "glMapGrid2f", + "glMaterialf", + "glMaterialfv", + "glMateriali", + "glMaterialiv", + "glMatrixMode", + "glMultMatrixd", + "glMultMatrixf", + "glNewList", + "glNormal3b", + "glNormal3bv", + "glNormal3d", + "glNormal3dv", + "glNormal3f", + "glNormal3fv", + "glNormal3i", + "glNormal3iv", + "glNormal3s", + "glNormal3sv", + "glNormalPointer", + "glOrtho", + "glPassThrough", + "glPixelMapfv", + "glPixelMapuiv", + "glPixelMapusv", + "glPixelStoref", + "glPixelStorei", + "glPixelTransferf", + "glPixelTransferi", + "glPixelZoom", + "glPointSize", + "glPolygonMode", + "glPolygonOffset", + "glPolygonStipple", + "glPopAttrib", + "glPopClientAttrib", + "glPopMatrix", + "glPopName", + "glPrioritizeTextures", + "glPushAttrib", + "glPushClientAttrib", + "glPushMatrix", + "glPushName", + "glRasterPos2d", + "glRasterPos2dv", + "glRasterPos2f", + "glRasterPos2fv", + "glRasterPos2i", + "glRasterPos2iv", + "glRasterPos2s", + "glRasterPos2sv", + "glRasterPos3d", + "glRasterPos3dv", + "glRasterPos3f", + "glRasterPos3fv", + "glRasterPos3i", + "glRasterPos3iv", + "glRasterPos3s", + "glRasterPos3sv", + "glRasterPos4d", + "glRasterPos4dv", + "glRasterPos4f", + "glRasterPos4fv", + "glRasterPos4i", + "glRasterPos4iv", + "glRasterPos4s", + "glRasterPos4sv", + "glReadBuffer", + "glReadPixels", + "glRectd", + "glRectdv", + "glRectf", + "glRectfv", + "glRecti", + "glRectiv", + "glRects", + "glRectsv", + "glRenderMode", + "glRotated", + "glRotatef", + "glScaled", + "glScalef", + "glScissor", + "glSelectBuffer", + "glShadeModel", + "glStencilFunc", + "glStencilMask", + "glStencilOp", + "glTexCoord1d", + "glTexCoord1dv", + "glTexCoord1f", + "glTexCoord1fv", + "glTexCoord1i", + "glTexCoord1iv", + "glTexCoord1s", + "glTexCoord1sv", + "glTexCoord2d", + "glTexCoord2dv", + "glTexCoord2f", + "glTexCoord2fv", + "glTexCoord2i", + "glTexCoord2iv", + "glTexCoord2s", + "glTexCoord2sv", + "glTexCoord3d", + "glTexCoord3dv", + "glTexCoord3f", + "glTexCoord3fv", + "glTexCoord3i", + "glTexCoord3iv", + "glTexCoord3s", + "glTexCoord3sv", + "glTexCoord4d", + "glTexCoord4dv", + "glTexCoord4f", + "glTexCoord4fv", + "glTexCoord4i", + "glTexCoord4iv", + "glTexCoord4s", + "glTexCoord4sv", + "glTexCoordPointer", + "glTexEnvf", + "glTexEnvfv", + "glTexEnvi", + "glTexEnviv", + "glTexGend", + "glTexGendv", + "glTexGenf", + "glTexGenfv", + "glTexGeni", + "glTexGeniv", + "glTexImage1D", + "glTexImage2D", + "glTexParameterf", + "glTexParameterfv", + "glTexParameteri", + "glTexParameteriv", + "glTexSubImage1D", + "glTexSubImage2D", + "glTranslated", + "glTranslatef", + "glVertex2d", + "glVertex2dv", + "glVertex2f", + "glVertex2fv", + "glVertex2i", + "glVertex2iv", + "glVertex2s", + "glVertex2sv", + "glVertex3d", + "glVertex3dv", + "glVertex3f", + "glVertex3fv", + "glVertex3i", + "glVertex3iv", + "glVertex3s", + "glVertex3sv", + "glVertex4d", + "glVertex4dv", + "glVertex4f", + "glVertex4fv", + "glVertex4i", + "glVertex4iv", + "glVertex4s", + "glVertex4sv", + "glVertexPointer", + "glViewport", + + # GLX 1.3 and GLX_ARB_get_proc_address + "glXChooseVisual", + "glXCreateContext", + "glXDestroyContext", + "glXMakeCurrent", + "glXCopyContext", + "glXSwapBuffers", + "glXCreateGLXPixmap", + "glXDestroyGLXPixmap", + "glXQueryExtension", + "glXQueryVersion", + "glXIsDirect", + "glXGetConfig", + "glXGetCurrentContext", + "glXGetCurrentDrawable", + "glXWaitGL", + "glXWaitX", + "glXUseXFont", + "glXQueryExtensionsString", + "glXQueryServerString", + "glXGetClientString", + "glXGetCurrentDisplay", + "glXChooseFBConfig", + "glXGetFBConfigAttrib", + "glXGetFBConfigs", + "glXGetVisualFromFBConfig", + "glXCreateWindow", + "glXDestroyWindow", + "glXCreatePixmap", + "glXDestroyPixmap", + "glXCreatePbuffer", + "glXDestroyPbuffer", + "glXQueryDrawable", + "glXCreateNewContext", + "glXMakeContextCurrent", + "glXGetCurrentReadDrawable", + "glXQueryContext", + "glXSelectEvent", + "glXGetSelectedEvent", + "glXGetProcAddressARB", + "glXGetProcAddress", + + # WGL + #"glDebugEntry", + "wglChoosePixelFormat", + "wglCopyContext", + "wglCreateContext", + "wglCreateLayerContext", + "wglDeleteContext", + "wglDescribeLayerPlane", + "wglDescribePixelFormat", + "wglGetCurrentContext", + "wglGetCurrentDC", + "wglGetDefaultProcAddress", + "wglGetLayerPaletteEntries", + "wglGetPixelFormat", + "wglGetProcAddress", + "wglMakeCurrent", + "wglRealizeLayerPalette", + "wglSetLayerPaletteEntries", + "wglSetPixelFormat", + "wglShareLists", + "wglSwapBuffers", + "wglSwapLayerBuffers", + "wglSwapMultipleBuffers", + "wglUseFontBitmapsA", + "wglUseFontBitmapsW", + "wglUseFontOutlinesA", + "wglUseFontOutlinesW", + +]) + +# EGL 1.4 +public_symbols.update([ + "eglBindAPI", + "eglBindTexImage", + "eglChooseConfig", + "eglCopyBuffers", + "eglCreateContext", + "eglCreatePbufferFromClientBuffer", + "eglCreatePbufferSurface", + "eglCreatePixmapSurface", + "eglCreateWindowSurface", + "eglDestroyContext", + "eglDestroySurface", + "eglGetConfigAttrib", + "eglGetConfigs", + "eglGetCurrentContext", + "eglGetCurrentDisplay", + "eglGetCurrentSurface", + "eglGetDisplay", + "eglGetError", + "eglGetProcAddress", + "eglInitialize", + "eglMakeCurrent", + "eglQueryAPI", + "eglQueryContext", + "eglQueryString", + "eglQuerySurface", + "eglReleaseTexImage", + "eglReleaseThread", + "eglSurfaceAttrib", + "eglSwapBuffers", + "eglSwapInterval", + "eglTerminate", + "eglWaitClient", + "eglWaitGL", + "eglWaitNative", +]) + +class GlDispatcher(Dispatcher): + + def header(self): + print ''' +#if defined(_WIN32) +extern HINSTANCE __libGlHandle; +#else +extern void * __libGlHandle; +#endif + +void * __getPublicProcAddress(const char *procName); +void * __getPrivateProcAddress(const char *procName); +''' + + def isFunctionPublic(self, function): + return function.name in public_symbols or function.name.startswith('CGL') + + +if __name__ == '__main__': + print + print '#ifndef _GLPROC_HPP_' + print '#define _GLPROC_HPP_' + print + print '#include "glimports.hpp"' + print '#include "os.hpp"' + print + dispatcher = GlDispatcher() + print + dispatcher.header() + print + dispatcher.dispatch_api(eglapi) + print + print '#if defined(_WIN32)' + print + dispatcher.dispatch_api(wglapi) + print + print '#elif defined(__APPLE__)' + print + dispatcher.dispatch_api(cglapi) + print + print '#elif defined(HAVE_X11)' + print + dispatcher.dispatch_api(glxapi) + print + print '#endif' + print + dispatcher.dispatch_api(glapi) + print + dispatcher.dispatch_api(glesapi) + print + + print '#endif /* !_GLPROC_HPP_ */' + print diff --git a/dispatch/glproc_egl.cpp b/dispatch/glproc_egl.cpp new file mode 100644 index 0000000..8a0fb34 --- /dev/null +++ b/dispatch/glproc_egl.cpp @@ -0,0 +1,151 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * 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, 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 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 "glproc.hpp" + + +#if !defined(_WIN32) +#ifndef _GNU_SOURCE +#define _GNU_SOURCE // for dladdr +#endif +#include +#endif + + +/* + * Handle to the true OpenGL library. + * XXX: Not really used yet. + */ +#if defined(_WIN32) +HINSTANCE __libGlHandle = NULL; +#else +void *__libGlHandle = NULL; +#endif + + + +#if defined(_WIN32) + +#error Unsupported + +#elif defined(__APPLE__) + +#error Unsupported + +#else + +/* + * Lookup a public EGL/GL/GLES symbol + * + * The spec states that eglGetProcAddress should only be used for non-core + * (extensions) entry-points. Core entry-points should be taken directly from + * the API specific libraries. + * + * We cannot tell here which API a symbol is meant for here (as some are + * exported by many). So this code assumes that the appropriate shared + * libraries have been loaded previously (either dlopened with RTLD_GLOBAL, or + * as part of the executable dependencies), and that their symbols available + * for quering via dlsym(RTLD_NEXT, ...). + */ +void * +__getPublicProcAddress(const char *procName) +{ +#if defined(ANDROID) + /* + * Android does not support LD_PRELOAD. It is assumed that applications + * are explicitely loading egltrace.so. + */ + + if (procName[0] == 'e' && procName[1] == 'g' && procName[2] == 'l') { + static void *libEGL = NULL; + if (!libEGL) { + libEGL = dlopen("libEGL.so", RTLD_LOCAL | RTLD_LAZY); + if (!libEGL) { + return NULL; + } + } + return dlsym(libEGL, procName); + } + + if (procName[0] == 'g' && procName[1] == 'l') { + /* TODO: Use GLESv1/GLESv2 on a per-context basis. */ + static void *sym = NULL; + + static void *libGLESv2 = NULL; + if (!libGLESv2) { + libGLESv2 = dlopen("libGLESv2.so", RTLD_LOCAL | RTLD_LAZY); + } + if (libGLESv2) { + sym = dlsym(libGLESv2, procName); + } + if (sym) { + return sym; + } + + static void *libGLESv1 = NULL; + if (!libGLESv1) { + libGLESv1 = dlopen("libGLESv1_CM.so", RTLD_LOCAL | RTLD_LAZY); + } + if (libGLESv1) { + sym = dlsym(libGLESv1, procName); + } + if (sym) { + return sym; + } + } + + return NULL; +#else + return dlsym(RTLD_NEXT, procName); +#endif +} + +/* + * Lookup a private EGL/GL/GLES symbol + * + * Private symbols should always be available through eglGetProcAddress, and + * they are guaranteed to work with any context bound (regardless of the API). + * + * However, per issue#57, eglGetProcAddress returns garbage on some + * implementations, and the spec states that implementations may choose to also + * export extension functions publicly, so we always attempt dlsym before + * eglGetProcAddress to mitigate that. + */ +void * +__getPrivateProcAddress(const char *procName) +{ + void *proc; + proc = __getPublicProcAddress(procName); + if (!proc && + ((procName[0] == 'e' && procName[1] == 'g' && procName[2] == 'l') || + (procName[0] == 'g' && procName[1] == 'l'))) { + proc = (void *) __eglGetProcAddress(procName); + } + + return proc; +} + +#endif diff --git a/dispatch/glproc_gl.cpp b/dispatch/glproc_gl.cpp new file mode 100644 index 0000000..27b3ef7 --- /dev/null +++ b/dispatch/glproc_gl.cpp @@ -0,0 +1,228 @@ +/************************************************************************** + * + * Copyright 2011 Jose Fonseca + * 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, 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 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 "glproc.hpp" + + +#if !defined(_WIN32) +#include // for symlink +#include +#endif + + +/* + * Handle to the true OpenGL library. + */ +#if defined(_WIN32) +HINSTANCE __libGlHandle = NULL; +#else +void *__libGlHandle = NULL; +#endif + + + +#if defined(_WIN32) + +void * +__getPublicProcAddress(const char *procName) +{ + if (!__libGlHandle) { + char szDll[MAX_PATH] = {0}; + + if (!GetSystemDirectoryA(szDll, MAX_PATH)) { + return NULL; + } + + strcat(szDll, "\\\\opengl32.dll"); + + __libGlHandle = LoadLibraryA(szDll); + if (!__libGlHandle) { + os::log("apitrace: error: couldn't load %s\n", szDll); + return NULL; + } + } + + return (void *)GetProcAddress(__libGlHandle, procName); +} + + +void * +__getPrivateProcAddress(const char *procName) { + return (void *)__wglGetProcAddress(procName); +} + + +#elif defined(__APPLE__) + + +/* + * Path to the true OpenGL framework + */ +static const char *libgl_filename = "/System/Library/Frameworks/OpenGL.framework/OpenGL"; + + +/* + * Lookup a libGL symbol + */ +void * __libgl_sym(const char *symbol) +{ + void *result; + + if (!__libGlHandle) { + /* + * Unfortunately we can't just dlopen the true dynamic library because + * DYLD_LIBRARY_PATH/DYLD_FRAMEWORK_PATH take precedence, even for + * absolute paths. So we create a temporary symlink, and dlopen that + * instead. + */ + + char temp_filename[] = "/tmp/tmp.XXXXXX"; + + if (mktemp(temp_filename) != NULL) { + if (symlink(libgl_filename, temp_filename) == 0) { + __libGlHandle = dlopen(temp_filename, RTLD_LOCAL | RTLD_NOW | RTLD_FIRST); + remove(temp_filename); + } + } + + if (!__libGlHandle) { + os::log("apitrace: error: couldn't load %s\n", libgl_filename); + os::abort(); + return NULL; + } + } + + result = dlsym(__libGlHandle, symbol); + + if (resullt && result == dlsym(RTLD_SELF, symbol)) { + os::log("apitrace: error: symbol lookup recursion\n"); + os::abort(); + return NULL; + } + + return result; +} + + +void * +__getPublicProcAddress(const char *procName) +{ + return __libgl_sym(procName); +} + +void * +__getPrivateProcAddress(const char *procName) +{ + return __libgl_sym(procName); +} + + +#else + + +/* + * Invoke the true dlopen() function. + */ +static void * +__dlopen(const char *filename, int flag) +{ + typedef void * (*PFNDLOPEN)(const char *, int); + static PFNDLOPEN dlopen_ptr = NULL; + + if (!dlopen_ptr) { + dlopen_ptr = (PFNDLOPEN)dlsym(RTLD_NEXT, "dlopen"); + if (!dlopen_ptr) { + os::log("apitrace: error: dlsym(RTLD_NEXT, \"dlopen\") failed\n"); + return NULL; + } + } + + return dlopen_ptr(filename, flag); +} + + +/* + * Lookup a libGL symbol + */ +void * __libgl_sym(const char *symbol) +{ + void *result; + + if (!__libGlHandle) { + /* + * The app doesn't directly link against libGL.so, nor does it directly + * dlopen it. So we have to load it ourselves. + */ + + const char * libgl_filename = getenv("TRACE_LIBGL"); + + if (!libgl_filename) { + /* + * Try to use whatever libGL.so the library is linked against. + */ + + result = dlsym(RTLD_NEXT, symbol); + if (result) { + __libGlHandle = RTLD_NEXT; + return result; + } + + libgl_filename = "libGL.so.1"; + } + + /* + * It would have been preferable to use RTLD_LOCAL to ensure that the + * application can never access libGL.so symbols directly, but this + * won't work, given libGL.so often loads a driver specific SO and + * exposes symbols to it. + */ + + __libGlHandle = __dlopen(libgl_filename, RTLD_GLOBAL | RTLD_LAZY); + if (!__libGlHandle) { + os::log("apitrace: error: couldn't find libGL.so\n"); + return NULL; + } + } + + return dlsym(__libGlHandle, symbol); +} + + +void * +__getPublicProcAddress(const char *procName) +{ + return __libgl_sym(procName); +} + +void * +__getPrivateProcAddress(const char *procName) +{ + return (void *)__glXGetProcAddressARB((const GLubyte *)procName); +} + + +#endif + diff --git a/glproc.py b/glproc.py deleted file mode 100644 index b54f713..0000000 --- a/glproc.py +++ /dev/null @@ -1,544 +0,0 @@ -########################################################################## -# -# Copyright 2010 VMware, Inc. -# 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, 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 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. -# -##########################################################################/ - - -"""Generated an header, glproc.hpp, which does pretty much what GLEW does, but -covers all the functions we support. -""" - - -import specs.stdapi as stdapi -from dispatch import Dispatcher -from specs.glapi import glapi -from specs.glxapi import glxapi -from specs.wglapi import wglapi -from specs.cglapi import cglapi -from specs.eglapi import eglapi -from specs.glesapi import glesapi - - -# See http://www.opengl.org/registry/ABI/ -public_symbols = set([ - # GL 1.2 and ARB_multitexture - "glAccum", - "glAlphaFunc", - "glAreTexturesResident", - "glArrayElement", - "glBegin", - "glBindTexture", - "glBitmap", - "glBlendFunc", - "glCallList", - "glCallLists", - "glClear", - "glClearAccum", - "glClearColor", - "glClearDepth", - "glClearIndex", - "glClearStencil", - "glClipPlane", - "glColor3b", - "glColor3bv", - "glColor3d", - "glColor3dv", - "glColor3f", - "glColor3fv", - "glColor3i", - "glColor3iv", - "glColor3s", - "glColor3sv", - "glColor3ub", - "glColor3ubv", - "glColor3ui", - "glColor3uiv", - "glColor3us", - "glColor3usv", - "glColor4b", - "glColor4bv", - "glColor4d", - "glColor4dv", - "glColor4f", - "glColor4fv", - "glColor4i", - "glColor4iv", - "glColor4s", - "glColor4sv", - "glColor4ub", - "glColor4ubv", - "glColor4ui", - "glColor4uiv", - "glColor4us", - "glColor4usv", - "glColorMask", - "glColorMaterial", - "glColorPointer", - "glCopyPixels", - "glCopyTexImage1D", - "glCopyTexImage2D", - "glCopyTexSubImage1D", - "glCopyTexSubImage2D", - "glCullFace", - "glDeleteLists", - "glDeleteTextures", - "glDepthFunc", - "glDepthMask", - "glDepthRange", - "glDisable", - "glDisableClientState", - "glDrawArrays", - "glDrawBuffer", - "glDrawElements", - "glDrawPixels", - "glEdgeFlag", - "glEdgeFlagPointer", - "glEdgeFlagv", - "glEnable", - "glEnableClientState", - "glEnd", - "glEndList", - "glEvalCoord1d", - "glEvalCoord1dv", - "glEvalCoord1f", - "glEvalCoord1fv", - "glEvalCoord2d", - "glEvalCoord2dv", - "glEvalCoord2f", - "glEvalCoord2fv", - "glEvalMesh1", - "glEvalMesh2", - "glEvalPoint1", - "glEvalPoint2", - "glFeedbackBuffer", - "glFinish", - "glFlush", - "glFogf", - "glFogfv", - "glFogi", - "glFogiv", - "glFrontFace", - "glFrustum", - "glGenLists", - "glGenTextures", - "glGetBooleanv", - "glGetClipPlane", - "glGetDoublev", - "glGetError", - "glGetFloatv", - "glGetIntegerv", - "glGetLightfv", - "glGetLightiv", - "glGetMapdv", - "glGetMapfv", - "glGetMapiv", - "glGetMaterialfv", - "glGetMaterialiv", - "glGetPixelMapfv", - "glGetPixelMapuiv", - "glGetPixelMapusv", - "glGetPointerv", - "glGetPolygonStipple", - "glGetString", - "glGetTexEnvfv", - "glGetTexEnviv", - "glGetTexGendv", - "glGetTexGenfv", - "glGetTexGeniv", - "glGetTexImage", - "glGetTexLevelParameterfv", - "glGetTexLevelParameteriv", - "glGetTexParameterfv", - "glGetTexParameteriv", - "glHint", - "glIndexMask", - "glIndexPointer", - "glIndexd", - "glIndexdv", - "glIndexf", - "glIndexfv", - "glIndexi", - "glIndexiv", - "glIndexs", - "glIndexsv", - "glIndexub", - "glIndexubv", - "glInitNames", - "glInterleavedArrays", - "glIsEnabled", - "glIsList", - "glIsTexture", - "glLightModelf", - "glLightModelfv", - "glLightModeli", - "glLightModeliv", - "glLightf", - "glLightfv", - "glLighti", - "glLightiv", - "glLineStipple", - "glLineWidth", - "glListBase", - "glLoadIdentity", - "glLoadMatrixd", - "glLoadMatrixf", - "glLoadName", - "glLogicOp", - "glMap1d", - "glMap1f", - "glMap2d", - "glMap2f", - "glMapGrid1d", - "glMapGrid1f", - "glMapGrid2d", - "glMapGrid2f", - "glMaterialf", - "glMaterialfv", - "glMateriali", - "glMaterialiv", - "glMatrixMode", - "glMultMatrixd", - "glMultMatrixf", - "glNewList", - "glNormal3b", - "glNormal3bv", - "glNormal3d", - "glNormal3dv", - "glNormal3f", - "glNormal3fv", - "glNormal3i", - "glNormal3iv", - "glNormal3s", - "glNormal3sv", - "glNormalPointer", - "glOrtho", - "glPassThrough", - "glPixelMapfv", - "glPixelMapuiv", - "glPixelMapusv", - "glPixelStoref", - "glPixelStorei", - "glPixelTransferf", - "glPixelTransferi", - "glPixelZoom", - "glPointSize", - "glPolygonMode", - "glPolygonOffset", - "glPolygonStipple", - "glPopAttrib", - "glPopClientAttrib", - "glPopMatrix", - "glPopName", - "glPrioritizeTextures", - "glPushAttrib", - "glPushClientAttrib", - "glPushMatrix", - "glPushName", - "glRasterPos2d", - "glRasterPos2dv", - "glRasterPos2f", - "glRasterPos2fv", - "glRasterPos2i", - "glRasterPos2iv", - "glRasterPos2s", - "glRasterPos2sv", - "glRasterPos3d", - "glRasterPos3dv", - "glRasterPos3f", - "glRasterPos3fv", - "glRasterPos3i", - "glRasterPos3iv", - "glRasterPos3s", - "glRasterPos3sv", - "glRasterPos4d", - "glRasterPos4dv", - "glRasterPos4f", - "glRasterPos4fv", - "glRasterPos4i", - "glRasterPos4iv", - "glRasterPos4s", - "glRasterPos4sv", - "glReadBuffer", - "glReadPixels", - "glRectd", - "glRectdv", - "glRectf", - "glRectfv", - "glRecti", - "glRectiv", - "glRects", - "glRectsv", - "glRenderMode", - "glRotated", - "glRotatef", - "glScaled", - "glScalef", - "glScissor", - "glSelectBuffer", - "glShadeModel", - "glStencilFunc", - "glStencilMask", - "glStencilOp", - "glTexCoord1d", - "glTexCoord1dv", - "glTexCoord1f", - "glTexCoord1fv", - "glTexCoord1i", - "glTexCoord1iv", - "glTexCoord1s", - "glTexCoord1sv", - "glTexCoord2d", - "glTexCoord2dv", - "glTexCoord2f", - "glTexCoord2fv", - "glTexCoord2i", - "glTexCoord2iv", - "glTexCoord2s", - "glTexCoord2sv", - "glTexCoord3d", - "glTexCoord3dv", - "glTexCoord3f", - "glTexCoord3fv", - "glTexCoord3i", - "glTexCoord3iv", - "glTexCoord3s", - "glTexCoord3sv", - "glTexCoord4d", - "glTexCoord4dv", - "glTexCoord4f", - "glTexCoord4fv", - "glTexCoord4i", - "glTexCoord4iv", - "glTexCoord4s", - "glTexCoord4sv", - "glTexCoordPointer", - "glTexEnvf", - "glTexEnvfv", - "glTexEnvi", - "glTexEnviv", - "glTexGend", - "glTexGendv", - "glTexGenf", - "glTexGenfv", - "glTexGeni", - "glTexGeniv", - "glTexImage1D", - "glTexImage2D", - "glTexParameterf", - "glTexParameterfv", - "glTexParameteri", - "glTexParameteriv", - "glTexSubImage1D", - "glTexSubImage2D", - "glTranslated", - "glTranslatef", - "glVertex2d", - "glVertex2dv", - "glVertex2f", - "glVertex2fv", - "glVertex2i", - "glVertex2iv", - "glVertex2s", - "glVertex2sv", - "glVertex3d", - "glVertex3dv", - "glVertex3f", - "glVertex3fv", - "glVertex3i", - "glVertex3iv", - "glVertex3s", - "glVertex3sv", - "glVertex4d", - "glVertex4dv", - "glVertex4f", - "glVertex4fv", - "glVertex4i", - "glVertex4iv", - "glVertex4s", - "glVertex4sv", - "glVertexPointer", - "glViewport", - - # GLX 1.3 and GLX_ARB_get_proc_address - "glXChooseVisual", - "glXCreateContext", - "glXDestroyContext", - "glXMakeCurrent", - "glXCopyContext", - "glXSwapBuffers", - "glXCreateGLXPixmap", - "glXDestroyGLXPixmap", - "glXQueryExtension", - "glXQueryVersion", - "glXIsDirect", - "glXGetConfig", - "glXGetCurrentContext", - "glXGetCurrentDrawable", - "glXWaitGL", - "glXWaitX", - "glXUseXFont", - "glXQueryExtensionsString", - "glXQueryServerString", - "glXGetClientString", - "glXGetCurrentDisplay", - "glXChooseFBConfig", - "glXGetFBConfigAttrib", - "glXGetFBConfigs", - "glXGetVisualFromFBConfig", - "glXCreateWindow", - "glXDestroyWindow", - "glXCreatePixmap", - "glXDestroyPixmap", - "glXCreatePbuffer", - "glXDestroyPbuffer", - "glXQueryDrawable", - "glXCreateNewContext", - "glXMakeContextCurrent", - "glXGetCurrentReadDrawable", - "glXQueryContext", - "glXSelectEvent", - "glXGetSelectedEvent", - "glXGetProcAddressARB", - "glXGetProcAddress", - - # WGL - #"glDebugEntry", - "wglChoosePixelFormat", - "wglCopyContext", - "wglCreateContext", - "wglCreateLayerContext", - "wglDeleteContext", - "wglDescribeLayerPlane", - "wglDescribePixelFormat", - "wglGetCurrentContext", - "wglGetCurrentDC", - "wglGetDefaultProcAddress", - "wglGetLayerPaletteEntries", - "wglGetPixelFormat", - "wglGetProcAddress", - "wglMakeCurrent", - "wglRealizeLayerPalette", - "wglSetLayerPaletteEntries", - "wglSetPixelFormat", - "wglShareLists", - "wglSwapBuffers", - "wglSwapLayerBuffers", - "wglSwapMultipleBuffers", - "wglUseFontBitmapsA", - "wglUseFontBitmapsW", - "wglUseFontOutlinesA", - "wglUseFontOutlinesW", - -]) - -# EGL 1.4 -public_symbols.update([ - "eglBindAPI", - "eglBindTexImage", - "eglChooseConfig", - "eglCopyBuffers", - "eglCreateContext", - "eglCreatePbufferFromClientBuffer", - "eglCreatePbufferSurface", - "eglCreatePixmapSurface", - "eglCreateWindowSurface", - "eglDestroyContext", - "eglDestroySurface", - "eglGetConfigAttrib", - "eglGetConfigs", - "eglGetCurrentContext", - "eglGetCurrentDisplay", - "eglGetCurrentSurface", - "eglGetDisplay", - "eglGetError", - "eglGetProcAddress", - "eglInitialize", - "eglMakeCurrent", - "eglQueryAPI", - "eglQueryContext", - "eglQueryString", - "eglQuerySurface", - "eglReleaseTexImage", - "eglReleaseThread", - "eglSurfaceAttrib", - "eglSwapBuffers", - "eglSwapInterval", - "eglTerminate", - "eglWaitClient", - "eglWaitGL", - "eglWaitNative", -]) - -class GlDispatcher(Dispatcher): - - def header(self): - print ''' -#if defined(_WIN32) -extern HINSTANCE __libGlHandle; -#else -extern void * __libGlHandle; -#endif - -void * __getPublicProcAddress(const char *procName); -void * __getPrivateProcAddress(const char *procName); -''' - - def isFunctionPublic(self, function): - return function.name in public_symbols or function.name.startswith('CGL') - - -if __name__ == '__main__': - print - print '#ifndef _GLPROC_HPP_' - print '#define _GLPROC_HPP_' - print - print '#include "glimports.hpp"' - print '#include "os.hpp"' - print - dispatcher = GlDispatcher() - print - dispatcher.header() - print - dispatcher.dispatch_api(eglapi) - print - print '#if defined(_WIN32)' - print - dispatcher.dispatch_api(wglapi) - print - print '#elif defined(__APPLE__)' - print - dispatcher.dispatch_api(cglapi) - print - print '#elif defined(HAVE_X11)' - print - dispatcher.dispatch_api(glxapi) - print - print '#endif' - print - dispatcher.dispatch_api(glapi) - print - dispatcher.dispatch_api(glesapi) - print - - print '#endif /* !_GLPROC_HPP_ */' - print diff --git a/glproc_egl.cpp b/glproc_egl.cpp deleted file mode 100644 index 8a0fb34..0000000 --- a/glproc_egl.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/************************************************************************** - * - * Copyright 2011 Jose Fonseca - * 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, 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 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 "glproc.hpp" - - -#if !defined(_WIN32) -#ifndef _GNU_SOURCE -#define _GNU_SOURCE // for dladdr -#endif -#include -#endif - - -/* - * Handle to the true OpenGL library. - * XXX: Not really used yet. - */ -#if defined(_WIN32) -HINSTANCE __libGlHandle = NULL; -#else -void *__libGlHandle = NULL; -#endif - - - -#if defined(_WIN32) - -#error Unsupported - -#elif defined(__APPLE__) - -#error Unsupported - -#else - -/* - * Lookup a public EGL/GL/GLES symbol - * - * The spec states that eglGetProcAddress should only be used for non-core - * (extensions) entry-points. Core entry-points should be taken directly from - * the API specific libraries. - * - * We cannot tell here which API a symbol is meant for here (as some are - * exported by many). So this code assumes that the appropriate shared - * libraries have been loaded previously (either dlopened with RTLD_GLOBAL, or - * as part of the executable dependencies), and that their symbols available - * for quering via dlsym(RTLD_NEXT, ...). - */ -void * -__getPublicProcAddress(const char *procName) -{ -#if defined(ANDROID) - /* - * Android does not support LD_PRELOAD. It is assumed that applications - * are explicitely loading egltrace.so. - */ - - if (procName[0] == 'e' && procName[1] == 'g' && procName[2] == 'l') { - static void *libEGL = NULL; - if (!libEGL) { - libEGL = dlopen("libEGL.so", RTLD_LOCAL | RTLD_LAZY); - if (!libEGL) { - return NULL; - } - } - return dlsym(libEGL, procName); - } - - if (procName[0] == 'g' && procName[1] == 'l') { - /* TODO: Use GLESv1/GLESv2 on a per-context basis. */ - static void *sym = NULL; - - static void *libGLESv2 = NULL; - if (!libGLESv2) { - libGLESv2 = dlopen("libGLESv2.so", RTLD_LOCAL | RTLD_LAZY); - } - if (libGLESv2) { - sym = dlsym(libGLESv2, procName); - } - if (sym) { - return sym; - } - - static void *libGLESv1 = NULL; - if (!libGLESv1) { - libGLESv1 = dlopen("libGLESv1_CM.so", RTLD_LOCAL | RTLD_LAZY); - } - if (libGLESv1) { - sym = dlsym(libGLESv1, procName); - } - if (sym) { - return sym; - } - } - - return NULL; -#else - return dlsym(RTLD_NEXT, procName); -#endif -} - -/* - * Lookup a private EGL/GL/GLES symbol - * - * Private symbols should always be available through eglGetProcAddress, and - * they are guaranteed to work with any context bound (regardless of the API). - * - * However, per issue#57, eglGetProcAddress returns garbage on some - * implementations, and the spec states that implementations may choose to also - * export extension functions publicly, so we always attempt dlsym before - * eglGetProcAddress to mitigate that. - */ -void * -__getPrivateProcAddress(const char *procName) -{ - void *proc; - proc = __getPublicProcAddress(procName); - if (!proc && - ((procName[0] == 'e' && procName[1] == 'g' && procName[2] == 'l') || - (procName[0] == 'g' && procName[1] == 'l'))) { - proc = (void *) __eglGetProcAddress(procName); - } - - return proc; -} - -#endif diff --git a/glproc_gl.cpp b/glproc_gl.cpp deleted file mode 100644 index 27b3ef7..0000000 --- a/glproc_gl.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/************************************************************************** - * - * Copyright 2011 Jose Fonseca - * 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, 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 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 "glproc.hpp" - - -#if !defined(_WIN32) -#include // for symlink -#include -#endif - - -/* - * Handle to the true OpenGL library. - */ -#if defined(_WIN32) -HINSTANCE __libGlHandle = NULL; -#else -void *__libGlHandle = NULL; -#endif - - - -#if defined(_WIN32) - -void * -__getPublicProcAddress(const char *procName) -{ - if (!__libGlHandle) { - char szDll[MAX_PATH] = {0}; - - if (!GetSystemDirectoryA(szDll, MAX_PATH)) { - return NULL; - } - - strcat(szDll, "\\\\opengl32.dll"); - - __libGlHandle = LoadLibraryA(szDll); - if (!__libGlHandle) { - os::log("apitrace: error: couldn't load %s\n", szDll); - return NULL; - } - } - - return (void *)GetProcAddress(__libGlHandle, procName); -} - - -void * -__getPrivateProcAddress(const char *procName) { - return (void *)__wglGetProcAddress(procName); -} - - -#elif defined(__APPLE__) - - -/* - * Path to the true OpenGL framework - */ -static const char *libgl_filename = "/System/Library/Frameworks/OpenGL.framework/OpenGL"; - - -/* - * Lookup a libGL symbol - */ -void * __libgl_sym(const char *symbol) -{ - void *result; - - if (!__libGlHandle) { - /* - * Unfortunately we can't just dlopen the true dynamic library because - * DYLD_LIBRARY_PATH/DYLD_FRAMEWORK_PATH take precedence, even for - * absolute paths. So we create a temporary symlink, and dlopen that - * instead. - */ - - char temp_filename[] = "/tmp/tmp.XXXXXX"; - - if (mktemp(temp_filename) != NULL) { - if (symlink(libgl_filename, temp_filename) == 0) { - __libGlHandle = dlopen(temp_filename, RTLD_LOCAL | RTLD_NOW | RTLD_FIRST); - remove(temp_filename); - } - } - - if (!__libGlHandle) { - os::log("apitrace: error: couldn't load %s\n", libgl_filename); - os::abort(); - return NULL; - } - } - - result = dlsym(__libGlHandle, symbol); - - if (resullt && result == dlsym(RTLD_SELF, symbol)) { - os::log("apitrace: error: symbol lookup recursion\n"); - os::abort(); - return NULL; - } - - return result; -} - - -void * -__getPublicProcAddress(const char *procName) -{ - return __libgl_sym(procName); -} - -void * -__getPrivateProcAddress(const char *procName) -{ - return __libgl_sym(procName); -} - - -#else - - -/* - * Invoke the true dlopen() function. - */ -static void * -__dlopen(const char *filename, int flag) -{ - typedef void * (*PFNDLOPEN)(const char *, int); - static PFNDLOPEN dlopen_ptr = NULL; - - if (!dlopen_ptr) { - dlopen_ptr = (PFNDLOPEN)dlsym(RTLD_NEXT, "dlopen"); - if (!dlopen_ptr) { - os::log("apitrace: error: dlsym(RTLD_NEXT, \"dlopen\") failed\n"); - return NULL; - } - } - - return dlopen_ptr(filename, flag); -} - - -/* - * Lookup a libGL symbol - */ -void * __libgl_sym(const char *symbol) -{ - void *result; - - if (!__libGlHandle) { - /* - * The app doesn't directly link against libGL.so, nor does it directly - * dlopen it. So we have to load it ourselves. - */ - - const char * libgl_filename = getenv("TRACE_LIBGL"); - - if (!libgl_filename) { - /* - * Try to use whatever libGL.so the library is linked against. - */ - - result = dlsym(RTLD_NEXT, symbol); - if (result) { - __libGlHandle = RTLD_NEXT; - return result; - } - - libgl_filename = "libGL.so.1"; - } - - /* - * It would have been preferable to use RTLD_LOCAL to ensure that the - * application can never access libGL.so symbols directly, but this - * won't work, given libGL.so often loads a driver specific SO and - * exposes symbols to it. - */ - - __libGlHandle = __dlopen(libgl_filename, RTLD_GLOBAL | RTLD_LAZY); - if (!__libGlHandle) { - os::log("apitrace: error: couldn't find libGL.so\n"); - return NULL; - } - } - - return dlsym(__libGlHandle, symbol); -} - - -void * -__getPublicProcAddress(const char *procName) -{ - return __libgl_sym(procName); -} - -void * -__getPrivateProcAddress(const char *procName) -{ - return (void *)__glXGetProcAddressARB((const GLubyte *)procName); -} - - -#endif - diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt index 358361e..644fe98 100644 --- a/retrace/CMakeLists.txt +++ b/retrace/CMakeLists.txt @@ -1,7 +1,10 @@ ############################################################################## # API retracers -include_directories (${CMAKE_CURRENT_SOURCE_DIR}) +include_directories ( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_BINARY_DIR}/dispatch +) add_definitions (-DRETRACE) @@ -47,13 +50,13 @@ add_dependencies (retrace_common glproc) if (WIN32 OR APPLE OR X11_FOUND) add_executable (glretrace ${glws_os} - ${CMAKE_SOURCE_DIR}/glproc_gl.cpp ) add_dependencies (glretrace glproc) target_link_libraries (glretrace retrace_common + glproc_gl common ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} @@ -92,13 +95,13 @@ endif () if (ENABLE_EGL AND X11_FOUND AND NOT WIN32 AND NOT APPLE) add_executable (eglretrace glws_egl_xlib.cpp - ${CMAKE_SOURCE_DIR}/glproc_egl.cpp ) add_dependencies (eglretrace glproc) target_link_libraries (eglretrace retrace_common + glproc_egl common ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} @@ -121,7 +124,9 @@ if (WIN32 AND DirectX_D3DX9_INCLUDE_DIR) COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3dretrace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3dretrace_d3d9.cpp DEPENDS d3dretrace.py + dllretrace.py retrace.py + ${CMAKE_SOURCE_DIR}/dispatch/dispatch.py ${CMAKE_SOURCE_DIR}/specs/d3d9.py ${CMAKE_SOURCE_DIR}/specs/d3d9types.py ${CMAKE_SOURCE_DIR}/specs/d3d9caps.py diff --git a/wrappers/CMakeLists.txt b/wrappers/CMakeLists.txt index d47dc6d..2e8a095 100644 --- a/wrappers/CMakeLists.txt +++ b/wrappers/CMakeLists.txt @@ -2,7 +2,10 @@ # API tracers -include_directories (${CMAKE_CURRENT_SOURCE_DIR}) +include_directories ( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_BINARY_DIR}/dispatch +) if (WIN32) @@ -19,7 +22,9 @@ if (WIN32) COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/ddrawtrace.py > ${CMAKE_CURRENT_BINARY_DIR}/ddrawtrace.cpp DEPENDS ddrawtrace.py + dlltrace.py trace.py + ${CMAKE_SOURCE_DIR}/dispatch/dispatch.py ${CMAKE_SOURCE_DIR}/specs/d3d.py ${CMAKE_SOURCE_DIR}/specs/d3dtypes.py ${CMAKE_SOURCE_DIR}/specs/d3dcaps.py @@ -47,7 +52,9 @@ if (WIN32) COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d8trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d8trace.cpp DEPENDS d3d8trace.py + dlltrace.py trace.py + ${CMAKE_SOURCE_DIR}/dispatch/dispatch.py ${CMAKE_SOURCE_DIR}/specs/d3d8.py ${CMAKE_SOURCE_DIR}/specs/d3d8types.py ${CMAKE_SOURCE_DIR}/specs/d3d8caps.py @@ -74,7 +81,9 @@ if (WIN32) COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d9trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d9trace.cpp DEPENDS d3d9trace.py + dlltrace.py trace.py + ${CMAKE_SOURCE_DIR}/dispatch/dispatch.py ${CMAKE_SOURCE_DIR}/specs/d3d9.py ${CMAKE_SOURCE_DIR}/specs/d3d9types.py ${CMAKE_SOURCE_DIR}/specs/d3d9caps.py @@ -101,7 +110,9 @@ if (WIN32) COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d10trace.cpp DEPENDS d3d10trace.py + dlltrace.py trace.py + ${CMAKE_SOURCE_DIR}/dispatch/dispatch.py ${CMAKE_SOURCE_DIR}/specs/d3d10misc.py ${CMAKE_SOURCE_DIR}/specs/d3d10.py ${CMAKE_SOURCE_DIR}/specs/d3d10sdklayers.py @@ -132,7 +143,9 @@ if (WIN32) COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10_1trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d10_1trace.cpp DEPENDS d3d10_1trace.py + dlltrace.py trace.py + ${CMAKE_SOURCE_DIR}/dispatch/dispatch.py ${CMAKE_SOURCE_DIR}/specs/d3d10_1.py ${CMAKE_SOURCE_DIR}/specs/d3d10.py ${CMAKE_SOURCE_DIR}/specs/d3d10sdklayers.py @@ -163,6 +176,7 @@ if (WIN32) COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d11trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d11trace.cpp DEPENDS d3d11trace.py + dlltrace.py trace.py ${CMAKE_SOURCE_DIR}/specs/d3d11.py ${CMAKE_SOURCE_DIR}/specs/d3d11sdklayers.py @@ -193,6 +207,7 @@ if (WIN32) wgltrace.py gltrace.py trace.py + ${CMAKE_SOURCE_DIR}/dispatch/dispatch.py ${CMAKE_SOURCE_DIR}/specs/wglapi.py ${CMAKE_SOURCE_DIR}/specs/wglenum.py ${CMAKE_SOURCE_DIR}/specs/glapi.py @@ -204,10 +219,10 @@ if (WIN32) add_library (wgltrace MODULE opengl32.def wgltrace.cpp glcaps.cpp - ${CMAKE_SOURCE_DIR}/glproc_gl.cpp ) add_dependencies (wgltrace glproc) target_link_libraries (wgltrace + glproc_gl common ${ZLIB_LIBRARIES} ${SNAPPY_LIBRARIES} @@ -237,7 +252,6 @@ elseif (APPLE) add_library (cgltrace SHARED cgltrace.cpp glcaps.cpp - ${CMAKE_SOURCE_DIR}/glproc_gl.cpp ) add_dependencies (cgltrace glproc) @@ -250,6 +264,7 @@ elseif (APPLE) ) target_link_libraries (cgltrace + glproc_gl common ${ZLIB_LIBRARIES} ${SNAPPY_LIBRARIES} @@ -277,7 +292,6 @@ elseif (X11_FOUND) add_library (glxtrace SHARED glxtrace.cpp glcaps.cpp - ${CMAKE_SOURCE_DIR}/glproc_gl.cpp ) add_dependencies (glxtrace glproc) @@ -291,6 +305,7 @@ elseif (X11_FOUND) ) target_link_libraries (glxtrace + glproc_gl common ${ZLIB_LIBRARIES} ${SNAPPY_LIBRARIES} @@ -323,7 +338,6 @@ if (ENABLE_EGL AND NOT WIN32 AND NOT APPLE) add_library (egltrace SHARED egltrace.cpp glcaps.cpp - ${CMAKE_SOURCE_DIR}/glproc_egl.cpp ) add_dependencies (egltrace glproc) @@ -337,6 +351,7 @@ if (ENABLE_EGL AND NOT WIN32 AND NOT APPLE) ) target_link_libraries (egltrace + glproc_egl common ${ZLIB_LIBRARIES} ${SNAPPY_LIBRARIES}