Makefile
apitrace
build
-cgltrace.cpp
-d3d10trace.cpp
-d3d8trace.cpp
-d3d9trace.cpp
-ddrawtrace.cpp
dxsdk
-egltrace.cpp
eglretrace
glproc.hpp
glretrace
glretrace_gl.cpp
glstate_params.cpp
-glxtrace.cpp
install_manifest.txt
qapitrace
traces
-wgltrace.cpp
##############################################################################
# API tracers
-if (WIN32)
- if (MINGW)
- # Silence warnings about @nn suffix mismatch
- set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--enable-stdcall-fixup")
- endif ()
-
- # ddraw.dll
- if (DirectX_D3D_INCLUDE_DIR)
- include_directories (SYSTEM ${DirectX_D3D_INCLUDE_DIR})
- add_custom_command (
- OUTPUT ddrawtrace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/ddrawtrace.py > ${CMAKE_CURRENT_BINARY_DIR}/ddrawtrace.cpp
- DEPENDS ddrawtrace.py trace.py specs/d3d.py specs/d3dtypes.py specs/d3dcaps.py specs/ddraw.py specs/winapi.py specs/stdapi.py
- )
- add_library (ddraw MODULE specs/ddraw.def ddrawtrace.cpp)
- target_link_libraries (ddraw
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- )
- set_target_properties (ddraw
- PROPERTIES PREFIX ""
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS ddraw LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
- endif ()
-
- # d3d8.dll
- if (DirectX_D3D8_INCLUDE_DIR AND DirectX_D3DX9_INCLUDE_DIR)
- include_directories (SYSTEM ${DirectX_D3D8_INCLUDE_DIR} ${DirectX_D3DX9_INCLUDE_DIR})
- add_custom_command (
- OUTPUT d3d8trace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d8trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d8trace.cpp
- DEPENDS d3d8trace.py trace.py specs/d3d8.py specs/d3d8types.py specs/d3d8caps.py specs/winapi.py specs/stdapi.py
- )
- add_library (d3d8 MODULE specs/d3d8.def d3d8trace.cpp d3dshader.cpp)
- target_link_libraries (d3d8
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- )
- set_target_properties (d3d8
- PROPERTIES PREFIX ""
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS d3d8 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
- endif ()
-
- # d3d9.dll
- if (DirectX_D3DX9_INCLUDE_DIR)
- include_directories (SYSTEM ${DirectX_D3DX9_INCLUDE_DIR})
- add_custom_command (
- OUTPUT d3d9trace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d9trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d9trace.cpp
- DEPENDS d3d9trace.py trace.py specs/d3d9.py specs/d3d9types.py specs/d3d9caps.py specs/winapi.py specs/stdapi.py
- )
- add_library (d3d9 MODULE specs/d3d9.def d3d9trace.cpp d3dshader.cpp)
- target_link_libraries (d3d9
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- )
- set_target_properties (d3d9
- PROPERTIES PREFIX ""
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS d3d9 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
- endif ()
-
- # d3d10.dll
- if (DirectX_D3DX10_INCLUDE_DIR)
- include_directories (SYSTEM ${DirectX_D3DX10_INCLUDE_DIR})
- add_custom_command (
- OUTPUT d3d10trace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d10trace.cpp
- DEPENDS d3d10trace.py trace.py specs/d3d10misc.py specs/d3d10.py specs/d3d10sdklayers.py specs/d3dcommon.py specs/dxgi.py specs/dxgitype.py specs/dxgiformat.py specs/winapi.py specs/stdapi.py
- )
- add_library (d3d10 MODULE specs/d3d10.def d3d10trace.cpp)
- target_link_libraries (d3d10
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- )
- set_target_properties (d3d10
- PROPERTIES PREFIX ""
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS d3d10 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
- endif ()
-
- # d3d10_1.dll
- if (DirectX_D3DX10_INCLUDE_DIR AND DirectX_D3D10_1_INCLUDE_DIR)
- include_directories (SYSTEM ${DirectX_D3D10_1_INCLUDE_DIR})
- add_custom_command (
- OUTPUT d3d10_1trace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10_1trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d10_1trace.cpp
- DEPENDS d3d10_1trace.py trace.py specs/d3d10_1.py specs/d3d10.py specs/d3d10sdklayers.py specs/d3dcommon.py specs/dxgi.py specs/dxgitype.py specs/dxgiformat.py specs/winapi.py specs/stdapi.py
- )
- add_library (d3d10_1 MODULE specs/d3d10_1.def d3d10_1trace.cpp)
- target_link_libraries (d3d10_1
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- )
- set_target_properties (d3d10_1
- PROPERTIES PREFIX ""
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS d3d10_1 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
- endif ()
-
- # d3d11.dll
- if (DirectX_D3DX11_INCLUDE_DIR)
- include_directories (SYSTEM ${DirectX_D3DX11_INCLUDE_DIR})
- add_custom_command (
- OUTPUT d3d11trace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d11trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d11trace.cpp
- DEPENDS d3d11trace.py trace.py specs/d3d11.py specs/d3d11sdklayers.py specs/d3dcommon.py specs/dxgi.py specs/dxgitype.py specs/dxgiformat.py specs/winapi.py specs/stdapi.py
- )
- add_library (d3d11 MODULE specs/d3d11.def d3d11trace.cpp)
- target_link_libraries (d3d11
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- )
- set_target_properties (d3d11
- PROPERTIES PREFIX ""
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS d3d11 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
- endif ()
-
- # opengl32.dll
- add_custom_command (
- OUTPUT wgltrace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/wgltrace.py > ${CMAKE_CURRENT_BINARY_DIR}/wgltrace.cpp
- DEPENDS wgltrace.py gltrace.py trace.py specs/wglapi.py specs/wglenum.py specs/glapi.py specs/glparams.py specs/gltypes.py specs/winapi.py specs/stdapi.py
- )
- add_library (wgltrace MODULE specs/opengl32.def
- wgltrace.cpp
- glcaps.cpp
- glproc_gl.cpp
- )
- add_dependencies (wgltrace glproc)
- target_link_libraries (wgltrace
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- )
- set_target_properties (wgltrace PROPERTIES
- PREFIX ""
- OUTPUT_NAME opengl32
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS wgltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
-
-elseif (APPLE)
- # OpenGL framework
- add_custom_command (
- OUTPUT cgltrace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/cgltrace.py > ${CMAKE_CURRENT_BINARY_DIR}/cgltrace.cpp
- DEPENDS cgltrace.py gltrace.py trace.py specs/cglapi.py specs/glapi.py specs/glparams.py specs/gltypes.py specs/stdapi.py
- )
-
- add_library (cgltrace SHARED
- cgltrace.cpp
- glcaps.cpp
- glproc_gl.cpp
- )
-
- add_dependencies (cgltrace glproc)
-
- set_target_properties (cgltrace PROPERTIES
- # OpenGL framework name
- PREFIX "" OUTPUT_NAME "OpenGL" SUFFIX ""
- # Specificy the version and reexport GLU symbols
- LINK_FLAGS "-compatibility_version 1 -current_version 1.0.0 -Wl,-reexport_library,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib"
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
-
- target_link_libraries (cgltrace
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- ${CMAKE_THREAD_LIBS_INIT}
- dl
- )
-
- install (TARGETS cgltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
-elseif (X11_FOUND)
- # libGL.so
- add_custom_command (
- OUTPUT glxtrace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glxtrace.py > ${CMAKE_CURRENT_BINARY_DIR}/glxtrace.cpp
- DEPENDS glxtrace.py gltrace.py trace.py specs/glxapi.py specs/glapi.py specs/glparams.py specs/gltypes.py specs/stdapi.py
- )
-
- add_library (glxtrace SHARED
- glxtrace.cpp
- glcaps.cpp
- glproc_gl.cpp
- )
-
- add_dependencies (glxtrace glproc)
-
- set_target_properties (glxtrace PROPERTIES
- # avoid the default "lib" prefix
- PREFIX ""
- # Prevent symbol relocations internal to our wrapper library to be
- # overwritten by the application.
- LINK_FLAGS "-Wl,-Bsymbolic -Wl,-Bsymbolic-functions"
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
-
- target_link_libraries (glxtrace
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- ${X11_X11_LIB}
- ${CMAKE_THREAD_LIBS_INIT}
- dl
- )
-
- install (TARGETS glxtrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
-endif ()
-
-
-if (ENABLE_EGL AND NOT WIN32 AND NOT APPLE)
- # libEGL.so/libGL.so
- add_custom_command (
- OUTPUT egltrace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/egltrace.py > ${CMAKE_CURRENT_BINARY_DIR}/egltrace.cpp
- DEPENDS egltrace.py gltrace.py trace.py specs/eglapi.py specs/glesapi.py specs/glapi.py specs/glparams.py specs/gltypes.py specs/stdapi.py
- )
-
- add_library (egltrace SHARED
- egltrace.cpp
- glcaps.cpp
- glproc_egl.cpp
- )
-
- add_dependencies (egltrace glproc)
-
- set_target_properties (egltrace PROPERTIES
- # avoid the default "lib" prefix
- PREFIX ""
- LINK_FLAGS "-Wl,-Bsymbolic -Wl,-Bsymbolic-functions"
- # Prevent symbol relocations internal to our wrapper library to be
- # overwritten by the application.
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
-
- target_link_libraries (egltrace
- common
- ${ZLIB_LIBRARIES}
- ${SNAPPY_LIBRARIES}
- ${CMAKE_THREAD_LIBS_INIT}
- dl
- )
+add_subdirectory (wrappers)
- install (TARGETS egltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
-endif ()
##############################################################################
# API retracers
+++ /dev/null
-##########################################################################
-#
-# Copyright 2011 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.
-#
-##########################################################################/
-
-
-"""Cgl tracing generator."""
-
-
-from specs.stdapi import API
-from specs.glapi import glapi
-from specs.cglapi import cglapi
-from gltrace import GlTracer
-
-
-class CglTracer(GlTracer):
-
- def isFunctionPublic(self, function):
- # The symbols visible in libGL.dylib can vary, so expose them all
- return True
-
-
-if __name__ == '__main__':
- print
- print '#include <stdlib.h>'
- print '#include <string.h>'
- print
- print '#include "trace_writer_local.hpp"'
- print
- print '// To validate our prototypes'
- print '#define GL_GLEXT_PROTOTYPES'
- print
- print '#include "glproc.hpp"'
- print '#include "glsize.hpp"'
- print
-
- api = API()
- api.addApi(cglapi)
- api.addApi(glapi)
- tracer = CglTracer()
- tracer.trace_api(api)
-
- print r'''
-
-PUBLIC
-void * gll_noop = 0;
-
-'''
+++ /dev/null
-##########################################################################
-#
-# Copyright 2008-2009 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.
-#
-##########################################################################/
-
-
-from specs.d3d10_1 import d3d10_1
-from dlltrace import DllTracer
-
-
-if __name__ == '__main__':
- print '#define INITGUID'
- print
- print '#include "trace_writer_local.hpp"'
- print '#include "os.hpp"'
- print
- print '#include <windows.h>'
- print '#include <tchar.h>'
- print
- print '#include "compat.h"'
- print
- print '#include <d3d10_1.h>'
- print '#include <d3dx10.h>'
- print
- tracer = DllTracer('d3d10_1.dll')
- tracer.trace_api(d3d10_1)
+++ /dev/null
-##########################################################################
-#
-# Copyright 2008-2009 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.
-#
-##########################################################################/
-
-
-from specs.d3d10misc import d3d10
-from dlltrace import DllTracer
-
-
-if __name__ == '__main__':
- print '#define INITGUID'
- print
- print '#include "trace_writer_local.hpp"'
- print '#include "os.hpp"'
- print
- print '#include <windows.h>'
- print '#include <tchar.h>'
- print
- print '#include "compat.h"'
- print
- print '#include <d3d10.h>'
- print '#include <d3dx10.h>'
- print
- tracer = DllTracer('d3d10.dll')
- tracer.trace_api(d3d10)
+++ /dev/null
-##########################################################################
-#
-# Copyright 2008-2012 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.
-#
-##########################################################################/
-
-
-from specs.d3d11 import d3d11
-from dlltrace import DllTracer
-
-
-if __name__ == '__main__':
- print '#define INITGUID'
- print
- print '#include "trace_writer_local.hpp"'
- print '#include "os.hpp"'
- print
- print '#include <windows.h>'
- print '#include <tchar.h>'
- print
- print '#include "compat.h"'
- print
- print '#include <d3d11.h>'
- print '#include <d3dx11.h>'
- print
- tracer = DllTracer('d3d11.dll')
- tracer.trace_api(d3d11)
+++ /dev/null
-##########################################################################
-#
-# Copyright 2008-2009 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.
-#
-##########################################################################/
-
-
-from specs.d3d8 import d3d8
-from dlltrace import DllTracer
-
-
-class D3D8Tracer(DllTracer):
-
- def serializeArgValue(self, function, arg):
- # Dump shaders as strings
- if function.name in ('CreateVertexShader', 'CreatePixelShader') and arg.name == 'pFunction':
- print ' DumpShader(trace::localWriter, %s);' % (arg.name)
- return
-
- DllTracer.serializeArgValue(self, function, arg)
-
-
-if __name__ == '__main__':
- print '#define INITGUID'
- print
- print '#include <windows.h>'
- print '#include <d3d8.h>'
- print '#include "d3dshader.hpp"'
- print
- print '#include "trace_writer_local.hpp"'
- print '#include "os.hpp"'
- print
- tracer = D3D8Tracer('d3d8.dll')
- tracer.trace_api(d3d8)
-
+++ /dev/null
-##########################################################################
-#
-# Copyright 2008-2009 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.
-#
-##########################################################################/
-
-
-from dlltrace import DllTracer
-from specs.d3d9 import d3d9
-
-
-class D3D9Tracer(DllTracer):
-
- def serializeArgValue(self, function, arg):
- # Dump shaders as strings
- if function.name in ('CreateVertexShader', 'CreatePixelShader') and arg.name == 'pFunction':
- print ' DumpShader(trace::localWriter, %s);' % (arg.name)
- return
-
- DllTracer.serializeArgValue(self, function, arg)
-
- def declareWrapperInterfaceVariables(self, interface):
- DllTracer.declareWrapperInterfaceVariables(self, interface)
-
- if interface.name == 'IDirect3DVertexBuffer9':
- print ' UINT m_SizeToLock;'
- print ' VOID *m_pbData;'
-
- def implementWrapperInterfaceMethodBody(self, interface, base, method):
- if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Unlock':
- print ' if (m_pbData) {'
- self.emit_memcpy('(LPBYTE)m_pbData', '(LPBYTE)m_pbData', 'm_SizeToLock')
- print ' }'
-
- DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method)
-
- if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Lock':
- # FIXME: handle recursive locks
- print ' if (__result == D3D_OK && !(Flags & D3DLOCK_READONLY)) {'
- print ' if (SizeToLock) {'
- print ' m_SizeToLock = SizeToLock;'
- print ' } else {'
- print ' D3DVERTEXBUFFER_DESC Desc;'
- print ' m_pInstance->GetDesc(&Desc);'
- print ' m_SizeToLock = Desc.Size;'
- print ' }'
- print ' m_pbData = *ppbData;'
- print ' } else {'
- print ' m_pbData = NULL;'
- print ' }'
-
-
-if __name__ == '__main__':
- print '#define INITGUID'
- print
- print '#include "trace_writer_local.hpp"'
- print '#include "os.hpp"'
- print
- print '#include "d3d9imports.hpp"'
- print '#include "d3dshader.hpp"'
- print
- print '''
-static inline size_t
-_declCount(const D3DVERTEXELEMENT9 *pVertexElements) {
- size_t count = 0;
- if (pVertexElements) {
- while (pVertexElements[count++].Stream != 0xff)
- ;
- }
- return count;
-}
-'''
- tracer = D3D9Tracer('d3d9.dll')
- tracer.trace_api(d3d9)
-
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2011 Jose Fonseca
- * Copyright 2008-2009 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.
- *
- **************************************************************************/
-
-
-#include <stdio.h>
-
-#include "d3dshader.hpp"
-#include "d3d9imports.hpp"
-
-
-typedef HRESULT
-(WINAPI *PD3DXDISASSEMBLESHADER)(
- CONST DWORD *pShader,
- BOOL EnableColorCode,
- LPCSTR pComments,
- LPD3DXBUFFER *ppDisassembly
-);
-
-
-void DumpShader(trace::Writer &writer, const DWORD *tokens)
-{
- static BOOL firsttime = TRUE;
- static HMODULE hD3DXModule = NULL;
- static PD3DXDISASSEMBLESHADER pfnD3DXDisassembleShader = NULL;
-
- if (firsttime) {
- if (!hD3DXModule) {
- unsigned release;
- int version;
- for (release = 0; release <= 1; ++release) {
- /* Version 41 corresponds to Mar 2009 version of DirectX Runtime / SDK */
- for (version = 41; version >= 0; --version) {
- char filename[256];
- _snprintf(filename, sizeof(filename),
- "d3dx9%s%s%u.dll", release ? "" : "d", version ? "_" : "", version);
- hD3DXModule = LoadLibraryA(filename);
- if (hD3DXModule)
- goto found;
- }
- }
-found:
- ;
- }
-
- if (hD3DXModule) {
- if (!pfnD3DXDisassembleShader) {
- pfnD3DXDisassembleShader = (PD3DXDISASSEMBLESHADER)GetProcAddress(hD3DXModule, "D3DXDisassembleShader");
- }
- }
-
- firsttime = FALSE;
- }
-
- if (pfnD3DXDisassembleShader) {
- LPD3DXBUFFER pDisassembly = NULL;
- HRESULT hr;
-
- hr = pfnD3DXDisassembleShader( (DWORD *)tokens, FALSE, NULL, &pDisassembly);
- if (hr == D3D_OK) {
- writer.writeString((const char *)pDisassembly->GetBufferPointer());
- }
-
- if (pDisassembly) {
- pDisassembly->Release();
- }
-
- if (hr == D3D_OK) {
- return;
- }
- }
-
- writer.writeOpaque(tokens);
-}
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2011 Jose Fonseca
- * Copyright 2008-2009 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.
- *
- **************************************************************************/
-
-#ifndef _D3DSHADER_HPP_
-#define _D3DSHADER_HPP_
-
-
-#include <windows.h>
-
-#include "trace_writer.hpp"
-
-void DumpShader(trace::Writer &writer, const DWORD *tokens);
-
-
-#endif /* _D3DSHADER_HPP_ */
+++ /dev/null
-##########################################################################
-#
-# Copyright 2008-2009 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.
-#
-##########################################################################/
-
-
-from specs.d3d import ddraw, interfaces
-from dlltrace import DllTracer
-
-
-class DDrawTracer(DllTracer):
-
- def traceFunctionImplBody(self, function):
- if function.name in ('AcquireDDThreadLock', 'ReleaseDDThreadLock'):
- self.invokeFunction(function)
- return
-
- DllTracer.traceFunctionImplBody(self, function)
-
- def serializeArg(self, function, arg):
- if function.name == 'DirectDrawCreateEx' and arg.name == 'lplpDD':
- print ' if (*lplpDD) {'
- for iface in interfaces:
- print ' if (iid == IID_%s) {' % iface.name
- print ' *lplpDD = (LPVOID) new Wrap%s((%s *)*lplpDD);' % (iface.name, iface.name)
- print ' }'
- print ' }'
-
- DllTracer.serializeArg(self, function, arg)
-
-
-if __name__ == '__main__':
- print '#define INITGUID'
- print '#include <windows.h>'
- print '#include <ddraw.h>'
- print '#include <d3d.h>'
- print
- print '''
-
-#ifndef DDBLT_EXTENDED_FLAGS
-#define DDBLT_EXTENDED_FLAGS 0x40000000l
-#endif
-
-#ifndef DDBLT_EXTENDED_LINEAR_CONTENT
-#define DDBLT_EXTENDED_LINEAR_CONTENT 0x00000004l
-#endif
-
-#ifndef D3DLIGHT_PARALLELPOINT
-#define D3DLIGHT_PARALLELPOINT (D3DLIGHTTYPE)4
-#endif
-
-#ifndef D3DLIGHT_GLSPOT
-#define D3DLIGHT_GLSPOT (D3DLIGHTTYPE)5
-#endif
-
-'''
- print '#include "trace_writer_local.hpp"'
- print '#include "os.hpp"'
- print
- tracer = DDrawTracer('ddraw.dll')
- tracer.trace_api(ddraw)
+++ /dev/null
-##########################################################################
-#
-# Copyright 2008-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.
-#
-##########################################################################/
-
-"""Trace code generation for Windows DLLs."""
-
-
-from dispatch import Dispatcher
-from trace import Tracer
-
-
-class DllTracer(Tracer):
-
- def __init__(self, dllname):
- self.dllname = dllname
-
- def header(self, api):
- print '''
-static HINSTANCE g_hDll = NULL;
-
-static PROC
-__getPublicProcAddress(LPCSTR lpProcName)
-{
- if (!g_hDll) {
- char szDll[MAX_PATH] = {0};
-
- if (!GetSystemDirectoryA(szDll, MAX_PATH)) {
- return NULL;
- }
-
- strcat(szDll, "\\\\%s");
-
- g_hDll = LoadLibraryA(szDll);
- if (!g_hDll) {
- return NULL;
- }
- }
-
- return GetProcAddress(g_hDll, lpProcName);
-}
-
-''' % self.dllname
-
- dispatcher = Dispatcher()
- dispatcher.dispatch_api(api)
-
- Tracer.header(self, api)
-
+++ /dev/null
-##########################################################################
-#
-# Copyright 2011 LunarG, Inc.
-# All Rights Reserved.
-#
-# Based on glxtrace.py, which has
-#
-# Copyright 2011 Jose Fonseca
-# Copyright 2008-2010 VMware, Inc.
-#
-# 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.
-#
-##########################################################################/
-
-
-"""EGL tracing generator."""
-
-
-from specs.stdapi import API
-from specs.glapi import glapi
-from specs.eglapi import eglapi
-from specs.glesapi import glesapi
-from gltrace import GlTracer
-from dispatch import function_pointer_type, function_pointer_value
-
-
-class EglTracer(GlTracer):
-
- def isFunctionPublic(self, function):
- # The symbols visible in libEGL.so can vary, so expose them all
- return True
-
- def traceFunctionImplBody(self, function):
- GlTracer.traceFunctionImplBody(self, function)
-
- if function.name == 'eglMakeCurrent':
- print ' // update the profile'
- print ' if (ctx != EGL_NO_CONTEXT) {'
- print ' EGLint api = EGL_OPENGL_ES_API, version = 1;'
- print ' gltrace::Context *tr = gltrace::getContext();'
- print ' __eglQueryContext(dpy, ctx, EGL_CONTEXT_CLIENT_TYPE, &api);'
- print ' __eglQueryContext(dpy, ctx, EGL_CONTEXT_CLIENT_VERSION, &version);'
- print ' if (api == EGL_OPENGL_API)'
- print ' tr->profile = gltrace::PROFILE_COMPAT;'
- print ' else if (version == 1)'
- print ' tr->profile = gltrace::PROFILE_ES1;'
- print ' else'
- print ' tr->profile = gltrace::PROFILE_ES2;'
- print ' }'
-
- def wrapRet(self, function, instance):
- GlTracer.wrapRet(self, function, instance)
-
- if function.name == "eglGetProcAddress":
- print ' %s = __unwrap_proc_addr(procname, %s);' % (instance, instance)
-
-
-if __name__ == '__main__':
- print '#include <stdlib.h>'
- print '#include <string.h>'
- print '#include <dlfcn.h>'
- print
- print '#include "trace_writer_local.hpp"'
- print
- print '// To validate our prototypes'
- print '#define GL_GLEXT_PROTOTYPES'
- print '#define EGL_EGLEXT_PROTOTYPES'
- print
- print '#include "glproc.hpp"'
- print '#include "glsize.hpp"'
- print
- print 'static __eglMustCastToProperFunctionPointerType __unwrap_proc_addr(const char * procname, __eglMustCastToProperFunctionPointerType procPtr);'
- print
-
- api = API()
- api.addApi(eglapi)
- api.addApi(glapi)
- api.addApi(glesapi)
- tracer = EglTracer()
- tracer.trace_api(api)
-
- print 'static __eglMustCastToProperFunctionPointerType __unwrap_proc_addr(const char * procname, __eglMustCastToProperFunctionPointerType procPtr) {'
- print ' if (!procPtr) {'
- print ' return procPtr;'
- print ' }'
- for f in api.functions:
- ptype = function_pointer_type(f)
- pvalue = function_pointer_value(f)
- print ' if (!strcmp("%s", procname)) {' % f.name
- print ' %s = (%s)procPtr;' % (pvalue, ptype)
- print ' return (__eglMustCastToProperFunctionPointerType)&%s;' % (f.name,)
- print ' }'
- print ' os::log("apitrace: warning: unknown function \\"%s\\"\\n", procname);'
- print ' return procPtr;'
- print '}'
- print
- print r'''
-
-
-/*
- * Android does not support LD_PRELOAD.
- */
-#if !defined(ANDROID)
-
-
-/*
- * 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);
-}
-
-
-/*
- * Several applications, such as Quake3, use dlopen("libGL.so.1"), but
- * LD_PRELOAD does not intercept symbols obtained via dlopen/dlsym, therefore
- * we need to intercept the dlopen() call here, and redirect to our wrapper
- * shared object.
- */
-extern "C" PUBLIC
-void * dlopen(const char *filename, int flag)
-{
- bool intercept = false;
-
- if (filename) {
- intercept =
- strcmp(filename, "libEGL.so") == 0 ||
- strcmp(filename, "libEGL.so.1") == 0 ||
- strcmp(filename, "libGLESv1_CM.so") == 0 ||
- strcmp(filename, "libGLESv1_CM.so.1") == 0 ||
- strcmp(filename, "libGLESv2.so") == 0 ||
- strcmp(filename, "libGLESv2.so.2") == 0 ||
- strcmp(filename, "libGL.so") == 0 ||
- strcmp(filename, "libGL.so.1") == 0;
-
- if (intercept) {
- os::log("apitrace: redirecting dlopen(\"%s\", 0x%x)\n", filename, flag);
-
- /* The current dispatch implementation relies on core entry-points to be globally available, so force this.
- *
- * TODO: A better approach would be note down the entry points here and
- * use them latter. Another alternative would be to reopen the library
- * with RTLD_NOLOAD | RTLD_GLOBAL.
- */
- flag &= ~RTLD_LOCAL;
- flag |= RTLD_GLOBAL;
- }
- }
-
- void *handle = __dlopen(filename, flag);
-
- if (intercept) {
- // Get the file path for our shared object, and use it instead
- static int dummy = 0xdeedbeef;
- Dl_info info;
- if (dladdr(&dummy, &info)) {
- handle = __dlopen(info.dli_fname, flag);
- } else {
- os::log("apitrace: warning: dladdr() failed\n");
- }
- }
-
- return handle;
-}
-
-
-#endif /* !ANDROID */
-
-
-
-'''
+++ /dev/null
-/**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
-
-/*
- * Manipulation of GL extensions.
- *
- * So far we insert GREMEDY extensions, but in the future we could also clamp
- * the GL extensions to core GL versions here.
- */
-
-
-#include <assert.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <string>
-#include <map>
-
-#include "glproc.hpp"
-#include "gltrace.hpp"
-
-
-namespace gltrace {
-
-
-typedef std::map<std::string, const char *> ExtensionsMap;
-
-// Cache of the translated extensions strings
-static ExtensionsMap extensionsMap;
-
-
-// Additional extensions to be advertised
-static const char *
-extraExtension_stringsFull[] = {
- "GL_GREMEDY_string_marker",
- "GL_GREMEDY_frame_terminator",
-};
-
-static const char *
-extraExtension_stringsES[] = {
- "GL_EXT_debug_marker",
-};
-
-// Description of additional extensions we want to advertise
-struct ExtensionsDesc
-{
- unsigned numStrings;
- const char **strings;
-};
-
-#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
-
-const struct ExtensionsDesc
-extraExtensionsFull = {
- ARRAY_SIZE(extraExtension_stringsFull),
- extraExtension_stringsFull
-};
-
-const struct ExtensionsDesc
-extraExtensionsES = {
- ARRAY_SIZE(extraExtension_stringsES),
- extraExtension_stringsES
-};
-
-
-const struct ExtensionsDesc *
-getExtraExtensions(void)
-{
- Context *ctx = getContext();
-
- switch (ctx->profile) {
- case PROFILE_COMPAT:
- return &extraExtensionsFull;
- case PROFILE_ES1:
- case PROFILE_ES2:
- return &extraExtensionsES;
- default:
- assert(0);
- return &extraExtensionsFull;
- }
-}
-
-
-/**
- * Translate the GL extensions string, adding new extensions.
- */
-static const char *
-overrideExtensionsString(const char *extensions)
-{
- const ExtensionsDesc *desc = getExtraExtensions();
- size_t i;
-
- ExtensionsMap::const_iterator it = extensionsMap.find(extensions);
- if (it != extensionsMap.end()) {
- return it->second;
- }
-
- size_t extensionsLen = strlen(extensions);
-
- size_t extraExtensionsLen = 0;
- for (i = 0; i < desc->numStrings; ++i) {
- const char * extraExtension = desc->strings[i];
- size_t extraExtensionLen = strlen(extraExtension);
- extraExtensionsLen += extraExtensionLen + 1;
- }
-
- // We use malloc memory instead of a std::string because we need to ensure
- // that extensions strings will not move in memory as the extensionsMap is
- // updated.
- size_t newExtensionsLen = extensionsLen + 1 + extraExtensionsLen + 1;
- char *newExtensions = (char *)malloc(newExtensionsLen);
- if (!newExtensions) {
- return extensions;
- }
-
- if (extensionsLen) {
- memcpy(newExtensions, extensions, extensionsLen);
-
- // Add space separator if necessary
- if (newExtensions[extensionsLen - 1] != ' ') {
- newExtensions[extensionsLen++] = ' ';
- }
- }
-
- for (i = 0; i < desc->numStrings; ++i) {
- const char * extraExtension = desc->strings[i];
- size_t extraExtensionLen = strlen(extraExtension);
- memcpy(newExtensions + extensionsLen, extraExtension, extraExtensionLen);
- extensionsLen += extraExtensionLen;
- newExtensions[extensionsLen++] = ' ';
- }
- newExtensions[extensionsLen++] = '\0';
- assert(extensionsLen <= newExtensionsLen);
-
- extensionsMap[extensions] = newExtensions;
-
- return newExtensions;
-}
-
-
-const GLubyte *
-__glGetString_override(GLenum name)
-{
- const GLubyte *result = __glGetString(name);
-
- if (result) {
- switch (name) {
- case GL_EXTENSIONS:
- result = (const GLubyte *)overrideExtensionsString((const char *)result);
- break;
- default:
- break;
- }
- }
-
- return result;
-}
-
-
-void
-__glGetIntegerv_override(GLenum pname, GLint *params)
-{
- __glGetIntegerv(pname, params);
-
- if (params) {
- switch (pname) {
- case GL_NUM_EXTENSIONS:
- {
- const ExtensionsDesc *desc = getExtraExtensions();
- *params += desc->numStrings;
- }
- break;
- default:
- break;
- }
- }
-}
-
-
-const GLubyte *
-__glGetStringi_override(GLenum name, GLuint index)
-{
- switch (name) {
- case GL_EXTENSIONS:
- {
- const ExtensionsDesc *desc = getExtraExtensions();
- GLint numExtensions = 0;
- __glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
- if ((GLuint)numExtensions <= index && index < (GLuint)numExtensions + desc->numStrings) {
- return (const GLubyte *)desc->strings[index - (GLuint)numExtensions];
- }
- }
- break;
- default:
- break;
- }
-
- return __glGetStringi(name, index);
-}
-
-
-} /* namespace gltrace */
-
+++ /dev/null
-/**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
-#ifndef _GLTRACE_HPP_
-#define _GLTRACE_HPP_
-
-
-#include "glimports.hpp"
-
-
-namespace gltrace {
-
-
-enum Profile {
- PROFILE_COMPAT,
- PROFILE_ES1,
- PROFILE_ES2,
-};
-
-struct Context {
- enum Profile profile;
- bool user_arrays;
- bool user_arrays_arb;
- bool user_arrays_nv;
-};
-
-Context *
-getContext(void);
-
-const GLubyte *
-__glGetString_override(GLenum name);
-
-void
-__glGetIntegerv_override(GLenum pname, GLint *params);
-
-const GLubyte *
-__glGetStringi_override(GLenum name, GLuint index);
-
-
-} /* namespace gltrace */
-
-
-#endif /* _GLRETRACE_HPP_ */
+++ /dev/null
-##########################################################################
-#
-# Copyright 2008-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.
-#
-##########################################################################/
-
-
-"""GL tracing generator."""
-
-
-import specs.stdapi as stdapi
-import specs.glapi as glapi
-import specs.glparams as glparams
-from specs.glxapi import glxapi
-from trace import Tracer
-
-
-class TypeGetter(stdapi.Visitor):
- '''Determine which glGet*v function that matches the specified type.'''
-
- def __init__(self, prefix = 'glGet', long_suffix = True, ext_suffix = ''):
- self.prefix = prefix
- self.long_suffix = long_suffix
- self.ext_suffix = ext_suffix
-
- def visitConst(self, const):
- return self.visit(const.type)
-
- def visitAlias(self, alias):
- if alias.expr == 'GLboolean':
- if self.long_suffix:
- suffix = 'Booleanv'
- arg_type = alias.expr
- else:
- suffix = 'iv'
- arg_type = 'GLint'
- elif alias.expr == 'GLdouble':
- if self.long_suffix:
- suffix = 'Doublev'
- arg_type = alias.expr
- else:
- suffix = 'dv'
- arg_type = alias.expr
- elif alias.expr == 'GLfloat':
- if self.long_suffix:
- suffix = 'Floatv'
- arg_type = alias.expr
- else:
- suffix = 'fv'
- arg_type = alias.expr
- elif alias.expr in ('GLint', 'GLuint', 'GLsizei'):
- if self.long_suffix:
- suffix = 'Integerv'
- arg_type = 'GLint'
- else:
- suffix = 'iv'
- arg_type = 'GLint'
- else:
- print alias.expr
- assert False
- function_name = self.prefix + suffix + self.ext_suffix
- return function_name, arg_type
-
- def visitEnum(self, enum):
- return self.visit(glapi.GLint)
-
- def visitBitmask(self, bitmask):
- return self.visit(glapi.GLint)
-
- def visitOpaque(self, pointer):
- return self.prefix + 'Pointerv' + self.ext_suffix, 'GLvoid *'
-
-
-class GlTracer(Tracer):
-
- arrays = [
- ("Vertex", "VERTEX"),
- ("Normal", "NORMAL"),
- ("Color", "COLOR"),
- ("Index", "INDEX"),
- ("TexCoord", "TEXTURE_COORD"),
- ("EdgeFlag", "EDGE_FLAG"),
- ("FogCoord", "FOG_COORD"),
- ("SecondaryColor", "SECONDARY_COLOR"),
- ]
- arrays.reverse()
-
- # arrays available in PROFILE_ES1
- arrays_es1 = ("Vertex", "Normal", "Color", "TexCoord")
-
- def header(self, api):
- Tracer.header(self, api)
-
- print '#include "gltrace.hpp"'
- print
-
- # Which glVertexAttrib* variant to use
- print 'enum vertex_attrib {'
- print ' VERTEX_ATTRIB,'
- print ' VERTEX_ATTRIB_ARB,'
- print ' VERTEX_ATTRIB_NV,'
- print '};'
- print
- print 'gltrace::Context *'
- print 'gltrace::getContext(void)'
- print '{'
- print ' // TODO return the context set by other APIs (GLX, EGL, and etc.)'
- print ' static gltrace::Context __ctx = { gltrace::PROFILE_COMPAT, false, false, false };'
- print ' return &__ctx;'
- print '}'
- print
- print 'static vertex_attrib __get_vertex_attrib(void) {'
- print ' gltrace::Context *ctx = gltrace::getContext();'
- print ' if (ctx->user_arrays_arb || ctx->user_arrays_nv) {'
- print ' GLboolean __vertex_program = GL_FALSE;'
- print ' __glGetBooleanv(GL_VERTEX_PROGRAM_ARB, &__vertex_program);'
- print ' if (__vertex_program) {'
- print ' if (ctx->user_arrays_nv) {'
- print ' GLint __vertex_program_binding_nv = 0;'
- print ' __glGetIntegerv(GL_VERTEX_PROGRAM_BINDING_NV, &__vertex_program_binding_nv);'
- print ' if (__vertex_program_binding_nv) {'
- print ' return VERTEX_ATTRIB_NV;'
- print ' }'
- print ' }'
- print ' return VERTEX_ATTRIB_ARB;'
- print ' }'
- print ' }'
- print ' return VERTEX_ATTRIB;'
- print '}'
- print
-
- # Whether we need user arrays
- print 'static inline bool __need_user_arrays(void)'
- print '{'
- print ' gltrace::Context *ctx = gltrace::getContext();'
- print ' if (!ctx->user_arrays) {'
- print ' return false;'
- print ' }'
- print
-
- for camelcase_name, uppercase_name in self.arrays:
- # in which profile is the array available?
- profile_check = 'ctx->profile == gltrace::PROFILE_COMPAT'
- if camelcase_name in self.arrays_es1:
- profile_check = '(' + profile_check + ' || ctx->profile == gltrace::PROFILE_ES1)';
-
- function_name = 'gl%sPointer' % camelcase_name
- enable_name = 'GL_%s_ARRAY' % uppercase_name
- binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
- print ' // %s' % function_name
- print ' if (%s) {' % profile_check
- self.array_prolog(api, uppercase_name)
- print ' if (__glIsEnabled(%s)) {' % enable_name
- print ' GLint __binding = 0;'
- print ' __glGetIntegerv(%s, &__binding);' % binding_name
- print ' if (!__binding) {'
- self.array_cleanup(api, uppercase_name)
- print ' return true;'
- print ' }'
- print ' }'
- self.array_epilog(api, uppercase_name)
- print ' }'
- print
-
- print ' // ES1 does not support generic vertex attributes'
- print ' if (ctx->profile == gltrace::PROFILE_ES1)'
- print ' return false;'
- print
- print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
- print
- print ' // glVertexAttribPointer'
- print ' if (__vertex_attrib == VERTEX_ATTRIB) {'
- print ' GLint __max_vertex_attribs = 0;'
- print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
- print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
- print ' GLint __enabled = 0;'
- print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &__enabled);'
- print ' if (__enabled) {'
- print ' GLint __binding = 0;'
- print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &__binding);'
- print ' if (!__binding) {'
- print ' return true;'
- print ' }'
- print ' }'
- print ' }'
- print ' }'
- print
- print ' // glVertexAttribPointerARB'
- print ' if (__vertex_attrib == VERTEX_ATTRIB_ARB) {'
- print ' GLint __max_vertex_attribs = 0;'
- print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &__max_vertex_attribs);'
- print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
- print ' GLint __enabled = 0;'
- print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB, &__enabled);'
- print ' if (__enabled) {'
- print ' GLint __binding = 0;'
- print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB, &__binding);'
- print ' if (!__binding) {'
- print ' return true;'
- print ' }'
- print ' }'
- print ' }'
- print ' }'
- print
- print ' // glVertexAttribPointerNV'
- print ' if (__vertex_attrib == VERTEX_ATTRIB_NV) {'
- print ' for (GLint index = 0; index < 16; ++index) {'
- print ' GLint __enabled = 0;'
- print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
- print ' if (__enabled) {'
- print ' return true;'
- print ' }'
- print ' }'
- print ' }'
- print
-
- print ' return false;'
- print '}'
- print
-
- print 'static void __trace_user_arrays(GLuint maxindex);'
- print
-
- # Buffer mappings
- print '// whether glMapBufferRange(GL_MAP_WRITE_BIT) has ever been called'
- print 'static bool __checkBufferMapRange = false;'
- print
- print '// whether glBufferParameteriAPPLE(GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE) has ever been called'
- print 'static bool __checkBufferFlushingUnmapAPPLE = false;'
- print
- # Buffer mapping information, necessary for old Mesa 2.1 drivers which
- # do not support glGetBufferParameteriv(GL_BUFFER_ACCESS_FLAGS/GL_BUFFER_MAP_LENGTH)
- print 'struct buffer_mapping {'
- print ' void *map;'
- print ' GLint length;'
- print ' bool write;'
- print ' bool explicit_flush;'
- print '};'
- print
- for target in self.buffer_targets:
- print 'struct buffer_mapping __%s_mapping;' % target.lower();
- print
- print 'static inline struct buffer_mapping *'
- print 'get_buffer_mapping(GLenum target) {'
- print ' switch (target) {'
- for target in self.buffer_targets:
- print ' case GL_%s:' % target
- print ' return & __%s_mapping;' % target.lower()
- print ' default:'
- print ' os::log("apitrace: warning: unknown buffer target 0x%04X\\n", target);'
- print ' return NULL;'
- print ' }'
- print '}'
- print
-
- # Generate a helper function to determine whether a parameter name
- # refers to a symbolic value or not
- print 'static bool'
- print 'is_symbolic_pname(GLenum pname) {'
- print ' switch (pname) {'
- for function, type, count, name in glparams.parameters:
- if type is glapi.GLenum:
- print ' case %s:' % name
- print ' return true;'
- print ' default:'
- print ' return false;'
- print ' }'
- print '}'
- print
-
- # Generate a helper function to determine whether a parameter value is
- # potentially symbolic or not; i.e., if the value can be represented in
- # an enum or not
- print 'template<class T>'
- print 'static inline bool'
- print 'is_symbolic_param(T param) {'
- print ' return static_cast<T>(static_cast<GLenum>(param)) == param;'
- print '}'
- print
-
- # Generate a helper function to know how many elements a parameter has
- print 'static size_t'
- print '__gl_param_size(GLenum pname) {'
- print ' switch (pname) {'
- for function, type, count, name in glparams.parameters:
- if type is not None:
- print ' case %s: return %u;' % (name, count)
- print ' case GL_COMPRESSED_TEXTURE_FORMATS: {'
- print ' GLint num_compressed_texture_formats = 0;'
- print ' __glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_texture_formats);'
- print ' return num_compressed_texture_formats;'
- print ' }'
- print ' default:'
- print r' os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, pname);'
- print ' return 1;'
- print ' }'
- print '}'
- print
-
- # states such as GL_UNPACK_ROW_LENGTH are not available in GLES
- print 'static inline bool'
- print 'can_unpack_subimage(void) {'
- print ' gltrace::Context *ctx = gltrace::getContext();'
- print ' return (ctx->profile == gltrace::PROFILE_COMPAT);'
- print '}'
- print
-
- array_pointer_function_names = set((
- "glVertexPointer",
- "glNormalPointer",
- "glColorPointer",
- "glIndexPointer",
- "glTexCoordPointer",
- "glEdgeFlagPointer",
- "glFogCoordPointer",
- "glSecondaryColorPointer",
-
- "glInterleavedArrays",
-
- "glVertexPointerEXT",
- "glNormalPointerEXT",
- "glColorPointerEXT",
- "glIndexPointerEXT",
- "glTexCoordPointerEXT",
- "glEdgeFlagPointerEXT",
- "glFogCoordPointerEXT",
- "glSecondaryColorPointerEXT",
-
- "glVertexAttribPointer",
- "glVertexAttribPointerARB",
- "glVertexAttribPointerNV",
- "glVertexAttribIPointer",
- "glVertexAttribIPointerEXT",
- "glVertexAttribLPointer",
- "glVertexAttribLPointerEXT",
-
- #"glMatrixIndexPointerARB",
- ))
-
- draw_function_names = set((
- 'glDrawArrays',
- 'glDrawElements',
- 'glDrawRangeElements',
- 'glMultiDrawArrays',
- 'glMultiDrawElements',
- 'glDrawArraysInstanced',
- "glDrawArraysInstancedBaseInstance",
- 'glDrawElementsInstanced',
- 'glDrawArraysInstancedARB',
- 'glDrawElementsInstancedARB',
- 'glDrawElementsBaseVertex',
- 'glDrawRangeElementsBaseVertex',
- 'glDrawElementsInstancedBaseVertex',
- "glDrawElementsInstancedBaseInstance",
- "glDrawElementsInstancedBaseVertexBaseInstance",
- 'glMultiDrawElementsBaseVertex',
- 'glDrawArraysIndirect',
- 'glDrawElementsIndirect',
- 'glDrawArraysEXT',
- 'glDrawRangeElementsEXT',
- 'glDrawRangeElementsEXT_size',
- 'glMultiDrawArraysEXT',
- 'glMultiDrawElementsEXT',
- 'glMultiModeDrawArraysIBM',
- 'glMultiModeDrawElementsIBM',
- 'glDrawArraysInstancedEXT',
- 'glDrawElementsInstancedEXT',
- ))
-
- interleaved_formats = [
- 'GL_V2F',
- 'GL_V3F',
- 'GL_C4UB_V2F',
- 'GL_C4UB_V3F',
- 'GL_C3F_V3F',
- 'GL_N3F_V3F',
- 'GL_C4F_N3F_V3F',
- 'GL_T2F_V3F',
- 'GL_T4F_V4F',
- 'GL_T2F_C4UB_V3F',
- 'GL_T2F_C3F_V3F',
- 'GL_T2F_N3F_V3F',
- 'GL_T2F_C4F_N3F_V3F',
- 'GL_T4F_C4F_N3F_V4F',
- ]
-
- def traceFunctionImplBody(self, function):
- # Defer tracing of user array pointers...
- if function.name in self.array_pointer_function_names:
- print ' GLint __array_buffer = 0;'
- print ' __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
- print ' if (!__array_buffer) {'
- print ' gltrace::Context *ctx = gltrace::getContext();'
- print ' ctx->user_arrays = true;'
- if function.name == "glVertexAttribPointerARB":
- print ' ctx->user_arrays_arb = true;'
- if function.name == "glVertexAttribPointerNV":
- print ' ctx->user_arrays_nv = true;'
- self.invokeFunction(function)
-
- # And also break down glInterleavedArrays into the individual calls
- if function.name == 'glInterleavedArrays':
- print
-
- # Initialize the enable flags
- for camelcase_name, uppercase_name in self.arrays:
- flag_name = '__' + uppercase_name.lower()
- print ' GLboolean %s = GL_FALSE;' % flag_name
- print
-
- # Switch for the interleaved formats
- print ' switch (format) {'
- for format in self.interleaved_formats:
- print ' case %s:' % format
- for camelcase_name, uppercase_name in self.arrays:
- flag_name = '__' + uppercase_name.lower()
- if format.find('_' + uppercase_name[0]) >= 0:
- print ' %s = GL_TRUE;' % flag_name
- print ' break;'
- print ' default:'
- print ' return;'
- print ' }'
- print
-
- # Emit fake glEnableClientState/glDisableClientState flags
- for camelcase_name, uppercase_name in self.arrays:
- flag_name = '__' + uppercase_name.lower()
- enable_name = 'GL_%s_ARRAY' % uppercase_name
-
- # Emit a fake function
- print ' {'
- print ' static const trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
- print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
- print ' trace::localWriter.beginArg(0);'
- self.serializeValue(glapi.GLenum, enable_name)
- print ' trace::localWriter.endArg();'
- print ' trace::localWriter.endEnter();'
- print ' trace::localWriter.beginLeave(__call);'
- print ' trace::localWriter.endLeave();'
- print ' }'
-
- print ' return;'
- print ' }'
-
- # ... to the draw calls
- if function.name in self.draw_function_names:
- print ' if (__need_user_arrays()) {'
- arg_names = ', '.join([arg.name for arg in function.args[1:]])
- print ' GLuint maxindex = __%s_maxindex(%s);' % (function.name, arg_names)
- print ' __trace_user_arrays(maxindex);'
- print ' }'
-
- # Emit a fake memcpy on buffer uploads
- if function.name == 'glBufferParameteriAPPLE':
- print ' if (pname == GL_BUFFER_FLUSHING_UNMAP_APPLE && param == GL_FALSE) {'
- print ' __checkBufferFlushingUnmapAPPLE = true;'
- print ' }'
- if function.name in ('glUnmapBuffer', 'glUnmapBufferARB'):
- if function.name.endswith('ARB'):
- suffix = 'ARB'
- else:
- suffix = ''
- print ' GLint access = 0;'
- print ' __glGetBufferParameteriv%s(target, GL_BUFFER_ACCESS, &access);' % suffix
- print ' if (access != GL_READ_ONLY) {'
- print ' GLvoid *map = NULL;'
- print ' __glGetBufferPointerv%s(target, GL_BUFFER_MAP_POINTER, &map);' % suffix
- print ' if (map) {'
- print ' GLint length = -1;'
- print ' bool flush = true;'
- print ' if (__checkBufferMapRange) {'
- print ' __glGetBufferParameteriv%s(target, GL_BUFFER_MAP_LENGTH, &length);' % suffix
- print ' GLint access_flags = 0;'
- print ' __glGetBufferParameteriv(target, GL_BUFFER_ACCESS_FLAGS, &access_flags);'
- print ' flush = flush && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT);'
- print ' if (length == -1) {'
- print ' // Mesa drivers refuse GL_BUFFER_MAP_LENGTH without GL 3.0'
- print ' static bool warned = false;'
- print ' if (!warned) {'
- print ' os::log("apitrace: warning: glGetBufferParameteriv%s(GL_BUFFER_MAP_LENGTH) failed\\n");' % suffix
- print ' warned = true;'
- print ' }'
- print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
- print ' if (mapping) {'
- print ' length = mapping->length;'
- print ' flush = flush && !mapping->explicit_flush;'
- print ' } else {'
- print ' length = 0;'
- print ' flush = false;'
- print ' }'
- print ' }'
- print ' } else {'
- print ' length = 0;'
- print ' __glGetBufferParameteriv%s(target, GL_BUFFER_SIZE, &length);' % suffix
- print ' }'
- print ' if (__checkBufferFlushingUnmapAPPLE) {'
- print ' GLint flushing_unmap = GL_TRUE;'
- print ' __glGetBufferParameteriv%s(target, GL_BUFFER_FLUSHING_UNMAP_APPLE, &flushing_unmap);' % suffix
- print ' flush = flush && flushing_unmap;'
- print ' }'
- print ' if (flush && length > 0) {'
- self.emit_memcpy('map', 'map', 'length')
- print ' }'
- print ' }'
- print ' }'
- if function.name == 'glUnmapBufferOES':
- print ' GLint access = 0;'
- print ' __glGetBufferParameteriv(target, GL_BUFFER_ACCESS_OES, &access);'
- print ' if (access == GL_WRITE_ONLY_OES) {'
- print ' GLvoid *map = NULL;'
- print ' __glGetBufferPointervOES(target, GL_BUFFER_MAP_POINTER_OES, &map);'
- print ' GLint size = 0;'
- print ' __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size);'
- print ' if (map && size > 0) {'
- self.emit_memcpy('map', 'map', 'size')
- print ' }'
- print ' }'
- if function.name == 'glUnmapNamedBufferEXT':
- print ' GLint access_flags = 0;'
- print ' __glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_ACCESS_FLAGS, &access_flags);'
- print ' if ((access_flags & GL_MAP_WRITE_BIT) && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT)) {'
- print ' GLvoid *map = NULL;'
- print ' __glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);'
- print ' GLint length = 0;'
- print ' __glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_MAP_LENGTH, &length);'
- print ' if (map && length > 0) {'
- self.emit_memcpy('map', 'map', 'length')
- print ' }'
- print ' }'
- if function.name == 'glFlushMappedBufferRange':
- print ' GLvoid *map = NULL;'
- print ' __glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);'
- print ' if (map && length > 0) {'
- self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length')
- print ' }'
- if function.name == 'glFlushMappedBufferRangeAPPLE':
- print ' GLvoid *map = NULL;'
- print ' __glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);'
- print ' if (map && size > 0) {'
- self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'size')
- print ' }'
- if function.name == 'glFlushMappedNamedBufferRangeEXT':
- print ' GLvoid *map = NULL;'
- print ' __glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);'
- print ' if (map && length > 0) {'
- self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length')
- print ' }'
-
- # Don't leave vertex attrib locations to chance. Instead emit fake
- # glBindAttribLocation calls to ensure that the same locations will be
- # used when retracing. Trying to remap locations after the fact would
- # be an herculian task given that vertex attrib locations appear in
- # many entry-points, including non-shader related ones.
- if function.name == 'glLinkProgram':
- Tracer.invokeFunction(self, function)
- print ' GLint active_attributes = 0;'
- print ' __glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
- print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
- print ' GLint size = 0;'
- print ' GLenum type = 0;'
- print ' GLchar name[256];'
- # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
- print ' __glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
- print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
- print ' GLint location = __glGetAttribLocation(program, name);'
- print ' if (location >= 0) {'
- bind_function = glapi.glapi.get_function_by_name('glBindAttribLocation')
- self.fake_call(bind_function, ['program', 'location', 'name'])
- print ' }'
- print ' }'
- print ' }'
- if function.name == 'glLinkProgramARB':
- Tracer.invokeFunction(self, function)
- print ' GLint active_attributes = 0;'
- print ' __glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
- print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
- print ' GLint size = 0;'
- print ' GLenum type = 0;'
- print ' GLcharARB name[256];'
- # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
- print ' __glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
- print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
- print ' GLint location = __glGetAttribLocationARB(programObj, name);'
- print ' if (location >= 0) {'
- bind_function = glapi.glapi.get_function_by_name('glBindAttribLocationARB')
- self.fake_call(bind_function, ['programObj', 'location', 'name'])
- print ' }'
- print ' }'
- print ' }'
-
- Tracer.traceFunctionImplBody(self, function)
-
- marker_functions = [
- # GL_GREMEDY_string_marker
- 'glStringMarkerGREMEDY',
- # GL_GREMEDY_frame_terminator
- 'glFrameTerminatorGREMEDY',
- # GL_EXT_debug_marker
- 'glInsertEventMarkerEXT',
- 'glPushGroupMarkerEXT',
- 'glPopGroupMarkerEXT',
- ]
-
- def invokeFunction(self, function):
- if function.name in ('glLinkProgram', 'glLinkProgramARB'):
- # These functions have been dispatched already
- return
-
- # We implement GL_EXT_debug_marker, GL_GREMEDY_*, etc., and not the
- # driver
- if function.name in self.marker_functions:
- return
-
- if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'):
- else_ = ''
- for marker_function in self.marker_functions:
- if self.api.get_function_by_name(marker_function):
- print ' %sif (strcmp("%s", (const char *)%s) == 0) {' % (else_, marker_function, function.args[0].name)
- print ' __result = (%s)&%s;' % (function.type, marker_function)
- print ' }'
- else_ = 'else '
- print ' %s{' % else_
- Tracer.invokeFunction(self, function)
- print ' }'
- return
-
- # Override GL extensions
- if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'):
- Tracer.invokeFunction(self, function, prefix = 'gltrace::__', suffix = '_override')
- return
-
- Tracer.invokeFunction(self, function)
-
- buffer_targets = [
- 'ARRAY_BUFFER',
- 'ELEMENT_ARRAY_BUFFER',
- 'PIXEL_PACK_BUFFER',
- 'PIXEL_UNPACK_BUFFER',
- 'UNIFORM_BUFFER',
- 'TEXTURE_BUFFER',
- 'TRANSFORM_FEEDBACK_BUFFER',
- 'COPY_READ_BUFFER',
- 'COPY_WRITE_BUFFER',
- 'DRAW_INDIRECT_BUFFER',
- 'ATOMIC_COUNTER_BUFFER',
- ]
-
- def wrapRet(self, function, instance):
- Tracer.wrapRet(self, function, instance)
-
- # Keep track of buffer mappings
- if function.name in ('glMapBuffer', 'glMapBufferARB'):
- print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
- print ' if (mapping) {'
- print ' mapping->map = %s;' % (instance)
- print ' mapping->length = 0;'
- print ' __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &mapping->length);'
- print ' mapping->write = (access != GL_READ_ONLY);'
- print ' mapping->explicit_flush = false;'
- print ' }'
- if function.name == 'glMapBufferRange':
- print ' if (access & GL_MAP_WRITE_BIT) {'
- print ' __checkBufferMapRange = true;'
- print ' }'
- print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
- print ' if (mapping) {'
- print ' mapping->map = %s;' % (instance)
- print ' mapping->length = length;'
- print ' mapping->write = access & GL_MAP_WRITE_BIT;'
- print ' mapping->explicit_flush = access & GL_MAP_FLUSH_EXPLICIT_BIT;'
- print ' }'
-
- boolean_names = [
- 'GL_FALSE',
- 'GL_TRUE',
- ]
-
- def gl_boolean(self, value):
- return self.boolean_names[int(bool(value))]
-
- # Names of the functions that unpack from a pixel buffer object. See the
- # ARB_pixel_buffer_object specification.
- unpack_function_names = set([
- 'glBitmap',
- 'glColorSubTable',
- 'glColorTable',
- 'glCompressedTexImage1D',
- 'glCompressedTexImage2D',
- 'glCompressedTexImage3D',
- 'glCompressedTexSubImage1D',
- 'glCompressedTexSubImage2D',
- 'glCompressedTexSubImage3D',
- 'glConvolutionFilter1D',
- 'glConvolutionFilter2D',
- 'glDrawPixels',
- 'glMultiTexImage1DEXT',
- 'glMultiTexImage2DEXT',
- 'glMultiTexImage3DEXT',
- 'glMultiTexSubImage1DEXT',
- 'glMultiTexSubImage2DEXT',
- 'glMultiTexSubImage3DEXT',
- 'glPixelMapfv',
- 'glPixelMapuiv',
- 'glPixelMapusv',
- 'glPolygonStipple',
- 'glSeparableFilter2D',
- 'glTexImage1D',
- 'glTexImage1DEXT',
- 'glTexImage2D',
- 'glTexImage2DEXT',
- 'glTexImage3D',
- 'glTexImage3DEXT',
- 'glTexSubImage1D',
- 'glTexSubImage1DEXT',
- 'glTexSubImage2D',
- 'glTexSubImage2DEXT',
- 'glTexSubImage3D',
- 'glTexSubImage3DEXT',
- 'glTextureImage1DEXT',
- 'glTextureImage2DEXT',
- 'glTextureImage3DEXT',
- 'glTextureSubImage1DEXT',
- 'glTextureSubImage2DEXT',
- 'glTextureSubImage3DEXT',
- ])
-
- def serializeArgValue(self, function, arg):
- if function.name in self.draw_function_names and arg.name == 'indices':
- print ' GLint __element_array_buffer = 0;'
- print ' __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
- print ' if (!__element_array_buffer) {'
- if isinstance(arg.type, stdapi.Array):
- print ' trace::localWriter.beginArray(%s);' % arg.type.length
- print ' for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length
- print ' trace::localWriter.beginElement();'
- print ' trace::localWriter.writeBlob(%s[i], count[i]*__gl_type_size(type));' % (arg.name)
- print ' trace::localWriter.endElement();'
- print ' }'
- print ' trace::localWriter.endArray();'
- else:
- print ' trace::localWriter.writeBlob(%s, count*__gl_type_size(type));' % (arg.name)
- print ' } else {'
- Tracer.serializeArgValue(self, function, arg)
- print ' }'
- return
-
- # Recognize offsets instead of blobs when a PBO is bound
- if function.name in self.unpack_function_names \
- and (isinstance(arg.type, stdapi.Blob) \
- or (isinstance(arg.type, stdapi.Const) \
- and isinstance(arg.type.type, stdapi.Blob))):
- print ' {'
- print ' gltrace::Context *ctx = gltrace::getContext();'
- print ' GLint __unpack_buffer = 0;'
- print ' if (ctx->profile == gltrace::PROFILE_COMPAT)'
- print ' __glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &__unpack_buffer);'
- print ' if (__unpack_buffer) {'
- print ' trace::localWriter.writeOpaque(%s);' % arg.name
- print ' } else {'
- Tracer.serializeArgValue(self, function, arg)
- print ' }'
- print ' }'
- return
-
- # Several GL state functions take GLenum symbolic names as
- # integer/floats; so dump the symbolic name whenever possible
- if function.name.startswith('gl') \
- and arg.type in (glapi.GLint, glapi.GLfloat, glapi.GLdouble) \
- and arg.name == 'param':
- assert arg.index > 0
- assert function.args[arg.index - 1].name == 'pname'
- assert function.args[arg.index - 1].type == glapi.GLenum
- print ' if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
- self.serializeValue(glapi.GLenum, arg.name)
- print ' } else {'
- Tracer.serializeArgValue(self, function, arg)
- print ' }'
- return
-
- Tracer.serializeArgValue(self, function, arg)
-
- def footer(self, api):
- Tracer.footer(self, api)
-
- # A simple state tracker to track the pointer values
- # update the state
- print 'static void __trace_user_arrays(GLuint maxindex)'
- print '{'
- print ' gltrace::Context *ctx = gltrace::getContext();'
-
- for camelcase_name, uppercase_name in self.arrays:
- # in which profile is the array available?
- profile_check = 'ctx->profile == gltrace::PROFILE_COMPAT'
- if camelcase_name in self.arrays_es1:
- profile_check = '(' + profile_check + ' || ctx->profile == gltrace::PROFILE_ES1)';
-
- function_name = 'gl%sPointer' % camelcase_name
- enable_name = 'GL_%s_ARRAY' % uppercase_name
- binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
- function = api.get_function_by_name(function_name)
-
- print ' // %s' % function.prototype()
- print ' if (%s) {' % profile_check
- self.array_trace_prolog(api, uppercase_name)
- self.array_prolog(api, uppercase_name)
- print ' if (__glIsEnabled(%s)) {' % enable_name
- print ' GLint __binding = 0;'
- print ' __glGetIntegerv(%s, &__binding);' % binding_name
- print ' if (!__binding) {'
-
- # Get the arguments via glGet*
- for arg in function.args:
- arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
- arg_get_function, arg_type = TypeGetter().visit(arg.type)
- print ' %s %s = 0;' % (arg_type, arg.name)
- print ' __%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
-
- arg_names = ', '.join([arg.name for arg in function.args[:-1]])
- print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
-
- # Emit a fake function
- self.array_trace_intermezzo(api, uppercase_name)
- print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
- for arg in function.args:
- assert not arg.output
- print ' trace::localWriter.beginArg(%u);' % (arg.index,)
- if arg.name != 'pointer':
- self.serializeValue(arg.type, arg.name)
- else:
- print ' trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
- print ' trace::localWriter.endArg();'
-
- print ' trace::localWriter.endEnter();'
- print ' trace::localWriter.beginLeave(__call);'
- print ' trace::localWriter.endLeave();'
- print ' }'
- print ' }'
- self.array_epilog(api, uppercase_name)
- self.array_trace_epilog(api, uppercase_name)
- print ' }'
- print
-
- # Samething, but for glVertexAttribPointer*
- #
- # Some variants of glVertexAttribPointer alias conventional and generic attributes:
- # - glVertexAttribPointer: no
- # - glVertexAttribPointerARB: implementation dependent
- # - glVertexAttribPointerNV: yes
- #
- # This means that the implementations of these functions do not always
- # alias, and they need to be considered independently.
- #
- print ' // ES1 does not support generic vertex attributes'
- print ' if (ctx->profile == gltrace::PROFILE_ES1)'
- print ' return;'
- print
- print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
- print
- for suffix in ['', 'ARB', 'NV']:
- if suffix:
- SUFFIX = '_' + suffix
- else:
- SUFFIX = suffix
- function_name = 'glVertexAttribPointer' + suffix
- function = api.get_function_by_name(function_name)
-
- print ' // %s' % function.prototype()
- print ' if (__vertex_attrib == VERTEX_ATTRIB%s) {' % SUFFIX
- if suffix == 'NV':
- print ' GLint __max_vertex_attribs = 16;'
- else:
- print ' GLint __max_vertex_attribs = 0;'
- print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
- print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
- print ' GLint __enabled = 0;'
- if suffix == 'NV':
- print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
- else:
- print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED%s, &__enabled);' % (suffix, SUFFIX)
- print ' if (__enabled) {'
- print ' GLint __binding = 0;'
- if suffix != 'NV':
- # It doesn't seem possible to use VBOs with NV_vertex_program.
- print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING%s, &__binding);' % (suffix, SUFFIX)
- print ' if (!__binding) {'
-
- # Get the arguments via glGet*
- for arg in function.args[1:]:
- if suffix == 'NV':
- arg_get_enum = 'GL_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
- else:
- arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
- arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False, suffix).visit(arg.type)
- print ' %s %s = 0;' % (arg_type, arg.name)
- print ' __%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
-
- arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
- print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
-
- # Emit a fake function
- print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
- for arg in function.args:
- assert not arg.output
- print ' trace::localWriter.beginArg(%u);' % (arg.index,)
- if arg.name != 'pointer':
- self.serializeValue(arg.type, arg.name)
- else:
- print ' trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
- print ' trace::localWriter.endArg();'
-
- print ' trace::localWriter.endEnter();'
- print ' trace::localWriter.beginLeave(__call);'
- print ' trace::localWriter.endLeave();'
- print ' }'
- print ' }'
- print ' }'
- print ' }'
- print
-
- print '}'
- print
-
- #
- # Hooks for glTexCoordPointer, which is identical to the other array
- # pointers except the fact that it is indexed by glClientActiveTexture.
- #
-
- def array_prolog(self, api, uppercase_name):
- if uppercase_name == 'TEXTURE_COORD':
- print ' GLint client_active_texture = 0;'
- print ' __glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);'
- print ' GLint max_texture_coords = 0;'
- print ' if (ctx->profile == gltrace::PROFILE_COMPAT)'
- print ' __glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
- print ' else'
- print ' __glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_coords);'
- print ' for (GLint unit = 0; unit < max_texture_coords; ++unit) {'
- print ' GLint texture = GL_TEXTURE0 + unit;'
- print ' __glClientActiveTexture(texture);'
-
- def array_trace_prolog(self, api, uppercase_name):
- if uppercase_name == 'TEXTURE_COORD':
- print ' bool client_active_texture_dirty = false;'
-
- def array_epilog(self, api, uppercase_name):
- if uppercase_name == 'TEXTURE_COORD':
- print ' }'
- self.array_cleanup(api, uppercase_name)
-
- def array_cleanup(self, api, uppercase_name):
- if uppercase_name == 'TEXTURE_COORD':
- print ' __glClientActiveTexture(client_active_texture);'
-
- def array_trace_intermezzo(self, api, uppercase_name):
- if uppercase_name == 'TEXTURE_COORD':
- print ' if (texture != client_active_texture || client_active_texture_dirty) {'
- print ' client_active_texture_dirty = true;'
- self.fake_glClientActiveTexture_call(api, "texture");
- print ' }'
-
- def array_trace_epilog(self, api, uppercase_name):
- if uppercase_name == 'TEXTURE_COORD':
- print ' if (client_active_texture_dirty) {'
- self.fake_glClientActiveTexture_call(api, "client_active_texture");
- print ' }'
-
- def fake_glClientActiveTexture_call(self, api, texture):
- function = api.get_function_by_name('glClientActiveTexture')
- self.fake_call(function, [texture])
-
- def fake_call(self, function, args):
- print ' unsigned __fake_call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
- for arg, instance in zip(function.args, args):
- assert not arg.output
- print ' trace::localWriter.beginArg(%u);' % (arg.index,)
- self.serializeValue(arg.type, instance)
- print ' trace::localWriter.endArg();'
- print ' trace::localWriter.endEnter();'
- print ' trace::localWriter.beginLeave(__fake_call);'
- print ' trace::localWriter.endLeave();'
-
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-##########################################################################
-#
-# Copyright 2011 Jose Fonseca
-# Copyright 2008-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.
-#
-##########################################################################/
-
-
-"""GLX tracing generator."""
-
-
-from specs.stdapi import API
-from specs.glapi import glapi
-from specs.glxapi import glxapi
-from gltrace import GlTracer
-from dispatch import function_pointer_type, function_pointer_value
-
-
-class GlxTracer(GlTracer):
-
- def isFunctionPublic(self, function):
- # The symbols visible in libGL.so can vary, so expose them all
- return True
-
- def wrapRet(self, function, instance):
- GlTracer.wrapRet(self, function, instance)
-
- if function.name in ("glXGetProcAddress", "glXGetProcAddressARB"):
- print ' %s = __unwrap_proc_addr(procName, %s);' % (instance, instance)
-
-
-if __name__ == '__main__':
- print
- print '#include <stdlib.h>'
- print '#include <string.h>'
- print
- print '#ifndef _GNU_SOURCE'
- print '#define _GNU_SOURCE // for dladdr'
- print '#endif'
- print '#include <dlfcn.h>'
- print
- print '#include "trace_writer_local.hpp"'
- print
- print '// To validate our prototypes'
- print '#define GL_GLEXT_PROTOTYPES'
- print '#define GLX_GLXEXT_PROTOTYPES'
- print
- print '#include "glproc.hpp"'
- print '#include "glsize.hpp"'
- print
- print 'static __GLXextFuncPtr __unwrap_proc_addr(const GLubyte * procName, __GLXextFuncPtr procPtr);'
- print
-
- api = API()
- api.addApi(glxapi)
- api.addApi(glapi)
- tracer = GlxTracer()
- tracer.trace_api(api)
-
- print 'static __GLXextFuncPtr __unwrap_proc_addr(const GLubyte * procName, __GLXextFuncPtr procPtr) {'
- print ' if (!procPtr) {'
- print ' return procPtr;'
- print ' }'
- for f in api.functions:
- ptype = function_pointer_type(f)
- pvalue = function_pointer_value(f)
- print ' if (strcmp("%s", (const char *)procName) == 0) {' % f.name
- print ' %s = (%s)procPtr;' % (pvalue, ptype)
- print ' return (__GLXextFuncPtr)&%s;' % (f.name,)
- print ' }'
- print ' os::log("apitrace: warning: unknown function \\"%s\\"\\n", (const char *)procName);'
- print ' return procPtr;'
- print '}'
- print
- print r'''
-
-
-/*
- * 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);
-}
-
-
-/*
- * Several applications, such as Quake3, use dlopen("libGL.so.1"), but
- * LD_PRELOAD does not intercept symbols obtained via dlopen/dlsym, therefore
- * we need to intercept the dlopen() call here, and redirect to our wrapper
- * shared object.
- */
-extern "C" PUBLIC
-void * dlopen(const char *filename, int flag)
-{
- void *handle;
-
- handle = __dlopen(filename, flag);
-
- const char * libgl_filename = getenv("TRACE_LIBGL");
-
- if (filename && handle && !libgl_filename) {
- if (0) {
- os::log("apitrace: warning: dlopen(\"%s\", 0x%x)\n", filename, flag);
- }
-
- // FIXME: handle absolute paths and other versions
- if (strcmp(filename, "libGL.so") == 0 ||
- strcmp(filename, "libGL.so.1") == 0) {
-
- // Use the true libGL.so handle instead of RTLD_NEXT from now on
- __libGlHandle = handle;
-
- // Get the file path for our shared object, and use it instead
- static int dummy = 0xdeedbeef;
- Dl_info info;
- if (dladdr(&dummy, &info)) {
- os::log("apitrace: redirecting dlopen(\"%s\", 0x%x)\n", filename, flag);
- handle = __dlopen(info.dli_fname, flag);
- } else {
- os::log("apitrace: warning: dladdr() failed\n");
- }
- }
- }
-
- return handle;
-}
-
-
-
-'''
+++ /dev/null
-LIBRARY "d3d10"
-
-EXPORTS
- D3D10CreateDevice
- D3D10CreateDeviceAndSwapChain
- D3D10CreateBlob
+++ /dev/null
-LIBRARY "d3d10_1"
-
-EXPORTS
- D3D10CreateDevice1
- D3D10CreateDeviceAndSwapChain1
- D3D10CreateBlob
+++ /dev/null
-LIBRARY "d3d11"
-
-EXPORTS
- D3D11CreateDevice
- D3D11CreateDeviceAndSwapChain
+++ /dev/null
-LIBRARY "d3d8"
-
-EXPORTS
- Direct3DCreate8 @1
+++ /dev/null
-LIBRARY "d3d9"
-
-EXPORTS
- Direct3DCreate9
- Direct3DCreate9Ex
- D3DPERF_BeginEvent
- D3DPERF_EndEvent
- D3DPERF_SetMarker
- D3DPERF_SetRegion
- D3DPERF_QueryRepeatFrame
- D3DPERF_SetOptions
- D3DPERF_GetStatus
+++ /dev/null
-EXPORTS
- AcquireDDThreadLock
- CompleteCreateSysmemSurface
- D3DParseUnknownCommand
- DDGetAttachedSurfaceLcl
- DDInternalLock
- DDInternalUnlock
- DirectDrawCreate
- DirectDrawCreateClipper
- DirectDrawCreateEx
- DirectDrawEnumerateA
- DirectDrawEnumerateExA
- DirectDrawEnumerateExW
- DirectDrawEnumerateW
- DllCanUnloadNow PRIVATE
- DllGetClassObject PRIVATE
- DSoundHelp
- GetDDSurfaceLocal
- GetOLEThunkData
- GetSurfaceFromDC
- RegisterSpecialCase
- ReleaseDDThreadLock
- ;SetAppCompatData
+++ /dev/null
-LIBRARY opengl32
-
-EXPORTS
-; GlmfBeginGlsBlock
-; GlmfCloseMetaFile
-; GlmfEndGlsBlock
-; GlmfEndPlayback
-; GlmfInitPlayback
-; GlmfPlayGlsRecord
- 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
-; glDebugEntry
- 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
- 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
+++ /dev/null
-##########################################################################
-#
-# Copyright 2008-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.
-#
-##########################################################################/
-
-"""Common trace code generation."""
-
-
-import specs.stdapi as stdapi
-
-
-def getWrapperInterfaceName(interface):
- return "Wrap" + interface.expr
-
-
-class ComplexValueSerializer(stdapi.OnceVisitor):
- '''Type visitors which generates serialization functions for
- complex types.
-
- Simple types are serialized inline.
- '''
-
- def __init__(self, serializer):
- stdapi.OnceVisitor.__init__(self)
- self.serializer = serializer
-
- def visitVoid(self, literal):
- pass
-
- def visitLiteral(self, literal):
- pass
-
- def visitString(self, string):
- pass
-
- def visitConst(self, const):
- self.visit(const.type)
-
- def visitStruct(self, struct):
- for type, name in struct.members:
- self.visit(type)
- print 'static void _write__%s(const %s &value) {' % (struct.tag, struct.expr)
- print ' static const char * members[%u] = {' % (len(struct.members),)
- for type, name, in struct.members:
- print ' "%s",' % (name,)
- print ' };'
- print ' static const trace::StructSig sig = {'
- print ' %u, "%s", %u, members' % (struct.id, struct.name, len(struct.members))
- print ' };'
- print ' trace::localWriter.beginStruct(&sig);'
- for type, name in struct.members:
- self.serializer.visit(type, 'value.%s' % (name,))
- print ' trace::localWriter.endStruct();'
- print '}'
- print
-
- def visitArray(self, array):
- self.visit(array.type)
-
- def visitBlob(self, array):
- pass
-
- def visitEnum(self, enum):
- print 'static const trace::EnumValue __enum%s_values[] = {' % (enum.tag)
- for value in enum.values:
- print ' {"%s", %s},' % (value, value)
- print '};'
- print
- print 'static const trace::EnumSig __enum%s_sig = {' % (enum.tag)
- print ' %u, %u, __enum%s_values' % (enum.id, len(enum.values), enum.tag)
- print '};'
- print
-
- def visitBitmask(self, bitmask):
- print 'static const trace::BitmaskFlag __bitmask%s_flags[] = {' % (bitmask.tag)
- for value in bitmask.values:
- print ' {"%s", %s},' % (value, value)
- print '};'
- print
- print 'static const trace::BitmaskSig __bitmask%s_sig = {' % (bitmask.tag)
- print ' %u, %u, __bitmask%s_flags' % (bitmask.id, len(bitmask.values), bitmask.tag)
- print '};'
- print
-
- def visitPointer(self, pointer):
- self.visit(pointer.type)
-
- def visitIntPointer(self, pointer):
- pass
-
- def visitObjPointer(self, pointer):
- self.visit(pointer.type)
-
- def visitLinearPointer(self, pointer):
- self.visit(pointer.type)
-
- def visitHandle(self, handle):
- self.visit(handle.type)
-
- def visitReference(self, reference):
- self.visit(reference.type)
-
- def visitAlias(self, alias):
- self.visit(alias.type)
-
- def visitOpaque(self, opaque):
- pass
-
- def visitInterface(self, interface):
- pass
-
- def visitPolymorphic(self, polymorphic):
- print 'static void _write__%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr)
- print ' switch (selector) {'
- for cases, type in polymorphic.iterSwitch():
- for case in cases:
- print ' %s:' % case
- self.serializer.visit(type, 'static_cast<%s>(value)' % (type,))
- print ' break;'
- print ' }'
- print '}'
- print
-
-
-class ValueSerializer(stdapi.Visitor):
- '''Visitor which generates code to serialize any type.
-
- Simple types are serialized inline here, whereas the serialization of
- complex types is dispatched to the serialization functions generated by
- ComplexValueSerializer visitor above.
- '''
-
- def visitLiteral(self, literal, instance):
- print ' trace::localWriter.write%s(%s);' % (literal.kind, instance)
-
- def visitString(self, string, instance):
- if string.kind == 'String':
- cast = 'const char *'
- elif string.kind == 'WString':
- cast = 'const wchar_t *'
- else:
- assert False
- if cast != string.expr:
- # reinterpret_cast is necessary for GLubyte * <=> char *
- instance = 'reinterpret_cast<%s>(%s)' % (cast, instance)
- if string.length is not None:
- length = ', %s' % string.length
- else:
- length = ''
- print ' trace::localWriter.write%s(%s%s);' % (string.kind, instance, length)
-
- def visitConst(self, const, instance):
- self.visit(const.type, instance)
-
- def visitStruct(self, struct, instance):
- print ' _write__%s(%s);' % (struct.tag, instance)
-
- def visitArray(self, array, instance):
- length = '__c' + array.type.tag
- index = '__i' + array.type.tag
- print ' if (%s) {' % instance
- print ' size_t %s = %s;' % (length, array.length)
- print ' trace::localWriter.beginArray(%s);' % length
- print ' for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
- print ' trace::localWriter.beginElement();'
- self.visit(array.type, '(%s)[%s]' % (instance, index))
- print ' trace::localWriter.endElement();'
- print ' }'
- print ' trace::localWriter.endArray();'
- print ' } else {'
- print ' trace::localWriter.writeNull();'
- print ' }'
-
- def visitBlob(self, blob, instance):
- print ' trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
-
- def visitEnum(self, enum, instance):
- print ' trace::localWriter.writeEnum(&__enum%s_sig, %s);' % (enum.tag, instance)
-
- def visitBitmask(self, bitmask, instance):
- print ' trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.tag, instance)
-
- def visitPointer(self, pointer, instance):
- print ' if (%s) {' % instance
- print ' trace::localWriter.beginArray(1);'
- print ' trace::localWriter.beginElement();'
- self.visit(pointer.type, "*" + instance)
- print ' trace::localWriter.endElement();'
- print ' trace::localWriter.endArray();'
- print ' } else {'
- print ' trace::localWriter.writeNull();'
- print ' }'
-
- def visitIntPointer(self, pointer, instance):
- print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
-
- def visitObjPointer(self, pointer, instance):
- print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
-
- def visitLinearPointer(self, pointer, instance):
- print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
-
- def visitReference(self, reference, instance):
- self.visit(reference.type, instance)
-
- def visitHandle(self, handle, instance):
- self.visit(handle.type, instance)
-
- def visitAlias(self, alias, instance):
- self.visit(alias.type, instance)
-
- def visitOpaque(self, opaque, instance):
- print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
-
- def visitInterface(self, interface, instance):
- print ' trace::localWriter.writeOpaque((const void *)&%s);' % instance
-
- def visitPolymorphic(self, polymorphic, instance):
- print ' _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
-
-
-class ValueWrapper(stdapi.Visitor):
- '''Type visitor which will generate the code to wrap an instance.
-
- Wrapping is necessary mostly for interfaces, however interface pointers can
- appear anywhere inside complex types.
- '''
-
- def visitVoid(self, type, instance):
- raise NotImplementedError
-
- def visitLiteral(self, type, instance):
- pass
-
- def visitString(self, type, instance):
- pass
-
- def visitConst(self, type, instance):
- pass
-
- def visitStruct(self, struct, instance):
- for type, name in struct.members:
- self.visit(type, "(%s).%s" % (instance, name))
-
- def visitArray(self, array, instance):
- # XXX: actually it is possible to return an array of pointers
- pass
-
- def visitBlob(self, blob, instance):
- pass
-
- def visitEnum(self, enum, instance):
- pass
-
- def visitBitmask(self, bitmask, instance):
- pass
-
- def visitPointer(self, pointer, instance):
- print " if (%s) {" % instance
- self.visit(pointer.type, "*" + instance)
- print " }"
-
- def visitIntPointer(self, pointer, instance):
- pass
-
- def visitObjPointer(self, pointer, instance):
- print " if (%s) {" % instance
- self.visit(pointer.type, "*" + instance)
- print " }"
-
- def visitLinearPointer(self, pointer, instance):
- pass
-
- def visitReference(self, reference, instance):
- self.visit(reference.type, instance)
-
- def visitHandle(self, handle, instance):
- self.visit(handle.type, instance)
-
- def visitAlias(self, alias, instance):
- self.visit(alias.type, instance)
-
- def visitOpaque(self, opaque, instance):
- pass
-
- def visitInterface(self, interface, instance):
- assert instance.startswith('*')
- instance = instance[1:]
- print " if (%s) {" % instance
- print " %s = new %s(%s);" % (instance, getWrapperInterfaceName(interface), instance)
- print " }"
-
- def visitPolymorphic(self, type, instance):
- # XXX: There might be polymorphic values that need wrapping in the future
- pass
-
-
-class ValueUnwrapper(ValueWrapper):
- '''Reverse of ValueWrapper.'''
-
- def visitInterface(self, interface, instance):
- assert instance.startswith('*')
- instance = instance[1:]
- print r' if (%s) {' % instance
- print r' %s *pWrapper = static_cast<%s*>(%s);' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), instance)
- print r' if (pWrapper && pWrapper->m_dwMagic == 0xd8365d6c) {'
- print r' %s = pWrapper->m_pInstance;' % (instance,)
- print r' } else {'
- print r' os::log("apitrace: warning: %%s: unexpected %%s pointer\n", __FUNCTION__, "%s");' % interface.name
- print r' }'
- print r' }'
-
-
-class Tracer:
- '''Base class to orchestrate the code generation of API tracing.'''
-
- def __init__(self):
- self.api = None
-
- def serializerFactory(self):
- '''Create a serializer.
-
- Can be overriden by derived classes to inject their own serialzer.
- '''
-
- return ValueSerializer()
-
- def trace_api(self, api):
- self.api = api
-
- self.header(api)
-
- # Includes
- for header in api.headers:
- print header
- print
-
- # Generate the serializer functions
- types = api.getAllTypes()
- visitor = ComplexValueSerializer(self.serializerFactory())
- map(visitor.visit, types)
- print
-
- # Interfaces wrapers
- interfaces = api.getAllInterfaces()
- map(self.declareWrapperInterface, interfaces)
- map(self.implementWrapperInterface, interfaces)
- print
-
- # Function wrappers
- map(self.traceFunctionDecl, api.functions)
- map(self.traceFunctionImpl, api.functions)
- print
-
- self.footer(api)
-
- def header(self, api):
- pass
-
- def footer(self, api):
- pass
-
- def traceFunctionDecl(self, function):
- # Per-function declarations
-
- if function.args:
- print 'static const char * __%s_args[%u] = {%s};' % (function.name, len(function.args), ', '.join(['"%s"' % arg.name for arg in function.args]))
- else:
- print 'static const char ** __%s_args = NULL;' % (function.name,)
- print 'static const trace::FunctionSig __%s_sig = {%u, "%s", %u, __%s_args};' % (function.name, function.id, function.name, len(function.args), function.name)
- print
-
- def isFunctionPublic(self, function):
- return True
-
- def traceFunctionImpl(self, function):
- if self.isFunctionPublic(function):
- print 'extern "C" PUBLIC'
- else:
- print 'extern "C" PRIVATE'
- print function.prototype() + ' {'
- if function.type is not stdapi.Void:
- print ' %s __result;' % function.type
- self.traceFunctionImplBody(function)
- if function.type is not stdapi.Void:
- self.wrapRet(function, "__result")
- print ' return __result;'
- print '}'
- print
-
- def traceFunctionImplBody(self, function):
- print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
- for arg in function.args:
- if not arg.output:
- self.unwrapArg(function, arg)
- self.serializeArg(function, arg)
- print ' trace::localWriter.endEnter();'
- self.invokeFunction(function)
- print ' trace::localWriter.beginLeave(__call);'
- for arg in function.args:
- if arg.output:
- self.serializeArg(function, arg)
- self.wrapArg(function, arg)
- if function.type is not stdapi.Void:
- self.serializeRet(function, "__result")
- print ' trace::localWriter.endLeave();'
-
- def invokeFunction(self, function, prefix='__', suffix=''):
- if function.type is stdapi.Void:
- result = ''
- else:
- result = '__result = '
- dispatch = prefix + function.name + suffix
- print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
-
- def serializeArg(self, function, arg):
- print ' trace::localWriter.beginArg(%u);' % (arg.index,)
- self.serializeArgValue(function, arg)
- print ' trace::localWriter.endArg();'
-
- def serializeArgValue(self, function, arg):
- self.serializeValue(arg.type, arg.name)
-
- def wrapArg(self, function, arg):
- self.wrapValue(arg.type, arg.name)
-
- def unwrapArg(self, function, arg):
- self.unwrapValue(arg.type, arg.name)
-
- def serializeRet(self, function, instance):
- print ' trace::localWriter.beginReturn();'
- self.serializeValue(function.type, instance)
- print ' trace::localWriter.endReturn();'
-
- def serializeValue(self, type, instance):
- serializer = self.serializerFactory()
- serializer.visit(type, instance)
-
- def wrapRet(self, function, instance):
- self.wrapValue(function.type, instance)
-
- def unwrapRet(self, function, instance):
- self.unwrapValue(function.type, instance)
-
- def wrapValue(self, type, instance):
- visitor = ValueWrapper()
- visitor.visit(type, instance)
-
- def unwrapValue(self, type, instance):
- visitor = ValueUnwrapper()
- visitor.visit(type, instance)
-
- def declareWrapperInterface(self, interface):
- print "class %s : public %s " % (getWrapperInterfaceName(interface), interface.name)
- print "{"
- print "public:"
- print " %s(%s * pInstance);" % (getWrapperInterfaceName(interface), interface.name)
- print " virtual ~%s();" % getWrapperInterfaceName(interface)
- print
- for method in interface.iterMethods():
- print " " + method.prototype() + ";"
- print
- self.declareWrapperInterfaceVariables(interface)
- print "};"
- print
-
- def declareWrapperInterfaceVariables(self, interface):
- #print "private:"
- print " DWORD m_dwMagic;"
- print " %s * m_pInstance;" % (interface.name,)
-
- def implementWrapperInterface(self, interface):
- print '%s::%s(%s * pInstance) {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), interface.name)
- print ' m_dwMagic = 0xd8365d6c;'
- print ' m_pInstance = pInstance;'
- print '}'
- print
- print '%s::~%s() {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface))
- print '}'
- print
- for base, method in interface.iterBaseMethods():
- self.implementWrapperInterfaceMethod(interface, base, method)
- print
-
- def implementWrapperInterfaceMethod(self, interface, base, method):
- print method.prototype(getWrapperInterfaceName(interface) + '::' + method.name) + ' {'
- if method.type is not stdapi.Void:
- print ' %s __result;' % method.type
-
- self.implementWrapperInterfaceMethodBody(interface, base, method)
-
- if method.type is not stdapi.Void:
- print ' return __result;'
- print '}'
- print
-
- def implementWrapperInterfaceMethodBody(self, interface, base, method):
- print ' static const char * __args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args]))
- print ' static const trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
- print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
- print ' trace::localWriter.beginArg(0);'
- print ' trace::localWriter.writeOpaque((const void *)m_pInstance);'
- print ' trace::localWriter.endArg();'
-
- from specs.winapi import REFIID
- from specs.stdapi import Pointer, Opaque, Interface
-
- riid = None
- for arg in method.args:
- if not arg.output:
- self.unwrapArg(method, arg)
- self.serializeArg(method, arg)
- if arg.type is REFIID:
- riid = arg
- print ' trace::localWriter.endEnter();'
-
- self.invokeMethod(interface, base, method)
-
- print ' trace::localWriter.beginLeave(__call);'
- for arg in method.args:
- if arg.output:
- self.serializeArg(method, arg)
- self.wrapArg(method, arg)
- if riid is not None and isinstance(arg.type, Pointer):
- if isinstance(arg.type.type, Opaque):
- self.wrapIid(interface, method, riid, arg)
- else:
- assert isinstance(arg.type.type, Pointer)
- assert isinstance(arg.type.type.type, Interface)
-
- if method.type is not stdapi.Void:
- print ' trace::localWriter.beginReturn();'
- self.serializeValue(method.type, "__result")
- print ' trace::localWriter.endReturn();'
- self.wrapValue(method.type, '__result')
- print ' trace::localWriter.endLeave();'
- if method.name == 'Release':
- assert method.type is not stdapi.Void
- print ' if (!__result)'
- print ' delete this;'
-
- def wrapIid(self, interface, method, riid, out):
- print ' if (%s && *%s) {' % (out.name, out.name)
- print ' if (*%s == m_pInstance) {' % (out.name,)
- print ' *%s = this;' % (out.name,)
- print ' }'
- for iface in self.api.getAllInterfaces():
- print r' else if (%s == IID_%s) {' % (riid.name, iface.name)
- print r' *%s = new Wrap%s((%s *) *%s);' % (out.name, iface.name, iface.name, out.name)
- print r' }'
- print r' else {'
- print r' os::log("apitrace: warning: %s::%s: unknown IID {0x%08lX,0x%04X,0x%04X,{0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X}}\n",'
- print r' "%s", "%s",' % (interface.name, method.name)
- print r' %s.Data1, %s.Data2, %s.Data3,' % (riid.name, riid.name, riid.name)
- print r' %s.Data4[0],' % (riid.name,)
- print r' %s.Data4[1],' % (riid.name,)
- print r' %s.Data4[2],' % (riid.name,)
- print r' %s.Data4[3],' % (riid.name,)
- print r' %s.Data4[4],' % (riid.name,)
- print r' %s.Data4[5],' % (riid.name,)
- print r' %s.Data4[6],' % (riid.name,)
- print r' %s.Data4[7]);' % (riid.name,)
- print r' }'
- print ' }'
-
- def invokeMethod(self, interface, base, method):
- if method.type is stdapi.Void:
- result = ''
- else:
- result = '__result = '
- print ' %sstatic_cast<%s *>(m_pInstance)->%s(%s);' % (result, base, method.name, ', '.join([str(arg.name) for arg in method.args]))
-
- def emit_memcpy(self, dest, src, length):
- print ' unsigned __call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
- print ' trace::localWriter.beginArg(0);'
- print ' trace::localWriter.writeOpaque(%s);' % dest
- print ' trace::localWriter.endArg();'
- print ' trace::localWriter.beginArg(1);'
- print ' trace::localWriter.writeBlob(%s, %s);' % (src, length)
- print ' trace::localWriter.endArg();'
- print ' trace::localWriter.beginArg(2);'
- print ' trace::localWriter.writeUInt(%s);' % length
- print ' trace::localWriter.endArg();'
- print ' trace::localWriter.endEnter();'
- print ' trace::localWriter.beginLeave(__call);'
- print ' trace::localWriter.endLeave();'
-
+++ /dev/null
-##########################################################################
-#
-# Copyright 2008-2009 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.
-#
-##########################################################################/
-
-
-"""WGL tracing code generator."""
-
-
-from specs.stdapi import API
-from specs.glapi import glapi
-from specs.wglapi import wglapi
-from dispatch import function_pointer_type, function_pointer_value
-from gltrace import GlTracer
-from codegen import *
-
-
-class WglTracer(GlTracer):
-
- def wrapRet(self, function, instance):
- GlTracer.wrapRet(self, function, instance)
-
- if function.name == "wglGetProcAddress":
- print ' if (%s) {' % instance
-
- func_dict = dict([(f.name, f) for f in glapi.functions + wglapi.functions])
-
- def handle_case(function_name):
- f = func_dict[function_name]
- ptype = function_pointer_type(f)
- pvalue = function_pointer_value(f)
- print ' %s = (%s)%s;' % (pvalue, ptype, instance)
- print ' %s = (%s)&%s;' % (instance, function.type, f.name);
-
- def handle_default():
- print ' os::log("apitrace: warning: unknown function \\"%s\\"\\n", lpszProc);'
-
- string_switch('lpszProc', func_dict.keys(), handle_case, handle_default)
- print ' }'
-
-
-if __name__ == '__main__':
- print
- print '#define _GDI32_'
- print
- print '#include <string.h>'
- print '#include <windows.h>'
- print
- print '#include "trace_writer_local.hpp"'
- print '#include "os.hpp"'
- print
- print '// To validate our prototypes'
- print '#define GL_GLEXT_PROTOTYPES'
- print '#define WGL_GLXEXT_PROTOTYPES'
- print
- print '#include "glproc.hpp"'
- print '#include "glsize.hpp"'
- print
- api = API()
- api.addApi(glapi)
- api.addApi(wglapi)
- tracer = WglTracer()
- tracer.trace_api(api)
--- /dev/null
+cgltrace.cpp
+d3d10_1trace.cpp
+d3d10trace.cpp
+d3d11trace.cpp
+d3d8trace.cpp
+d3d9trace.cpp
+ddrawtrace.cpp
+dlltrace.cpp
+egltrace.cpp
+gltrace.cpp
+glxtrace.cpp
+trace.cpp
+wgltrace.cpp
--- /dev/null
+##############################################################################
+# API tracers
+
+
+include_directories (${CMAKE_CURRENT_SOURCE_DIR})
+
+
+if (WIN32)
+ if (MINGW)
+ # Silence warnings about @nn suffix mismatch
+ set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--enable-stdcall-fixup")
+ endif ()
+
+ # ddraw.dll
+ if (DirectX_D3D_INCLUDE_DIR)
+ include_directories (SYSTEM ${DirectX_D3D_INCLUDE_DIR})
+ add_custom_command (
+ OUTPUT ddrawtrace.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/ddrawtrace.py > ${CMAKE_CURRENT_BINARY_DIR}/ddrawtrace.cpp
+ DEPENDS
+ ddrawtrace.py
+ trace.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d.py
+ ${CMAKE_SOURCE_DIR}/specs/d3dtypes.py
+ ${CMAKE_SOURCE_DIR}/specs/d3dcaps.py
+ ${CMAKE_SOURCE_DIR}/specs/ddraw.py
+ ${CMAKE_SOURCE_DIR}/specs/winapi.py
+ ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+ )
+ add_library (ddraw MODULE ddraw.def ddrawtrace.cpp)
+ target_link_libraries (ddraw
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ )
+ set_target_properties (ddraw
+ PROPERTIES PREFIX ""
+ )
+ install (TARGETS ddraw LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+ endif ()
+
+ # d3d8.dll
+ if (DirectX_D3D8_INCLUDE_DIR AND DirectX_D3DX9_INCLUDE_DIR)
+ include_directories (SYSTEM ${DirectX_D3D8_INCLUDE_DIR} ${DirectX_D3DX9_INCLUDE_DIR})
+ add_custom_command (
+ OUTPUT d3d8trace.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d8trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d8trace.cpp
+ DEPENDS
+ d3d8trace.py
+ trace.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d8.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d8types.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d8caps.py
+ ${CMAKE_SOURCE_DIR}/specs/winapi.py
+ ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+ )
+ add_library (d3d8 MODULE d3d8.def d3d8trace.cpp d3dshader.cpp)
+ target_link_libraries (d3d8
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ )
+ set_target_properties (d3d8
+ PROPERTIES PREFIX ""
+ )
+ install (TARGETS d3d8 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+ endif ()
+
+ # d3d9.dll
+ if (DirectX_D3DX9_INCLUDE_DIR)
+ include_directories (SYSTEM ${DirectX_D3DX9_INCLUDE_DIR})
+ add_custom_command (
+ OUTPUT d3d9trace.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d9trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d9trace.cpp
+ DEPENDS
+ d3d9trace.py
+ trace.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d9.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d9types.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d9caps.py
+ ${CMAKE_SOURCE_DIR}/specs/winapi.py
+ ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+ )
+ add_library (d3d9 MODULE d3d9.def d3d9trace.cpp d3dshader.cpp)
+ target_link_libraries (d3d9
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ )
+ set_target_properties (d3d9
+ PROPERTIES PREFIX ""
+ )
+ install (TARGETS d3d9 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+ endif ()
+
+ # d3d10.dll
+ if (DirectX_D3DX10_INCLUDE_DIR)
+ include_directories (SYSTEM ${DirectX_D3DX10_INCLUDE_DIR})
+ add_custom_command (
+ OUTPUT d3d10trace.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d10trace.cpp
+ DEPENDS
+ d3d10trace.py
+ trace.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d10misc.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d10.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d10sdklayers.py
+ ${CMAKE_SOURCE_DIR}/specs/d3dcommon.py
+ ${CMAKE_SOURCE_DIR}/specs/dxgi.py
+ ${CMAKE_SOURCE_DIR}/specs/dxgitype.py
+ ${CMAKE_SOURCE_DIR}/specs/dxgiformat.py
+ ${CMAKE_SOURCE_DIR}/specs/winapi.py
+ ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+ )
+ add_library (d3d10 MODULE d3d10.def d3d10trace.cpp)
+ target_link_libraries (d3d10
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ )
+ set_target_properties (d3d10
+ PROPERTIES PREFIX ""
+ )
+ install (TARGETS d3d10 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+ endif ()
+
+ # d3d10_1.dll
+ if (DirectX_D3DX10_INCLUDE_DIR AND DirectX_D3D10_1_INCLUDE_DIR)
+ include_directories (SYSTEM ${DirectX_D3D10_1_INCLUDE_DIR})
+ add_custom_command (
+ OUTPUT d3d10_1trace.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10_1trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d10_1trace.cpp
+ DEPENDS
+ d3d10_1trace.py
+ trace.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d10_1.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d10.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d10sdklayers.py
+ ${CMAKE_SOURCE_DIR}/specs/d3dcommon.py
+ ${CMAKE_SOURCE_DIR}/specs/dxgi.py
+ ${CMAKE_SOURCE_DIR}/specs/dxgitype.py
+ ${CMAKE_SOURCE_DIR}/specs/dxgiformat.py
+ ${CMAKE_SOURCE_DIR}/specs/winapi.py
+ ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+ )
+ add_library (d3d10_1 MODULE d3d10_1.def d3d10_1trace.cpp)
+ target_link_libraries (d3d10_1
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ )
+ set_target_properties (d3d10_1
+ PROPERTIES PREFIX ""
+ )
+ install (TARGETS d3d10_1 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+ endif ()
+
+ # d3d11.dll
+ if (DirectX_D3DX11_INCLUDE_DIR)
+ include_directories (SYSTEM ${DirectX_D3DX11_INCLUDE_DIR})
+ add_custom_command (
+ OUTPUT d3d11trace.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d11trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d11trace.cpp
+ DEPENDS
+ d3d11trace.py
+ trace.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d11.py
+ ${CMAKE_SOURCE_DIR}/specs/d3d11sdklayers.py
+ ${CMAKE_SOURCE_DIR}/specs/d3dcommon.py
+ ${CMAKE_SOURCE_DIR}/specs/dxgi.py
+ ${CMAKE_SOURCE_DIR}/specs/dxgitype.py
+ ${CMAKE_SOURCE_DIR}/specs/dxgiformat.py
+ ${CMAKE_SOURCE_DIR}/specs/winapi.py
+ ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+ )
+ add_library (d3d11 MODULE d3d11.def d3d11trace.cpp)
+ target_link_libraries (d3d11
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ )
+ set_target_properties (d3d11
+ PROPERTIES PREFIX ""
+ )
+ install (TARGETS d3d11 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+ endif ()
+
+ # opengl32.dll
+ add_custom_command (
+ OUTPUT wgltrace.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/wgltrace.py > ${CMAKE_CURRENT_BINARY_DIR}/wgltrace.cpp
+ DEPENDS
+ wgltrace.py
+ gltrace.py
+ trace.py
+ ${CMAKE_SOURCE_DIR}/specs/wglapi.py
+ ${CMAKE_SOURCE_DIR}/specs/wglenum.py
+ ${CMAKE_SOURCE_DIR}/specs/glapi.py
+ ${CMAKE_SOURCE_DIR}/specs/glparams.py
+ ${CMAKE_SOURCE_DIR}/specs/gltypes.py
+ ${CMAKE_SOURCE_DIR}/specs/winapi.py
+ ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+ )
+ add_library (wgltrace MODULE opengl32.def
+ wgltrace.cpp
+ glcaps.cpp
+ ${CMAKE_SOURCE_DIR}/glproc_gl.cpp
+ )
+ add_dependencies (wgltrace glproc)
+ target_link_libraries (wgltrace
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ )
+ set_target_properties (wgltrace PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME opengl32
+ )
+ install (TARGETS wgltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+
+elseif (APPLE)
+ # OpenGL framework
+ add_custom_command (
+ OUTPUT cgltrace.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/cgltrace.py > ${CMAKE_CURRENT_BINARY_DIR}/cgltrace.cpp
+ DEPENDS
+ cgltrace.py
+ gltrace.py
+ trace.py
+ ${CMAKE_SOURCE_DIR}/specs/cglapi.py
+ ${CMAKE_SOURCE_DIR}/specs/glapi.py
+ ${CMAKE_SOURCE_DIR}/specs/glparams.py
+ ${CMAKE_SOURCE_DIR}/specs/gltypes.py
+ ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+ )
+
+ add_library (cgltrace SHARED
+ cgltrace.cpp
+ glcaps.cpp
+ ${CMAKE_SOURCE_DIR}/glproc_gl.cpp
+ )
+
+ add_dependencies (cgltrace glproc)
+
+ set_target_properties (cgltrace PROPERTIES
+ # OpenGL framework name
+ PREFIX "" OUTPUT_NAME "OpenGL" SUFFIX ""
+ # Specificy the version and reexport GLU symbols
+ LINK_FLAGS "-compatibility_version 1 -current_version 1.0.0 -Wl,-reexport_library,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib"
+ )
+
+ target_link_libraries (cgltrace
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ ${CMAKE_THREAD_LIBS_INIT}
+ dl
+ )
+
+ install (TARGETS cgltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+elseif (X11_FOUND)
+ # libGL.so
+ add_custom_command (
+ OUTPUT glxtrace.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glxtrace.py > ${CMAKE_CURRENT_BINARY_DIR}/glxtrace.cpp
+ DEPENDS
+ glxtrace.py
+ gltrace.py
+ trace.py
+ ${CMAKE_SOURCE_DIR}/specs/glxapi.py
+ ${CMAKE_SOURCE_DIR}/specs/glapi.py
+ ${CMAKE_SOURCE_DIR}/specs/glparams.py
+ ${CMAKE_SOURCE_DIR}/specs/gltypes.py
+ ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+ )
+
+ add_library (glxtrace SHARED
+ glxtrace.cpp
+ glcaps.cpp
+ ${CMAKE_SOURCE_DIR}/glproc_gl.cpp
+ )
+
+ add_dependencies (glxtrace glproc)
+
+ set_target_properties (glxtrace PROPERTIES
+ # avoid the default "lib" prefix
+ PREFIX ""
+ # Prevent symbol relocations internal to our wrapper library to be
+ # overwritten by the application.
+ LINK_FLAGS "-Wl,-Bsymbolic -Wl,-Bsymbolic-functions"
+ )
+
+ target_link_libraries (glxtrace
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ ${X11_X11_LIB}
+ ${CMAKE_THREAD_LIBS_INIT}
+ dl
+ )
+
+ install (TARGETS glxtrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+endif ()
+
+
+if (ENABLE_EGL AND NOT WIN32 AND NOT APPLE)
+ # libEGL.so/libGL.so
+ add_custom_command (
+ OUTPUT egltrace.cpp
+ COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/egltrace.py > ${CMAKE_CURRENT_BINARY_DIR}/egltrace.cpp
+ DEPENDS
+ egltrace.py
+ gltrace.py
+ trace.py
+ ${CMAKE_SOURCE_DIR}/specs/eglapi.py
+ ${CMAKE_SOURCE_DIR}/specs/glesapi.py
+ ${CMAKE_SOURCE_DIR}/specs/glapi.py
+ ${CMAKE_SOURCE_DIR}/specs/glparams.py
+ ${CMAKE_SOURCE_DIR}/specs/gltypes.py
+ ${CMAKE_SOURCE_DIR}/specs/stdapi.py
+ )
+
+ add_library (egltrace SHARED
+ egltrace.cpp
+ glcaps.cpp
+ ${CMAKE_SOURCE_DIR}/glproc_egl.cpp
+ )
+
+ add_dependencies (egltrace glproc)
+
+ set_target_properties (egltrace PROPERTIES
+ # avoid the default "lib" prefix
+ PREFIX ""
+ # Prevent symbol relocations internal to our wrapper library to be
+ # overwritten by the application.
+ LINK_FLAGS "-Wl,-Bsymbolic -Wl,-Bsymbolic-functions"
+ )
+
+ target_link_libraries (egltrace
+ common
+ ${ZLIB_LIBRARIES}
+ ${SNAPPY_LIBRARIES}
+ ${CMAKE_THREAD_LIBS_INIT}
+ dl
+ )
+
+ install (TARGETS egltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
+endif ()
--- /dev/null
+##########################################################################
+#
+# Copyright 2011 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.
+#
+##########################################################################/
+
+
+"""Cgl tracing generator."""
+
+
+from gltrace import GlTracer
+from specs.stdapi import API
+from specs.glapi import glapi
+from specs.cglapi import cglapi
+
+
+class CglTracer(GlTracer):
+
+ def isFunctionPublic(self, function):
+ # The symbols visible in libGL.dylib can vary, so expose them all
+ return True
+
+
+if __name__ == '__main__':
+ print
+ print '#include <stdlib.h>'
+ print '#include <string.h>'
+ print
+ print '#include "trace_writer_local.hpp"'
+ print
+ print '// To validate our prototypes'
+ print '#define GL_GLEXT_PROTOTYPES'
+ print
+ print '#include "glproc.hpp"'
+ print '#include "glsize.hpp"'
+ print
+
+ api = API()
+ api.addApi(cglapi)
+ api.addApi(glapi)
+ tracer = CglTracer()
+ tracer.trace_api(api)
+
+ print r'''
+
+PUBLIC
+void * gll_noop = 0;
+
+'''
--- /dev/null
+LIBRARY "d3d10"
+
+EXPORTS
+ D3D10CreateDevice
+ D3D10CreateDeviceAndSwapChain
+ D3D10CreateBlob
--- /dev/null
+LIBRARY "d3d10_1"
+
+EXPORTS
+ D3D10CreateDevice1
+ D3D10CreateDeviceAndSwapChain1
+ D3D10CreateBlob
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-2009 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.
+#
+##########################################################################/
+
+
+from dlltrace import DllTracer
+from specs.d3d10_1 import d3d10_1
+
+
+if __name__ == '__main__':
+ print '#define INITGUID'
+ print
+ print '#include "trace_writer_local.hpp"'
+ print '#include "os.hpp"'
+ print
+ print '#include <windows.h>'
+ print '#include <tchar.h>'
+ print
+ print '#include "compat.h"'
+ print
+ print '#include <d3d10_1.h>'
+ print '#include <d3dx10.h>'
+ print
+ tracer = DllTracer('d3d10_1.dll')
+ tracer.trace_api(d3d10_1)
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-2009 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.
+#
+##########################################################################/
+
+
+from dlltrace import DllTracer
+from specs.d3d10misc import d3d10
+
+
+if __name__ == '__main__':
+ print '#define INITGUID'
+ print
+ print '#include "trace_writer_local.hpp"'
+ print '#include "os.hpp"'
+ print
+ print '#include <windows.h>'
+ print '#include <tchar.h>'
+ print
+ print '#include "compat.h"'
+ print
+ print '#include <d3d10.h>'
+ print '#include <d3dx10.h>'
+ print
+ tracer = DllTracer('d3d10.dll')
+ tracer.trace_api(d3d10)
--- /dev/null
+LIBRARY "d3d11"
+
+EXPORTS
+ D3D11CreateDevice
+ D3D11CreateDeviceAndSwapChain
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-2012 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.
+#
+##########################################################################/
+
+
+from dlltrace import DllTracer
+from specs.d3d11 import d3d11
+
+
+if __name__ == '__main__':
+ print '#define INITGUID'
+ print
+ print '#include "trace_writer_local.hpp"'
+ print '#include "os.hpp"'
+ print
+ print '#include <windows.h>'
+ print '#include <tchar.h>'
+ print
+ print '#include "compat.h"'
+ print
+ print '#include <d3d11.h>'
+ print '#include <d3dx11.h>'
+ print
+ tracer = DllTracer('d3d11.dll')
+ tracer.trace_api(d3d11)
--- /dev/null
+LIBRARY "d3d8"
+
+EXPORTS
+ Direct3DCreate8 @1
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-2009 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.
+#
+##########################################################################/
+
+
+from dlltrace import DllTracer
+from specs.d3d8 import d3d8
+
+
+class D3D8Tracer(DllTracer):
+
+ def serializeArgValue(self, function, arg):
+ # Dump shaders as strings
+ if function.name in ('CreateVertexShader', 'CreatePixelShader') and arg.name == 'pFunction':
+ print ' DumpShader(trace::localWriter, %s);' % (arg.name)
+ return
+
+ DllTracer.serializeArgValue(self, function, arg)
+
+
+if __name__ == '__main__':
+ print '#define INITGUID'
+ print
+ print '#include <windows.h>'
+ print '#include <d3d8.h>'
+ print '#include "d3dshader.hpp"'
+ print
+ print '#include "trace_writer_local.hpp"'
+ print '#include "os.hpp"'
+ print
+ tracer = D3D8Tracer('d3d8.dll')
+ tracer.trace_api(d3d8)
+
--- /dev/null
+LIBRARY "d3d9"
+
+EXPORTS
+ Direct3DCreate9
+ Direct3DCreate9Ex
+ D3DPERF_BeginEvent
+ D3DPERF_EndEvent
+ D3DPERF_SetMarker
+ D3DPERF_SetRegion
+ D3DPERF_QueryRepeatFrame
+ D3DPERF_SetOptions
+ D3DPERF_GetStatus
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-2009 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.
+#
+##########################################################################/
+
+
+from dlltrace import DllTracer
+from specs.d3d9 import d3d9
+
+
+class D3D9Tracer(DllTracer):
+
+ def serializeArgValue(self, function, arg):
+ # Dump shaders as strings
+ if function.name in ('CreateVertexShader', 'CreatePixelShader') and arg.name == 'pFunction':
+ print ' DumpShader(trace::localWriter, %s);' % (arg.name)
+ return
+
+ DllTracer.serializeArgValue(self, function, arg)
+
+ def declareWrapperInterfaceVariables(self, interface):
+ DllTracer.declareWrapperInterfaceVariables(self, interface)
+
+ if interface.name == 'IDirect3DVertexBuffer9':
+ print ' UINT m_SizeToLock;'
+ print ' VOID *m_pbData;'
+
+ def implementWrapperInterfaceMethodBody(self, interface, base, method):
+ if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Unlock':
+ print ' if (m_pbData) {'
+ self.emit_memcpy('(LPBYTE)m_pbData', '(LPBYTE)m_pbData', 'm_SizeToLock')
+ print ' }'
+
+ DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method)
+
+ if interface.name == 'IDirect3DVertexBuffer9' and method.name == 'Lock':
+ # FIXME: handle recursive locks
+ print ' if (__result == D3D_OK && !(Flags & D3DLOCK_READONLY)) {'
+ print ' if (SizeToLock) {'
+ print ' m_SizeToLock = SizeToLock;'
+ print ' } else {'
+ print ' D3DVERTEXBUFFER_DESC Desc;'
+ print ' m_pInstance->GetDesc(&Desc);'
+ print ' m_SizeToLock = Desc.Size;'
+ print ' }'
+ print ' m_pbData = *ppbData;'
+ print ' } else {'
+ print ' m_pbData = NULL;'
+ print ' }'
+
+
+if __name__ == '__main__':
+ print '#define INITGUID'
+ print
+ print '#include "trace_writer_local.hpp"'
+ print '#include "os.hpp"'
+ print
+ print '#include "d3d9imports.hpp"'
+ print '#include "d3dshader.hpp"'
+ print
+ print '''
+static inline size_t
+_declCount(const D3DVERTEXELEMENT9 *pVertexElements) {
+ size_t count = 0;
+ if (pVertexElements) {
+ while (pVertexElements[count++].Stream != 0xff)
+ ;
+ }
+ return count;
+}
+'''
+ tracer = D3D9Tracer('d3d9.dll')
+ tracer.trace_api(d3d9)
+
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2011 Jose Fonseca
+ * Copyright 2008-2009 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.
+ *
+ **************************************************************************/
+
+
+#include <stdio.h>
+
+#include "d3dshader.hpp"
+#include "d3d9imports.hpp"
+
+
+typedef HRESULT
+(WINAPI *PD3DXDISASSEMBLESHADER)(
+ CONST DWORD *pShader,
+ BOOL EnableColorCode,
+ LPCSTR pComments,
+ LPD3DXBUFFER *ppDisassembly
+);
+
+
+void DumpShader(trace::Writer &writer, const DWORD *tokens)
+{
+ static BOOL firsttime = TRUE;
+ static HMODULE hD3DXModule = NULL;
+ static PD3DXDISASSEMBLESHADER pfnD3DXDisassembleShader = NULL;
+
+ if (firsttime) {
+ if (!hD3DXModule) {
+ unsigned release;
+ int version;
+ for (release = 0; release <= 1; ++release) {
+ /* Version 41 corresponds to Mar 2009 version of DirectX Runtime / SDK */
+ for (version = 41; version >= 0; --version) {
+ char filename[256];
+ _snprintf(filename, sizeof(filename),
+ "d3dx9%s%s%u.dll", release ? "" : "d", version ? "_" : "", version);
+ hD3DXModule = LoadLibraryA(filename);
+ if (hD3DXModule)
+ goto found;
+ }
+ }
+found:
+ ;
+ }
+
+ if (hD3DXModule) {
+ if (!pfnD3DXDisassembleShader) {
+ pfnD3DXDisassembleShader = (PD3DXDISASSEMBLESHADER)GetProcAddress(hD3DXModule, "D3DXDisassembleShader");
+ }
+ }
+
+ firsttime = FALSE;
+ }
+
+ if (pfnD3DXDisassembleShader) {
+ LPD3DXBUFFER pDisassembly = NULL;
+ HRESULT hr;
+
+ hr = pfnD3DXDisassembleShader( (DWORD *)tokens, FALSE, NULL, &pDisassembly);
+ if (hr == D3D_OK) {
+ writer.writeString((const char *)pDisassembly->GetBufferPointer());
+ }
+
+ if (pDisassembly) {
+ pDisassembly->Release();
+ }
+
+ if (hr == D3D_OK) {
+ return;
+ }
+ }
+
+ writer.writeOpaque(tokens);
+}
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2011 Jose Fonseca
+ * Copyright 2008-2009 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.
+ *
+ **************************************************************************/
+
+#ifndef _D3DSHADER_HPP_
+#define _D3DSHADER_HPP_
+
+
+#include <windows.h>
+
+#include "trace_writer.hpp"
+
+void DumpShader(trace::Writer &writer, const DWORD *tokens);
+
+
+#endif /* _D3DSHADER_HPP_ */
--- /dev/null
+EXPORTS
+ AcquireDDThreadLock
+ CompleteCreateSysmemSurface
+ D3DParseUnknownCommand
+ DDGetAttachedSurfaceLcl
+ DDInternalLock
+ DDInternalUnlock
+ DirectDrawCreate
+ DirectDrawCreateClipper
+ DirectDrawCreateEx
+ DirectDrawEnumerateA
+ DirectDrawEnumerateExA
+ DirectDrawEnumerateExW
+ DirectDrawEnumerateW
+ DllCanUnloadNow PRIVATE
+ DllGetClassObject PRIVATE
+ DSoundHelp
+ GetDDSurfaceLocal
+ GetOLEThunkData
+ GetSurfaceFromDC
+ RegisterSpecialCase
+ ReleaseDDThreadLock
+ ;SetAppCompatData
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-2009 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.
+#
+##########################################################################/
+
+
+from dlltrace import DllTracer
+from specs.d3d import ddraw, interfaces
+
+
+class DDrawTracer(DllTracer):
+
+ def traceFunctionImplBody(self, function):
+ if function.name in ('AcquireDDThreadLock', 'ReleaseDDThreadLock'):
+ self.invokeFunction(function)
+ return
+
+ DllTracer.traceFunctionImplBody(self, function)
+
+ def serializeArg(self, function, arg):
+ if function.name == 'DirectDrawCreateEx' and arg.name == 'lplpDD':
+ print ' if (*lplpDD) {'
+ for iface in interfaces:
+ print ' if (iid == IID_%s) {' % iface.name
+ print ' *lplpDD = (LPVOID) new Wrap%s((%s *)*lplpDD);' % (iface.name, iface.name)
+ print ' }'
+ print ' }'
+
+ DllTracer.serializeArg(self, function, arg)
+
+
+if __name__ == '__main__':
+ print '#define INITGUID'
+ print '#include <windows.h>'
+ print '#include <ddraw.h>'
+ print '#include <d3d.h>'
+ print
+ print '''
+
+#ifndef DDBLT_EXTENDED_FLAGS
+#define DDBLT_EXTENDED_FLAGS 0x40000000l
+#endif
+
+#ifndef DDBLT_EXTENDED_LINEAR_CONTENT
+#define DDBLT_EXTENDED_LINEAR_CONTENT 0x00000004l
+#endif
+
+#ifndef D3DLIGHT_PARALLELPOINT
+#define D3DLIGHT_PARALLELPOINT (D3DLIGHTTYPE)4
+#endif
+
+#ifndef D3DLIGHT_GLSPOT
+#define D3DLIGHT_GLSPOT (D3DLIGHTTYPE)5
+#endif
+
+'''
+ print '#include "trace_writer_local.hpp"'
+ print '#include "os.hpp"'
+ print
+ tracer = DDrawTracer('ddraw.dll')
+ tracer.trace_api(ddraw)
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-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.
+#
+##########################################################################/
+
+"""Trace code generation for Windows DLLs."""
+
+
+from trace import Tracer
+from dispatch import Dispatcher
+
+
+class DllTracer(Tracer):
+
+ def __init__(self, dllname):
+ self.dllname = dllname
+
+ def header(self, api):
+ print '''
+static HINSTANCE g_hDll = NULL;
+
+static PROC
+__getPublicProcAddress(LPCSTR lpProcName)
+{
+ if (!g_hDll) {
+ char szDll[MAX_PATH] = {0};
+
+ if (!GetSystemDirectoryA(szDll, MAX_PATH)) {
+ return NULL;
+ }
+
+ strcat(szDll, "\\\\%s");
+
+ g_hDll = LoadLibraryA(szDll);
+ if (!g_hDll) {
+ return NULL;
+ }
+ }
+
+ return GetProcAddress(g_hDll, lpProcName);
+}
+
+''' % self.dllname
+
+ dispatcher = Dispatcher()
+ dispatcher.dispatch_api(api)
+
+ Tracer.header(self, api)
+
--- /dev/null
+##########################################################################
+#
+# Copyright 2011 LunarG, Inc.
+# All Rights Reserved.
+#
+# Based on glxtrace.py, which has
+#
+# Copyright 2011 Jose Fonseca
+# Copyright 2008-2010 VMware, Inc.
+#
+# 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.
+#
+##########################################################################/
+
+
+"""EGL tracing generator."""
+
+
+from gltrace import GlTracer
+from dispatch import function_pointer_type, function_pointer_value
+from specs.stdapi import API
+from specs.glapi import glapi
+from specs.eglapi import eglapi
+from specs.glesapi import glesapi
+
+
+class EglTracer(GlTracer):
+
+ def isFunctionPublic(self, function):
+ # The symbols visible in libEGL.so can vary, so expose them all
+ return True
+
+ def traceFunctionImplBody(self, function):
+ GlTracer.traceFunctionImplBody(self, function)
+
+ if function.name == 'eglMakeCurrent':
+ print ' // update the profile'
+ print ' if (ctx != EGL_NO_CONTEXT) {'
+ print ' EGLint api = EGL_OPENGL_ES_API, version = 1;'
+ print ' gltrace::Context *tr = gltrace::getContext();'
+ print ' __eglQueryContext(dpy, ctx, EGL_CONTEXT_CLIENT_TYPE, &api);'
+ print ' __eglQueryContext(dpy, ctx, EGL_CONTEXT_CLIENT_VERSION, &version);'
+ print ' if (api == EGL_OPENGL_API)'
+ print ' tr->profile = gltrace::PROFILE_COMPAT;'
+ print ' else if (version == 1)'
+ print ' tr->profile = gltrace::PROFILE_ES1;'
+ print ' else'
+ print ' tr->profile = gltrace::PROFILE_ES2;'
+ print ' }'
+
+ def wrapRet(self, function, instance):
+ GlTracer.wrapRet(self, function, instance)
+
+ if function.name == "eglGetProcAddress":
+ print ' %s = __unwrap_proc_addr(procname, %s);' % (instance, instance)
+
+
+if __name__ == '__main__':
+ print '#include <stdlib.h>'
+ print '#include <string.h>'
+ print '#include <dlfcn.h>'
+ print
+ print '#include "trace_writer_local.hpp"'
+ print
+ print '// To validate our prototypes'
+ print '#define GL_GLEXT_PROTOTYPES'
+ print '#define EGL_EGLEXT_PROTOTYPES'
+ print
+ print '#include "glproc.hpp"'
+ print '#include "glsize.hpp"'
+ print
+ print 'static __eglMustCastToProperFunctionPointerType __unwrap_proc_addr(const char * procname, __eglMustCastToProperFunctionPointerType procPtr);'
+ print
+
+ api = API()
+ api.addApi(eglapi)
+ api.addApi(glapi)
+ api.addApi(glesapi)
+ tracer = EglTracer()
+ tracer.trace_api(api)
+
+ print 'static __eglMustCastToProperFunctionPointerType __unwrap_proc_addr(const char * procname, __eglMustCastToProperFunctionPointerType procPtr) {'
+ print ' if (!procPtr) {'
+ print ' return procPtr;'
+ print ' }'
+ for f in api.functions:
+ ptype = function_pointer_type(f)
+ pvalue = function_pointer_value(f)
+ print ' if (!strcmp("%s", procname)) {' % f.name
+ print ' %s = (%s)procPtr;' % (pvalue, ptype)
+ print ' return (__eglMustCastToProperFunctionPointerType)&%s;' % (f.name,)
+ print ' }'
+ print ' os::log("apitrace: warning: unknown function \\"%s\\"\\n", procname);'
+ print ' return procPtr;'
+ print '}'
+ print
+ print r'''
+
+
+/*
+ * Android does not support LD_PRELOAD.
+ */
+#if !defined(ANDROID)
+
+
+/*
+ * 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);
+}
+
+
+/*
+ * Several applications, such as Quake3, use dlopen("libGL.so.1"), but
+ * LD_PRELOAD does not intercept symbols obtained via dlopen/dlsym, therefore
+ * we need to intercept the dlopen() call here, and redirect to our wrapper
+ * shared object.
+ */
+extern "C" PUBLIC
+void * dlopen(const char *filename, int flag)
+{
+ bool intercept = false;
+
+ if (filename) {
+ intercept =
+ strcmp(filename, "libEGL.so") == 0 ||
+ strcmp(filename, "libEGL.so.1") == 0 ||
+ strcmp(filename, "libGLESv1_CM.so") == 0 ||
+ strcmp(filename, "libGLESv1_CM.so.1") == 0 ||
+ strcmp(filename, "libGLESv2.so") == 0 ||
+ strcmp(filename, "libGLESv2.so.2") == 0 ||
+ strcmp(filename, "libGL.so") == 0 ||
+ strcmp(filename, "libGL.so.1") == 0;
+
+ if (intercept) {
+ os::log("apitrace: redirecting dlopen(\"%s\", 0x%x)\n", filename, flag);
+
+ /* The current dispatch implementation relies on core entry-points to be globally available, so force this.
+ *
+ * TODO: A better approach would be note down the entry points here and
+ * use them latter. Another alternative would be to reopen the library
+ * with RTLD_NOLOAD | RTLD_GLOBAL.
+ */
+ flag &= ~RTLD_LOCAL;
+ flag |= RTLD_GLOBAL;
+ }
+ }
+
+ void *handle = __dlopen(filename, flag);
+
+ if (intercept) {
+ // Get the file path for our shared object, and use it instead
+ static int dummy = 0xdeedbeef;
+ Dl_info info;
+ if (dladdr(&dummy, &info)) {
+ handle = __dlopen(info.dli_fname, flag);
+ } else {
+ os::log("apitrace: warning: dladdr() failed\n");
+ }
+ }
+
+ return handle;
+}
+
+
+#endif /* !ANDROID */
+
+
+
+'''
--- /dev/null
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+
+/*
+ * Manipulation of GL extensions.
+ *
+ * So far we insert GREMEDY extensions, but in the future we could also clamp
+ * the GL extensions to core GL versions here.
+ */
+
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <string>
+#include <map>
+
+#include "glproc.hpp"
+#include "gltrace.hpp"
+
+
+namespace gltrace {
+
+
+typedef std::map<std::string, const char *> ExtensionsMap;
+
+// Cache of the translated extensions strings
+static ExtensionsMap extensionsMap;
+
+
+// Additional extensions to be advertised
+static const char *
+extraExtension_stringsFull[] = {
+ "GL_GREMEDY_string_marker",
+ "GL_GREMEDY_frame_terminator",
+};
+
+static const char *
+extraExtension_stringsES[] = {
+ "GL_EXT_debug_marker",
+};
+
+// Description of additional extensions we want to advertise
+struct ExtensionsDesc
+{
+ unsigned numStrings;
+ const char **strings;
+};
+
+#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
+
+const struct ExtensionsDesc
+extraExtensionsFull = {
+ ARRAY_SIZE(extraExtension_stringsFull),
+ extraExtension_stringsFull
+};
+
+const struct ExtensionsDesc
+extraExtensionsES = {
+ ARRAY_SIZE(extraExtension_stringsES),
+ extraExtension_stringsES
+};
+
+
+const struct ExtensionsDesc *
+getExtraExtensions(void)
+{
+ Context *ctx = getContext();
+
+ switch (ctx->profile) {
+ case PROFILE_COMPAT:
+ return &extraExtensionsFull;
+ case PROFILE_ES1:
+ case PROFILE_ES2:
+ return &extraExtensionsES;
+ default:
+ assert(0);
+ return &extraExtensionsFull;
+ }
+}
+
+
+/**
+ * Translate the GL extensions string, adding new extensions.
+ */
+static const char *
+overrideExtensionsString(const char *extensions)
+{
+ const ExtensionsDesc *desc = getExtraExtensions();
+ size_t i;
+
+ ExtensionsMap::const_iterator it = extensionsMap.find(extensions);
+ if (it != extensionsMap.end()) {
+ return it->second;
+ }
+
+ size_t extensionsLen = strlen(extensions);
+
+ size_t extraExtensionsLen = 0;
+ for (i = 0; i < desc->numStrings; ++i) {
+ const char * extraExtension = desc->strings[i];
+ size_t extraExtensionLen = strlen(extraExtension);
+ extraExtensionsLen += extraExtensionLen + 1;
+ }
+
+ // We use malloc memory instead of a std::string because we need to ensure
+ // that extensions strings will not move in memory as the extensionsMap is
+ // updated.
+ size_t newExtensionsLen = extensionsLen + 1 + extraExtensionsLen + 1;
+ char *newExtensions = (char *)malloc(newExtensionsLen);
+ if (!newExtensions) {
+ return extensions;
+ }
+
+ if (extensionsLen) {
+ memcpy(newExtensions, extensions, extensionsLen);
+
+ // Add space separator if necessary
+ if (newExtensions[extensionsLen - 1] != ' ') {
+ newExtensions[extensionsLen++] = ' ';
+ }
+ }
+
+ for (i = 0; i < desc->numStrings; ++i) {
+ const char * extraExtension = desc->strings[i];
+ size_t extraExtensionLen = strlen(extraExtension);
+ memcpy(newExtensions + extensionsLen, extraExtension, extraExtensionLen);
+ extensionsLen += extraExtensionLen;
+ newExtensions[extensionsLen++] = ' ';
+ }
+ newExtensions[extensionsLen++] = '\0';
+ assert(extensionsLen <= newExtensionsLen);
+
+ extensionsMap[extensions] = newExtensions;
+
+ return newExtensions;
+}
+
+
+const GLubyte *
+__glGetString_override(GLenum name)
+{
+ const GLubyte *result = __glGetString(name);
+
+ if (result) {
+ switch (name) {
+ case GL_EXTENSIONS:
+ result = (const GLubyte *)overrideExtensionsString((const char *)result);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return result;
+}
+
+
+void
+__glGetIntegerv_override(GLenum pname, GLint *params)
+{
+ __glGetIntegerv(pname, params);
+
+ if (params) {
+ switch (pname) {
+ case GL_NUM_EXTENSIONS:
+ {
+ const ExtensionsDesc *desc = getExtraExtensions();
+ *params += desc->numStrings;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+
+const GLubyte *
+__glGetStringi_override(GLenum name, GLuint index)
+{
+ switch (name) {
+ case GL_EXTENSIONS:
+ {
+ const ExtensionsDesc *desc = getExtraExtensions();
+ GLint numExtensions = 0;
+ __glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
+ if ((GLuint)numExtensions <= index && index < (GLuint)numExtensions + desc->numStrings) {
+ return (const GLubyte *)desc->strings[index - (GLuint)numExtensions];
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return __glGetStringi(name, index);
+}
+
+
+} /* namespace gltrace */
+
--- /dev/null
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+#ifndef _GLTRACE_HPP_
+#define _GLTRACE_HPP_
+
+
+#include "glimports.hpp"
+
+
+namespace gltrace {
+
+
+enum Profile {
+ PROFILE_COMPAT,
+ PROFILE_ES1,
+ PROFILE_ES2,
+};
+
+struct Context {
+ enum Profile profile;
+ bool user_arrays;
+ bool user_arrays_arb;
+ bool user_arrays_nv;
+};
+
+Context *
+getContext(void);
+
+const GLubyte *
+__glGetString_override(GLenum name);
+
+void
+__glGetIntegerv_override(GLenum pname, GLint *params);
+
+const GLubyte *
+__glGetStringi_override(GLenum name, GLuint index);
+
+
+} /* namespace gltrace */
+
+
+#endif /* _GLRETRACE_HPP_ */
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-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.
+#
+##########################################################################/
+
+
+"""GL tracing generator."""
+
+
+from trace import Tracer
+import specs.stdapi as stdapi
+import specs.glapi as glapi
+import specs.glparams as glparams
+from specs.glxapi import glxapi
+
+
+class TypeGetter(stdapi.Visitor):
+ '''Determine which glGet*v function that matches the specified type.'''
+
+ def __init__(self, prefix = 'glGet', long_suffix = True, ext_suffix = ''):
+ self.prefix = prefix
+ self.long_suffix = long_suffix
+ self.ext_suffix = ext_suffix
+
+ def visitConst(self, const):
+ return self.visit(const.type)
+
+ def visitAlias(self, alias):
+ if alias.expr == 'GLboolean':
+ if self.long_suffix:
+ suffix = 'Booleanv'
+ arg_type = alias.expr
+ else:
+ suffix = 'iv'
+ arg_type = 'GLint'
+ elif alias.expr == 'GLdouble':
+ if self.long_suffix:
+ suffix = 'Doublev'
+ arg_type = alias.expr
+ else:
+ suffix = 'dv'
+ arg_type = alias.expr
+ elif alias.expr == 'GLfloat':
+ if self.long_suffix:
+ suffix = 'Floatv'
+ arg_type = alias.expr
+ else:
+ suffix = 'fv'
+ arg_type = alias.expr
+ elif alias.expr in ('GLint', 'GLuint', 'GLsizei'):
+ if self.long_suffix:
+ suffix = 'Integerv'
+ arg_type = 'GLint'
+ else:
+ suffix = 'iv'
+ arg_type = 'GLint'
+ else:
+ print alias.expr
+ assert False
+ function_name = self.prefix + suffix + self.ext_suffix
+ return function_name, arg_type
+
+ def visitEnum(self, enum):
+ return self.visit(glapi.GLint)
+
+ def visitBitmask(self, bitmask):
+ return self.visit(glapi.GLint)
+
+ def visitOpaque(self, pointer):
+ return self.prefix + 'Pointerv' + self.ext_suffix, 'GLvoid *'
+
+
+class GlTracer(Tracer):
+
+ arrays = [
+ ("Vertex", "VERTEX"),
+ ("Normal", "NORMAL"),
+ ("Color", "COLOR"),
+ ("Index", "INDEX"),
+ ("TexCoord", "TEXTURE_COORD"),
+ ("EdgeFlag", "EDGE_FLAG"),
+ ("FogCoord", "FOG_COORD"),
+ ("SecondaryColor", "SECONDARY_COLOR"),
+ ]
+ arrays.reverse()
+
+ # arrays available in PROFILE_ES1
+ arrays_es1 = ("Vertex", "Normal", "Color", "TexCoord")
+
+ def header(self, api):
+ Tracer.header(self, api)
+
+ print '#include "gltrace.hpp"'
+ print
+
+ # Which glVertexAttrib* variant to use
+ print 'enum vertex_attrib {'
+ print ' VERTEX_ATTRIB,'
+ print ' VERTEX_ATTRIB_ARB,'
+ print ' VERTEX_ATTRIB_NV,'
+ print '};'
+ print
+ print 'gltrace::Context *'
+ print 'gltrace::getContext(void)'
+ print '{'
+ print ' // TODO return the context set by other APIs (GLX, EGL, and etc.)'
+ print ' static gltrace::Context __ctx = { gltrace::PROFILE_COMPAT, false, false, false };'
+ print ' return &__ctx;'
+ print '}'
+ print
+ print 'static vertex_attrib __get_vertex_attrib(void) {'
+ print ' gltrace::Context *ctx = gltrace::getContext();'
+ print ' if (ctx->user_arrays_arb || ctx->user_arrays_nv) {'
+ print ' GLboolean __vertex_program = GL_FALSE;'
+ print ' __glGetBooleanv(GL_VERTEX_PROGRAM_ARB, &__vertex_program);'
+ print ' if (__vertex_program) {'
+ print ' if (ctx->user_arrays_nv) {'
+ print ' GLint __vertex_program_binding_nv = 0;'
+ print ' __glGetIntegerv(GL_VERTEX_PROGRAM_BINDING_NV, &__vertex_program_binding_nv);'
+ print ' if (__vertex_program_binding_nv) {'
+ print ' return VERTEX_ATTRIB_NV;'
+ print ' }'
+ print ' }'
+ print ' return VERTEX_ATTRIB_ARB;'
+ print ' }'
+ print ' }'
+ print ' return VERTEX_ATTRIB;'
+ print '}'
+ print
+
+ # Whether we need user arrays
+ print 'static inline bool __need_user_arrays(void)'
+ print '{'
+ print ' gltrace::Context *ctx = gltrace::getContext();'
+ print ' if (!ctx->user_arrays) {'
+ print ' return false;'
+ print ' }'
+ print
+
+ for camelcase_name, uppercase_name in self.arrays:
+ # in which profile is the array available?
+ profile_check = 'ctx->profile == gltrace::PROFILE_COMPAT'
+ if camelcase_name in self.arrays_es1:
+ profile_check = '(' + profile_check + ' || ctx->profile == gltrace::PROFILE_ES1)';
+
+ function_name = 'gl%sPointer' % camelcase_name
+ enable_name = 'GL_%s_ARRAY' % uppercase_name
+ binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
+ print ' // %s' % function_name
+ print ' if (%s) {' % profile_check
+ self.array_prolog(api, uppercase_name)
+ print ' if (__glIsEnabled(%s)) {' % enable_name
+ print ' GLint __binding = 0;'
+ print ' __glGetIntegerv(%s, &__binding);' % binding_name
+ print ' if (!__binding) {'
+ self.array_cleanup(api, uppercase_name)
+ print ' return true;'
+ print ' }'
+ print ' }'
+ self.array_epilog(api, uppercase_name)
+ print ' }'
+ print
+
+ print ' // ES1 does not support generic vertex attributes'
+ print ' if (ctx->profile == gltrace::PROFILE_ES1)'
+ print ' return false;'
+ print
+ print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
+ print
+ print ' // glVertexAttribPointer'
+ print ' if (__vertex_attrib == VERTEX_ATTRIB) {'
+ print ' GLint __max_vertex_attribs = 0;'
+ print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
+ print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
+ print ' GLint __enabled = 0;'
+ print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &__enabled);'
+ print ' if (__enabled) {'
+ print ' GLint __binding = 0;'
+ print ' __glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &__binding);'
+ print ' if (!__binding) {'
+ print ' return true;'
+ print ' }'
+ print ' }'
+ print ' }'
+ print ' }'
+ print
+ print ' // glVertexAttribPointerARB'
+ print ' if (__vertex_attrib == VERTEX_ATTRIB_ARB) {'
+ print ' GLint __max_vertex_attribs = 0;'
+ print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &__max_vertex_attribs);'
+ print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
+ print ' GLint __enabled = 0;'
+ print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB, &__enabled);'
+ print ' if (__enabled) {'
+ print ' GLint __binding = 0;'
+ print ' __glGetVertexAttribivARB(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB, &__binding);'
+ print ' if (!__binding) {'
+ print ' return true;'
+ print ' }'
+ print ' }'
+ print ' }'
+ print ' }'
+ print
+ print ' // glVertexAttribPointerNV'
+ print ' if (__vertex_attrib == VERTEX_ATTRIB_NV) {'
+ print ' for (GLint index = 0; index < 16; ++index) {'
+ print ' GLint __enabled = 0;'
+ print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
+ print ' if (__enabled) {'
+ print ' return true;'
+ print ' }'
+ print ' }'
+ print ' }'
+ print
+
+ print ' return false;'
+ print '}'
+ print
+
+ print 'static void __trace_user_arrays(GLuint maxindex);'
+ print
+
+ # Buffer mappings
+ print '// whether glMapBufferRange(GL_MAP_WRITE_BIT) has ever been called'
+ print 'static bool __checkBufferMapRange = false;'
+ print
+ print '// whether glBufferParameteriAPPLE(GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE) has ever been called'
+ print 'static bool __checkBufferFlushingUnmapAPPLE = false;'
+ print
+ # Buffer mapping information, necessary for old Mesa 2.1 drivers which
+ # do not support glGetBufferParameteriv(GL_BUFFER_ACCESS_FLAGS/GL_BUFFER_MAP_LENGTH)
+ print 'struct buffer_mapping {'
+ print ' void *map;'
+ print ' GLint length;'
+ print ' bool write;'
+ print ' bool explicit_flush;'
+ print '};'
+ print
+ for target in self.buffer_targets:
+ print 'struct buffer_mapping __%s_mapping;' % target.lower();
+ print
+ print 'static inline struct buffer_mapping *'
+ print 'get_buffer_mapping(GLenum target) {'
+ print ' switch (target) {'
+ for target in self.buffer_targets:
+ print ' case GL_%s:' % target
+ print ' return & __%s_mapping;' % target.lower()
+ print ' default:'
+ print ' os::log("apitrace: warning: unknown buffer target 0x%04X\\n", target);'
+ print ' return NULL;'
+ print ' }'
+ print '}'
+ print
+
+ # Generate a helper function to determine whether a parameter name
+ # refers to a symbolic value or not
+ print 'static bool'
+ print 'is_symbolic_pname(GLenum pname) {'
+ print ' switch (pname) {'
+ for function, type, count, name in glparams.parameters:
+ if type is glapi.GLenum:
+ print ' case %s:' % name
+ print ' return true;'
+ print ' default:'
+ print ' return false;'
+ print ' }'
+ print '}'
+ print
+
+ # Generate a helper function to determine whether a parameter value is
+ # potentially symbolic or not; i.e., if the value can be represented in
+ # an enum or not
+ print 'template<class T>'
+ print 'static inline bool'
+ print 'is_symbolic_param(T param) {'
+ print ' return static_cast<T>(static_cast<GLenum>(param)) == param;'
+ print '}'
+ print
+
+ # Generate a helper function to know how many elements a parameter has
+ print 'static size_t'
+ print '__gl_param_size(GLenum pname) {'
+ print ' switch (pname) {'
+ for function, type, count, name in glparams.parameters:
+ if type is not None:
+ print ' case %s: return %u;' % (name, count)
+ print ' case GL_COMPRESSED_TEXTURE_FORMATS: {'
+ print ' GLint num_compressed_texture_formats = 0;'
+ print ' __glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_texture_formats);'
+ print ' return num_compressed_texture_formats;'
+ print ' }'
+ print ' default:'
+ print r' os::log("apitrace: warning: %s: unknown GLenum 0x%04X\n", __FUNCTION__, pname);'
+ print ' return 1;'
+ print ' }'
+ print '}'
+ print
+
+ # states such as GL_UNPACK_ROW_LENGTH are not available in GLES
+ print 'static inline bool'
+ print 'can_unpack_subimage(void) {'
+ print ' gltrace::Context *ctx = gltrace::getContext();'
+ print ' return (ctx->profile == gltrace::PROFILE_COMPAT);'
+ print '}'
+ print
+
+ array_pointer_function_names = set((
+ "glVertexPointer",
+ "glNormalPointer",
+ "glColorPointer",
+ "glIndexPointer",
+ "glTexCoordPointer",
+ "glEdgeFlagPointer",
+ "glFogCoordPointer",
+ "glSecondaryColorPointer",
+
+ "glInterleavedArrays",
+
+ "glVertexPointerEXT",
+ "glNormalPointerEXT",
+ "glColorPointerEXT",
+ "glIndexPointerEXT",
+ "glTexCoordPointerEXT",
+ "glEdgeFlagPointerEXT",
+ "glFogCoordPointerEXT",
+ "glSecondaryColorPointerEXT",
+
+ "glVertexAttribPointer",
+ "glVertexAttribPointerARB",
+ "glVertexAttribPointerNV",
+ "glVertexAttribIPointer",
+ "glVertexAttribIPointerEXT",
+ "glVertexAttribLPointer",
+ "glVertexAttribLPointerEXT",
+
+ #"glMatrixIndexPointerARB",
+ ))
+
+ draw_function_names = set((
+ 'glDrawArrays',
+ 'glDrawElements',
+ 'glDrawRangeElements',
+ 'glMultiDrawArrays',
+ 'glMultiDrawElements',
+ 'glDrawArraysInstanced',
+ "glDrawArraysInstancedBaseInstance",
+ 'glDrawElementsInstanced',
+ 'glDrawArraysInstancedARB',
+ 'glDrawElementsInstancedARB',
+ 'glDrawElementsBaseVertex',
+ 'glDrawRangeElementsBaseVertex',
+ 'glDrawElementsInstancedBaseVertex',
+ "glDrawElementsInstancedBaseInstance",
+ "glDrawElementsInstancedBaseVertexBaseInstance",
+ 'glMultiDrawElementsBaseVertex',
+ 'glDrawArraysIndirect',
+ 'glDrawElementsIndirect',
+ 'glDrawArraysEXT',
+ 'glDrawRangeElementsEXT',
+ 'glDrawRangeElementsEXT_size',
+ 'glMultiDrawArraysEXT',
+ 'glMultiDrawElementsEXT',
+ 'glMultiModeDrawArraysIBM',
+ 'glMultiModeDrawElementsIBM',
+ 'glDrawArraysInstancedEXT',
+ 'glDrawElementsInstancedEXT',
+ ))
+
+ interleaved_formats = [
+ 'GL_V2F',
+ 'GL_V3F',
+ 'GL_C4UB_V2F',
+ 'GL_C4UB_V3F',
+ 'GL_C3F_V3F',
+ 'GL_N3F_V3F',
+ 'GL_C4F_N3F_V3F',
+ 'GL_T2F_V3F',
+ 'GL_T4F_V4F',
+ 'GL_T2F_C4UB_V3F',
+ 'GL_T2F_C3F_V3F',
+ 'GL_T2F_N3F_V3F',
+ 'GL_T2F_C4F_N3F_V3F',
+ 'GL_T4F_C4F_N3F_V4F',
+ ]
+
+ def traceFunctionImplBody(self, function):
+ # Defer tracing of user array pointers...
+ if function.name in self.array_pointer_function_names:
+ print ' GLint __array_buffer = 0;'
+ print ' __glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &__array_buffer);'
+ print ' if (!__array_buffer) {'
+ print ' gltrace::Context *ctx = gltrace::getContext();'
+ print ' ctx->user_arrays = true;'
+ if function.name == "glVertexAttribPointerARB":
+ print ' ctx->user_arrays_arb = true;'
+ if function.name == "glVertexAttribPointerNV":
+ print ' ctx->user_arrays_nv = true;'
+ self.invokeFunction(function)
+
+ # And also break down glInterleavedArrays into the individual calls
+ if function.name == 'glInterleavedArrays':
+ print
+
+ # Initialize the enable flags
+ for camelcase_name, uppercase_name in self.arrays:
+ flag_name = '__' + uppercase_name.lower()
+ print ' GLboolean %s = GL_FALSE;' % flag_name
+ print
+
+ # Switch for the interleaved formats
+ print ' switch (format) {'
+ for format in self.interleaved_formats:
+ print ' case %s:' % format
+ for camelcase_name, uppercase_name in self.arrays:
+ flag_name = '__' + uppercase_name.lower()
+ if format.find('_' + uppercase_name[0]) >= 0:
+ print ' %s = GL_TRUE;' % flag_name
+ print ' break;'
+ print ' default:'
+ print ' return;'
+ print ' }'
+ print
+
+ # Emit fake glEnableClientState/glDisableClientState flags
+ for camelcase_name, uppercase_name in self.arrays:
+ flag_name = '__' + uppercase_name.lower()
+ enable_name = 'GL_%s_ARRAY' % uppercase_name
+
+ # Emit a fake function
+ print ' {'
+ print ' static const trace::FunctionSig &__sig = %s ? __glEnableClientState_sig : __glDisableClientState_sig;' % flag_name
+ print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
+ print ' trace::localWriter.beginArg(0);'
+ self.serializeValue(glapi.GLenum, enable_name)
+ print ' trace::localWriter.endArg();'
+ print ' trace::localWriter.endEnter();'
+ print ' trace::localWriter.beginLeave(__call);'
+ print ' trace::localWriter.endLeave();'
+ print ' }'
+
+ print ' return;'
+ print ' }'
+
+ # ... to the draw calls
+ if function.name in self.draw_function_names:
+ print ' if (__need_user_arrays()) {'
+ arg_names = ', '.join([arg.name for arg in function.args[1:]])
+ print ' GLuint maxindex = __%s_maxindex(%s);' % (function.name, arg_names)
+ print ' __trace_user_arrays(maxindex);'
+ print ' }'
+
+ # Emit a fake memcpy on buffer uploads
+ if function.name == 'glBufferParameteriAPPLE':
+ print ' if (pname == GL_BUFFER_FLUSHING_UNMAP_APPLE && param == GL_FALSE) {'
+ print ' __checkBufferFlushingUnmapAPPLE = true;'
+ print ' }'
+ if function.name in ('glUnmapBuffer', 'glUnmapBufferARB'):
+ if function.name.endswith('ARB'):
+ suffix = 'ARB'
+ else:
+ suffix = ''
+ print ' GLint access = 0;'
+ print ' __glGetBufferParameteriv%s(target, GL_BUFFER_ACCESS, &access);' % suffix
+ print ' if (access != GL_READ_ONLY) {'
+ print ' GLvoid *map = NULL;'
+ print ' __glGetBufferPointerv%s(target, GL_BUFFER_MAP_POINTER, &map);' % suffix
+ print ' if (map) {'
+ print ' GLint length = -1;'
+ print ' bool flush = true;'
+ print ' if (__checkBufferMapRange) {'
+ print ' __glGetBufferParameteriv%s(target, GL_BUFFER_MAP_LENGTH, &length);' % suffix
+ print ' GLint access_flags = 0;'
+ print ' __glGetBufferParameteriv(target, GL_BUFFER_ACCESS_FLAGS, &access_flags);'
+ print ' flush = flush && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT);'
+ print ' if (length == -1) {'
+ print ' // Mesa drivers refuse GL_BUFFER_MAP_LENGTH without GL 3.0'
+ print ' static bool warned = false;'
+ print ' if (!warned) {'
+ print ' os::log("apitrace: warning: glGetBufferParameteriv%s(GL_BUFFER_MAP_LENGTH) failed\\n");' % suffix
+ print ' warned = true;'
+ print ' }'
+ print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
+ print ' if (mapping) {'
+ print ' length = mapping->length;'
+ print ' flush = flush && !mapping->explicit_flush;'
+ print ' } else {'
+ print ' length = 0;'
+ print ' flush = false;'
+ print ' }'
+ print ' }'
+ print ' } else {'
+ print ' length = 0;'
+ print ' __glGetBufferParameteriv%s(target, GL_BUFFER_SIZE, &length);' % suffix
+ print ' }'
+ print ' if (__checkBufferFlushingUnmapAPPLE) {'
+ print ' GLint flushing_unmap = GL_TRUE;'
+ print ' __glGetBufferParameteriv%s(target, GL_BUFFER_FLUSHING_UNMAP_APPLE, &flushing_unmap);' % suffix
+ print ' flush = flush && flushing_unmap;'
+ print ' }'
+ print ' if (flush && length > 0) {'
+ self.emit_memcpy('map', 'map', 'length')
+ print ' }'
+ print ' }'
+ print ' }'
+ if function.name == 'glUnmapBufferOES':
+ print ' GLint access = 0;'
+ print ' __glGetBufferParameteriv(target, GL_BUFFER_ACCESS_OES, &access);'
+ print ' if (access == GL_WRITE_ONLY_OES) {'
+ print ' GLvoid *map = NULL;'
+ print ' __glGetBufferPointervOES(target, GL_BUFFER_MAP_POINTER_OES, &map);'
+ print ' GLint size = 0;'
+ print ' __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size);'
+ print ' if (map && size > 0) {'
+ self.emit_memcpy('map', 'map', 'size')
+ print ' }'
+ print ' }'
+ if function.name == 'glUnmapNamedBufferEXT':
+ print ' GLint access_flags = 0;'
+ print ' __glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_ACCESS_FLAGS, &access_flags);'
+ print ' if ((access_flags & GL_MAP_WRITE_BIT) && !(access_flags & GL_MAP_FLUSH_EXPLICIT_BIT)) {'
+ print ' GLvoid *map = NULL;'
+ print ' __glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);'
+ print ' GLint length = 0;'
+ print ' __glGetNamedBufferParameterivEXT(buffer, GL_BUFFER_MAP_LENGTH, &length);'
+ print ' if (map && length > 0) {'
+ self.emit_memcpy('map', 'map', 'length')
+ print ' }'
+ print ' }'
+ if function.name == 'glFlushMappedBufferRange':
+ print ' GLvoid *map = NULL;'
+ print ' __glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);'
+ print ' if (map && length > 0) {'
+ self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length')
+ print ' }'
+ if function.name == 'glFlushMappedBufferRangeAPPLE':
+ print ' GLvoid *map = NULL;'
+ print ' __glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, &map);'
+ print ' if (map && size > 0) {'
+ self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'size')
+ print ' }'
+ if function.name == 'glFlushMappedNamedBufferRangeEXT':
+ print ' GLvoid *map = NULL;'
+ print ' __glGetNamedBufferPointervEXT(buffer, GL_BUFFER_MAP_POINTER, &map);'
+ print ' if (map && length > 0) {'
+ self.emit_memcpy('(char *)map + offset', '(const char *)map + offset', 'length')
+ print ' }'
+
+ # Don't leave vertex attrib locations to chance. Instead emit fake
+ # glBindAttribLocation calls to ensure that the same locations will be
+ # used when retracing. Trying to remap locations after the fact would
+ # be an herculian task given that vertex attrib locations appear in
+ # many entry-points, including non-shader related ones.
+ if function.name == 'glLinkProgram':
+ Tracer.invokeFunction(self, function)
+ print ' GLint active_attributes = 0;'
+ print ' __glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &active_attributes);'
+ print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
+ print ' GLint size = 0;'
+ print ' GLenum type = 0;'
+ print ' GLchar name[256];'
+ # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
+ print ' __glGetActiveAttrib(program, attrib, sizeof name, NULL, &size, &type, name);'
+ print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
+ print ' GLint location = __glGetAttribLocation(program, name);'
+ print ' if (location >= 0) {'
+ bind_function = glapi.glapi.get_function_by_name('glBindAttribLocation')
+ self.fake_call(bind_function, ['program', 'location', 'name'])
+ print ' }'
+ print ' }'
+ print ' }'
+ if function.name == 'glLinkProgramARB':
+ Tracer.invokeFunction(self, function)
+ print ' GLint active_attributes = 0;'
+ print ' __glGetObjectParameterivARB(programObj, GL_OBJECT_ACTIVE_ATTRIBUTES_ARB, &active_attributes);'
+ print ' for (GLint attrib = 0; attrib < active_attributes; ++attrib) {'
+ print ' GLint size = 0;'
+ print ' GLenum type = 0;'
+ print ' GLcharARB name[256];'
+ # TODO: Use ACTIVE_ATTRIBUTE_MAX_LENGTH instead of 256
+ print ' __glGetActiveAttribARB(programObj, attrib, sizeof name, NULL, &size, &type, name);'
+ print " if (name[0] != 'g' || name[1] != 'l' || name[2] != '_') {"
+ print ' GLint location = __glGetAttribLocationARB(programObj, name);'
+ print ' if (location >= 0) {'
+ bind_function = glapi.glapi.get_function_by_name('glBindAttribLocationARB')
+ self.fake_call(bind_function, ['programObj', 'location', 'name'])
+ print ' }'
+ print ' }'
+ print ' }'
+
+ Tracer.traceFunctionImplBody(self, function)
+
+ marker_functions = [
+ # GL_GREMEDY_string_marker
+ 'glStringMarkerGREMEDY',
+ # GL_GREMEDY_frame_terminator
+ 'glFrameTerminatorGREMEDY',
+ # GL_EXT_debug_marker
+ 'glInsertEventMarkerEXT',
+ 'glPushGroupMarkerEXT',
+ 'glPopGroupMarkerEXT',
+ ]
+
+ def invokeFunction(self, function):
+ if function.name in ('glLinkProgram', 'glLinkProgramARB'):
+ # These functions have been dispatched already
+ return
+
+ # We implement GL_EXT_debug_marker, GL_GREMEDY_*, etc., and not the
+ # driver
+ if function.name in self.marker_functions:
+ return
+
+ if function.name in ('glXGetProcAddress', 'glXGetProcAddressARB', 'wglGetProcAddress'):
+ else_ = ''
+ for marker_function in self.marker_functions:
+ if self.api.get_function_by_name(marker_function):
+ print ' %sif (strcmp("%s", (const char *)%s) == 0) {' % (else_, marker_function, function.args[0].name)
+ print ' __result = (%s)&%s;' % (function.type, marker_function)
+ print ' }'
+ else_ = 'else '
+ print ' %s{' % else_
+ Tracer.invokeFunction(self, function)
+ print ' }'
+ return
+
+ # Override GL extensions
+ if function.name in ('glGetString', 'glGetIntegerv', 'glGetStringi'):
+ Tracer.invokeFunction(self, function, prefix = 'gltrace::__', suffix = '_override')
+ return
+
+ Tracer.invokeFunction(self, function)
+
+ buffer_targets = [
+ 'ARRAY_BUFFER',
+ 'ELEMENT_ARRAY_BUFFER',
+ 'PIXEL_PACK_BUFFER',
+ 'PIXEL_UNPACK_BUFFER',
+ 'UNIFORM_BUFFER',
+ 'TEXTURE_BUFFER',
+ 'TRANSFORM_FEEDBACK_BUFFER',
+ 'COPY_READ_BUFFER',
+ 'COPY_WRITE_BUFFER',
+ 'DRAW_INDIRECT_BUFFER',
+ 'ATOMIC_COUNTER_BUFFER',
+ ]
+
+ def wrapRet(self, function, instance):
+ Tracer.wrapRet(self, function, instance)
+
+ # Keep track of buffer mappings
+ if function.name in ('glMapBuffer', 'glMapBufferARB'):
+ print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
+ print ' if (mapping) {'
+ print ' mapping->map = %s;' % (instance)
+ print ' mapping->length = 0;'
+ print ' __glGetBufferParameteriv(target, GL_BUFFER_SIZE, &mapping->length);'
+ print ' mapping->write = (access != GL_READ_ONLY);'
+ print ' mapping->explicit_flush = false;'
+ print ' }'
+ if function.name == 'glMapBufferRange':
+ print ' if (access & GL_MAP_WRITE_BIT) {'
+ print ' __checkBufferMapRange = true;'
+ print ' }'
+ print ' struct buffer_mapping *mapping = get_buffer_mapping(target);'
+ print ' if (mapping) {'
+ print ' mapping->map = %s;' % (instance)
+ print ' mapping->length = length;'
+ print ' mapping->write = access & GL_MAP_WRITE_BIT;'
+ print ' mapping->explicit_flush = access & GL_MAP_FLUSH_EXPLICIT_BIT;'
+ print ' }'
+
+ boolean_names = [
+ 'GL_FALSE',
+ 'GL_TRUE',
+ ]
+
+ def gl_boolean(self, value):
+ return self.boolean_names[int(bool(value))]
+
+ # Names of the functions that unpack from a pixel buffer object. See the
+ # ARB_pixel_buffer_object specification.
+ unpack_function_names = set([
+ 'glBitmap',
+ 'glColorSubTable',
+ 'glColorTable',
+ 'glCompressedTexImage1D',
+ 'glCompressedTexImage2D',
+ 'glCompressedTexImage3D',
+ 'glCompressedTexSubImage1D',
+ 'glCompressedTexSubImage2D',
+ 'glCompressedTexSubImage3D',
+ 'glConvolutionFilter1D',
+ 'glConvolutionFilter2D',
+ 'glDrawPixels',
+ 'glMultiTexImage1DEXT',
+ 'glMultiTexImage2DEXT',
+ 'glMultiTexImage3DEXT',
+ 'glMultiTexSubImage1DEXT',
+ 'glMultiTexSubImage2DEXT',
+ 'glMultiTexSubImage3DEXT',
+ 'glPixelMapfv',
+ 'glPixelMapuiv',
+ 'glPixelMapusv',
+ 'glPolygonStipple',
+ 'glSeparableFilter2D',
+ 'glTexImage1D',
+ 'glTexImage1DEXT',
+ 'glTexImage2D',
+ 'glTexImage2DEXT',
+ 'glTexImage3D',
+ 'glTexImage3DEXT',
+ 'glTexSubImage1D',
+ 'glTexSubImage1DEXT',
+ 'glTexSubImage2D',
+ 'glTexSubImage2DEXT',
+ 'glTexSubImage3D',
+ 'glTexSubImage3DEXT',
+ 'glTextureImage1DEXT',
+ 'glTextureImage2DEXT',
+ 'glTextureImage3DEXT',
+ 'glTextureSubImage1DEXT',
+ 'glTextureSubImage2DEXT',
+ 'glTextureSubImage3DEXT',
+ ])
+
+ def serializeArgValue(self, function, arg):
+ if function.name in self.draw_function_names and arg.name == 'indices':
+ print ' GLint __element_array_buffer = 0;'
+ print ' __glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &__element_array_buffer);'
+ print ' if (!__element_array_buffer) {'
+ if isinstance(arg.type, stdapi.Array):
+ print ' trace::localWriter.beginArray(%s);' % arg.type.length
+ print ' for(GLsizei i = 0; i < %s; ++i) {' % arg.type.length
+ print ' trace::localWriter.beginElement();'
+ print ' trace::localWriter.writeBlob(%s[i], count[i]*__gl_type_size(type));' % (arg.name)
+ print ' trace::localWriter.endElement();'
+ print ' }'
+ print ' trace::localWriter.endArray();'
+ else:
+ print ' trace::localWriter.writeBlob(%s, count*__gl_type_size(type));' % (arg.name)
+ print ' } else {'
+ Tracer.serializeArgValue(self, function, arg)
+ print ' }'
+ return
+
+ # Recognize offsets instead of blobs when a PBO is bound
+ if function.name in self.unpack_function_names \
+ and (isinstance(arg.type, stdapi.Blob) \
+ or (isinstance(arg.type, stdapi.Const) \
+ and isinstance(arg.type.type, stdapi.Blob))):
+ print ' {'
+ print ' gltrace::Context *ctx = gltrace::getContext();'
+ print ' GLint __unpack_buffer = 0;'
+ print ' if (ctx->profile == gltrace::PROFILE_COMPAT)'
+ print ' __glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &__unpack_buffer);'
+ print ' if (__unpack_buffer) {'
+ print ' trace::localWriter.writeOpaque(%s);' % arg.name
+ print ' } else {'
+ Tracer.serializeArgValue(self, function, arg)
+ print ' }'
+ print ' }'
+ return
+
+ # Several GL state functions take GLenum symbolic names as
+ # integer/floats; so dump the symbolic name whenever possible
+ if function.name.startswith('gl') \
+ and arg.type in (glapi.GLint, glapi.GLfloat, glapi.GLdouble) \
+ and arg.name == 'param':
+ assert arg.index > 0
+ assert function.args[arg.index - 1].name == 'pname'
+ assert function.args[arg.index - 1].type == glapi.GLenum
+ print ' if (is_symbolic_pname(pname) && is_symbolic_param(%s)) {' % arg.name
+ self.serializeValue(glapi.GLenum, arg.name)
+ print ' } else {'
+ Tracer.serializeArgValue(self, function, arg)
+ print ' }'
+ return
+
+ Tracer.serializeArgValue(self, function, arg)
+
+ def footer(self, api):
+ Tracer.footer(self, api)
+
+ # A simple state tracker to track the pointer values
+ # update the state
+ print 'static void __trace_user_arrays(GLuint maxindex)'
+ print '{'
+ print ' gltrace::Context *ctx = gltrace::getContext();'
+
+ for camelcase_name, uppercase_name in self.arrays:
+ # in which profile is the array available?
+ profile_check = 'ctx->profile == gltrace::PROFILE_COMPAT'
+ if camelcase_name in self.arrays_es1:
+ profile_check = '(' + profile_check + ' || ctx->profile == gltrace::PROFILE_ES1)';
+
+ function_name = 'gl%sPointer' % camelcase_name
+ enable_name = 'GL_%s_ARRAY' % uppercase_name
+ binding_name = 'GL_%s_ARRAY_BUFFER_BINDING' % uppercase_name
+ function = api.get_function_by_name(function_name)
+
+ print ' // %s' % function.prototype()
+ print ' if (%s) {' % profile_check
+ self.array_trace_prolog(api, uppercase_name)
+ self.array_prolog(api, uppercase_name)
+ print ' if (__glIsEnabled(%s)) {' % enable_name
+ print ' GLint __binding = 0;'
+ print ' __glGetIntegerv(%s, &__binding);' % binding_name
+ print ' if (!__binding) {'
+
+ # Get the arguments via glGet*
+ for arg in function.args:
+ arg_get_enum = 'GL_%s_ARRAY_%s' % (uppercase_name, arg.name.upper())
+ arg_get_function, arg_type = TypeGetter().visit(arg.type)
+ print ' %s %s = 0;' % (arg_type, arg.name)
+ print ' __%s(%s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
+
+ arg_names = ', '.join([arg.name for arg in function.args[:-1]])
+ print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
+
+ # Emit a fake function
+ self.array_trace_intermezzo(api, uppercase_name)
+ print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
+ for arg in function.args:
+ assert not arg.output
+ print ' trace::localWriter.beginArg(%u);' % (arg.index,)
+ if arg.name != 'pointer':
+ self.serializeValue(arg.type, arg.name)
+ else:
+ print ' trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
+ print ' trace::localWriter.endArg();'
+
+ print ' trace::localWriter.endEnter();'
+ print ' trace::localWriter.beginLeave(__call);'
+ print ' trace::localWriter.endLeave();'
+ print ' }'
+ print ' }'
+ self.array_epilog(api, uppercase_name)
+ self.array_trace_epilog(api, uppercase_name)
+ print ' }'
+ print
+
+ # Samething, but for glVertexAttribPointer*
+ #
+ # Some variants of glVertexAttribPointer alias conventional and generic attributes:
+ # - glVertexAttribPointer: no
+ # - glVertexAttribPointerARB: implementation dependent
+ # - glVertexAttribPointerNV: yes
+ #
+ # This means that the implementations of these functions do not always
+ # alias, and they need to be considered independently.
+ #
+ print ' // ES1 does not support generic vertex attributes'
+ print ' if (ctx->profile == gltrace::PROFILE_ES1)'
+ print ' return;'
+ print
+ print ' vertex_attrib __vertex_attrib = __get_vertex_attrib();'
+ print
+ for suffix in ['', 'ARB', 'NV']:
+ if suffix:
+ SUFFIX = '_' + suffix
+ else:
+ SUFFIX = suffix
+ function_name = 'glVertexAttribPointer' + suffix
+ function = api.get_function_by_name(function_name)
+
+ print ' // %s' % function.prototype()
+ print ' if (__vertex_attrib == VERTEX_ATTRIB%s) {' % SUFFIX
+ if suffix == 'NV':
+ print ' GLint __max_vertex_attribs = 16;'
+ else:
+ print ' GLint __max_vertex_attribs = 0;'
+ print ' __glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &__max_vertex_attribs);'
+ print ' for (GLint index = 0; index < __max_vertex_attribs; ++index) {'
+ print ' GLint __enabled = 0;'
+ if suffix == 'NV':
+ print ' __glGetIntegerv(GL_VERTEX_ATTRIB_ARRAY0_NV + index, &__enabled);'
+ else:
+ print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED%s, &__enabled);' % (suffix, SUFFIX)
+ print ' if (__enabled) {'
+ print ' GLint __binding = 0;'
+ if suffix != 'NV':
+ # It doesn't seem possible to use VBOs with NV_vertex_program.
+ print ' __glGetVertexAttribiv%s(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING%s, &__binding);' % (suffix, SUFFIX)
+ print ' if (!__binding) {'
+
+ # Get the arguments via glGet*
+ for arg in function.args[1:]:
+ if suffix == 'NV':
+ arg_get_enum = 'GL_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
+ else:
+ arg_get_enum = 'GL_VERTEX_ATTRIB_ARRAY_%s%s' % (arg.name.upper(), SUFFIX)
+ arg_get_function, arg_type = TypeGetter('glGetVertexAttrib', False, suffix).visit(arg.type)
+ print ' %s %s = 0;' % (arg_type, arg.name)
+ print ' __%s(index, %s, &%s);' % (arg_get_function, arg_get_enum, arg.name)
+
+ arg_names = ', '.join([arg.name for arg in function.args[1:-1]])
+ print ' size_t __size = __%s_size(%s, maxindex);' % (function.name, arg_names)
+
+ # Emit a fake function
+ print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
+ for arg in function.args:
+ assert not arg.output
+ print ' trace::localWriter.beginArg(%u);' % (arg.index,)
+ if arg.name != 'pointer':
+ self.serializeValue(arg.type, arg.name)
+ else:
+ print ' trace::localWriter.writeBlob((const void *)%s, __size);' % (arg.name)
+ print ' trace::localWriter.endArg();'
+
+ print ' trace::localWriter.endEnter();'
+ print ' trace::localWriter.beginLeave(__call);'
+ print ' trace::localWriter.endLeave();'
+ print ' }'
+ print ' }'
+ print ' }'
+ print ' }'
+ print
+
+ print '}'
+ print
+
+ #
+ # Hooks for glTexCoordPointer, which is identical to the other array
+ # pointers except the fact that it is indexed by glClientActiveTexture.
+ #
+
+ def array_prolog(self, api, uppercase_name):
+ if uppercase_name == 'TEXTURE_COORD':
+ print ' GLint client_active_texture = 0;'
+ print ' __glGetIntegerv(GL_CLIENT_ACTIVE_TEXTURE, &client_active_texture);'
+ print ' GLint max_texture_coords = 0;'
+ print ' if (ctx->profile == gltrace::PROFILE_COMPAT)'
+ print ' __glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);'
+ print ' else'
+ print ' __glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_coords);'
+ print ' for (GLint unit = 0; unit < max_texture_coords; ++unit) {'
+ print ' GLint texture = GL_TEXTURE0 + unit;'
+ print ' __glClientActiveTexture(texture);'
+
+ def array_trace_prolog(self, api, uppercase_name):
+ if uppercase_name == 'TEXTURE_COORD':
+ print ' bool client_active_texture_dirty = false;'
+
+ def array_epilog(self, api, uppercase_name):
+ if uppercase_name == 'TEXTURE_COORD':
+ print ' }'
+ self.array_cleanup(api, uppercase_name)
+
+ def array_cleanup(self, api, uppercase_name):
+ if uppercase_name == 'TEXTURE_COORD':
+ print ' __glClientActiveTexture(client_active_texture);'
+
+ def array_trace_intermezzo(self, api, uppercase_name):
+ if uppercase_name == 'TEXTURE_COORD':
+ print ' if (texture != client_active_texture || client_active_texture_dirty) {'
+ print ' client_active_texture_dirty = true;'
+ self.fake_glClientActiveTexture_call(api, "texture");
+ print ' }'
+
+ def array_trace_epilog(self, api, uppercase_name):
+ if uppercase_name == 'TEXTURE_COORD':
+ print ' if (client_active_texture_dirty) {'
+ self.fake_glClientActiveTexture_call(api, "client_active_texture");
+ print ' }'
+
+ def fake_glClientActiveTexture_call(self, api, texture):
+ function = api.get_function_by_name('glClientActiveTexture')
+ self.fake_call(function, [texture])
+
+ def fake_call(self, function, args):
+ print ' unsigned __fake_call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
+ for arg, instance in zip(function.args, args):
+ assert not arg.output
+ print ' trace::localWriter.beginArg(%u);' % (arg.index,)
+ self.serializeValue(arg.type, instance)
+ print ' trace::localWriter.endArg();'
+ print ' trace::localWriter.endEnter();'
+ print ' trace::localWriter.beginLeave(__fake_call);'
+ print ' trace::localWriter.endLeave();'
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null
+##########################################################################
+#
+# Copyright 2011 Jose Fonseca
+# Copyright 2008-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.
+#
+##########################################################################/
+
+
+"""GLX tracing generator."""
+
+
+from gltrace import GlTracer
+from dispatch import function_pointer_type, function_pointer_value
+from specs.stdapi import API
+from specs.glapi import glapi
+from specs.glxapi import glxapi
+
+
+class GlxTracer(GlTracer):
+
+ def isFunctionPublic(self, function):
+ # The symbols visible in libGL.so can vary, so expose them all
+ return True
+
+ def wrapRet(self, function, instance):
+ GlTracer.wrapRet(self, function, instance)
+
+ if function.name in ("glXGetProcAddress", "glXGetProcAddressARB"):
+ print ' %s = __unwrap_proc_addr(procName, %s);' % (instance, instance)
+
+
+if __name__ == '__main__':
+ print
+ print '#include <stdlib.h>'
+ print '#include <string.h>'
+ print
+ print '#ifndef _GNU_SOURCE'
+ print '#define _GNU_SOURCE // for dladdr'
+ print '#endif'
+ print '#include <dlfcn.h>'
+ print
+ print '#include "trace_writer_local.hpp"'
+ print
+ print '// To validate our prototypes'
+ print '#define GL_GLEXT_PROTOTYPES'
+ print '#define GLX_GLXEXT_PROTOTYPES'
+ print
+ print '#include "glproc.hpp"'
+ print '#include "glsize.hpp"'
+ print
+ print 'static __GLXextFuncPtr __unwrap_proc_addr(const GLubyte * procName, __GLXextFuncPtr procPtr);'
+ print
+
+ api = API()
+ api.addApi(glxapi)
+ api.addApi(glapi)
+ tracer = GlxTracer()
+ tracer.trace_api(api)
+
+ print 'static __GLXextFuncPtr __unwrap_proc_addr(const GLubyte * procName, __GLXextFuncPtr procPtr) {'
+ print ' if (!procPtr) {'
+ print ' return procPtr;'
+ print ' }'
+ for f in api.functions:
+ ptype = function_pointer_type(f)
+ pvalue = function_pointer_value(f)
+ print ' if (strcmp("%s", (const char *)procName) == 0) {' % f.name
+ print ' %s = (%s)procPtr;' % (pvalue, ptype)
+ print ' return (__GLXextFuncPtr)&%s;' % (f.name,)
+ print ' }'
+ print ' os::log("apitrace: warning: unknown function \\"%s\\"\\n", (const char *)procName);'
+ print ' return procPtr;'
+ print '}'
+ print
+ print r'''
+
+
+/*
+ * 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);
+}
+
+
+/*
+ * Several applications, such as Quake3, use dlopen("libGL.so.1"), but
+ * LD_PRELOAD does not intercept symbols obtained via dlopen/dlsym, therefore
+ * we need to intercept the dlopen() call here, and redirect to our wrapper
+ * shared object.
+ */
+extern "C" PUBLIC
+void * dlopen(const char *filename, int flag)
+{
+ void *handle;
+
+ handle = __dlopen(filename, flag);
+
+ const char * libgl_filename = getenv("TRACE_LIBGL");
+
+ if (filename && handle && !libgl_filename) {
+ if (0) {
+ os::log("apitrace: warning: dlopen(\"%s\", 0x%x)\n", filename, flag);
+ }
+
+ // FIXME: handle absolute paths and other versions
+ if (strcmp(filename, "libGL.so") == 0 ||
+ strcmp(filename, "libGL.so.1") == 0) {
+
+ // Use the true libGL.so handle instead of RTLD_NEXT from now on
+ __libGlHandle = handle;
+
+ // Get the file path for our shared object, and use it instead
+ static int dummy = 0xdeedbeef;
+ Dl_info info;
+ if (dladdr(&dummy, &info)) {
+ os::log("apitrace: redirecting dlopen(\"%s\", 0x%x)\n", filename, flag);
+ handle = __dlopen(info.dli_fname, flag);
+ } else {
+ os::log("apitrace: warning: dladdr() failed\n");
+ }
+ }
+ }
+
+ return handle;
+}
+
+
+
+'''
--- /dev/null
+LIBRARY opengl32
+
+EXPORTS
+; GlmfBeginGlsBlock
+; GlmfCloseMetaFile
+; GlmfEndGlsBlock
+; GlmfEndPlayback
+; GlmfInitPlayback
+; GlmfPlayGlsRecord
+ 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
+; glDebugEntry
+ 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
+ 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
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-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.
+#
+##########################################################################/
+
+"""Common trace code generation."""
+
+
+# Adjust path
+import os.path
+import sys
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
+
+
+import specs.stdapi as stdapi
+
+
+def getWrapperInterfaceName(interface):
+ return "Wrap" + interface.expr
+
+
+class ComplexValueSerializer(stdapi.OnceVisitor):
+ '''Type visitors which generates serialization functions for
+ complex types.
+
+ Simple types are serialized inline.
+ '''
+
+ def __init__(self, serializer):
+ stdapi.OnceVisitor.__init__(self)
+ self.serializer = serializer
+
+ def visitVoid(self, literal):
+ pass
+
+ def visitLiteral(self, literal):
+ pass
+
+ def visitString(self, string):
+ pass
+
+ def visitConst(self, const):
+ self.visit(const.type)
+
+ def visitStruct(self, struct):
+ for type, name in struct.members:
+ self.visit(type)
+ print 'static void _write__%s(const %s &value) {' % (struct.tag, struct.expr)
+ print ' static const char * members[%u] = {' % (len(struct.members),)
+ for type, name, in struct.members:
+ print ' "%s",' % (name,)
+ print ' };'
+ print ' static const trace::StructSig sig = {'
+ print ' %u, "%s", %u, members' % (struct.id, struct.name, len(struct.members))
+ print ' };'
+ print ' trace::localWriter.beginStruct(&sig);'
+ for type, name in struct.members:
+ self.serializer.visit(type, 'value.%s' % (name,))
+ print ' trace::localWriter.endStruct();'
+ print '}'
+ print
+
+ def visitArray(self, array):
+ self.visit(array.type)
+
+ def visitBlob(self, array):
+ pass
+
+ def visitEnum(self, enum):
+ print 'static const trace::EnumValue __enum%s_values[] = {' % (enum.tag)
+ for value in enum.values:
+ print ' {"%s", %s},' % (value, value)
+ print '};'
+ print
+ print 'static const trace::EnumSig __enum%s_sig = {' % (enum.tag)
+ print ' %u, %u, __enum%s_values' % (enum.id, len(enum.values), enum.tag)
+ print '};'
+ print
+
+ def visitBitmask(self, bitmask):
+ print 'static const trace::BitmaskFlag __bitmask%s_flags[] = {' % (bitmask.tag)
+ for value in bitmask.values:
+ print ' {"%s", %s},' % (value, value)
+ print '};'
+ print
+ print 'static const trace::BitmaskSig __bitmask%s_sig = {' % (bitmask.tag)
+ print ' %u, %u, __bitmask%s_flags' % (bitmask.id, len(bitmask.values), bitmask.tag)
+ print '};'
+ print
+
+ def visitPointer(self, pointer):
+ self.visit(pointer.type)
+
+ def visitIntPointer(self, pointer):
+ pass
+
+ def visitObjPointer(self, pointer):
+ self.visit(pointer.type)
+
+ def visitLinearPointer(self, pointer):
+ self.visit(pointer.type)
+
+ def visitHandle(self, handle):
+ self.visit(handle.type)
+
+ def visitReference(self, reference):
+ self.visit(reference.type)
+
+ def visitAlias(self, alias):
+ self.visit(alias.type)
+
+ def visitOpaque(self, opaque):
+ pass
+
+ def visitInterface(self, interface):
+ pass
+
+ def visitPolymorphic(self, polymorphic):
+ print 'static void _write__%s(int selector, const %s & value) {' % (polymorphic.tag, polymorphic.expr)
+ print ' switch (selector) {'
+ for cases, type in polymorphic.iterSwitch():
+ for case in cases:
+ print ' %s:' % case
+ self.serializer.visit(type, 'static_cast<%s>(value)' % (type,))
+ print ' break;'
+ print ' }'
+ print '}'
+ print
+
+
+class ValueSerializer(stdapi.Visitor):
+ '''Visitor which generates code to serialize any type.
+
+ Simple types are serialized inline here, whereas the serialization of
+ complex types is dispatched to the serialization functions generated by
+ ComplexValueSerializer visitor above.
+ '''
+
+ def visitLiteral(self, literal, instance):
+ print ' trace::localWriter.write%s(%s);' % (literal.kind, instance)
+
+ def visitString(self, string, instance):
+ if string.kind == 'String':
+ cast = 'const char *'
+ elif string.kind == 'WString':
+ cast = 'const wchar_t *'
+ else:
+ assert False
+ if cast != string.expr:
+ # reinterpret_cast is necessary for GLubyte * <=> char *
+ instance = 'reinterpret_cast<%s>(%s)' % (cast, instance)
+ if string.length is not None:
+ length = ', %s' % string.length
+ else:
+ length = ''
+ print ' trace::localWriter.write%s(%s%s);' % (string.kind, instance, length)
+
+ def visitConst(self, const, instance):
+ self.visit(const.type, instance)
+
+ def visitStruct(self, struct, instance):
+ print ' _write__%s(%s);' % (struct.tag, instance)
+
+ def visitArray(self, array, instance):
+ length = '__c' + array.type.tag
+ index = '__i' + array.type.tag
+ print ' if (%s) {' % instance
+ print ' size_t %s = %s;' % (length, array.length)
+ print ' trace::localWriter.beginArray(%s);' % length
+ print ' for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
+ print ' trace::localWriter.beginElement();'
+ self.visit(array.type, '(%s)[%s]' % (instance, index))
+ print ' trace::localWriter.endElement();'
+ print ' }'
+ print ' trace::localWriter.endArray();'
+ print ' } else {'
+ print ' trace::localWriter.writeNull();'
+ print ' }'
+
+ def visitBlob(self, blob, instance):
+ print ' trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
+
+ def visitEnum(self, enum, instance):
+ print ' trace::localWriter.writeEnum(&__enum%s_sig, %s);' % (enum.tag, instance)
+
+ def visitBitmask(self, bitmask, instance):
+ print ' trace::localWriter.writeBitmask(&__bitmask%s_sig, %s);' % (bitmask.tag, instance)
+
+ def visitPointer(self, pointer, instance):
+ print ' if (%s) {' % instance
+ print ' trace::localWriter.beginArray(1);'
+ print ' trace::localWriter.beginElement();'
+ self.visit(pointer.type, "*" + instance)
+ print ' trace::localWriter.endElement();'
+ print ' trace::localWriter.endArray();'
+ print ' } else {'
+ print ' trace::localWriter.writeNull();'
+ print ' }'
+
+ def visitIntPointer(self, pointer, instance):
+ print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
+
+ def visitObjPointer(self, pointer, instance):
+ print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
+
+ def visitLinearPointer(self, pointer, instance):
+ print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
+
+ def visitReference(self, reference, instance):
+ self.visit(reference.type, instance)
+
+ def visitHandle(self, handle, instance):
+ self.visit(handle.type, instance)
+
+ def visitAlias(self, alias, instance):
+ self.visit(alias.type, instance)
+
+ def visitOpaque(self, opaque, instance):
+ print ' trace::localWriter.writeOpaque((const void *)%s);' % instance
+
+ def visitInterface(self, interface, instance):
+ print ' trace::localWriter.writeOpaque((const void *)&%s);' % instance
+
+ def visitPolymorphic(self, polymorphic, instance):
+ print ' _write__%s(%s, %s);' % (polymorphic.tag, polymorphic.switchExpr, instance)
+
+
+class ValueWrapper(stdapi.Visitor):
+ '''Type visitor which will generate the code to wrap an instance.
+
+ Wrapping is necessary mostly for interfaces, however interface pointers can
+ appear anywhere inside complex types.
+ '''
+
+ def visitVoid(self, type, instance):
+ raise NotImplementedError
+
+ def visitLiteral(self, type, instance):
+ pass
+
+ def visitString(self, type, instance):
+ pass
+
+ def visitConst(self, type, instance):
+ pass
+
+ def visitStruct(self, struct, instance):
+ for type, name in struct.members:
+ self.visit(type, "(%s).%s" % (instance, name))
+
+ def visitArray(self, array, instance):
+ # XXX: actually it is possible to return an array of pointers
+ pass
+
+ def visitBlob(self, blob, instance):
+ pass
+
+ def visitEnum(self, enum, instance):
+ pass
+
+ def visitBitmask(self, bitmask, instance):
+ pass
+
+ def visitPointer(self, pointer, instance):
+ print " if (%s) {" % instance
+ self.visit(pointer.type, "*" + instance)
+ print " }"
+
+ def visitIntPointer(self, pointer, instance):
+ pass
+
+ def visitObjPointer(self, pointer, instance):
+ print " if (%s) {" % instance
+ self.visit(pointer.type, "*" + instance)
+ print " }"
+
+ def visitLinearPointer(self, pointer, instance):
+ pass
+
+ def visitReference(self, reference, instance):
+ self.visit(reference.type, instance)
+
+ def visitHandle(self, handle, instance):
+ self.visit(handle.type, instance)
+
+ def visitAlias(self, alias, instance):
+ self.visit(alias.type, instance)
+
+ def visitOpaque(self, opaque, instance):
+ pass
+
+ def visitInterface(self, interface, instance):
+ assert instance.startswith('*')
+ instance = instance[1:]
+ print " if (%s) {" % instance
+ print " %s = new %s(%s);" % (instance, getWrapperInterfaceName(interface), instance)
+ print " }"
+
+ def visitPolymorphic(self, type, instance):
+ # XXX: There might be polymorphic values that need wrapping in the future
+ pass
+
+
+class ValueUnwrapper(ValueWrapper):
+ '''Reverse of ValueWrapper.'''
+
+ def visitInterface(self, interface, instance):
+ assert instance.startswith('*')
+ instance = instance[1:]
+ print r' if (%s) {' % instance
+ print r' %s *pWrapper = static_cast<%s*>(%s);' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), instance)
+ print r' if (pWrapper && pWrapper->m_dwMagic == 0xd8365d6c) {'
+ print r' %s = pWrapper->m_pInstance;' % (instance,)
+ print r' } else {'
+ print r' os::log("apitrace: warning: %%s: unexpected %%s pointer\n", __FUNCTION__, "%s");' % interface.name
+ print r' }'
+ print r' }'
+
+
+class Tracer:
+ '''Base class to orchestrate the code generation of API tracing.'''
+
+ def __init__(self):
+ self.api = None
+
+ def serializerFactory(self):
+ '''Create a serializer.
+
+ Can be overriden by derived classes to inject their own serialzer.
+ '''
+
+ return ValueSerializer()
+
+ def trace_api(self, api):
+ self.api = api
+
+ self.header(api)
+
+ # Includes
+ for header in api.headers:
+ print header
+ print
+
+ # Generate the serializer functions
+ types = api.getAllTypes()
+ visitor = ComplexValueSerializer(self.serializerFactory())
+ map(visitor.visit, types)
+ print
+
+ # Interfaces wrapers
+ interfaces = api.getAllInterfaces()
+ map(self.declareWrapperInterface, interfaces)
+ map(self.implementWrapperInterface, interfaces)
+ print
+
+ # Function wrappers
+ map(self.traceFunctionDecl, api.functions)
+ map(self.traceFunctionImpl, api.functions)
+ print
+
+ self.footer(api)
+
+ def header(self, api):
+ pass
+
+ def footer(self, api):
+ pass
+
+ def traceFunctionDecl(self, function):
+ # Per-function declarations
+
+ if function.args:
+ print 'static const char * __%s_args[%u] = {%s};' % (function.name, len(function.args), ', '.join(['"%s"' % arg.name for arg in function.args]))
+ else:
+ print 'static const char ** __%s_args = NULL;' % (function.name,)
+ print 'static const trace::FunctionSig __%s_sig = {%u, "%s", %u, __%s_args};' % (function.name, function.id, function.name, len(function.args), function.name)
+ print
+
+ def isFunctionPublic(self, function):
+ return True
+
+ def traceFunctionImpl(self, function):
+ if self.isFunctionPublic(function):
+ print 'extern "C" PUBLIC'
+ else:
+ print 'extern "C" PRIVATE'
+ print function.prototype() + ' {'
+ if function.type is not stdapi.Void:
+ print ' %s __result;' % function.type
+ self.traceFunctionImplBody(function)
+ if function.type is not stdapi.Void:
+ self.wrapRet(function, "__result")
+ print ' return __result;'
+ print '}'
+ print
+
+ def traceFunctionImplBody(self, function):
+ print ' unsigned __call = trace::localWriter.beginEnter(&__%s_sig);' % (function.name,)
+ for arg in function.args:
+ if not arg.output:
+ self.unwrapArg(function, arg)
+ self.serializeArg(function, arg)
+ print ' trace::localWriter.endEnter();'
+ self.invokeFunction(function)
+ print ' trace::localWriter.beginLeave(__call);'
+ for arg in function.args:
+ if arg.output:
+ self.serializeArg(function, arg)
+ self.wrapArg(function, arg)
+ if function.type is not stdapi.Void:
+ self.serializeRet(function, "__result")
+ print ' trace::localWriter.endLeave();'
+
+ def invokeFunction(self, function, prefix='__', suffix=''):
+ if function.type is stdapi.Void:
+ result = ''
+ else:
+ result = '__result = '
+ dispatch = prefix + function.name + suffix
+ print ' %s%s(%s);' % (result, dispatch, ', '.join([str(arg.name) for arg in function.args]))
+
+ def serializeArg(self, function, arg):
+ print ' trace::localWriter.beginArg(%u);' % (arg.index,)
+ self.serializeArgValue(function, arg)
+ print ' trace::localWriter.endArg();'
+
+ def serializeArgValue(self, function, arg):
+ self.serializeValue(arg.type, arg.name)
+
+ def wrapArg(self, function, arg):
+ self.wrapValue(arg.type, arg.name)
+
+ def unwrapArg(self, function, arg):
+ self.unwrapValue(arg.type, arg.name)
+
+ def serializeRet(self, function, instance):
+ print ' trace::localWriter.beginReturn();'
+ self.serializeValue(function.type, instance)
+ print ' trace::localWriter.endReturn();'
+
+ def serializeValue(self, type, instance):
+ serializer = self.serializerFactory()
+ serializer.visit(type, instance)
+
+ def wrapRet(self, function, instance):
+ self.wrapValue(function.type, instance)
+
+ def unwrapRet(self, function, instance):
+ self.unwrapValue(function.type, instance)
+
+ def wrapValue(self, type, instance):
+ visitor = ValueWrapper()
+ visitor.visit(type, instance)
+
+ def unwrapValue(self, type, instance):
+ visitor = ValueUnwrapper()
+ visitor.visit(type, instance)
+
+ def declareWrapperInterface(self, interface):
+ print "class %s : public %s " % (getWrapperInterfaceName(interface), interface.name)
+ print "{"
+ print "public:"
+ print " %s(%s * pInstance);" % (getWrapperInterfaceName(interface), interface.name)
+ print " virtual ~%s();" % getWrapperInterfaceName(interface)
+ print
+ for method in interface.iterMethods():
+ print " " + method.prototype() + ";"
+ print
+ self.declareWrapperInterfaceVariables(interface)
+ print "};"
+ print
+
+ def declareWrapperInterfaceVariables(self, interface):
+ #print "private:"
+ print " DWORD m_dwMagic;"
+ print " %s * m_pInstance;" % (interface.name,)
+
+ def implementWrapperInterface(self, interface):
+ print '%s::%s(%s * pInstance) {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface), interface.name)
+ print ' m_dwMagic = 0xd8365d6c;'
+ print ' m_pInstance = pInstance;'
+ print '}'
+ print
+ print '%s::~%s() {' % (getWrapperInterfaceName(interface), getWrapperInterfaceName(interface))
+ print '}'
+ print
+ for base, method in interface.iterBaseMethods():
+ self.implementWrapperInterfaceMethod(interface, base, method)
+ print
+
+ def implementWrapperInterfaceMethod(self, interface, base, method):
+ print method.prototype(getWrapperInterfaceName(interface) + '::' + method.name) + ' {'
+ if method.type is not stdapi.Void:
+ print ' %s __result;' % method.type
+
+ self.implementWrapperInterfaceMethodBody(interface, base, method)
+
+ if method.type is not stdapi.Void:
+ print ' return __result;'
+ print '}'
+ print
+
+ def implementWrapperInterfaceMethodBody(self, interface, base, method):
+ print ' static const char * __args[%u] = {%s};' % (len(method.args) + 1, ', '.join(['"this"'] + ['"%s"' % arg.name for arg in method.args]))
+ print ' static const trace::FunctionSig __sig = {%u, "%s", %u, __args};' % (method.id, interface.name + '::' + method.name, len(method.args) + 1)
+ print ' unsigned __call = trace::localWriter.beginEnter(&__sig);'
+ print ' trace::localWriter.beginArg(0);'
+ print ' trace::localWriter.writeOpaque((const void *)m_pInstance);'
+ print ' trace::localWriter.endArg();'
+
+ from specs.winapi import REFIID
+ from specs.stdapi import Pointer, Opaque, Interface
+
+ riid = None
+ for arg in method.args:
+ if not arg.output:
+ self.unwrapArg(method, arg)
+ self.serializeArg(method, arg)
+ if arg.type is REFIID:
+ riid = arg
+ print ' trace::localWriter.endEnter();'
+
+ self.invokeMethod(interface, base, method)
+
+ print ' trace::localWriter.beginLeave(__call);'
+ for arg in method.args:
+ if arg.output:
+ self.serializeArg(method, arg)
+ self.wrapArg(method, arg)
+ if riid is not None and isinstance(arg.type, Pointer):
+ if isinstance(arg.type.type, Opaque):
+ self.wrapIid(interface, method, riid, arg)
+ else:
+ assert isinstance(arg.type.type, Pointer)
+ assert isinstance(arg.type.type.type, Interface)
+
+ if method.type is not stdapi.Void:
+ print ' trace::localWriter.beginReturn();'
+ self.serializeValue(method.type, "__result")
+ print ' trace::localWriter.endReturn();'
+ self.wrapValue(method.type, '__result')
+ print ' trace::localWriter.endLeave();'
+ if method.name == 'Release':
+ assert method.type is not stdapi.Void
+ print ' if (!__result)'
+ print ' delete this;'
+
+ def wrapIid(self, interface, method, riid, out):
+ print ' if (%s && *%s) {' % (out.name, out.name)
+ print ' if (*%s == m_pInstance) {' % (out.name,)
+ print ' *%s = this;' % (out.name,)
+ print ' }'
+ for iface in self.api.getAllInterfaces():
+ print r' else if (%s == IID_%s) {' % (riid.name, iface.name)
+ print r' *%s = new Wrap%s((%s *) *%s);' % (out.name, iface.name, iface.name, out.name)
+ print r' }'
+ print r' else {'
+ print r' os::log("apitrace: warning: %s::%s: unknown IID {0x%08lX,0x%04X,0x%04X,{0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X,0x%02X}}\n",'
+ print r' "%s", "%s",' % (interface.name, method.name)
+ print r' %s.Data1, %s.Data2, %s.Data3,' % (riid.name, riid.name, riid.name)
+ print r' %s.Data4[0],' % (riid.name,)
+ print r' %s.Data4[1],' % (riid.name,)
+ print r' %s.Data4[2],' % (riid.name,)
+ print r' %s.Data4[3],' % (riid.name,)
+ print r' %s.Data4[4],' % (riid.name,)
+ print r' %s.Data4[5],' % (riid.name,)
+ print r' %s.Data4[6],' % (riid.name,)
+ print r' %s.Data4[7]);' % (riid.name,)
+ print r' }'
+ print ' }'
+
+ def invokeMethod(self, interface, base, method):
+ if method.type is stdapi.Void:
+ result = ''
+ else:
+ result = '__result = '
+ print ' %sstatic_cast<%s *>(m_pInstance)->%s(%s);' % (result, base, method.name, ', '.join([str(arg.name) for arg in method.args]))
+
+ def emit_memcpy(self, dest, src, length):
+ print ' unsigned __call = trace::localWriter.beginEnter(&trace::memcpy_sig);'
+ print ' trace::localWriter.beginArg(0);'
+ print ' trace::localWriter.writeOpaque(%s);' % dest
+ print ' trace::localWriter.endArg();'
+ print ' trace::localWriter.beginArg(1);'
+ print ' trace::localWriter.writeBlob(%s, %s);' % (src, length)
+ print ' trace::localWriter.endArg();'
+ print ' trace::localWriter.beginArg(2);'
+ print ' trace::localWriter.writeUInt(%s);' % length
+ print ' trace::localWriter.endArg();'
+ print ' trace::localWriter.endEnter();'
+ print ' trace::localWriter.beginLeave(__call);'
+ print ' trace::localWriter.endLeave();'
+
--- /dev/null
+##########################################################################
+#
+# Copyright 2008-2009 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.
+#
+##########################################################################/
+
+
+"""WGL tracing code generator."""
+
+
+from gltrace import GlTracer
+from dispatch import function_pointer_type, function_pointer_value
+from codegen import *
+from specs.stdapi import API
+from specs.glapi import glapi
+from specs.wglapi import wglapi
+
+
+class WglTracer(GlTracer):
+
+ def wrapRet(self, function, instance):
+ GlTracer.wrapRet(self, function, instance)
+
+ if function.name == "wglGetProcAddress":
+ print ' if (%s) {' % instance
+
+ func_dict = dict([(f.name, f) for f in glapi.functions + wglapi.functions])
+
+ def handle_case(function_name):
+ f = func_dict[function_name]
+ ptype = function_pointer_type(f)
+ pvalue = function_pointer_value(f)
+ print ' %s = (%s)%s;' % (pvalue, ptype, instance)
+ print ' %s = (%s)&%s;' % (instance, function.type, f.name);
+
+ def handle_default():
+ print ' os::log("apitrace: warning: unknown function \\"%s\\"\\n", lpszProc);'
+
+ string_switch('lpszProc', func_dict.keys(), handle_case, handle_default)
+ print ' }'
+
+
+if __name__ == '__main__':
+ print
+ print '#define _GDI32_'
+ print
+ print '#include <string.h>'
+ print '#include <windows.h>'
+ print
+ print '#include "trace_writer_local.hpp"'
+ print '#include "os.hpp"'
+ print
+ print '// To validate our prototypes'
+ print '#define GL_GLEXT_PROTOTYPES'
+ print '#define WGL_GLXEXT_PROTOTYPES'
+ print
+ print '#include "glproc.hpp"'
+ print '#include "glsize.hpp"'
+ print
+ api = API()
+ api.addApi(glapi)
+ api.addApi(wglapi)
+ tracer = WglTracer()
+ tracer.trace_api(api)