--- /dev/null
+set sw=4 ts=4 et
cmake_minimum_required (VERSION 2.8)
+
+# Use clang on MacOSX. gcc doesn't support __thread key, and Apple has
+# abandoned it for clang. This must be done before the project is defined.
+if (APPLE)
+ set (CMAKE_C_COMPILER "clang")
+ set (CMAKE_CXX_COMPILER "clang++")
+endif ()
+
+
project (apitrace)
##############################################################################
# Find dependencies
+# Ensure __thread is support
+if (NOT MSVC)
+ include (CheckCXXSourceCompiles)
+ check_cxx_source_compiles("__thread int i; int main() { return 0; }" HAVE_COMPILER_TLS)
+ if (NOT HAVE_COMPILER_TLS)
+ if (APPLE)
+ message (FATAL_ERROR "C++ compiler does not support __thread keyword. Please install XCode 4.5 or higher.")
+ else (MINGW32)
+ message (FATAL_ERROR "C++ compiler does not support __thread keyword. Please use MinGW g++ version 4.4 or higher")
+ else ()
+ message (FATAL_ERROR "C++ compiler does not support __thread keyword.")
+ endif ()
+ endif ()
+endif ()
+
set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
set (CMAKE_USE_PYTHON_VERSION 2.7 2.6)
set (REQUIRE_GUI REQUIRED)
endif ()
find_package (Qt4 4.7 COMPONENTS QtCore QtGui QtWebKit ${REQUIRE_GUI})
- find_package (QJSON ${REQUIRE_GUI})
endif ()
if (WIN32)
if (X11_FOUND)
include_directories (${X11_INCLUDE_DIR})
add_definitions (-DHAVE_X11)
+ else ()
+ # Print a clear message when X11 is not found
+ include (FindPackageMessage)
+ find_package_message (X11 "Could not find X11" "")
endif ()
endif ()
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -O0")
set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -ggdb")
endif ()
+
+ # Be nice to Eclipse
+ add_definitions (-fmessage-length=0)
endif ()
if (MINGW)
add_subdirectory (thirdparty/less)
endif ()
-# The Qt website provides binaries for Windows and MacOSX, and they are
-# automatically found by cmake without any manual intervention. The situation
-# for QJSON is substantially different: there are no binaries for QJSON
-# available, and there is no standard installation directory that is detected
-# by cmake.
-#
-# By bundling the QJSON source, we make it much more easier to build the GUI on
-# Windows and MacOSX. But we only use the bundled sources when ENABLE_GUI is
-# AUTO.
-if (QT4_FOUND AND NOT QJSON_FOUND AND (ENABLE_GUI STREQUAL "AUTO"))
+# Always use bundled QJSon.
+# - The packaged versions QJson are very old, and do not support NaN/Infinity.
+# - To make it easier to build the GUI on Windows and MacOSX, as there are no
+# binaries at all.
+if (QT4_FOUND)
+ add_definitions (-DQJSON_EXPORT=)
add_subdirectory (thirdparty/qjson EXCLUDE_FROM_ALL)
set (QJSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty)
set (QJSON_LIBRARY_DIRS)
common/trace_loader.cpp
common/trace_resource.cpp
common/trace_tools_trace.cpp
+ common/trace_profiler.cpp
common/image.cpp
common/image_bmp.cpp
common/image_pnm.cpp
The GUI also dependends on:
-* Qt version 4.7
+* Qt version 4.7 or higher (tested with version 4.8)
* QJSON version 0.5 or higher (tested with version 0.7.1, which is bundled)
-Qt and QJSON will be required if `-DENABLE_GUI=TRUE` is passed to `cmake`, and
-never used if `-DENABLED_GUI=FALSE` is passed instead. The implicit default is
+Qt and QJSON will be required if `-DENABLE_GUI=TRUE` is passed to CMake, and
+never used if `-DENABLE_GUI=FALSE` is passed instead. The implicit default is
`-DENABLE_GUI=AUTO`, which will build the GUI if Qt is available, using the
bundled QJSON if it is not found on the system.
cmake -H. -Bbuild
make -C build
-You can also build the 32bit GL wrapper on 64bit distro with a multilib gcc by
-doing:
- cmake -H. -Bbuild32 -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 -DENABLE_GUI=FALSE
+You can also build the 32-bits GL wrapper on a 64-bits distribution, provided
+you have a multilib gcc and 32-bits X11 libraries, by doing:
+
+ cmake \
+ -DCMAKE_C_FLAGS=-m32 \
+ -DCMAKE_CXX_FLAGS=-m32 \
+ -DCMAKE_EXE_LINKER_FLAGS=-m32 \
+ -DCMAKE_SYSTEM_LIBRARY_PATH=/usr/lib32 \
+ -DENABLE_GUI=FALSE \
+ -H. -Bbuild32
make -C build32 glxtrace
+The `/usr/lib32` refers to the path where the 32-bits shared objects are may
+differ depending on the actual Linux distribution.
+
+
Android
-------
To build with Visual Studio first invoke CMake GUI as:
- cmake-gui -H. -B%cd%\build
+ cmake-gui -H%cd% -B%cd%\build
and press the _Configure_ button.
dependencies from the CMake GUI.
After you've successfully configured, you can start the build by opening the
-generated `build\apitrace.sln` solution file, or invoking `cmake` as:
+generated `build\apitrace.sln` solution file, or invoking CMake as:
cmake --build build --config MinSizeRel
The steps to build 64bit version are similar, but choosing _Visual Studio 10
Win64_ instead of _Visual Studio 10_.
-It's also possible to instruct `cmake` build Windows binaries on Linux with
+It's also possible to instruct CMake build Windows binaries on Linux with
[MinGW cross compilers](http://www.cmake.org/Wiki/CmakeMingw).
-Copyright 2011 Jose Fonseca, Zack Rusin
-Copyright 2008-2010 VMware, Inc.
+Copyright 2007-2012 VMware, Inc.
+Copyright 2011 Intel Corporation
+Copyright 2011 LunarG, Inc.
+Copyright 2011 Zack Rusin
+Copyright 2011-2012 Jose Fonseca
+
All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-
* visualize and edit trace files.
+See the [apitrace homepage](http://apitrace.github.com/) for more details.
+
Obtaining **apitrace**
======================
glretrace application.trace
Pass the `-sb` option to use a single buffered visual. Pass `--help` to
-glretrace for more options.
+`glretrace` for more options.
+
+EGL traces must be replayed with `eglretrace` instead of `glretrace`.
Basic GUI usage
But beware of wrapper shell scripts -- what matters is the architecture of the
main process.
-Run the application you want to trace as
+Run the GLX application you want to trace as
- LD_PRELOAD=/path/to/apitrace/wrappers/glxtrace.so /path/to/application
+ LD_PRELOAD=/path/to/apitrace/wrappers/glxtrace.so /path/to/application
and it will generate a trace named `application.trace` in the current
directory. You can specify the written trace filename by setting the
`TRACE_FILE` environment variable before running.
-The `LD_PRELOAD` mechanism should work with most applications. There are some
-applications, e.g., Unigine Heaven, which global function pointers with the
-same name as GL entrypoints, living in a shared object that wasn't linked with
-`-Bsymbolic` flag, so relocations to those globals function pointers get
-overwritten with the address to our wrapper library, and the application will
-segfault when trying to write to them. For these applications it is possible
-to trace by using `glxtrace.so` as an ordinary `libGL.so` and injecting into
-`LD_LIBRARY_PATH`:
+For EGL applications you will need to use `egltrace.so` instead of
+`glxtrace.so`.
+
+The `LD_PRELOAD` mechanism should work with the majority applications. There
+are some applications (e.g., Unigine Heaven, Android GPU emulator, etc.), that
+have global function pointers with the same name as GL entrypoints, living in a
+shared object that wasn't linked with `-Bsymbolic` flag, so relocations to
+those globals function pointers get overwritten with the address to our wrapper
+library, and the application will segfault when trying to write to them. For
+these applications it is possible to trace by using `glxtrace.so` as an
+ordinary `libGL.so` and injecting it via `LD_LIBRARY_PATH`:
ln -s glxtrace.so wrappers/libGL.so
ln -s glxtrace.so wrappers/libGL.so.1
export TRACE_LIBGL=/path/to/real/libGL.so.1
/path/to/application
+If you are an application developer, you can avoid this either by linking with
+`-Bsymbolic` flag, or by using some unique prefix for your function pointers.
+
See the `ld.so` man page for more information about `LD_PRELOAD` and
`LD_LIBRARY_PATH` environment flags.
For standalone applications the instructions above for Linux should
work. To trace applications started from within the Android VM process
-(app_process aka zygote) you'll have to wrap this process and enable
+(`app_process` aka zygote) you'll have to wrap this process and enable
tracing dynamically for the application to be traced.
- Wrapping the android main VM process:
- In the Android root /init.rc add the LD_PRELOAD setting to zygote's
+ In the Android root /init.rc add the `LD_PRELOAD` setting to zygote's
environment in the 'service zygote' section:
- """
- service zygote ...
- setenv LD_PRELOAD /data/egltrace.so
- ...
- """
+ service zygote ...
+ setenv LD_PRELOAD /data/egltrace.so
+ ...
Note that ICS will overwrite the /init.rc during each boot with the
version in the recovery image. So you'll have to change the file in
your ICS source tree, rebuild and reflash the device.
Rebuilding/reflashing only the recovery image should be sufficient.
-
- Copy egltrace.so to /data
On the host:
- $ adb push /path/to/apitrace/build/wrappers/egltrace.so /data
+ adb push /path/to/apitrace/build/wrappers/egltrace.so /data
- Adjust file permissions to store the trace file:
By default egltrace.so will store the trace in
- /data/app_process.trace. For this to work for applications running
- with a uid other than 0, you have to allow writes to the /data
+ `/data/app_process.trace`. For this to work for applications running
+ with a uid other than 0, you have to allow writes to the `/data`
directory on the device:
- # chmod 0777 /data
-
+ chmod 0777 /data
- Enable tracing for a specific process name:
To trace for example the Settings application:
- # setprop debug.apitrace.procname com.android.settings
- In general this name will match what 'ps' reports.
+ setprop debug.apitrace.procname com.android.settings
+ In general this name will match what `ps` reports.
- Start the application:
of pre-starting the apps, you might have to kill the application
first:
- # kill <pid of app>
+ kill <pid of app>
Launch the application for example from the application menu.
extension.
-For Direct3D applications you can follow the same procedure used for
-[instrumenting an application for PIX](http://technet.microsoft.com/en-us/query/ee417250)
+For Direct3D applications you can follow the standard procedure for
+[adding user defined events to Visual Studio Graphics Debugger / PIX](http://msdn.microsoft.com/en-us/library/vstudio/hh873200.aspx):
+
+- `D3DPERF_BeginEvent`, `D3DPERF_EndEvent`, and `D3DPERF_SetMarker` for D3D9 applications.
+
+- `ID3DUserDefinedAnnotation::BeginEvent`,
+ `ID3DUserDefinedAnnotation::EndEvent`, and
+ `ID3DUserDefinedAnnotation::SetMarker` for D3D11.1 applications.
Dump GL state at a particular call
| ffmpeg -r 30 -f image2pipe -vcodec ppm -i pipe: -vcodec mpeg4 -y output.mp4
-Triming a trace
----------------
+Trimming a trace
+----------------
You can make a smaller trace by doing:
section above.
+Profiling a trace
+-----------------
+
+You can perform gpu and cpu profiling with the command line options:
+
+ * `-pgpu` record gpu times for frames and draw calls.
+
+ * `-pcpu` record cpu times for frames and draw calls.
+
+ * `-ppd` record pixels drawn for each draw call.
+
+The results from this can then be read by hand or analysed with a script.
+
+`scripts/profileshader.py` will read the profile results and format them into a
+table which displays profiling results per shader.
+
+For example, to record all profiling data and utilise the per shader script:
+
+ ./glretrace -pgpu -pcpu -ppd foo.trace | ./scripts/profileshader.py
+
+
Advanced usage for OpenGL implementors
======================================
python scripts\retracediff.py --retrace \path\to\glretrace.exe --ref-env TRACE_LIBGL=\path\to\reference\opengl32.dll application.trace
-Links
-=====
-
-About **apitrace**:
-
-* [Official mailing list](http://lists.freedesktop.org/mailman/listinfo/apitrace)
-
-* [Zack Rusin's blog introducing the GUI](http://zrusin.blogspot.com/2011/04/apitrace.html)
-
-* [Jose's Fonseca blog introducing the tool](http://jrfonseca.blogspot.com/2008/07/tracing-d3d-applications.html)
-
-
-Direct3D
---------
-
-Open-source:
-
-* [Proxy DLL](http://www.mikoweb.eu/index.php?node=21)
-
- * [Intercept Calls to DirectX with a Proxy DLL](http://www.codeguru.com/cpp/g-m/directx/directx8/article.php/c11453/)
-
-* [Direct3D 9 API Interceptor](http://graphics.stanford.edu/~mdfisher/D3D9Interceptor.html)
-
-Closed-source:
-
-* [Microsoft PIX](http://msdn.microsoft.com/en-us/library/ee417062.aspx)
-
- * [D3DSpy](http://doc.51windows.net/Directx9_SDK/?url=/directx9_sdk/graphics/programmingguide/TutorialsAndSamplesAndToolsAndTips/Tools/D3DSpy.htm): the predecessor of PIX
-
-* [NVIDIA PerfKit](http://developer.nvidia.com/nvidia-perfkit)
-
-* [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)
-
-* [Intel Graphics Performance Analyzers](http://www.intel.com/software/gpa/)
-
-
-OpenGL
-------
-
-Open-source:
-
-* [BuGLe](http://www.opengl.org/sdk/tools/BuGLe/)
-
-* [GLIntercept](http://code.google.com/p/glintercept/)
-
-* [tracy](https://gitorious.org/tracy): OpenGL ES and OpenVG trace, retrace, and state inspection
-
-* [WebGL-Inspector](http://benvanik.github.com/WebGL-Inspector/)
-
-Closed-source:
-
-* [gDEBugger](http://www.gremedy.com/products.php) and [AMD gDEBugger](http://developer.amd.com/tools/gDEBugger/Pages/default.aspx)
-
-* [glslDevil](http://cumbia.informatik.uni-stuttgart.de/glsldevil/index.html)
-
-* [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)
-
+[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/c1062ad633aa7a458e9d7520021307e4 "githalytics.com")](http://githalytics.com/apitrace/apitrace)
+++ /dev/null
-# Find QJSON - JSON handling library for Qt
-#
-# This module defines
-# QJSON_FOUND - whether the qsjon library was found
-# QJSON_LIBRARIES - the qjson library
-# QJSON_INCLUDE_DIR - the include path of the qjson library
-#
-
-if (QJSON_INCLUDE_DIR AND QJSON_LIBRARIES)
-
- # Already in cache
- set (QJSON_FOUND TRUE)
-
-else (QJSON_INCLUDE_DIR AND QJSON_LIBRARIES)
-
- if (NOT WIN32)
- # use pkg-config to get the values of QJSON_INCLUDE_DIRS
- # and QJSON_LIBRARY_DIRS to add as hints to the find commands.
- include (FindPkgConfig)
- pkg_check_modules (PC_QJSON QJson>=0.5)
- endif (NOT WIN32)
-
- find_library (QJSON_LIBRARIES
- NAMES
- qjson
- PATHS
- ${PC_QJSON_LIBRARY_DIRS}
- ${LIB_INSTALL_DIR}
- ${KDE4_LIB_DIR}
- )
-
- find_path (QJSON_INCLUDE_DIR
- NAMES
- qjson/parser.h
- PATHS
- ${PC_QJSON_INCLUDE_DIRS}
- ${INCLUDE_INSTALL_DIR}
- ${KDE4_INCLUDE_DIR}
- )
-
- include(FindPackageHandleStandardArgs)
- find_package_handle_standard_args(QJSON DEFAULT_MSG QJSON_LIBRARIES QJSON_INCLUDE_DIR)
-
-endif (QJSON_INCLUDE_DIR AND QJSON_LIBRARIES)
# ------------------------------------------------------------------------------
-# Android CMake toolchain file, for use with the Android NDK r5-r7
-# Requires cmake 2.6.3 or newer (2.8.3 or newer is recommended).
+# Android CMake toolchain file, for use with the Android NDK r5-r8
+# Requires cmake 2.6.3 or newer (2.8.5 or newer is recommended).
# See home page: http://code.google.com/p/android-cmake/
#
# The file is mantained by the OpenCV project. And also can be found at
-# http://code.opencv.org/svn/opencv/trunk/opencv/android/android.toolchain.cmake
+# http://code.opencv.org/projects/opencv/repository/revisions/master/changes/android/android.toolchain.cmake
#
# Usage Linux:
# $ export ANDROID_NDK=/absolute/path/to/the/android-ndk
#
# Usage Windows:
# You need native port of make to build your project.
-# Android NDK r7 already has make.exe on board.
+# Android NDK r7 (or newer) already has make.exe on board.
# For older NDK you have to install it separately.
# For example, this one: http://gnuwin32.sourceforge.net/packages/make.htm
#
# ANDROID_NDK=/opt/android-ndk - path to the NDK root.
# Can be set as environment variable. Can be set only at first cmake run.
#
-# ANDROID_STANDALONE_TOOLCHAIN=/opt/android-toolchain - path to the
+# ANDROID_STANDALONE_TOOLCHAIN=/opt/android-toolchain - path to the
# standalone toolchain. This option is not used if full NDK is found
# (ignored if ANDROID_NDK is set).
# Can be set as environment variable. Can be set only at first cmake run.
#
# ANDROID_ABI=armeabi-v7a - specifies the target Application Binary
-# Interface (ABI). This option nearly matches to the APP_ABI variable
+# Interface (ABI). This option nearly matches to the APP_ABI variable
# used by ndk-build tool from Android NDK.
-# Possible values are:
+#
+# Possible targets are:
# "armeabi" - matches to the NDK ABI with the same name.
# See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation.
# "armeabi-v7a" - matches to the NDK ABI with the same name.
# sets VFPV3 as floating-point unit (has 32 registers instead of 16).
# "armeabi-v6 with VFP" - tuned for ARMv6 processors having VFP.
# "x86" - matches to the NDK ABI with the same name.
-# See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation.
+# See ${ANDROID_NDK}/docs/CPU-ARCH-ABIS.html for the documentation.
+# "mips" - matches to the NDK ABI with the same name
+# (not testes on real devices)
#
# ANDROID_NATIVE_API_LEVEL=android-8 - level of Android API compile for.
# Option is read-only when standalone toolchain used.
# The flags will be prepopulated with critical flags, so don't loose them.
# Also be aware that toolchain also sets configuration-specific compiler
# flags and linker flags.
-#
-# ANDROID and BUILD_ANDROID will be set to true, you may test any of these
+#
+# ANDROID and BUILD_ANDROID will be set to true, you may test any of these
# variables to make necessary Android-specific configuration changes.
-#
+#
# Also ARMEABI or ARMEABI_V7A or X86 will be set true, mutually exclusive.
# NEON option will be set true if VFP is set to NEON.
#
# under the ${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}
# (depending on the target ABI). This is convenient for Android packaging.
#
+# Authors:
+# Ethan Rublee ethan.ruble@gmail.com
+# Andrey Kamaev andrey.kamaev@itseez.com
#
# Change Log:
-# - initial version December 2010 Ethan Rublee ethan.ruble@gmail.com
-# - modified April 2011 Andrey Kamaev andrey.kamaev@itseez.com
+# - initial version December 2010
+# - modified April 2011
# [+] added possibility to build with NDK (without standalone toolchain)
# [+] support cross-compilation on Windows (native, no cygwin support)
# [+] added compiler option to force "char" type to be signed
# [+] EXECUTABLE_OUTPUT_PATH is set by toolchain (required on Windows)
# [~] Fixed bug with ANDROID_API_LEVEL variable
# [~] turn off SWIG search if it is not found first time
-# - modified May 2011 Andrey Kamaev andrey.kamaev@itseez.com
+# - modified May 2011
# [~] ANDROID_LEVEL is renamed to ANDROID_API_LEVEL
# [+] ANDROID_API_LEVEL is detected by toolchain if not specified
# [~] added guard to prevent changing of output directories on the first
# cmake pass
# [~] toolchain exits with error if ARM_TARGET is not recognized
-# - modified June 2011 Andrey Kamaev andrey.kamaev@itseez.com
-# [~] default NDK path is updated for version r5c
+# - modified June 2011
+# [~] default NDK path is updated for version r5c
# [+] variable CMAKE_SYSTEM_PROCESSOR is set based on ARM_TARGET
# [~] toolchain install directory is added to linker paths
# [-] removed SWIG-related stuff from toolchain
# [+] added macro find_host_package, find_host_program to search
# packages/programs on the host system
# [~] fixed path to STL library
-# - modified July 2011 Andrey Kamaev andrey.kamaev@itseez.com
+# - modified July 2011
# [~] fixed options caching
# [~] search for all supported NDK versions
# [~] allowed spaces in NDK path
-# - modified September 2011 Andrey Kamaev andrey.kamaev@itseez.com
+# - modified September 2011
# [~] updated for NDK r6b
-# - modified November 2011 Andrey Kamaev andrey.kamaev@itseez.com
+# - modified November 2011
# [*] rewritten for NDK r7
# [+] x86 toolchain support (experimental)
# [+] added "armeabi-v6 with VFP" ABI for ARMv6 processors.
# [~] ARM_TARGET is renamed to ANDROID_ABI
# [~] ARMEABI_NDK_NAME is renamed to ANDROID_NDK_ABI_NAME
# [~] ANDROID_API_LEVEL is renamed to ANDROID_NATIVE_API_LEVEL
-# - modified January 2012 Andrey Kamaev andrey.kamaev@itseez.com
+# - modified January 2012
# [+] added stlport_static support (experimental)
# [+] added special check for cygwin
# [+] filtered out hidden files (starting with .) while globbing inside NDK
# [+] automatically applied GLESv2 linkage fix for NDK revisions 5-6
# [+] added ANDROID_GET_ABI_RAWNAME to get NDK ABI names by CMake flags
-# - modified February 2012 Andrey Kamaev andrey.kamaev@itseez.com
+# - modified February 2012
# [+] updated for NDK r7b
# [~] fixed cmake try_compile() command
# [~] Fix for missing install_name_tool on OS X
+# - modified March 2012
+# [~] fixed incorrect C compiler flags
+# [~] fixed CMAKE_SYSTEM_PROCESSOR change on ANDROID_ABI change
+# [+] improved toolchain loading speed
+# [+] added assembler language support (.S)
+# [+] allowed preset search paths and extra search suffixes
+# - modified April 2012
+# [+] updated for NDK r7c
+# [~] fixed most of problems with compiler/linker flags and caching
+# [+] added option ANDROID_FUNCTION_LEVEL_LINKING
+# - modified May 2012
+# [+] updated for NDK r8
+# [+] added mips architecture support
+# - modified August 2012
+# [+] updated for NDK r8b
+# [~] all intermediate files generated by toolchain are moved into CMakeFiles
+# [~] libstdc++ and libsupc are removed from explicit link libraries
# ------------------------------------------------------------------------------
cmake_minimum_required( VERSION 2.6.3 )
-if( PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" )
+if( DEFINED CMAKE_CROSSCOMPILING )
+ # subsequent toolchain loading is not really needed
+ return()
+endif()
+
+get_property(_CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)
+if( _CMAKE_IN_TRY_COMPILE )
include( "${CMAKE_CURRENT_SOURCE_DIR}/../android.toolchain.config.cmake" OPTIONAL )
endif()
# this one is important
set( CMAKE_SYSTEM_NAME Linux )
-#this one not so much
+# this one not so much
set( CMAKE_SYSTEM_VERSION 1 )
-set( ANDROID_SUPPORTED_NDK_VERSIONS -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
-if( CMAKE_HOST_WIN32 )
- file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS )
- set( ANDROID_NDK_SEARCH_PATHS "${ANDROID_NDK_SEARCH_PATHS}/android-ndk" "$ENV{SystemDrive}/NVPACK/android-ndk" )
-else()
- set( ANDROID_NDK_SEARCH_PATHS /opt/android-ndk "$ENV{HOME}/NVPACK/android-ndk" )
+set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" )
+if(NOT DEFINED ANDROID_NDK_SEARCH_PATHS)
+ if( CMAKE_HOST_WIN32 )
+ file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS )
+ set( ANDROID_NDK_SEARCH_PATHS "${ANDROID_NDK_SEARCH_PATHS}/android-ndk" "$ENV{SystemDrive}/NVPACK/android-ndk" )
+ else()
+ file( TO_CMAKE_PATH "$ENV{HOME}" ANDROID_NDK_SEARCH_PATHS )
+ set( ANDROID_NDK_SEARCH_PATHS /opt/android-ndk "${ANDROID_NDK_SEARCH_PATHS}/NVPACK/android-ndk" )
+ endif()
endif()
-set( ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH /opt/android-toolchain )
+if(NOT DEFINED ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH)
+ set( ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH /opt/android-toolchain )
+endif()
+
set( ANDROID_SUPPORTED_ABIS_arm "armeabi-v7a;armeabi;armeabi-v7a with NEON;armeabi-v7a with VFPV3;armeabi-v6 with VFP" )
set( ANDROID_SUPPORTED_ABIS_x86 "x86" )
+set( ANDROID_SUPPORTED_ABIS_mipsel "mips" )
set( ANDROID_DEFAULT_NDK_API_LEVEL 8 )
set( ANDROID_DEFAULT_NDK_API_LEVEL_x86 9 )
+set( ANDROID_DEFAULT_NDK_API_LEVEL_mips 9 )
macro( __LIST_FILTER listvar regex )
endmacro()
-#stl version: by default gnustl_static will be used
+# stl version: by default gnustl_static will be used
set( ANDROID_USE_STLPORT FALSE CACHE BOOL "Experimental: use stlport_static instead of gnustl_static")
mark_as_advanced( ANDROID_USE_STLPORT )
-#fight against cygwin
+# fight against cygwin
set( ANDROID_FORBID_SYGWIN TRUE CACHE BOOL "Prevent cmake from working under cygwin and using cygwin tools")
mark_as_advanced( ANDROID_FORBID_SYGWIN )
if( ANDROID_FORBID_SYGWIN )
endif()
if( CMAKE_HOST_WIN32 )
- #remove cygwin from PATH
+ # remove cygwin from PATH
set( __new_path "$ENV{PATH}")
__LIST_FILTER( __new_path "cygwin" )
set(ENV{PATH} "${__new_path}")
endif()
endif()
-#detect current host platform
+# detect current host platform
set( TOOL_OS_SUFFIX "" )
if( CMAKE_HOST_APPLE )
set( ANDROID_NDK_HOST_SYSTEM_NAME "darwin-x86" )
message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" )
endif()
-#see if we have path to Android NDK
+# see if we have path to Android NDK
__INIT_VARIABLE( ANDROID_NDK PATH ENV_ANDROID_NDK )
if( NOT ANDROID_NDK )
- #see if we have path to Android standalone toolchain
+ # see if we have path to Android standalone toolchain
__INIT_VARIABLE( ANDROID_STANDALONE_TOOLCHAIN PATH ENV_ANDROID_STANDALONE_TOOLCHAIN OBSOLETE_ANDROID_NDK_TOOLCHAIN_ROOT OBSOLETE_ENV_ANDROID_NDK_TOOLCHAIN_ROOT )
if( NOT ANDROID_STANDALONE_TOOLCHAIN )
endif( NOT ANDROID_STANDALONE_TOOLCHAIN )
endif( NOT ANDROID_NDK )
-#remember found paths
+# remember found paths
if( ANDROID_NDK )
get_filename_component( ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE )
- #try to detect change
+ # try to detect change
if( CMAKE_AR )
string( LENGTH "${ANDROID_NDK}" __length )
string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidNdkPreviousPath )
set( BUILD_WITH_ANDROID_NDK True )
elseif( ANDROID_STANDALONE_TOOLCHAIN )
get_filename_component( ANDROID_STANDALONE_TOOLCHAIN "${ANDROID_STANDALONE_TOOLCHAIN}" ABSOLUTE )
- #try to detect change
+ # try to detect change
if( CMAKE_AR )
string( LENGTH "${ANDROID_STANDALONE_TOOLCHAIN}" __length )
string( SUBSTRING "${CMAKE_AR}" 0 ${__length} __androidStandaloneToolchainPreviousPath )
sudo ln -s ~/my-android-toolchain ${ANDROID_STANDALONE_TOOLCHAIN_SEARCH_PATH}" )
endif()
-#get all the details about standalone toolchain
+# get all the details about standalone toolchain
if( BUILD_WITH_STANDALONE_TOOLCHAIN )
__DETECT_NATIVE_API_LEVEL( ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot/usr/include/android/api-level.h" )
+ set( ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
set( __availableToolchains "standalone" )
__DETECT_TOOLCHAIN_MACHINE_NAME( __availableToolchainMachines "${ANDROID_STANDALONE_TOOLCHAIN}" )
if( NOT __availableToolchainMachines )
set( __availableToolchainArchs "x86" )
elseif( __availableToolchainMachines MATCHES arm )
set( __availableToolchainArchs "arm" )
+ elseif( __availableToolchainMachines MATCHES mipsel )
+ set( __availableToolchainArchs "mipsel" )
endif()
if( ANDROID_COMPILER_VERSION )
- #do not run gcc every time because it is relatevely expencive
+ # do not run gcc every time because it is relatevely expencive
set( __availableToolchainCompilerVersions "${ANDROID_COMPILER_VERSION}" )
else()
execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" --version
endif()
endif()
-#get all the details about NDK
+# get all the details about NDK
if( BUILD_WITH_ANDROID_NDK )
file( GLOB ANDROID_SUPPORTED_NATIVE_API_LEVELS RELATIVE "${ANDROID_NDK}/platforms" "${ANDROID_NDK}/platforms/android-*" )
string( REPLACE "android-" "" ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_SUPPORTED_NATIVE_API_LEVELS}" )
foreach( __toolchain ${__availableToolchains} )
__DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" )
if( __machine )
- string( REGEX MATCH "[0-9]+.[0-9]+.[0-9]+$" __version "${__toolchain}" )
+ string( REGEX MATCH "[0-9]+[.][0-9]+[.]*[0-9]*$" __version "${__toolchain}" )
string( REGEX MATCH "^[^-]+" __arch "${__toolchain}" )
- list( APPEND __availableToolchainMachines ${__machine} )
- list( APPEND __availableToolchainArchs ${__arch} )
- list( APPEND __availableToolchainCompilerVersions ${__version} )
+ list( APPEND __availableToolchainMachines "${__machine}" )
+ list( APPEND __availableToolchainArchs "${__arch}" )
+ list( APPEND __availableToolchainCompilerVersions "${__version}" )
else()
list( REMOVE_ITEM __availableToolchains "${__toolchain}" )
endif()
endif()
endif()
-#build list of available ABIs
+# build list of available ABIs
if( NOT ANDROID_SUPPORTED_ABIS )
set( ANDROID_SUPPORTED_ABIS "" )
set( __uniqToolchainArchNames ${__availableToolchainArchs} )
endif()
endif()
-#choose target ABI
+# choose target ABI
__INIT_VARIABLE( ANDROID_ABI OBSOLETE_ARM_TARGET OBSOLETE_ARM_TARGETS VALUES ${ANDROID_SUPPORTED_ABIS} )
-#verify that target ABI is supported
+# verify that target ABI is supported
list( FIND ANDROID_SUPPORTED_ABIS "${ANDROID_ABI}" __androidAbiIdx )
if( __androidAbiIdx EQUAL -1 )
string( REPLACE ";" "\", \"", PRINTABLE_ANDROID_SUPPORTED_ABIS "${ANDROID_SUPPORTED_ABIS}" )
endif()
unset( __androidAbiIdx )
-#remember target ABI
+# remember target ABI
set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE )
-#set target ABI options
+# set target ABI options
if( ANDROID_ABI STREQUAL "x86" )
set( X86 true )
set( ANDROID_NDK_ABI_NAME "x86" )
set( ANDROID_ARCH_NAME "x86" )
+ set( ANDROID_ARCH_FULLNAME "x86" )
set( CMAKE_SYSTEM_PROCESSOR "i686" )
+elseif( ANDROID_ABI STREQUAL "mips" )
+ set( MIPS true )
+ set( ANDROID_NDK_ABI_NAME "mips" )
+ set( ANDROID_ARCH_NAME "mips" )
+ set( ANDROID_ARCH_FULLNAME "mipsel" )
+ set( CMAKE_SYSTEM_PROCESSOR "mips" )
elseif( ANDROID_ABI STREQUAL "armeabi" )
set( ARMEABI true )
set( ANDROID_NDK_ABI_NAME "armeabi" )
set( ANDROID_ARCH_NAME "arm" )
+ set( ANDROID_ARCH_FULLNAME "arm" )
set( CMAKE_SYSTEM_PROCESSOR "armv5te" )
elseif( ANDROID_ABI STREQUAL "armeabi-v6 with VFP" )
set( ARMEABI_V6 true )
set( ANDROID_NDK_ABI_NAME "armeabi" )
set( ANDROID_ARCH_NAME "arm" )
+ set( ANDROID_ARCH_FULLNAME "arm" )
set( CMAKE_SYSTEM_PROCESSOR "armv6" )
- #need always fallback to older platform
+ # need always fallback to older platform
set( ARMEABI true )
elseif( ANDROID_ABI STREQUAL "armeabi-v7a")
set( ARMEABI_V7A true )
set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
set( ANDROID_ARCH_NAME "arm" )
+ set( ANDROID_ARCH_FULLNAME "arm" )
set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
elseif( ANDROID_ABI STREQUAL "armeabi-v7a with VFPV3" )
set( ARMEABI_V7A true )
set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
set( ANDROID_ARCH_NAME "arm" )
+ set( ANDROID_ARCH_FULLNAME "arm" )
set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
set( VFPV3 true )
elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" )
set( ARMEABI_V7A true )
set( ANDROID_NDK_ABI_NAME "armeabi-v7a" )
set( ANDROID_ARCH_NAME "arm" )
+ set( ANDROID_ARCH_FULLNAME "arm" )
set( CMAKE_SYSTEM_PROCESSOR "armv7-a" )
set( VFPV3 true )
set( NEON true )
message( SEND_ERROR "Unknown ANDROID_ABI=\"${ANDROID_ABI}\" is specified." )
endif()
-set( ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_NAME}} CACHE INTERNAL "ANDROID_ABI can be changed only to one of these ABIs. Changing to any other ABI requires to reset cmake cache." )
+if( CMAKE_BINARY_DIR AND EXISTS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" )
+ # really dirty hack
+ # it is not possible to change CMAKE_SYSTEM_PROCESSOR after the first run...
+ file( APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" "SET(CMAKE_SYSTEM_PROCESSOR \"${CMAKE_SYSTEM_PROCESSOR}\")\n" )
+endif()
+
+set( ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} CACHE INTERNAL "ANDROID_ABI can be changed only to one of these ABIs. Changing to any other ABI requires to reset cmake cache." )
if( CMAKE_VERSION VERSION_GREATER "2.8" )
- list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_NAME} )
- set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_NAME}} )
+ list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME} )
+ set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} )
endif()
if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 )
unset( ANDROID_FORCE_ARM_BUILD CACHE )
endif()
-#choose toolchain
+# choose toolchain
if( ANDROID_TOOLCHAIN_NAME )
list( FIND __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" __toolchainIdx )
if( __toolchainIdx EQUAL -1 )
message( FATAL_ERROR "Previously selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing. You need to remove CMakeCache.txt and rerun cmake manually to change the toolchain" )
endif()
list( GET __availableToolchainArchs ${__toolchainIdx} __toolchainArch )
- if( NOT __toolchainArch STREQUAL ANDROID_ARCH_NAME )
+ if( NOT __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME )
message( SEND_ERROR "Previously selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." )
endif()
else()
math( EXPR __availableToolchainsCount "${__availableToolchainsCount}-1" )
foreach( __idx RANGE ${__availableToolchainsCount} )
list( GET __availableToolchainArchs ${__idx} __toolchainArch )
- if( __toolchainArch STREQUAL ANDROID_ARCH_NAME )
+ if( __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME )
list( GET __availableToolchainCompilerVersions ${__idx} __toolchainVersion )
if( __toolchainVersion VERSION_GREATER __toolchainMaxVersion )
set( __toolchainMaxVersion "${__toolchainVersion}" )
unset( __availableToolchainArchs )
unset( __availableToolchainCompilerVersions )
-#choose native API level
-__INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL )
+# choose native API level
+__INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL )
string( REGEX MATCH "[0-9]+" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" )
-#validate
+# validate
list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx )
if( __levelIdx EQUAL -1 )
message( SEND_ERROR "Specified Android native API level (${ANDROID_NATIVE_API_LEVEL}) is not supported by your NDK/toolchain." )
set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} )
endif()
-#setup paths
+# setup paths
if( BUILD_WITH_STANDALONE_TOOLCHAIN )
set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" )
set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" )
set( __stlIncludePath "${ANDROID_NDK}/sources/cxx-stl/stlport/stlport" )
set( __stlLibPath "${ANDROID_NDK}/sources/cxx-stl/stlport/libs/${ANDROID_NDK_ABI_NAME}" )
else()
- set( __stlIncludePath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/include" )
- set( __stlLibPath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}" )
+ if( EXISTS "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}" )
+ set( __stlIncludePath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/include" )
+ set( __stlLibPath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_COMPILER_VERSION}/libs/${ANDROID_NDK_ABI_NAME}" )
+ else()
+ set( __stlIncludePath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/include" )
+ set( __stlLibPath "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}" )
+ endif()
endif()
endif()
# specify the cross compiler
set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "gcc" )
set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "g++" )
+set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "Assembler" )
+if( CMAKE_VERSION VERSION_LESS 2.8.5 )
+ set( CMAKE_ASM_COMPILER_ARG1 "-c" )
+endif()
+# there may be a way to make cmake deduce these TODO deduce the rest of the tools
set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" )
-#there may be a way to make cmake deduce these TODO deduce the rest of the tools
set( CMAKE_AR "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" )
set( CMAKE_LINKER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ld${TOOL_OS_SUFFIX}" CACHE PATH "linker" )
set( CMAKE_NM "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-nm${TOOL_OS_SUFFIX}" CACHE PATH "nm" )
set( CMAKE_OBJCOPY "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" )
set( CMAKE_OBJDUMP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump" )
set( CMAKE_RANLIB "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-ranlib${TOOL_OS_SUFFIX}" CACHE PATH "ranlib" )
+set( _CMAKE_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_MACHINE_NAME}-" )
if( APPLE )
find_program( CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool )
if( NOT CMAKE_INSTALL_NAME_TOOL )
endif()
mark_as_advanced( CMAKE_INSTALL_NAME_TOOL )
endif()
-#export directories
+
+# export directories
set( ANDROID_SYSTEM_INCLUDE_DIRS "" )
set( ANDROID_SYSTEM_LIB_DIRS "" )
-#setup output directories
-set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" )
-set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
-
-set( DO_NOT_CHANGE_OUTPUT_PATHS_ON_FIRST_PASS OFF CACHE BOOL "" )
-if( DO_NOT_CHANGE_OUTPUT_PATHS_ON_FIRST_PASS )
- if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" )
- set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" )
- else()
- set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" )
- endif()
- set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" )
-endif()
-set( DO_NOT_CHANGE_OUTPUT_PATHS_ON_FIRST_PASS ON CACHE INTERNAL "" FORCE )
-
-#includes
+# XXX: commented for apitrace
+## setup output directories
+#set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" )
+#set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
+#
+#if(NOT _CMAKE_IN_TRY_COMPILE)
+# if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" )
+# set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" )
+# else()
+# set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" )
+# endif()
+# set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" )
+#endif()
+
+# includes
list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_SYSROOT}/usr/include" )
if( __stlIncludePath AND EXISTS "${__stlIncludePath}" )
list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${__stlIncludePath}" )
endif()
-#STL bits includes
+# c++ bits includes
if( __stlLibPath AND EXISTS "${__stlLibPath}/include" )
list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${__stlLibPath}/include" )
endif()
list( APPEND ANDROID_SYSTEM_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" )
endif()
-#flags and definitions
+# flags and definitions
if(ANDROID_SYSROOT MATCHES "[ ;\"]")
set( ANDROID_CXX_FLAGS "--sysroot=\"${ANDROID_SYSROOT}\"" )
# quotes will break try_compile and compiler identification
# Force set compilers because standard identification works badly for us
include( CMakeForceCompiler )
CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU )
-CMAKE_FORCE_CXX_COMPILER( "${CMAKE_CXX_COMPILER}" GNU )
-set( CMAKE_SIZEOF_VOID_P 4 )
+set( CMAKE_C_PLATFORM_ID Linux )
set( CMAKE_C_SIZEOF_DATA_PTR 4 )
+set( CMAKE_C_HAS_ISYSROOT 1 )
+set( CMAKE_C_COMPILER_ABI ELF )
+CMAKE_FORCE_CXX_COMPILER( "${CMAKE_CXX_COMPILER}" GNU )
+set( CMAKE_CXX_PLATFORM_ID Linux )
set( CMAKE_CXX_SIZEOF_DATA_PTR 4 )
+set( CMAKE_CXX_HAS_ISYSROOT 1 )
+set( CMAKE_CXX_COMPILER_ABI ELF )
+# force ASM compiler (required for CMake < 2.8.5)
+set( CMAKE_ASM_COMPILER_ID_RUN TRUE )
+set( CMAKE_ASM_COMPILER_ID GNU )
+set( CMAKE_ASM_COMPILER_WORKS TRUE )
+set( CMAKE_ASM_COMPILER_FORCED TRUE )
+set( CMAKE_COMPILER_IS_GNUASM 1)
# NDK flags
if( ARMEABI OR ARMEABI_V7A )
# NDK also defines -ffunction-sections -funwind-tables but they result in worse OpenCV performance
- set( CMAKE_CXX_FLAGS "-fPIC -Wno-psabi" )
- set( CMAKE_C_FLAGS "-fPIC -Wno-psabi" )
- if( ANDROID_USE_STLPORT )
- set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions" )
- set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions" )
- else()
- set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti -fexceptions" )
- set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexceptions" )
- endif()
+ set( _CMAKE_CXX_FLAGS "-fPIC -Wno-psabi" )
+ set( _CMAKE_C_FLAGS "-fPIC -Wno-psabi" )
remove_definitions( -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ )
add_definitions( -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ )
# extra arm-specific flags
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" )
elseif( X86 )
- set( CMAKE_CXX_FLAGS "-ffunction-sections -funwind-tables" )
- set( CMAKE_C_FLAGS "-ffunction-sections -funwind-tables" )
- if( ANDROID_USE_STLPORT )
- set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions" )
- set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions" )
- else()
- set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -frtti -fexceptions" )
- set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexceptions" )
- endif()
+ set( _CMAKE_CXX_FLAGS "-funwind-tables" )
+ set( _CMAKE_C_FLAGS "-funwind-tables" )
+elseif( MIPS )
+ set( _CMAKE_CXX_FLAGS "-fpic -Wno-psabi -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" )
+ set( _CMAKE_CXX_FLAGS "-fpic -Wno-psabi -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers" )
+ set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fsigned-char" )
+else()
+ set( _CMAKE_CXX_FLAGS "" )
+ set( _CMAKE_C_FLAGS "" )
+endif()
+
+if( ANDROID_USE_STLPORT )
+ set( _CMAKE_CXX_FLAGS "${_CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions" )
+ set( _CMAKE_C_FLAGS "${_CMAKE_C_FLAGS} -fno-exceptions" )
else()
- set( CMAKE_CXX_FLAGS "" )
- set( CMAKE_C_FLAGS "" )
+ set( _CMAKE_CXX_FLAGS "${_CMAKE_CXX_FLAGS} -frtti -fexceptions" )
+ set( _CMAKE_C_FLAGS "${_CMAKE_C_FLAGS} -fexceptions" )
endif()
-#release and debug flags
+# release and debug flags
if( ARMEABI OR ARMEABI_V7A )
if( NOT ANDROID_FORCE_ARM_BUILD AND NOT ARMEABI_V6 )
- #It is recommended to use the -mthumb compiler flag to force the generation
- #of 16-bit Thumb-1 instructions (the default being 32-bit ARM ones).
+ # It is recommended to use the -mthumb compiler flag to force the generation
+ # of 16-bit Thumb-1 instructions (the default being 32-bit ARM ones).
# O3 instead of O2/Os in release mode - like cmake sets for desktop gcc
- set( CMAKE_CXX_FLAGS_RELEASE "-mthumb -O3" )
- set( CMAKE_C_FLAGS_RELEASE "-mthumb -O3" )
- set( CMAKE_CXX_FLAGS_DEBUG "-marm -Os -finline-limit=64" )
- set( CMAKE_C_FLAGS_DEBUG "-marm -Os -finline-limit=64" )
+ set( _CMAKE_CXX_FLAGS_RELEASE "-mthumb -O3" )
+ set( _CMAKE_C_FLAGS_RELEASE "-mthumb -O3" )
+ set( _CMAKE_CXX_FLAGS_DEBUG "-marm -Os -finline-limit=64" )
+ set( _CMAKE_C_FLAGS_DEBUG "-marm -Os -finline-limit=64" )
else()
# always compile ARMEABI_V6 in arm mode; otherwise there is no difference from ARMEABI
# O3 instead of O2/Os in release mode - like cmake sets for desktop gcc
- set( CMAKE_CXX_FLAGS_RELEASE "-marm -O3 -fstrict-aliasing" )
- set( CMAKE_C_FLAGS_RELEASE "-marm -O3 -fstrict-aliasing" )
- set( CMAKE_CXX_FLAGS_DEBUG "-marm -O0 -finline-limit=300" )
- set( CMAKE_C_FLAGS_DEBUG "-marm -O0 -finline-limit=300" )
+ set( _CMAKE_CXX_FLAGS_RELEASE "-marm -O3 -fstrict-aliasing" )
+ set( _CMAKE_C_FLAGS_RELEASE "-marm -O3 -fstrict-aliasing" )
+ set( _CMAKE_CXX_FLAGS_DEBUG "-marm -O0 -finline-limit=300" )
+ set( _CMAKE_C_FLAGS_DEBUG "-marm -O0 -finline-limit=300" )
endif()
elseif( X86 )
- set( CMAKE_CXX_FLAGS_RELEASE "-O3 -fstrict-aliasing" )
- set( CMAKE_C_FLAGS_RELEASE "-O3 -fstrict-aliasing" )
- set( CMAKE_CXX_FLAGS_DEBUG "-O0 -finline-limit=300" )
- set( CMAKE_C_FLAGS_DEBUG "-O0 -finline-limit=300" )
+ set( _CMAKE_CXX_FLAGS_RELEASE "-O3 -fstrict-aliasing" )
+ set( _CMAKE_C_FLAGS_RELEASE "-O3 -fstrict-aliasing" )
+ set( _CMAKE_CXX_FLAGS_DEBUG "-O0 -finline-limit=300" )
+ set( _CMAKE_C_FLAGS_DEBUG "-O0 -finline-limit=300" )
+elseif( MIPS )
+ set( _CMAKE_CXX_FLAGS_RELEASE "-O3 -funswitch-loops -finline-limit=300" )
+ set( _CMAKE_C_FLAGS_RELEASE "-O3 -funswitch-loops -finline-limit=300" )
+ set( _CMAKE_CXX_FLAGS_DEBUG "-O0 -g" )
+ set( _CMAKE_C_FLAGS_DEBUG "-O0 -g" )
endif()
-set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -DNDEBUG" )
-set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer -DNDEBUG" )
-set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-strict-aliasing -fno-omit-frame-pointer -DDEBUG -D_DEBUG" )
-set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-strict-aliasing -fno-omit-frame-pointer -DDEBUG -D_DEBUG" )
+set( _CMAKE_CXX_FLAGS_RELEASE "${_CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -DNDEBUG" )
+set( _CMAKE_C_FLAGS_RELEASE "${_CMAKE_C_FLAGS_RELEASE} -fomit-frame-pointer -DNDEBUG" )
+set( _CMAKE_CXX_FLAGS_DEBUG "${_CMAKE_CXX_FLAGS_DEBUG} -fno-strict-aliasing -fno-omit-frame-pointer -DDEBUG -D_DEBUG" )
+set( _CMAKE_C_FLAGS_DEBUG "${_CMAKE_C_FLAGS_DEBUG} -fno-strict-aliasing -fno-omit-frame-pointer -DDEBUG -D_DEBUG" )
-#ABI-specific flags
+# ABI-specific flags
if( ARMEABI_V7A )
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv7-a -mfloat-abi=softfp" )
if( NEON )
set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" )#sse?
endif()
-#linker flags
-list( APPEND ANDROID_SYSTEM_LIB_DIRS "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}" "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" )
-set( LINKER_FLAGS "" )
-#STL
+# linker flags
+if( NOT DEFINED __ndklibspath )
+ set( __ndklibspath "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/ndklibs/${ANDROID_NDK_ABI_NAME}" )
+endif()
+list( APPEND ANDROID_SYSTEM_LIB_DIRS "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" )
+set( ANDROID_LINKER_FLAGS "" )
+
+# STL
if( ANDROID_USE_STLPORT )
if( EXISTS "${__stlLibPath}/libstlport_static.a" )
- __COPY_IF_DIFFERENT( "${__stlLibPath}/libstlport_static.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstlport_static.a" )
- endif()
- if( EXISTS "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstlport_static.a" )
- set( LINKER_FLAGS "${LINKER_FLAGS} -Wl,--start-group -lstlport_static" )
+ set( CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES> \"${__stlLibPath}/libstlport_static.a\"")
+ set( CMAKE_CXX_CREATE_SHARED_MODULE "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES> \"${__stlLibPath}/libstlport_static.a\"")
endif()
else( ANDROID_USE_STLPORT )
if( EXISTS "${__stlLibPath}/libgnustl_static.a" )
- __COPY_IF_DIFFERENT( "${__stlLibPath}/libgnustl_static.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
+ __COPY_IF_DIFFERENT( "${__stlLibPath}/libgnustl_static.a" "${__ndklibspath}/libstdc++.a" )
elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" )
- __COPY_IF_DIFFERENT( "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
+ __COPY_IF_DIFFERENT( "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" "${__ndklibspath}/libstdc++.a" )
elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" )
- __COPY_IF_DIFFERENT( "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
+ __COPY_IF_DIFFERENT( "${__stlLibPath}/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" "${__ndklibspath}/libstdc++.a" )
elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${__stlLibPath}/thumb/libstdc++.a" )
- __COPY_IF_DIFFERENT( "${__stlLibPath}/thumb/libstdc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
+ __COPY_IF_DIFFERENT( "${__stlLibPath}/thumb/libstdc++.a" "${__ndklibspath}/libstdc++.a" )
elseif( EXISTS "${__stlLibPath}/libstdc++.a" )
- __COPY_IF_DIFFERENT( "${__stlLibPath}/libstdc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
- endif()
- if( EXISTS "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libstdc++.a" )
- set( LINKER_FLAGS "${LINKER_FLAGS} -lstdc++" )
+ __COPY_IF_DIFFERENT( "${__stlLibPath}/libstdc++.a" "${__ndklibspath}/libstdc++.a" )
endif()
-
- #gcc exception & rtti support
if( EXISTS "${__stlLibPath}/libsupc++.a" )
- __COPY_IF_DIFFERENT( "${__stlLibPath}/libsupc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
+ __COPY_IF_DIFFERENT( "${__stlLibPath}/libsupc++.a" "${__ndklibspath}/libsupc++.a" )
elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" )
- __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
+ __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libsupc++.a" "${__ndklibspath}/libsupc++.a" )
elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" )
- __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
+ __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libsupc++.a" "${__ndklibspath}/libsupc++.a" )
elseif( ANDROID_ARCH_NAME STREQUAL "arm" AND EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" )
- __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
+ __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libsupc++.a" "${__ndklibspath}/libsupc++.a" )
elseif( EXISTS "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" )
- __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
- endif()
- if( EXISTS "${CMAKE_BINARY_DIR}/systemlibs/${ANDROID_NDK_ABI_NAME}/libsupc++.a" )
- set( LINKER_FLAGS "${LINKER_FLAGS} -lsupc++" )
+ __COPY_IF_DIFFERENT( "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libsupc++.a" "${__ndklibspath}/libsupc++.a" )
endif()
+ list( APPEND ANDROID_SYSTEM_LIB_DIRS "${__ndklibspath}" )
endif( ANDROID_USE_STLPORT )
-#cleanup for STL search
+# cleanup for STL search
unset( __stlIncludePath )
unset( __stlLibPath )
-#other linker flags
+# other linker flags
__INIT_VARIABLE( ANDROID_NO_UNDEFINED OBSOLETE_NO_UNDEFINED VALUES ON )
set( ANDROID_NO_UNDEFINED ${ANDROID_NO_UNDEFINED} CACHE BOOL "Show all undefined symbols as linker errors" FORCE )
mark_as_advanced( ANDROID_NO_UNDEFINED )
if( ANDROID_NO_UNDEFINED )
- set( LINKER_FLAGS "-Wl,--no-undefined ${LINKER_FLAGS}" )
+ set( ANDROID_LINKER_FLAGS "-Wl,--no-undefined ${ANDROID_LINKER_FLAGS}" )
endif()
if (ANDROID_NDK MATCHES "-r[56].?$")
- #libGLESv2.so in NDK's prior to r7 refers to exteranal symbols. So this flag option is required for all projects using OpenGL from native.
+ # libGLESv2.so in NDK's prior to r7 refers to exteranal symbols. So this flag option is required for all projects using OpenGL from native.
__INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES ON )
else()
__INIT_VARIABLE( ANDROID_SO_UNDEFINED VALUES OFF )
endif()
+
set( ANDROID_SO_UNDEFINED ${ANDROID_SO_UNDEFINED} CACHE BOOL "Allows or disallows undefined symbols in shared libraries" FORCE )
mark_as_advanced( ANDROID_SO_UNDEFINED )
if( ANDROID_SO_UNDEFINED )
- set( LINKER_FLAGS "${LINKER_FLAGS} -Wl,-allow-shlib-undefined" )
+ set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-allow-shlib-undefined" )
+endif()
+
+__INIT_VARIABLE( ANDROID_FUNCTION_LEVEL_LINKING VALUES ON )
+set( ANDROID_FUNCTION_LEVEL_LINKING ON CACHE BOOL "Allows or disallows undefined symbols in shared libraries" FORCE )
+mark_as_advanced( ANDROID_FUNCTION_LEVEL_LINKING )
+if( ANDROID_FUNCTION_LEVEL_LINKING )
+ set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" )
+ set( ANDROID_LINKER_FLAGS "-Wl,--gc-sections ${ANDROID_LINKER_FLAGS}" )
endif()
if( ARMEABI_V7A )
# this is *required* to use the following linker flags that routes around
# a CPU bug in some Cortex-A8 implementations:
- set( LINKER_FLAGS "-Wl,--fix-cortex-a8 ${LINKER_FLAGS}" )
+ set( ANDROID_LINKER_FLAGS "-Wl,--fix-cortex-a8 ${ANDROID_LINKER_FLAGS}" )
endif()
-#cache flags
-set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags" )
-set( CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c flags" )
-set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "c++ Release flags" )
-set( CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "c Release flags" )
-set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "c++ Debug flags" )
-set( CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "c Debug flags" )
-set( CMAKE_SHARED_LINKER_FLAGS "${LINKER_FLAGS}" CACHE STRING "linker flags" )
-set( CMAKE_MODULE_LINKER_FLAGS "${LINKER_FLAGS}" CACHE STRING "linker flags" )
-set( CMAKE_EXE_LINKER_FLAGS "-Wl,--gc-sections -Wl,-z,nocopyreloc ${LINKER_FLAGS}" CACHE STRING "linker flags" )
+# cache flags
+set( CMAKE_CXX_FLAGS "${_CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags" )
+set( CMAKE_C_FLAGS "${_CMAKE_C_FLAGS}" CACHE STRING "c flags" )
+set( CMAKE_CXX_FLAGS_RELEASE "${_CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "c++ Release flags" )
+set( CMAKE_C_FLAGS_RELEASE "${_CMAKE_C_FLAGS_RELEASE}" CACHE STRING "c Release flags" )
+set( CMAKE_CXX_FLAGS_DEBUG "${_CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "c++ Debug flags" )
+set( CMAKE_C_FLAGS_DEBUG "${_CMAKE_C_FLAGS_DEBUG}" CACHE STRING "c Debug flags" )
+set( CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "linker flags" )
+set( CMAKE_MODULE_LINKER_FLAGS "" CACHE STRING "linker flags" )
+set( CMAKE_EXE_LINKER_FLAGS "-Wl,-z,nocopyreloc" CACHE STRING "linker flags" )
include_directories( SYSTEM ${ANDROID_SYSTEM_INCLUDE_DIRS} )
link_directories( ${ANDROID_SYSTEM_LIB_DIRS} )
-#finish flags
-set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Extra Android falgs")
-set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
-set( CMAKE_C_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
+# finish flags
+set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Extra Android compiler flags")
+set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}" CACHE INTERNAL "Extra Android linker flags")
+set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
+set( CMAKE_C_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
+if( MIPS AND BUILD_WITH_ANDROID_NDK )
+ set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.xsc ${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" )
+ set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.xsc ${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" )
+ set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.x ${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )
+else()
+ set( CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}" )
+ set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}" )
+ set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )
+endif()
-#set these global flags for cmake client scripts to change behavior
+# set these global flags for cmake client scripts to change behavior
set( ANDROID True )
set( BUILD_ANDROID True )
-# where is the target environment
+# where is the target environment
set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_ROOT}/bin" "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" "${ANDROID_SYSROOT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share" )
# only search for libraries and includes in the ndk toolchain
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
-#macro to find packages on the host OS
+# macro to find packages on the host OS
macro( find_host_package )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
endmacro()
-#macro to find programs on the host OS
+# macro to find programs on the host OS
macro( find_host_program )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
# export toolchain settings for the try_compile() command
if( NOT PROJECT_NAME STREQUAL "CMAKE_TRY_COMPILE" )
set( __toolchain_config "")
- foreach( __var ANDROID_ABI ANDROID_FORCE_ARM_BUILD ANDROID_NATIVE_API_LEVEL ANDROID_NO_UNDEFINED ANDROID_SO_UNDEFINED ANDROID_SET_OBSOLETE_VARIABLES LIBRARY_OUTPUT_PATH_ROOT ANDROID_USE_STLPORT ANDROID_FORBID_SYGWIN ANDROID_NDK ANDROID_STANDALONE_TOOLCHAIN )
+ foreach( __var ANDROID_ABI ANDROID_FORCE_ARM_BUILD ANDROID_NATIVE_API_LEVEL ANDROID_NO_UNDEFINED ANDROID_SO_UNDEFINED ANDROID_SET_OBSOLETE_VARIABLES LIBRARY_OUTPUT_PATH_ROOT ANDROID_USE_STLPORT ANDROID_FORBID_SYGWIN ANDROID_NDK ANDROID_STANDALONE_TOOLCHAIN ANDROID_FUNCTION_LEVEL_LINKING __ndklibspath )
if( DEFINED ${__var} )
- set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" )\n" )
+ if( "${__var}" MATCHES " ")
+ set( __toolchain_config "${__toolchain_config}set( ${__var} \"${${__var}}\" CACHE INTERNAL \"\" )\n" )
+ else()
+ set( __toolchain_config "${__toolchain_config}set( ${__var} ${${__var}} CACHE INTERNAL \"\" )\n" )
+ endif()
endif()
endforeach()
- file( WRITE "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/android.toolchain.config.cmake" "${__toolchain_config}" )
+ file( WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/android.toolchain.config.cmake" "${__toolchain_config}" )
unset( __toolchain_config )
+ unset( __ndklibspath )
endif()
set( ARMEABI_NDK_NAME "${ANDROID_NDK_ABI_NAME}" )
endif()
+
# Variables controlling behavior or set by cmake toolchain:
-# ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86"
-# ANDROID_FORCE_ARM_BUILD : ON/OFF
+# ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips"
# ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14 (depends on NDK version)
+# ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF
+# ANDROID_USE_STLPORT : OFF/ON - EXPERIMENTAL!!!
+# ANDROID_FORBID_SYGWIN : ON/OFF
# ANDROID_NO_UNDEFINED : ON/OFF
# ANDROID_SO_UNDEFINED : OFF/ON (default depends on NDK version)
-# ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF
+# ANDROID_FUNCTION_LEVEL_LINKING : ON/OFF
+# Variables that takes effect only at first run:
+# ANDROID_FORCE_ARM_BUILD : ON/OFF
# LIBRARY_OUTPUT_PATH_ROOT : <any valid path>
-# ANDROID_USE_STLPORT : OFF/ON - EXPERIMENTAL!!!
-# ANDROID_FORBID_SYGWIN : ON/OFF
# Can be set only at the first run:
# ANDROID_NDK
# ANDROID_STANDALONE_TOOLCHAIN
+# ANDROID_TOOLCHAIN_NAME : "arm-linux-androideabi-4.4.3" or "arm-linux-androideabi-4.6" or "mipsel-linux-android-4.4.3" or "mipsel-linux-android-4.6" or "x86-4.4.3" or "x86-4.6"
# Obsolete:
# ANDROID_API_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL
# ARM_TARGET : superseded by ANDROID_ABI
# BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used
# ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform
# ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a" or "x86" depending on ANDROID_ABI
-# ANDROID_ARCH_NAME : "arm" or "x86" depending on ANDROID_ABI
+# ANDROID_ARCH_NAME : "arm" or "x86" or "mips" depending on ANDROID_ABI
# TOOL_OS_SUFFIX : "" or ".exe" depending on host platform
+# ANDROID_SYSROOT : path to the compiler sysroot
# ANDROID_SYSTEM_INCLUDE_DIRS
# ANDROID_SYSTEM_LIB_DIRS
# Obsolete:
# ANDROID_COMPILER_VERSION : GCC version used
# ANDROID_CXX_FLAGS : C/C++ compiler flags required by Android platform
# ANDROID_SUPPORTED_ABIS : list of currently allowed values for ANDROID_ABI
-# ANDROID_SYSROOT : path to the compiler sysroot
-# ANDROID_TOOLCHAIN_NAME : "standalone", "arm-linux-androideabi-4.4.3" or "x86-4.4.3" or something similar.
# ANDROID_TOOLCHAIN_MACHINE_NAME : "arm-linux-androideabi", "arm-eabi" or "i686-android-linux"
# ANDROID_TOOLCHAIN_ROOT : path to the top level of toolchain (standalone or placed inside NDK)
# ANDROID_SUPPORTED_NATIVE_API_LEVELS : list of native API levels found inside NDK
if (pid == 0) {
// child
execvp(args[0], args);
- fprintf(stderr, "error: failed to execute %s\n", args[0]);
+ fprintf(stderr, "error: failed to execute:");
+ for (unsigned i = 0; args[i]; ++i) {
+ fprintf(stderr, " %s", args[i]);
+ }
+ fprintf(stderr, "\n");
exit(-1);
} else {
// parent
/**************************************************************************
*
- * Copyright 2011 Jose Fonseca
+ * Copyright 2011-2012 Jose Fonseca
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
**************************************************************************/
/*
- * Simple OS abstraction.
+ * OS native thread abstraction.
*
- * Mimics C++11 / boost threads.
+ * Mimics C++11 threads.
*/
#ifndef _OS_THREAD_HPP_
#include <pthread.h>
#endif
+
+#define USE_WIN32_CONDITION_VARIABLES 0
+
+
+/**
+ * Compiler TLS.
+ *
+ * See also:
+ * - http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Thread_002dLocal.html
+ * - http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx
+ */
+#if defined(_MSC_VER)
+# define thread_specific __declspec(thread)
+#elif defined(__GNUC__)
+# define thread_specific __thread
+#else
+# define thread_specific
+# error "Unsupported compiler"
+#endif
+
+
namespace os {
- class recursive_mutex
+ /**
+ * Base class for mutex and recursive_mutex.
+ */
+ class _base_mutex
{
public:
#ifdef _WIN32
typedef pthread_mutex_t native_handle_type;
#endif
- recursive_mutex(void) {
+ _base_mutex(void) {
#ifdef _WIN32
InitializeCriticalSection(&_native_handle);
#else
#endif
}
- ~recursive_mutex() {
+ ~_base_mutex() {
#ifdef _WIN32
DeleteCriticalSection(&_native_handle);
#else
#endif
}
- private:
+ native_handle_type & native_handle() {
+ return _native_handle;
+ }
+
+ protected:
native_handle_type _native_handle;
};
- template <typename T>
- class thread_specific_ptr
+ /**
+ * Same interface as std::mutex.
+ */
+ class mutex : public _base_mutex
{
- private:
+ public:
+ inline
+ mutex(void) {
#ifdef _WIN32
- DWORD dwTlsIndex;
+ InitializeCriticalSection(&_native_handle);
#else
- pthread_key_t key;
+ pthread_mutex_init(&_native_handle, NULL);
+#endif
+ }
+ };
+
+
+ /**
+ * Same interface as std::recursive_mutex.
+ */
+ class recursive_mutex : public _base_mutex
+ {
+ public:
+ inline
+ recursive_mutex(void) {
+#ifdef _WIN32
+ InitializeCriticalSection(&_native_handle);
+#else
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&_native_handle, &attr);
+ pthread_mutexattr_destroy(&attr);
+#endif
+ }
+ };
+
+
+ /**
+ * Same interface as std::unique_lock;
+ */
+ template< class Mutex >
+ class unique_lock
+ {
+ public:
+ typedef Mutex mutex_type;
+
+ inline explicit
+ unique_lock(mutex_type & mutex) :
+ _mutex(&mutex)
+ {
+ _mutex->lock();
+ }
+
+ inline
+ ~unique_lock() {
+ _mutex->unlock();
+ }
+
+ inline void
+ lock() {
+ _mutex->lock();
+ }
- static void destructor(void *ptr) {
- delete static_cast<T *>(ptr);
+ inline void
+ unlock() {
+ _mutex->unlock();
+ }
+
+ mutex_type *
+ mutex() const {
+ return _mutex;
}
+
+ protected:
+ mutex_type *_mutex;
+ };
+
+
+ /**
+ * Same interface as std::condition_variable
+ */
+ class condition_variable
+ {
+ private:
+#ifdef _WIN32
+# if USE_WIN32_CONDITION_VARIABLES
+ // XXX: Only supported on Vista an higher. Not yet supported by WINE.
+ typedef CONDITION_VARIABLE native_handle_type;
+ native_handle_type _native_handle;
+#else
+ // http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ LONG cWaiters;
+ HANDLE hEvent;
+#endif
+#else
+ typedef pthread_cond_t native_handle_type;
+ native_handle_type _native_handle;
#endif
public:
- thread_specific_ptr(void) {
+ condition_variable() {
+#ifdef _WIN32
+# if USE_WIN32_CONDITION_VARIABLES
+ InitializeConditionVariable(&_native_handle);
+# else
+ cWaiters = 0;
+ hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+# endif
+#else
+ pthread_cond_init(&_native_handle, NULL);
+#endif
+ }
+
+ ~condition_variable() {
#ifdef _WIN32
- dwTlsIndex = TlsAlloc();
+# if USE_WIN32_CONDITION_VARIABLES
+ /* No-op */
+# else
+ CloseHandle(hEvent);
+# endif
#else
- pthread_key_create(&key, &destructor);
+ pthread_cond_destroy(&_native_handle);
#endif
}
- ~thread_specific_ptr() {
+ inline void
+ signal(void) {
#ifdef _WIN32
- TlsFree(dwTlsIndex);
+# if USE_WIN32_CONDITION_VARIABLES
+ WakeConditionVariable(&_native_handle);
+# else
+ if (cWaiters) {
+ SetEvent(hEvent);
+ }
+# endif
#else
- pthread_key_delete(key);
+ pthread_cond_signal(&_native_handle);
#endif
}
- T* get(void) const {
- void *ptr;
+ inline void
+ wait(unique_lock<mutex> & lock) {
+ mutex::native_handle_type & mutex_native_handle = lock.mutex()->native_handle();
#ifdef _WIN32
- ptr = TlsGetValue(dwTlsIndex);
+# if USE_WIN32_CONDITION_VARIABLES
+ SleepConditionVariableCS(&_native_handle, &mutex_native_handle, INFINITE);
+# else
+ InterlockedIncrement(&cWaiters);
+ LeaveCriticalSection(&mutex_native_handle);
+ WaitForSingleObject(hEvent, INFINITE);
+ EnterCriticalSection(&mutex_native_handle);
+ InterlockedDecrement(&cWaiters);
+# endif
#else
- ptr = pthread_getspecific(key);
+ pthread_cond_wait(&_native_handle, &mutex_native_handle);
#endif
- return static_cast<T*>(ptr);
}
+ };
- T* operator -> (void) const
+
+ /**
+ * Same interface as std::thread
+ */
+ class thread {
+ public:
+#ifdef _WIN32
+ typedef HANDLE native_handle_type;
+#else
+ typedef pthread_t native_handle_type;
+#endif
+
+ inline
+ thread() :
+ _native_handle(0)
{
- return get();
}
- T& operator * (void) const
+ inline
+ thread(thread &other) :
+ _native_handle(other._native_handle)
{
- return *get();
}
- void reset(T* new_value=0) {
- T * old_value = get();
+ template< class Function, class Arg >
+ explicit thread( Function& f, Arg arg ) {
#ifdef _WIN32
- TlsSetValue(dwTlsIndex, new_value);
+ DWORD id = 0;
+ _native_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)f, (LPVOID)arg, 0, &id);
#else
- pthread_setspecific(key, new_value);
+ pthread_create(&_native_handle, NULL, ( void *(*) (void *))f, arg);
#endif
- if (old_value) {
- delete old_value;
- }
}
+
+ inline bool
+ joinable(void) const {
+ return _native_handle != 0;
+ }
+
+ inline void
+ join() {
+#ifdef _WIN32
+ WaitForSingleObject(_native_handle, INFINITE);
+#else
+ pthread_join(_native_handle, NULL);
+#endif
+ }
+
+ private:
+ native_handle_type _native_handle;
+
+#if 0
+#ifdef _WIN32
+ template< class Function, class Arg >
+ static DWORD WINAPI
+ ThreadProc(LPVOID lpParameter) {
+
+ );
+#endif
+#endif
};
} /* namespace os */
#if defined(_WIN32)
-#include <windows.h>
-#elif defined(__linux__)
-#include <time.h>
-#elif defined(__APPLE__)
-#include <mach/mach_time.h>
+# include <windows.h>
#else
-#include <sys/time.h>
+# if defined(__linux__)
+# include <time.h>
+# elif defined(__APPLE__)
+# include <mach/mach_time.h>
+# else
+# include <sys/time.h>
+# endif
+# include <unistd.h>
#endif
#endif
}
+ // Suspend execution
+ inline void
+ sleep(unsigned long usecs) {
+#if defined(_WIN32)
+ Sleep((usecs + 999) / 1000);
+#else
+ usleep(usecs);
+#endif
+ }
} /* namespace os */
return EXCEPTION_CONTINUE_SEARCH;
}
+ /*
+ * Ignore .NET exception.
+ *
+ * http://ig2600.blogspot.co.uk/2011/01/why-do-i-keep-getting-exception-code.html
+ */
+ if (pExceptionRecord->ExceptionCode == 0xe0434352) {
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+
// Clear direction flag
#ifdef _MSC_VER
#ifndef _WIN64
return;
}
- unsigned c = 1;
// Same as l >> (8 * sizeof l), but without the warnings
T sign = l < 0 ? ~0 : 0;
- while ((l >> (8 * c)) != sign) {
+
+ T sl = l;
+ unsigned c = 0;
+ do {
++c;
- }
+ } while (sl >>= 8 != sign);
+
// Add an extra byte if sign bit doesn't match
if (((l >> (8 * c - 1)) & 1) != ((l >> (8 * sizeof l - 1)) & 1)) {
++c;
const Entry<CallFlags>
callFlagTable[] = {
{ "CGLFlushDrawable", CALL_FLAG_END_FRAME },
+ { "CGLGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "IDirect3D9::CheckDeviceFormat", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "IDirect3D9::EnumAdapterModes", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "IDirect3D9::GetAdapterModeCount", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "IDirect3DDevice9::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "IDirect3DDevice9::GetRenderTargetData", CALL_FLAG_END_FRAME },
{ "IDirect3DDevice9::Present", CALL_FLAG_END_FRAME },
+ { "IDirect3DDevice9::SetRenderTarget", CALL_FLAG_SWAP_RENDERTARGET },
{ "IDirect3DDevice9Ex::Clear", CALL_FLAG_RENDER },
{ "IDirect3DDevice9Ex::DrawIndexedPrimitive", CALL_FLAG_RENDER },
{ "IDirect3DDevice9Ex::DrawIndexedPrimitiveUP", CALL_FLAG_RENDER },
{ "IDirect3DDevice9Ex::GetDeviceCaps", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "IDirect3DDevice9Ex::GetRenderTargetData", CALL_FLAG_END_FRAME },
{ "IDirect3DDevice9Ex::Present", CALL_FLAG_END_FRAME },
+ { "IDirect3DDevice9Ex::SetRenderTarget", CALL_FLAG_SWAP_RENDERTARGET },
{ "IDirect3DSwapChain9::Present", CALL_FLAG_END_FRAME },
{ "IDirect3DSwapChain9Ex::Present", CALL_FLAG_END_FRAME },
{ "eglGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "glXGetCurrentContext", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "glXGetCurrentDisplay", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "glXGetCurrentDrawable", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
+ { "glXGetFBConfigAttrib", CALL_FLAG_VERBOSE },
+ { "glXGetFBConfigAttribSGIX", CALL_FLAG_VERBOSE },
{ "glXGetProcAddress", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "glXGetProcAddressARB", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
{ "glXIsDirect", CALL_FLAG_NO_SIDE_EFFECTS | CALL_FLAG_VERBOSE },
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 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.
+ *
+ **************************************************************************/
+
+#include "trace_profiler.hpp"
+#include "os_time.hpp"
+#include <iostream>
+#include <string.h>
+#include <sstream>
+
+namespace trace {
+Profiler::Profiler()
+ : baseGpuTime(0),
+ baseCpuTime(0),
+ minCpuTime(1000),
+ cpuTimes(false),
+ gpuTimes(true),
+ pixelsDrawn(false)
+{
+}
+
+Profiler::~Profiler()
+{
+}
+
+void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_)
+{
+ cpuTimes = cpuTimes_;
+ gpuTimes = gpuTimes_;
+ pixelsDrawn = pixelsDrawn_;
+
+ std::cout << "# call no gpu_start gpu_dura cpu_start cpu_dura pixels program name" << std::endl;
+}
+
+int64_t Profiler::getBaseCpuTime()
+{
+ return baseCpuTime;
+}
+
+int64_t Profiler::getBaseGpuTime()
+{
+ return baseGpuTime;
+}
+
+void Profiler::setBaseCpuTime(int64_t cpuStart)
+{
+ baseCpuTime = cpuStart;
+}
+
+void Profiler::setBaseGpuTime(int64_t gpuStart)
+{
+ baseGpuTime = gpuStart;
+}
+
+bool Profiler::hasBaseTimes()
+{
+ return baseCpuTime != 0 || baseGpuTime != 0;
+}
+
+void Profiler::addCall(unsigned no,
+ const char *name,
+ unsigned program,
+ int64_t pixels,
+ int64_t gpuStart, int64_t gpuDuration,
+ int64_t cpuStart, int64_t cpuDuration)
+{
+ if (gpuTimes && gpuStart) {
+ gpuStart -= baseGpuTime;
+ } else {
+ gpuStart = 0;
+ gpuDuration = 0;
+ }
+
+ if (cpuTimes && cpuStart) {
+ double cpuTimeScale = 1.0E9 / os::timeFrequency;
+ cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale;
+ cpuDuration = cpuDuration * cpuTimeScale;
+
+ if (cpuDuration < minCpuTime) {
+ return;
+ }
+ } else {
+ cpuStart = 0;
+ cpuDuration = 0;
+ }
+
+ if (!pixelsDrawn) {
+ pixels = 0;
+ }
+
+ std::cout << "call"
+ << " " << no
+ << " " << gpuStart
+ << " " << gpuDuration
+ << " " << cpuStart
+ << " " << cpuDuration
+ << " " << pixels
+ << " " << program
+ << " " << name
+ << std::endl;
+}
+
+void Profiler::addFrameEnd()
+{
+ std::cout << "frame_end" << std::endl;
+}
+
+void Profiler::parseLine(const char* in, Profile* profile)
+{
+ std::stringstream line(in, std::ios_base::in);
+ std::string type;
+ static int64_t lastGpuTime;
+ static int64_t lastCpuTime;
+
+ if (in[0] == '#' || strlen(in) < 4)
+ return;
+
+ if (profile->programs.size() == 0 && profile->calls.size() == 0 && profile->frames.size() == 0) {
+ lastGpuTime = 0;
+ lastCpuTime = 0;
+ }
+
+ line >> type;
+
+ if (type.compare("call") == 0) {
+ Profile::Call call;
+
+ line >> call.no
+ >> call.gpuStart
+ >> call.gpuDuration
+ >> call.cpuStart
+ >> call.cpuDuration
+ >> call.pixels
+ >> call.program
+ >> call.name;
+
+ if (lastGpuTime < call.gpuStart + call.gpuDuration) {
+ lastGpuTime = call.gpuStart + call.gpuDuration;
+ }
+
+ if (lastCpuTime < call.cpuStart + call.cpuDuration) {
+ lastCpuTime = call.cpuStart + call.cpuDuration;
+ }
+
+ profile->calls.push_back(call);
+
+ if (call.pixels >= 0) {
+ if (profile->programs.size() <= call.program) {
+ profile->programs.resize(call.program + 1);
+ }
+
+ Profile::Program& program = profile->programs[call.program];
+ program.cpuTotal += call.cpuDuration;
+ program.gpuTotal += call.gpuDuration;
+ program.pixelTotal += call.pixels;
+ program.calls.push_back(profile->calls.size() - 1);
+ }
+ } else if (type.compare("frame_end") == 0) {
+ Profile::Frame frame;
+ frame.no = profile->frames.size();
+
+ if (frame.no == 0) {
+ frame.gpuStart = 0;
+ frame.cpuStart = 0;
+ frame.calls.begin = 0;
+ } else {
+ frame.gpuStart = profile->frames.back().gpuStart + profile->frames.back().gpuDuration;
+ frame.cpuStart = profile->frames.back().cpuStart + profile->frames.back().cpuDuration;
+ frame.calls.begin = profile->frames.back().calls.end + 1;
+ }
+
+ frame.gpuDuration = lastGpuTime - frame.gpuStart;
+ frame.cpuDuration = lastCpuTime - frame.cpuStart;
+ frame.calls.end = profile->calls.size() - 1;
+
+ profile->frames.push_back(frame);
+ }
+}
+}
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 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.
+ *
+ **************************************************************************/
+
+#ifndef TRACE_PROFILER_H
+#define TRACE_PROFILER_H
+
+#include <string>
+#include <vector>
+#include <stdint.h>
+
+namespace trace
+{
+
+struct Profile {
+ struct Call {
+ unsigned no;
+
+ unsigned program;
+
+ int64_t gpuStart;
+ int64_t gpuDuration;
+
+ int64_t cpuStart;
+ int64_t cpuDuration;
+
+ int64_t pixels;
+
+ std::string name;
+ };
+
+ struct Frame {
+ unsigned no;
+
+ int64_t gpuStart;
+ int64_t gpuDuration;
+
+ int64_t cpuStart;
+ int64_t cpuDuration;
+
+ /* Indices to profile->calls array */
+ struct {
+ unsigned begin;
+ unsigned end;
+ } calls;
+ };
+
+ struct Program {
+ Program() : gpuTotal(0), cpuTotal(0), pixelTotal(0) {}
+
+ uint64_t gpuTotal;
+ uint64_t cpuTotal;
+ uint64_t pixelTotal;
+
+ /* Indices to profile->calls array */
+ std::vector<unsigned> calls;
+ };
+
+ std::vector<Call> calls;
+ std::vector<Frame> frames;
+ std::vector<Program> programs;
+};
+
+class Profiler
+{
+public:
+ Profiler();
+ ~Profiler();
+
+ void setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_);
+
+ void addCall(unsigned no,
+ const char* name,
+ unsigned program,
+ int64_t pixels,
+ int64_t gpuStart, int64_t gpuDuration,
+ int64_t cpuStart, int64_t cpuDuration);
+
+ void addFrameEnd();
+
+ bool hasBaseTimes();
+
+ void setBaseCpuTime(int64_t cpuStart);
+ void setBaseGpuTime(int64_t gpuStart);
+
+ int64_t getBaseCpuTime();
+ int64_t getBaseGpuTime();
+
+ static void parseLine(const char* line, Profile* profile);
+
+private:
+ int64_t baseGpuTime;
+ int64_t baseCpuTime;
+ int64_t minCpuTime;
+
+ bool cpuTimes;
+ bool gpuTimes;
+ bool pixelsDrawn;
+};
+}
+
+#endif // TRACE_PROFILER_H
#endif
}
-static unsigned next_thread_id = 0;
-static os::thread_specific_ptr<unsigned> thread_id_specific_ptr;
+static unsigned next_thread_num = 1;
+static thread_specific unsigned thread_num = 0;
unsigned LocalWriter::beginEnter(const FunctionSig *sig) {
mutex.lock();
open();
}
- unsigned *thread_id_ptr = thread_id_specific_ptr.get();
- unsigned thread_id;
- if (thread_id_ptr) {
- thread_id = *thread_id_ptr;
- } else {
- thread_id = next_thread_id++;
- thread_id_ptr = new unsigned;
- *thread_id_ptr = thread_id;
- thread_id_specific_ptr.reset(thread_id_ptr);
+ unsigned this_thread_num = thread_num;
+ if (!this_thread_num) {
+ this_thread_num = thread_num = next_thread_num++;
}
+ assert(thread_num > 0);
+ unsigned thread_id = thread_num - 1;
return Writer::beginEnter(sig, thread_id);
}
jumpwidget.cpp
mainwindow.cpp
main.cpp
+ profiledialog.cpp
+ profiletablemodel.cpp
retracer.cpp
saverthread.cpp
searchwidget.cpp
traceprocess.cpp
trimprocess.cpp
vertexdatainterpreter.cpp
+ graphing/frameaxiswidget.cpp
+ graphing/graphwidget.cpp
+ graphing/graphaxiswidget.cpp
+ graphing/graphview.cpp
+ graphing/heatmapview.cpp
+ graphing/heatmapverticalaxiswidget.cpp
+ graphing/histogramview.cpp
+ graphing/timeaxiswidget.cpp
)
qt4_automoc(${qapitrace_SRCS})
ui/imageviewer.ui
ui/jumpwidget.ui
ui/mainwindow.ui
+ ui/profiledialog.ui
+ ui/profilereplaydialog.ui
ui/retracerdialog.ui
ui/settings.ui
ui/tracedialog.ui
${QT_LIBRARIES}
)
+# Recent builds of Qt no longer support i386 architecture
+if (APPLE)
+ set_target_properties (qapitrace PROPERTIES OSX_ARCHITECTURES x86_64)
+endif ()
+
########### install files ###############
install (TARGETS qapitrace RUNTIME DESTINATION bin)
bool ApiTrace::hasErrors() const
{
- return !m_errors.isEmpty();
+ return !m_errors.isEmpty() || !m_queuedErrors.isEmpty();
}
void ApiTrace::loadFrame(ApiTraceFrame *frame)
--- /dev/null
+#ifndef CALLDURATIONGRAPH_H
+#define CALLDURATIONGRAPH_H
+
+#include "graphing/graphwidget.h"
+#include "trace_profiler.hpp"
+#include "profiling.h"
+
+/**
+ * Wrapper for call duration graphs.
+ *
+ * This implements the transformSelectionIn and transformSelectionOut to
+ * allow sharing the selection between the graphs and the heatmap as they
+ * are using different scales. The duration graphs have call.no on the X-axis
+ * whereas the heatmap has time on the X axis.
+ */
+class CallDurationGraph : public GraphWidget {
+public:
+ CallDurationGraph(QWidget* parent = 0) :
+ GraphWidget(parent),
+ m_profile(NULL)
+ {
+ }
+
+ void setProfile(const trace::Profile* profile)
+ {
+ m_profile = profile;
+ }
+
+protected:
+ /* Transform from time-based horizontal selection to call no based. */
+ virtual SelectionState transformSelectionIn(SelectionState state)
+ {
+ if (!m_profile || state.type != SelectionState::Horizontal) {
+ return state;
+ }
+
+ qint64 timeStart = state.start;
+ qint64 timeEnd = state.end;
+
+ std::vector<trace::Profile::Call>::const_iterator itr;
+
+ itr =
+ Profiling::binarySearchTimespan<
+ trace::Profile::Call,
+ &trace::Profile::Call::cpuStart,
+ &trace::Profile::Call::cpuDuration>
+ (m_profile->calls.begin(), m_profile->calls.end(), timeStart, true);
+
+ state.start = itr - m_profile->calls.begin();
+
+ itr =
+ Profiling::binarySearchTimespan<
+ trace::Profile::Call,
+ &trace::Profile::Call::cpuStart,
+ &trace::Profile::Call::cpuDuration>
+ (m_profile->calls.begin(), m_profile->calls.end(), timeEnd, true);
+
+ state.end = itr - m_profile->calls.begin();
+
+ return state;
+ }
+
+ virtual SelectionState transformSelectionOut(SelectionState state)
+ {
+ if (!m_profile || state.type != SelectionState::Horizontal) {
+ return state;
+ }
+
+ qint64 start = qMax<qint64>(0, state.start);
+ qint64 end = qMin<qint64>(state.end, m_profile->calls.size());
+
+ /* Call based -> time based */
+ state.start = m_profile->calls[start].cpuStart;
+ state.end = m_profile->calls[end].cpuStart + m_profile->calls[end].cpuDuration;
+
+ return state;
+ }
+
+private:
+ const trace::Profile* m_profile;
+};
+
+/* Data provider for call duration graphs */
+class CallDurationDataProvider : public GraphDataProvider {
+public:
+ CallDurationDataProvider(const trace::Profile* profile, bool gpu) :
+ m_gpu(gpu),
+ m_profile(profile),
+ m_selectionState(NULL)
+ {
+ }
+
+ virtual qint64 size() const
+ {
+ return m_profile ? m_profile->calls.size() : 0;
+ }
+
+ virtual bool selected(qint64 index) const
+ {
+ if (m_selectionState) {
+ if (m_selectionState->type == SelectionState::Horizontal) {
+ if (m_selectionState->start <= index && index < m_selectionState->end) {
+ return true;
+ }
+ } else if (m_selectionState->type == SelectionState::Vertical) {
+ return m_profile->calls[index].program == m_selectionState->start;
+ }
+ }
+
+ return false;
+ }
+
+ virtual void setSelectionState(SelectionState* state)
+ {
+ m_selectionState = state;
+ }
+
+ virtual qint64 value(qint64 index) const
+ {
+ if (m_gpu) {
+ return m_profile->calls[index].gpuDuration;
+ } else {
+ return m_profile->calls[index].cpuDuration;
+ }
+ }
+
+ virtual void itemDoubleClicked(qint64 index) const
+ {
+ if (!m_profile) {
+ return;
+ }
+
+ if (index < 0 || index >= m_profile->calls.size()) {
+ return;
+ }
+
+ const trace::Profile::Call& call = m_profile->calls[index];
+ Profiling::jumpToCall(call.no);
+ }
+
+ virtual QString itemTooltip(qint64 index) const
+ {
+ if (!m_profile) {
+ return QString();
+ }
+
+ if (index < 0 || index >= m_profile->calls.size()) {
+ return QString();
+ }
+
+ const trace::Profile::Call& call = m_profile->calls[index];
+
+ QString text;
+ text = QString::fromStdString(call.name);
+ text += QString("\nCall: %1").arg(call.no);
+ text += QString("\nCPU Duration: %1").arg(Profiling::getTimeString(call.cpuDuration));
+
+ if (call.pixels >= 0) {
+ text += QString("\nGPU Duration: %1").arg(Profiling::getTimeString(call.gpuDuration));
+ text += QString("\nPixels Drawn: %1").arg(QLocale::system().toString((qlonglong)call.pixels));
+ text += QString("\nProgram: %1").arg(call.program);
+ }
+
+ return text;
+ }
+
+private:
+ bool m_gpu;
+ const trace::Profile* m_profile;
+ SelectionState* m_selectionState;
+};
+
+#endif
--- /dev/null
+#include "frameaxiswidget.h"
+
+#include <QPainter>
+
+FrameAxisWidget::FrameAxisWidget(QWidget* parent) :
+ GraphAxisWidget(parent),
+ m_data(NULL)
+{
+ setSelectable(GraphAxisWidget::Range);
+}
+
+void FrameAxisWidget::setDataProvider(FrameDataProvider* data)
+{
+ delete m_data;
+ m_data = data;
+}
+
+void FrameAxisWidget::paintEvent(QPaintEvent *)
+{
+ if (!m_data || m_orientation != GraphAxisWidget::Horizontal) {
+ /* TODO: Vertical axis support */
+ return;
+ }
+
+ QPainter painter(this);
+ painter.setPen(Qt::black);
+ painter.setBrush(Qt::lightGray);
+ painter.drawRect(0, 0, width() - 1, height() - 1);
+
+ qint64 range = m_valueEnd - m_valueBegin;
+ double dxdv = width() / (double)range;
+ double scroll = dxdv * m_valueBegin;
+ int lastLabel = -9999;
+
+ /* Iterate over frames, drawing a label when there is space to do so */
+ for (unsigned i = 0; i < m_data->size(); ++i) {
+ static const int padding = 4;
+ qint64 start = m_data->frameStart(i);
+ qint64 end = m_data->frameEnd(i);
+ bool visible = false;
+
+ if (start > m_valueEnd) {
+ break;
+ }
+
+ if (end < m_valueBegin) {
+ visible = false;
+ }
+
+ double left = dxdv * start;
+ double right = dxdv * end;
+ QString text = QString("%1").arg(i);
+
+ int width = painter.fontMetrics().width(text) + padding * 2;
+
+ if (right > scroll) {
+ visible = true;
+ }
+
+ if (left - lastLabel > width) {
+ lastLabel = left + width;
+
+ if (visible) {
+ int textX;
+
+ if (left < scroll && right - left > width) {
+ if (right - scroll > width) {
+ textX = 0;
+ } else {
+ textX = right - scroll - width;
+ }
+ } else {
+ textX = left - scroll;
+ }
+
+ painter.drawText(textX + padding, 0, width - padding, height() - 5, Qt::AlignLeft | Qt::AlignVCenter, text);
+ painter.drawLine(left - scroll, height() / 2, left - scroll, height() - 1);
+ }
+ } else if (visible) {
+ painter.drawLine(left - scroll, height() * 3/4.0, left - scroll, height() - 1);
+ }
+ }
+
+ /* Draw selection */
+ if (hasSelection()) {
+ double left = (dxdv * m_selectionState->start) - scroll;
+ double right = (dxdv * m_selectionState->end) - scroll;
+
+ painter.setPen(Qt::green);
+
+ if (left >= 0 && left <= width()) {
+ painter.drawLine(left, 0, left, height());
+ }
+
+ if (right >= 0 && right <= width()) {
+ painter.drawLine(right, 0, right, height());
+ }
+ }
+}
--- /dev/null
+#ifndef FRAMEAXISWIDGET_H
+#define FRAMEAXISWIDGET_H
+
+#include "graphaxiswidget.h"
+
+class FrameDataProvider {
+public:
+ /* Number of frames */
+ virtual unsigned size() const = 0;
+
+ /* Start and end values of frame */
+ virtual qint64 frameStart(unsigned frame) const = 0;
+ virtual qint64 frameEnd(unsigned frame) const = 0;
+};
+
+/**
+ * A generic axis which will draw frame numbers over a period of values.
+ * Frames designated by start / end values.
+ */
+class FrameAxisWidget : public GraphAxisWidget {
+public:
+ FrameAxisWidget(QWidget* parent = 0);
+
+ void setDataProvider(FrameDataProvider* data);
+
+ virtual void paintEvent(QPaintEvent *e);
+
+protected:
+ FrameDataProvider* m_data;
+};
+
+#endif
--- /dev/null
+#include "graphaxiswidget.h"
+
+#include <QMouseEvent>
+
+GraphAxisWidget::GraphAxisWidget(QWidget* parent) :
+ QWidget(parent),
+ m_selectable(None),
+ m_selectionState(NULL)
+{
+}
+
+
+bool GraphAxisWidget::hasSelection()
+{
+ if (!m_selectionState) {
+ return false;
+ }
+
+ if (m_selectionState->type == SelectionState::Horizontal && m_orientation == GraphAxisWidget::Horizontal) {
+ return true;
+ }
+
+ if (m_selectionState->type == SelectionState::Vertical && m_orientation == GraphAxisWidget::Vertical) {
+ return true;
+ }
+
+ return false;
+}
+
+
+void GraphAxisWidget::setSelectable(SelectionStyle selectable)
+{
+ m_selectable = selectable;
+}
+
+
+void GraphAxisWidget::setSelectionState(SelectionState* state)
+{
+ m_selectionState = state;
+}
+
+
+void GraphAxisWidget::setOrientation(Orientation v)
+{
+ m_orientation = v;
+
+ if (m_orientation == Horizontal) {
+ setMinimumWidth(60);
+ } else {
+ setMinimumHeight(60);
+ }
+}
+
+
+void GraphAxisWidget::mouseMoveEvent(QMouseEvent *e)
+{
+ if (m_selectable == None) {
+ return;
+ }
+
+ int pos, max;
+
+ if (m_orientation == Horizontal) {
+ pos = e->x();
+ max = width();
+ } else {
+ pos = e->y();
+ max = height();
+ }
+
+ double value = m_valueEnd - m_valueBegin;
+ value *= pos / (double)max;
+ value += m_valueBegin;
+
+ if (e->buttons().testFlag(Qt::LeftButton)) {
+ m_selectionState->start = qMin<qint64>(m_mousePressValue, value);
+ m_selectionState->end = qMax<qint64>(m_mousePressValue, value);
+ m_selectionState->type = m_orientation == Horizontal ? SelectionState::Horizontal : SelectionState::Vertical;
+ emit selectionChanged();
+ update();
+ }
+}
+
+
+void GraphAxisWidget::mousePressEvent(QMouseEvent *e)
+{
+ if (m_selectable == None) {
+ return;
+ }
+
+ int pos, max;
+
+ if (m_orientation == Horizontal) {
+ pos = e->x();
+ max = width();
+ } else {
+ pos = e->y();
+ max = height();
+ }
+
+ double value = m_valueEnd - m_valueBegin;
+ value *= pos / (double)max;
+ value += m_valueBegin;
+
+ m_mousePressPosition = e->pos();
+ m_mousePressValue = value;
+}
+
+
+void GraphAxisWidget::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (m_selectable == None) {
+ return;
+ }
+
+ int dx = qAbs(m_mousePressPosition.x() - e->x());
+ int dy = qAbs(m_mousePressPosition.y() - e->y());
+
+ if (dx + dy < 2) {
+ m_selectionState->type = SelectionState::None;
+ emit selectionChanged();
+ }
+}
+
+
+void GraphAxisWidget::setRange(qint64 min, qint64 max)
+{
+ m_valueMin = min;
+ m_valueMax = max;
+ update();
+}
+
+
+void GraphAxisWidget::setView(qint64 start, qint64 end)
+{
+ m_valueBegin = start;
+ m_valueEnd = end;
+ update();
+}
+
+#include "graphaxiswidget.moc"
--- /dev/null
+#ifndef GRAPHAXISWIDGET_H
+#define GRAPHAXISWIDGET_H
+
+#include "graphing.h"
+
+#include <QWidget>
+
+/**
+ * The generic base class of all graph axes.
+ *
+ * Handles orientation, simple selections, and view area.
+ */
+class GraphAxisWidget : public QWidget {
+ Q_OBJECT
+public:
+ enum Orientation {
+ Horizontal,
+ Vertical
+ };
+
+ enum SelectionStyle {
+ None,
+ Single,
+ Range
+ };
+
+public:
+ GraphAxisWidget(QWidget* parent = 0);
+ virtual ~GraphAxisWidget(){}
+
+ /* Is this axis part of the active selection */
+ bool hasSelection();
+
+ void setSelectable(SelectionStyle selectable);
+ void setSelectionState(SelectionState* state);
+
+ void setOrientation(Orientation v);
+
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+
+public slots:
+ /* The minimum and maximum values of this axis */
+ void setRange(qint64 min, qint64 max);
+
+ /* The currently visible range of values */
+ void setView(qint64 start, qint64 end);
+
+signals:
+ void selectionChanged();
+
+protected:
+ Orientation m_orientation;
+
+ /* The min/max value of this axis */
+ qint64 m_valueMin;
+ qint64 m_valueMax;
+
+ /* The highest and lowest currently visible value */
+ qint64 m_valueBegin;
+ qint64 m_valueEnd;
+
+ /* Selection */
+ SelectionStyle m_selectable;
+ SelectionState* m_selectionState;
+
+ /* Mouse tracking */
+ QPoint m_mousePressPosition;
+ qint64 m_mousePressValue;
+};
+
+#endif
--- /dev/null
+#ifndef GRAPHING_H
+#define GRAPHING_H
+
+#include <QString>
+
+/**
+ * A simple struct to hold a horizontal or vertical selection
+ */
+struct SelectionState {
+ enum SelectionType {
+ None,
+ Horizontal,
+ Vertical
+ };
+
+ SelectionType type;
+ qint64 start;
+ qint64 end;
+};
+
+
+/**
+ * Fairly generic data provider for graphs
+ */
+class GraphDataProvider {
+public:
+ virtual ~GraphDataProvider(){}
+
+ /* Number of elements in graph */
+ virtual qint64 size() const = 0;
+
+ /* Returns value for index */
+ virtual qint64 value(qint64 index) const = 0;
+
+ /* Is the item at index selected */
+ virtual bool selected(qint64 index) const = 0;
+
+ /* Get mouse hover tooltip for item */
+ virtual QString itemTooltip(qint64 index) const = 0;
+
+ /* Called on item double click */
+ virtual void itemDoubleClicked(qint64 index) const = 0;
+
+ /* Set pointer to selection state */
+ virtual void setSelectionState(SelectionState* state) = 0;
+};
+
+#endif
--- /dev/null
+#ifndef GRAPHLABELWIDGET_H
+#define GRAPHLABELWIDGET_H
+
+#include <QWidget>
+#include <QPainter>
+
+/**
+ * A very simple label widget, basically a box with text in.
+ */
+class GraphLabelWidget : public QWidget {
+public:
+ GraphLabelWidget(QString text = QString(), QWidget* parent = 0) :
+ QWidget(parent),
+ m_flags(Qt::AlignHCenter | Qt::AlignVCenter),
+ m_text(text)
+ {
+ }
+
+ void setText(const QString& text)
+ {
+ m_text = text;
+ }
+
+ void setFlags(int flags)
+ {
+ m_flags = flags;
+ }
+
+ virtual void paintEvent(QPaintEvent *)
+ {
+ QPainter painter(this);
+ painter.setPen(Qt::black);
+ painter.fillRect(rect(), Qt::lightGray);
+ painter.drawText(rect(), m_flags, m_text);
+ }
+
+protected:
+ int m_flags;
+ QString m_text;
+};
+
+#endif
--- /dev/null
+#include "graphview.h"
+
+#include <QMouseEvent>
+#include <QApplication>
+
+GraphView::GraphView(QWidget* parent) :
+ QWidget(parent),
+ m_viewLeft(0),
+ m_viewRight(0),
+ m_viewBottom(0),
+ m_viewTop(0),
+ m_graphLeft(0),
+ m_graphRight(0),
+ m_graphBottom(0),
+ m_graphTop(0),
+ m_viewWidth(0),
+ m_viewWidthMin(0),
+ m_viewWidthMax(0),
+ m_viewHeight(0),
+ m_viewHeightMin(0),
+ m_viewHeightMax(0),
+ m_selectionState(NULL)
+{
+ memset(&m_previous, -1, sizeof(m_previous));
+}
+
+void GraphView::update()
+{
+ if (m_graphLeft != m_previous.m_graphLeft || m_graphRight != m_previous.m_graphRight) {
+ m_previous.m_graphLeft = m_graphLeft;
+ m_previous.m_graphRight = m_graphRight;
+
+ emit horizontalRangeChanged(m_graphLeft, m_graphRight);
+ }
+
+ if (m_viewLeft != m_previous.m_viewLeft || m_viewRight != m_previous.m_viewRight) {
+ m_previous.m_viewLeft = m_viewLeft;
+ m_previous.m_viewRight = m_viewRight;
+
+ emit horizontalViewChanged(m_viewLeft, m_viewRight);
+ }
+
+ if (m_graphBottom != m_previous.m_graphBottom || m_graphTop != m_previous.m_graphTop) {
+ m_previous.m_graphBottom = m_graphBottom;
+ m_previous.m_graphTop = m_graphTop;
+
+ emit verticalRangeChanged(m_graphBottom, m_graphTop);
+ }
+
+ if (m_viewBottom != m_previous.m_viewBottom || m_viewTop != m_previous.m_viewTop) {
+ m_previous.m_viewBottom = m_viewBottom;
+ m_previous.m_viewTop = m_viewTop;
+
+ emit verticalViewChanged(m_viewBottom, m_viewTop);
+ }
+
+ QWidget::update();
+}
+
+void GraphView::resizeEvent(QResizeEvent *)
+{
+ m_viewHeight = height();
+ m_viewHeightMin = m_viewHeight;
+ m_viewHeightMax = m_viewHeight;
+
+ m_viewTop = m_viewBottom + m_viewHeight;
+
+ update();
+}
+
+void GraphView::wheelEvent(QWheelEvent *e)
+{
+ int zoomPercent = 10;
+
+ /* If holding Ctrl key then zoom 2x faster */
+ if (QApplication::keyboardModifiers() & Qt::ControlModifier) {
+ zoomPercent = 20;
+ }
+
+ /* Zoom view by adjusting width */
+ double dt = m_viewWidth;
+ double size = dt;
+ size *= -e->delta();
+
+ /* Zoom deltas normally come in increments of 120 */
+ size /= 120 * (100 / zoomPercent);
+
+ m_viewWidth += size;
+ m_viewWidth = qBound(m_viewWidthMin, m_viewWidth, m_viewWidthMax);
+
+ /* Scroll view to zoom around mouse */
+ dt -= m_viewWidth;
+ dt *= e->x();
+ dt /= width();
+
+ m_viewLeft = dt + m_viewLeft;
+ m_viewLeft = qBound(m_graphLeft, m_viewLeft, m_graphRight - m_viewWidth);
+ m_viewRight = m_viewLeft + m_viewWidth;
+
+ update();
+}
+
+void GraphView::mouseMoveEvent(QMouseEvent *e)
+{
+ if (e->buttons().testFlag(Qt::LeftButton)) {
+ /* Horizontal scroll */
+ double dvdx = m_viewWidth / (double)width();
+ dvdx *= m_mousePressPosition.x() - e->pos().x();
+
+ m_viewLeft = m_mousePressViewLeft + dvdx;
+ m_viewLeft = qBound(m_graphLeft, m_viewLeft, m_graphRight - m_viewWidth);
+ m_viewRight = m_viewLeft + m_viewWidth;
+
+ /* Vertical scroll */
+ double dvdy = m_viewHeight / (double)height();
+ dvdy *= m_mousePressPosition.y() - e->pos().y();
+
+ m_viewBottom = m_mousePressViewBottom + dvdy;
+ m_viewBottom = qBound(m_graphBottom, m_viewBottom, m_graphTop - m_viewHeight);
+ m_viewTop = m_viewBottom + m_viewHeight;
+
+ update();
+ }
+}
+
+void GraphView::mousePressEvent(QMouseEvent *e)
+{
+ m_mousePressPosition = e->pos();
+ m_mousePressViewLeft = m_viewLeft;
+ m_mousePressViewBottom = m_viewBottom;
+}
+
+void GraphView::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (m_selectionState) {
+ m_selectionState->type = SelectionState::None;
+ emit selectionChanged();
+ }
+}
+
+void GraphView::setSelectionState(SelectionState* state)
+{
+ m_selectionState = state;
+}
+
+void GraphView::setHorizontalView(qint64 start, qint64 end)
+{
+ m_viewLeft = qBound(m_graphLeft, start, m_graphRight - (end - start));
+ m_viewRight = qBound(m_graphLeft, end, m_graphRight);
+ m_viewWidth = m_viewRight - m_viewLeft;
+ update();
+}
+
+void GraphView::setVerticalView(qint64 start, qint64 end)
+{
+ m_viewBottom = qBound(m_graphBottom, start, m_graphTop - (end - start));
+ m_viewTop = qBound(m_graphBottom, end, m_graphTop);
+ m_viewHeight = m_viewTop - m_viewBottom;
+ update();
+}
+
+void GraphView::setDefaultView(qint64 min, qint64 max)
+{
+ m_graphLeft = min;
+ m_graphRight = max;
+ m_viewWidth = max - min;
+
+ m_viewWidthMin = 1;
+ m_viewWidthMax = m_viewWidth;
+
+ m_viewLeft = min;
+ m_viewRight = max;
+
+ m_viewHeight = height();
+ m_viewHeightMin = m_viewHeight;
+ m_viewHeightMax = m_viewHeight;
+
+ m_viewBottom = 0;
+ m_viewTop = m_viewHeight;
+
+ m_graphBottom = 0;
+ m_graphTop = m_viewHeight;
+
+ update();
+}
+
+#include "graphview.moc"
--- /dev/null
+#ifndef GRAPHVIEW_H
+#define GRAPHVIEW_H
+
+#include "graphing.h"
+
+#include <QWidget>
+
+/**
+ * The generic base class for a graph's view, this is the component that
+ * displays the actual data for the graph.
+ *
+ * - Stores the view area within the graph
+ * - Simple user interaction such as translating and zooming with mouse
+ * - Selection tracking synchronised with axis
+ */
+class GraphView : public QWidget {
+ Q_OBJECT
+public:
+ GraphView(QWidget* parent = 0);
+ virtual ~GraphView(){}
+
+ virtual void update();
+
+ virtual void resizeEvent(QResizeEvent *);
+
+ virtual void wheelEvent(QWheelEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+
+ virtual void setSelectionState(SelectionState* state);
+
+ void setHorizontalView(qint64 start, qint64 end);
+ void setVerticalView(qint64 start, qint64 end);
+
+protected:
+ void setDefaultView(qint64 min, qint64 max);
+
+signals:
+ void selectionChanged();
+
+ void verticalViewChanged(qint64 start, qint64 end);
+ void verticalRangeChanged(qint64 min, qint64 max);
+
+ void horizontalRangeChanged(qint64 min, qint64 max);
+ void horizontalViewChanged(qint64 start, qint64 end);
+
+protected:
+ /* Viewport area */
+ qint64 m_viewLeft;
+ qint64 m_viewRight;
+ qint64 m_viewBottom;
+ qint64 m_viewTop;
+
+ /* Graph limits */
+ qint64 m_graphLeft;
+ qint64 m_graphRight;
+ qint64 m_graphBottom;
+ qint64 m_graphTop;
+
+ /* Viewport width (m_viewRight - m_viewLeft), used for zoom */
+ qint64 m_viewWidth;
+ qint64 m_viewWidthMin;
+ qint64 m_viewWidthMax;
+
+ /* Viewport height (m_viewTop - m_viewBottom), used for zoom */
+ qint64 m_viewHeight;
+ qint64 m_viewHeightMin;
+ qint64 m_viewHeightMax;
+
+ /* Mouse tracking */
+ QPoint m_mousePressPosition;
+ qint64 m_mousePressViewLeft;
+ qint64 m_mousePressViewBottom;
+
+ /* Selection */
+ SelectionState* m_selectionState;
+
+ /* State from the last update() call */
+ struct PreviousUpdate {
+ qint64 m_viewLeft;
+ qint64 m_viewRight;
+ qint64 m_viewBottom;
+ qint64 m_viewTop;
+
+ qint64 m_graphLeft;
+ qint64 m_graphRight;
+ qint64 m_graphBottom;
+ qint64 m_graphTop;
+ } m_previous;
+};
+
+#endif
--- /dev/null
+#include "graphwidget.h"
+
+#include <QScrollBar>
+
+GraphWidget::GraphWidget(QWidget* parent) :
+ QWidget(parent),
+ m_view(NULL),
+ m_label(NULL),
+ m_axisTop(NULL),
+ m_axisLeft(NULL),
+ m_axisRight(NULL),
+ m_axisBottom(NULL),
+ m_horizontalScrollbar(NULL),
+ m_horizontalMin(0),
+ m_horizontalMax(0),
+ m_horizontalStart(0),
+ m_horizontalEnd(0),
+ m_horizontalScrollbarPolicy(Qt::ScrollBarAlwaysOff),
+ m_verticalScrollbar(NULL),
+ m_verticalMin(0),
+ m_verticalMax(0),
+ m_verticalStart(0),
+ m_verticalEnd(0),
+ m_verticalScrollbarPolicy(Qt::ScrollBarAlwaysOff)
+{
+ m_selection.type = SelectionState::None;
+
+ m_verticalScrollbar = new QScrollBar(this);
+ m_verticalScrollbar->setOrientation(Qt::Vertical);
+ m_verticalScrollbar->hide();
+ m_verticalScrollbar->resize(m_verticalScrollbar->sizeHint());
+
+ m_horizontalScrollbar = new QScrollBar(this);
+ m_horizontalScrollbar->setOrientation(Qt::Horizontal);
+ m_horizontalScrollbar->hide();
+ m_horizontalScrollbar->resize(m_horizontalScrollbar->sizeHint());
+
+ updateLayout();
+ setAutoFillBackground(true);
+}
+
+
+GraphView* GraphWidget::view()
+{
+ return m_view;
+}
+
+
+GraphLabelWidget* GraphWidget::label()
+{
+ return m_label;
+}
+
+
+GraphAxisWidget* GraphWidget::axis(AxisPosition pos)
+{
+ switch(pos) {
+ case AxisTop:
+ return m_axisTop;
+
+ case AxisLeft:
+ return m_axisLeft;
+
+ case AxisRight:
+ return m_axisRight;
+
+ case AxisBottom:
+ return m_axisBottom;
+
+ default:
+ return NULL;
+ }
+}
+
+
+void GraphWidget::setView(GraphView* view)
+{
+ delete m_view;
+ m_view = view;
+
+ updateConnections();
+
+ m_view->setSelectionState(&m_selection);
+ m_view->show();
+ m_view->update();
+}
+
+
+void GraphWidget::setLabel(GraphLabelWidget* label)
+{
+ delete m_label;
+ m_label = label;
+}
+
+
+void GraphWidget::setAxis(AxisPosition pos, GraphAxisWidget* axis)
+{
+ switch(pos) {
+ case AxisTop:
+ delete m_axisTop;
+ m_axisTop = axis;
+ m_axisTop->setOrientation(GraphAxisWidget::Horizontal);
+ m_axisTop->setSelectionState(&m_selection);
+ break;
+
+ case AxisLeft:
+ delete m_axisLeft;
+ m_axisLeft = axis;
+ m_axisLeft->setOrientation(GraphAxisWidget::Vertical);
+ m_axisLeft->setSelectionState(&m_selection);
+ break;
+
+ case AxisRight:
+ delete m_axisRight;
+ m_axisRight = axis;
+ m_axisRight->setOrientation(GraphAxisWidget::Vertical);
+ m_axisRight->setSelectionState(&m_selection);
+ break;
+
+ case AxisBottom:
+ delete m_axisBottom;
+ m_axisBottom = axis;
+ m_axisBottom->setOrientation(GraphAxisWidget::Horizontal);
+ m_axisBottom->setSelectionState(&m_selection);
+ break;
+ }
+
+ updateConnections();
+ updateSelection();
+ axis->show();
+}
+
+
+void GraphWidget::setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy)
+{
+ m_horizontalScrollbarPolicy = policy;
+ updateScrollbars();
+}
+
+
+void GraphWidget::setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy)
+{
+ m_verticalScrollbarPolicy = policy;
+ updateScrollbars();
+}
+
+
+void GraphWidget::resizeEvent(QResizeEvent *e)
+{
+ updateLayout();
+ update();
+}
+
+
+/* Used if a selection would be shared between graphs with different axis */
+SelectionState GraphWidget::transformSelectionIn(SelectionState state)
+{
+ return state;
+}
+
+
+/* Used if a selection would be shared between graphs with different axis */
+SelectionState GraphWidget::transformSelectionOut(SelectionState state)
+{
+ return state;
+}
+
+
+/* Update the scrollbars based on current view */
+void GraphWidget::updateScrollbars()
+{
+ /* Vertical scroll bar */
+ qint64 size = (m_verticalMax - m_verticalMin) - (m_verticalEnd - m_verticalStart);
+
+ if (size <= INT_MAX) {
+ m_verticalScrollbar->setValue(m_verticalStart - m_verticalMin);
+ m_verticalScrollbar->setPageStep(m_verticalEnd - m_verticalStart);
+ m_verticalScrollbar->setRange(0, size);
+ } else {
+ /* QScrollBar only supports up to INT_MAX values,
+ * here we must scale our values to match this */
+ double curSize = m_verticalEnd - m_verticalStart;
+ double pages = (m_verticalMax - m_verticalMin) / curSize;
+ double value = (m_verticalStart - m_verticalMin) / curSize;
+
+ m_verticalScrollbar->setValue(value);
+ m_verticalScrollbar->setPageStep(1);
+ m_verticalScrollbar->setRange(0, pages);
+ }
+
+ /* Adhere to scrollbar policy */
+ bool visible = false;
+
+ if (m_verticalScrollbarPolicy == Qt::ScrollBarAlwaysOn) {
+ visible = true;
+ } else if (m_verticalScrollbarPolicy == Qt::ScrollBarAlwaysOff) {
+ visible = false;
+ } else if (m_verticalScrollbarPolicy == Qt::ScrollBarAsNeeded) {
+ visible = m_verticalMin != m_verticalStart || m_verticalMax != m_verticalEnd;
+ }
+
+ if (visible != m_verticalScrollbar->isVisible()) {
+ m_verticalScrollbar->setVisible(visible);
+ updateLayout();
+ }
+
+ /* Horizontal scroll bar */
+ size = (m_horizontalMax - m_horizontalMin) - (m_horizontalEnd - m_horizontalStart);
+
+ if (size <= INT_MAX) {
+ m_horizontalScrollbar->setValue(m_horizontalStart - m_horizontalMin);
+ m_horizontalScrollbar->setPageStep(m_horizontalEnd - m_horizontalStart);
+ m_horizontalScrollbar->setRange(0, size);
+ } else {
+ /* QScrollBar only supports up to INT_MAX values,
+ * here we must scale our values to match this */
+ double dxdv = INT_MAX / (double)size;
+ double value = (m_horizontalStart - m_horizontalMin) * dxdv;
+ double pageStep = (m_horizontalEnd - m_horizontalStart) * dxdv;
+
+ m_horizontalScrollbar->setValue((int)value);
+ m_horizontalScrollbar->setPageStep((int)pageStep);
+ m_horizontalScrollbar->setRange(0, INT_MAX);
+ }
+
+ /* Adhere to scrollbar policy */
+ visible = false;
+
+ if (m_horizontalScrollbarPolicy == Qt::ScrollBarAlwaysOn) {
+ visible = true;
+ } else if (m_horizontalScrollbarPolicy == Qt::ScrollBarAlwaysOff) {
+ visible = false;
+ } else if (m_horizontalScrollbarPolicy == Qt::ScrollBarAsNeeded) {
+ visible = m_horizontalMin != m_horizontalStart || m_horizontalMax != m_horizontalEnd;
+ }
+
+ if (visible != m_horizontalScrollbar->isVisible()) {
+ m_horizontalScrollbar->setVisible(visible);
+ updateLayout();
+ }
+}
+
+
+/* Update all signal / slot connections */
+void GraphWidget::updateConnections()
+{
+ if (m_view) {
+ connect(m_view, SIGNAL(selectionChanged()), this, SLOT(updateSelection()), Qt::UniqueConnection);
+
+ connect(m_view, SIGNAL(horizontalViewChanged(qint64,qint64)), this, SLOT(horizontalViewChange(qint64,qint64)), Qt::UniqueConnection);
+ connect(m_view, SIGNAL(horizontalRangeChanged(qint64,qint64)), this, SLOT(horizontalRangeChange(qint64,qint64)), Qt::UniqueConnection);
+
+ connect(m_view, SIGNAL(verticalViewChanged(qint64,qint64)), this, SLOT(verticalViewChange(qint64,qint64)), Qt::UniqueConnection);
+ connect(m_view, SIGNAL(verticalRangeChanged(qint64,qint64)), this, SLOT(verticalRangeChange(qint64,qint64)), Qt::UniqueConnection);
+ }
+
+ if (m_axisTop) {
+ if (m_view) {
+ connect(m_view, SIGNAL(horizontalViewChanged(qint64,qint64)), m_axisTop, SLOT(setView(qint64,qint64)), Qt::UniqueConnection);
+ connect(m_view, SIGNAL(horizontalRangeChanged(qint64,qint64)), m_axisTop, SLOT(setRange(qint64,qint64)), Qt::UniqueConnection);
+ }
+
+ connect(m_axisTop, SIGNAL(selectionChanged()), this, SLOT(updateSelection()), Qt::UniqueConnection);
+ }
+
+ if (m_axisLeft) {
+ if (m_view) {
+ connect(m_view, SIGNAL(verticalViewChanged(qint64,qint64)), m_axisLeft, SLOT(setView(qint64,qint64)), Qt::UniqueConnection);
+ connect(m_view, SIGNAL(verticalRangeChanged(qint64,qint64)), m_axisLeft, SLOT(setRange(qint64,qint64)), Qt::UniqueConnection);
+ }
+
+ connect(m_axisLeft, SIGNAL(selectionChanged()), this, SLOT(updateSelection()), Qt::UniqueConnection);
+ }
+
+ if (m_axisRight) {
+ if (m_view) {
+ connect(m_view, SIGNAL(verticalViewChanged(qint64,qint64)), m_axisRight, SLOT(setView(qint64,qint64)), Qt::UniqueConnection);
+ connect(m_view, SIGNAL(verticalRangeChanged(qint64,qint64)), m_axisRight, SLOT(setRange(qint64,qint64)), Qt::UniqueConnection);
+ }
+
+ connect(m_axisRight, SIGNAL(selectionChanged()), this, SLOT(updateSelection()), Qt::UniqueConnection);
+ }
+
+ if (m_axisBottom) {
+ if (m_view) {
+ connect(m_view, SIGNAL(horizontalViewChanged(qint64,qint64)), m_axisBottom, SLOT(setView(qint64,qint64)), Qt::UniqueConnection);
+ connect(m_view, SIGNAL(horizontalRangeChanged(qint64,qint64)), m_axisBottom, SLOT(setRange(qint64,qint64)), Qt::UniqueConnection);
+ }
+
+ connect(m_axisBottom, SIGNAL(selectionChanged()), this, SLOT(updateSelection()), Qt::UniqueConnection);
+ }
+
+ if (m_horizontalScrollbar) {
+ connect(m_horizontalScrollbar, SIGNAL(actionTriggered(int)), this, SLOT(horizontalScrollAction(int)));
+ }
+
+ if (m_verticalScrollbar) {
+ connect(m_verticalScrollbar, SIGNAL(actionTriggered(int)), this, SLOT(verticalScrollAction(int)));
+ }
+}
+
+
+/* Recalculate the layout */
+void GraphWidget::updateLayout()
+{
+ int x, y;
+ int padX = 0, padY = 0;
+
+ if (m_axisTop) {
+ padY += m_axisTop->height();
+ }
+
+ if (m_axisBottom) {
+ padY += m_axisBottom->height();
+ }
+
+ if (m_axisLeft) {
+ padX += m_axisLeft->width();
+ }
+
+ if (m_axisRight) {
+ padX += m_axisRight->width();
+ }
+
+ if (m_horizontalScrollbar->isVisible()) {
+ padY += m_horizontalScrollbar->height();
+ }
+
+ if (m_verticalScrollbar->isVisible()) {
+ padX += m_verticalScrollbar->width();
+ }
+
+ if (m_axisTop) {
+ x = m_axisLeft ? m_axisLeft->width() : 0;
+ y = 0;
+
+ m_axisTop->move(x, y);
+ m_axisTop->resize(width() - padX, m_axisTop->height());
+ }
+
+ if (m_axisBottom) {
+ x = m_axisLeft ? m_axisLeft->width() : 0;
+ y = height() - m_axisBottom->height();
+
+ if (m_horizontalScrollbar->isVisible()) {
+ y -= m_horizontalScrollbar->height();
+ }
+
+ m_axisBottom->move(x, y);
+ m_axisBottom->resize(width() - padX, m_axisBottom->height());
+ }
+
+ if (m_axisLeft) {
+ x = 0;
+ y = m_axisTop ? m_axisTop->height() : 0;
+
+ m_axisLeft->move(x, y);
+ m_axisLeft->resize(m_axisLeft->width(), height() - padY);
+ }
+
+ if (m_axisRight) {
+ x = width() - m_axisRight->width();
+ y = m_axisTop ? m_axisTop->height() : 0;
+
+ if (m_verticalScrollbar->isVisible()) {
+ x -= m_verticalScrollbar->width();
+ }
+
+ m_axisRight->move(x, y);
+ m_axisRight->resize(m_axisRight->width(), height() - padY);
+ }
+
+ if (m_view) {
+ x = m_axisLeft ? m_axisLeft->width() : 0;
+ y = m_axisTop ? m_axisTop->height() : 0;
+
+ m_view->move(x, y);
+ m_view->resize(width() - padX, height() - padY);
+ }
+
+ if (m_label) {
+ if (m_axisTop && m_axisLeft) {
+ m_label->move(0, 0);
+ m_label->resize(m_axisLeft->width(), m_axisTop->height());
+ }
+ }
+
+ if (m_verticalScrollbar) {
+ m_verticalScrollbar->move(width() - m_verticalScrollbar->width(), 0);
+
+ if (m_horizontalScrollbar) {
+ m_verticalScrollbar->resize(m_verticalScrollbar->width(), height() - m_horizontalScrollbar->height());
+ } else {
+ m_verticalScrollbar->resize(m_verticalScrollbar->width(), height());
+ }
+ }
+
+ if (m_horizontalScrollbar) {
+ m_horizontalScrollbar->move(0, height() - m_horizontalScrollbar->height());
+
+ if (m_verticalScrollbar) {
+ m_horizontalScrollbar->resize(width() - m_verticalScrollbar->width(), m_horizontalScrollbar->height());
+ } else {
+ m_horizontalScrollbar->resize(width(), m_horizontalScrollbar->height());
+ }
+ }
+}
+
+
+void GraphWidget::setSelection(SelectionState state)
+{
+ m_selection = transformSelectionIn(state);
+ updateSelection(false);
+}
+
+
+void GraphWidget::setHorizontalView(qint64 start, qint64 end)
+{
+ if (m_view) {
+ m_view->setHorizontalView(start, end);
+ }
+}
+
+
+void GraphWidget::setVerticalView(qint64 start, qint64 end)
+{
+ if (m_view) {
+ m_view->setVerticalView(start, end);
+ }
+}
+
+
+/* Called when the view is translated / zoomed */
+void GraphWidget::verticalViewChange(qint64 start, qint64 end)
+{
+ m_verticalStart = start;
+ m_verticalEnd = end;
+ updateScrollbars();
+
+ emit verticalViewChanged(start, end);
+}
+
+
+void GraphWidget::verticalRangeChange(qint64 start, qint64 end)
+{
+ m_verticalMin = start;
+ m_verticalMax = end;
+ updateScrollbars();
+
+ emit verticalRangeChanged(start, end);
+}
+
+
+void GraphWidget::horizontalViewChange(qint64 start, qint64 end)
+{
+ m_horizontalStart = start;
+ m_horizontalEnd = end;
+ updateScrollbars();
+
+ emit horizontalViewChanged(start, end);
+}
+
+
+void GraphWidget::horizontalRangeChange(qint64 start, qint64 end)
+{
+ m_horizontalMin = start;
+ m_horizontalMax = end;
+ updateScrollbars();
+
+ emit horizontalRangeChanged(start, end);
+}
+
+
+/* User interaction with horizontal scroll bar */
+void GraphWidget::horizontalScrollAction(int /*action*/)
+{
+ int value = m_horizontalScrollbar->sliderPosition();
+ qint64 size = (m_horizontalMax - m_horizontalMin) - (m_horizontalEnd - m_horizontalStart);
+
+ /* Calculate the new scroll values */
+ if (size <= INT_MAX) {
+ m_horizontalEnd -= m_horizontalStart;
+ m_horizontalStart = value + m_horizontalMin;
+ m_horizontalEnd += value;
+ } else {
+ /* QScrollBar only supports up to INT_MAX values, here we must scale
+ * our values to match this */
+ double dxdv = INT_MAX / (double)size;
+
+ size = m_horizontalEnd - m_horizontalStart;
+ m_horizontalStart = value / dxdv + m_horizontalMin;
+ m_horizontalEnd = m_horizontalStart + size;
+ }
+
+ /* Update view */
+ if (m_view) {
+ m_view->setHorizontalView(m_horizontalStart, m_horizontalEnd);
+ }
+
+ /* Update horizontal axes */
+ if (m_axisTop) {
+ m_axisTop->setView(m_horizontalStart, m_horizontalEnd);
+ }
+
+ if (m_axisBottom) {
+ m_axisBottom->setView(m_horizontalStart, m_horizontalEnd);
+ }
+
+ /* Inform the world of our changes! */
+ emit horizontalViewChanged(m_horizontalStart, m_horizontalEnd);
+}
+
+
+/* User interaction with vertical scroll bar */
+void GraphWidget::verticalScrollAction(int /*action*/)
+{
+ int value = m_verticalScrollbar->sliderPosition();
+ qint64 size = (m_verticalMax - m_verticalMin) - (m_verticalEnd - m_verticalStart);
+
+ /* Calculate the new scroll values */
+ if (size <= INT_MAX) {
+ m_verticalEnd -= m_verticalStart;
+ m_verticalStart = value + m_verticalMin;
+ m_verticalEnd += value;
+ } else {
+ /* QScrollBar only supports up to INT_MAX values, here we must scale
+ * our values to match this */
+ double dxdv = INT_MAX / (double)size;
+
+ size = m_verticalEnd - m_verticalStart;
+ m_verticalStart = value / dxdv + m_verticalMin;
+ m_verticalEnd = m_verticalStart + size;
+ }
+
+ /* Update view */
+ if (m_view) {
+ m_view->setVerticalView(m_verticalStart, m_verticalEnd);
+ }
+
+ /* Update vertical axes */
+ if (m_axisLeft) {
+ m_axisLeft->setView(m_verticalStart, m_verticalEnd);
+ }
+
+ if (m_axisRight) {
+ m_axisRight->setView(m_verticalStart, m_verticalEnd);
+ }
+
+ /* Inform the world of our changes! */
+ emit verticalViewChanged(m_verticalStart, m_verticalEnd);
+}
+
+
+/* Update child elements when selection changes */
+void GraphWidget::updateSelection(bool emitSignal)
+{
+ if (m_view) {
+ m_view->update();
+ }
+
+ if (m_axisTop) {
+ m_axisTop->update();
+ }
+
+ if (m_axisLeft) {
+ m_axisLeft->update();
+ }
+
+ if (m_axisRight) {
+ m_axisRight->update();
+ }
+
+ if (m_axisBottom) {
+ m_axisBottom->update();
+ }
+
+ if (emitSignal) {
+ emit selectionChanged(transformSelectionOut(m_selection));
+ }
+}
+
+
+#include "graphwidget.moc"
--- /dev/null
+#ifndef GRAPHWIDGET_H
+#define GRAPHWIDGET_H
+
+#include "graphview.h"
+#include "graphaxiswidget.h"
+#include "graphlabelwidget.h"
+
+class QScrollBar;
+
+/**
+ * The generic GraphWidget class which combines the elements of a graph,
+ * the axis, view, scrollbars and label.
+ */
+class GraphWidget : public QWidget {
+ Q_OBJECT
+public:
+ enum AxisPosition {
+ AxisTop,
+ AxisLeft,
+ AxisRight,
+ AxisBottom
+ };
+
+public:
+ GraphWidget(QWidget* parent = 0);
+ virtual ~GraphWidget(){}
+
+ GraphView* view();
+ GraphLabelWidget* label();
+ GraphAxisWidget* axis(AxisPosition pos);
+
+ void setView(GraphView* view);
+ void setLabel(GraphLabelWidget* label);
+ void setAxis(AxisPosition pos, GraphAxisWidget* axis);
+
+ void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy policy);
+ void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy policy);
+
+ virtual void resizeEvent(QResizeEvent *e);
+
+protected:
+ /* Used if a selection would be shared between graphs with different axis */
+ virtual SelectionState transformSelectionIn(SelectionState state);
+ virtual SelectionState transformSelectionOut(SelectionState state);
+
+ /* Update the scrollbars based on current view */
+ void updateScrollbars();
+
+ /* Update all signal / slot connections */
+ void updateConnections();
+
+ /* Recalculate child widget layout */
+ void updateLayout();
+
+public slots:
+ void setSelection(SelectionState state);
+
+ /* Set view areas */
+ void setHorizontalView(qint64 start, qint64 end);
+ void setVerticalView(qint64 start, qint64 end);
+
+protected slots:
+ /* View changed by translation / zooming */
+ void verticalViewChange(qint64 start, qint64 end);
+ void verticalRangeChange(qint64 start, qint64 end);
+ void horizontalViewChange(qint64 start, qint64 end);
+ void horizontalRangeChange(qint64 start, qint64 end);
+
+ /* User interaction with scroll bars */
+ void horizontalScrollAction(int action);
+ void verticalScrollAction(int action);
+
+ /* Update child elements when selection changes */
+ void updateSelection(bool emitSignal = true);
+
+signals:
+ void selectionChanged(SelectionState state);
+
+ void verticalViewChanged(qint64 start, qint64 end);
+ void verticalRangeChanged(qint64 start, qint64 end);
+
+ void horizontalViewChanged(qint64 start, qint64 end);
+ void horizontalRangeChanged(qint64 start, qint64 end);
+
+protected:
+ SelectionState m_selection;
+
+ GraphView* m_view;
+
+ GraphLabelWidget* m_label;
+
+ GraphAxisWidget* m_axisTop;
+ GraphAxisWidget* m_axisLeft;
+ GraphAxisWidget* m_axisRight;
+ GraphAxisWidget* m_axisBottom;
+
+ QScrollBar* m_horizontalScrollbar;
+ qint64 m_horizontalMin;
+ qint64 m_horizontalMax;
+ qint64 m_horizontalStart;
+ qint64 m_horizontalEnd;
+ Qt::ScrollBarPolicy m_horizontalScrollbarPolicy;
+
+ QScrollBar* m_verticalScrollbar;
+ qint64 m_verticalMin;
+ qint64 m_verticalMax;
+ qint64 m_verticalStart;
+ qint64 m_verticalEnd;
+ Qt::ScrollBarPolicy m_verticalScrollbarPolicy;
+};
+
+#endif
--- /dev/null
+#include "heatmapverticalaxiswidget.h"
+
+#include <qmath.h>
+#include <QPainter>
+#include <QMouseEvent>
+
+HeatmapVerticalAxisWidget::HeatmapVerticalAxisWidget(QWidget* parent) :
+ GraphAxisWidget(parent),
+ m_data(NULL)
+{
+ m_rowHeight = 20;
+}
+
+void HeatmapVerticalAxisWidget::setDataProvider(HeatmapDataProvider* data)
+{
+ delete m_data;
+ m_data = data;
+
+ m_valueMin = 0;
+ m_valueMax = (data->dataRows() + data->headerRows()) * m_rowHeight;
+
+ m_valueBegin = m_valueMin;
+ m_valueEnd = m_valueMax;
+
+ update();
+}
+
+void HeatmapVerticalAxisWidget::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (e->pos().y() < m_data->headerRows() * m_rowHeight) {
+ m_selectionState->type = SelectionState::None;
+ emit selectionChanged();
+ } else {
+ int row = e->pos().y();
+ row -= m_data->headerRows() * m_rowHeight;
+ row += m_valueBegin;
+ row /= m_rowHeight;
+
+ if (row >= m_data->dataRows()) {
+ m_selectionState->type = SelectionState::None;
+ emit selectionChanged();
+ } else {
+ m_selectionState->type = SelectionState::Vertical;
+ m_selectionState->start = m_data->dataRowAt(row);
+ m_selectionState->end = m_selectionState->start;
+ emit selectionChanged();
+ }
+ }
+}
+
+void HeatmapVerticalAxisWidget::paintEvent(QPaintEvent *)
+{
+ if (!m_data) {
+ return;
+ }
+
+ QPainter painter(this);
+ painter.setPen(Qt::black);
+ painter.setBrush(Qt::lightGray);
+ painter.drawRect(0, 0, width() - 1, height() - 1);
+
+ /* Draw scrollable rows */
+ painter.translate(0, m_data->headerRows() * m_rowHeight - m_valueBegin % m_rowHeight);
+ int rowStart = m_valueBegin / m_rowHeight;
+ int rowEnd = qMin<int>(qCeil(m_valueEnd / (double)m_rowHeight), m_data->dataRows());
+
+ for (unsigned i = rowStart; i < rowEnd; ++i) {
+ painter.drawText(0, 0, width(), m_rowHeight, Qt::AlignHCenter | Qt::AlignVCenter, m_data->dataLabel(i));
+ painter.drawLine(0, m_rowHeight, width(), m_rowHeight);
+ painter.translate(0, m_rowHeight);
+ }
+
+ /* Draw fixed position headers */
+ painter.resetTransform();
+ painter.drawRect(0, 0, width() - 1, m_data->headerRows() * m_rowHeight);
+
+ for (unsigned i = 0; i < m_data->headerRows(); ++i) {
+ painter.drawText(0, 0, width(), m_rowHeight, Qt::AlignHCenter | Qt::AlignVCenter, m_data->headerLabel(i));
+ painter.drawLine(0, m_rowHeight, width(), m_rowHeight);
+ painter.translate(0, m_rowHeight);
+ }
+}
--- /dev/null
+#ifndef HEATMAPVERTICALAXISWIDGET_H
+#define HEATMAPVERTICALAXISWIDGET_H
+
+#include "heatmapview.h"
+#include "graphaxiswidget.h"
+
+/**
+ * Vertical axis specifically for heatmap displaying header and data rows
+ */
+class HeatmapVerticalAxisWidget : public GraphAxisWidget {
+public:
+ HeatmapVerticalAxisWidget(QWidget* parent);
+
+ void setDataProvider(HeatmapDataProvider* data);
+
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void paintEvent(QPaintEvent *);
+
+protected:
+ int m_rowHeight;
+ HeatmapDataProvider* m_data;
+};
+
+#endif
--- /dev/null
+#include "heatmapview.h"
+
+#include <qmath.h>
+#include <QToolTip>
+#include <QPainter>
+#include <QMouseEvent>
+
+HeatmapView::HeatmapView(QWidget* parent) :
+ GraphView(parent),
+ m_data(NULL)
+{
+ m_rowHeight = 20;
+ setMouseTracking(true);
+}
+
+
+void HeatmapView::setDataProvider(HeatmapDataProvider* data)
+{
+ delete m_data;
+ m_data = data;
+
+ if (m_data) {
+ m_data->setSelectionState(m_selectionState);
+
+ setDefaultView(m_data->start(), m_data->end());
+
+ m_viewWidthMin = 1000;
+
+ m_graphBottom = 0;
+ m_graphTop = (m_data->headerRows() + m_data->dataRows()) * m_rowHeight;
+ } else {
+ setDefaultView(0, 0);
+ m_graphBottom = m_graphTop = 0;
+ }
+
+ update();
+}
+
+
+void HeatmapView::setSelectionState(SelectionState* state)
+{
+ if (m_data) {
+ m_data->setSelectionState(state);
+ }
+
+ GraphView::setSelectionState(state);
+}
+
+
+void HeatmapView::mouseMoveEvent(QMouseEvent *e)
+{
+ GraphView::mouseMoveEvent(e);
+
+ if (e->buttons() || !m_data) {
+ QToolTip::hideText();
+ return;
+ }
+
+ qint64 index = itemAtPosition(e->pos());
+
+ if (index >= 0) {
+ QToolTip::showText(e->globalPos(), m_data->itemTooltip(index));
+ } else {
+ QToolTip::hideText();
+ }
+}
+
+
+void HeatmapView::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (m_data && e->button() == Qt::LeftButton) {
+ qint64 index = itemAtPosition(e->pos());
+
+ if (index >= 0) {
+ m_data->itemDoubleClicked(index);
+ return;
+ }
+ }
+
+ GraphView::mouseDoubleClickEvent(e);
+}
+
+
+void HeatmapView::paintEvent(QPaintEvent *)
+{
+ if (!m_data) {
+ return;
+ }
+
+ QPainter painter(this);
+ painter.fillRect(0, m_data->headerRows() * m_rowHeight, width(), height(), Qt::white);
+
+ /* Draw data rows */
+ painter.translate(0, m_data->headerRows() * m_rowHeight - m_viewBottom % m_rowHeight);
+ int rowStart = m_viewBottom / m_rowHeight;
+ int rowEnd = qMin<int>(qCeil(m_viewTop / (double)m_rowHeight), m_data->dataRows());
+
+ for (unsigned i = rowStart; i < rowEnd; ++i) {
+ HeatmapRowIterator* itr = m_data->dataRowIterator(i, m_viewLeft, m_viewRight, width());
+ paintRow(painter, itr);
+ painter.translate(0, m_rowHeight);
+ delete itr;
+ }
+
+ /* Draw Header */
+ painter.resetTransform();
+ painter.fillRect(0, 0, width(), m_data->headerRows() * m_rowHeight, Qt::white);
+
+ for (unsigned i = 0; i < m_data->headerRows(); ++i) {
+ HeatmapRowIterator* itr = m_data->headerRowIterator(i, m_viewLeft, m_viewRight, width());
+ paintRow(painter, itr);
+ painter.translate(0, m_rowHeight);
+ delete itr;
+ }
+
+ /* Draw Axis Lines */
+ painter.resetTransform();
+ painter.setPen(Qt::black);
+ painter.drawLine(0, m_rowHeight, width(), m_rowHeight);
+ painter.drawLine(0, m_rowHeight * 2, width(), m_rowHeight * 2);
+
+ painter.setPen(QColor(240, 240, 240));
+ painter.translate(0, m_data->headerRows() * m_rowHeight - m_viewBottom % m_rowHeight);
+
+ for (unsigned i = rowStart; i < rowEnd; ++i) {
+ painter.drawLine(0, m_rowHeight, width(), m_rowHeight);
+ painter.translate(0, m_rowHeight);
+ }
+
+ /* Draw selection borders */
+ painter.resetTransform();
+ painter.setPen(Qt::green);
+
+ if (m_selectionState->type == SelectionState::Horizontal) {
+ double dxdt = width() / (double)m_viewWidth;
+ double scroll = m_viewLeft * dxdt;
+ double left = (m_selectionState->start * dxdt) - scroll;
+ double right = (m_selectionState->end * dxdt) - scroll;
+
+ /* Highlight time */
+ if (left >= 0 && left <= width()) {
+ painter.drawLine(left, 0, left, height());
+ }
+
+ if (right >= 0 && right <= width()) {
+ painter.drawLine(right, 0, right, height());
+ }
+ } else if (m_selectionState->type == SelectionState::Vertical) {
+ /* Highlight row */
+ int row = m_selectionState->start;
+
+ for (unsigned i = rowStart; i < rowEnd; ++i) {
+ if (m_data->dataRowAt(i) == row) {
+ row = i - rowStart;
+
+ painter.translate(0, m_data->headerRows() * m_rowHeight - m_viewBottom % m_rowHeight);
+ painter.drawLine(0, (row + 1) * m_rowHeight, width(), (row + 1) * m_rowHeight);
+
+ if (row > 0) {
+ painter.drawLine(0, row * m_rowHeight, width(), row * m_rowHeight);
+ }
+
+ break;
+ }
+ }
+ }
+}
+
+
+void HeatmapView::paintRow(QPainter& painter, HeatmapRowIterator* itr)
+{
+ bool selection = m_selectionState ? m_selectionState->type != SelectionState::None : false;
+
+ while (itr->next())
+ {
+ double heat = itr->heat();
+ int width = itr->width();
+ int x = itr->step();
+
+ /* Gamma correction */
+ heat = qPow(heat, 1.0 / 2.0);
+
+ if (width == 1) {
+ /* Draw single line */
+ if (selection) {
+ double selectedHeat = itr->selectedHeat();
+
+ if (selectedHeat >= 0.999) {
+ heat = 255.0 - qBound(0.0, heat * 255.0, 255.0);
+
+ if (itr->isGpu()) {
+ painter.setPen(QColor(255, heat, heat));
+ } else {
+ painter.setPen(QColor(heat, heat, 255));
+ }
+
+ painter.drawLine(x, 0, x, m_rowHeight - 1);
+ } else {
+ heat = 255.0 - qBound(0.0, heat * 100.0, 100.0);
+ painter.setPen(QColor(heat, heat, heat));
+ painter.drawLine(x, 0, x, m_rowHeight - 1);
+
+ if (selectedHeat > 0.001) {
+ selectedHeat = qPow(selectedHeat, 1.0 / 2.0);
+ selectedHeat = qBound(0.0, selectedHeat * 255.0, 255.0);
+
+ if (itr->isGpu()) {
+ painter.setPen(QColor(255, 0, 0, selectedHeat));
+ } else {
+ painter.setPen(QColor(0, 0, 255, selectedHeat));
+ }
+
+ painter.drawLine(x, 0, x, m_rowHeight - 1);
+ }
+ }
+ } else {
+ heat = qBound(0.0, heat * 255.0, 255.0);
+
+ if (itr->isGpu()) {
+ painter.setPen(QColor(255, 255 - heat, 255 - heat));
+ } else {
+ painter.setPen(QColor(255 - heat, 255 - heat, 255));
+ }
+
+ painter.drawLine(x, 0, x, m_rowHeight - 1);
+ }
+ } else {
+ double selectedHeat = itr->selectedHeat();
+
+ if (selection && selectedHeat < 0.9) {
+ painter.fillRect(x, 0, width, m_rowHeight, QColor(255 - 100, 255 - 100, 255 - 100));
+ } else if (itr->isGpu()) {
+ painter.fillRect(x, 0, width, m_rowHeight, QColor(255, 0, 0));
+ } else {
+ painter.fillRect(x, 0, width, m_rowHeight, QColor(0, 0, 255));
+ }
+
+ if (width > 6) {
+ painter.setPen(Qt::white);
+ QString elided = painter.fontMetrics().elidedText(itr->label(), Qt::ElideRight, width - 1);
+
+ painter.drawText(x + 1, 0, width - 1, m_rowHeight - 1,
+ Qt::AlignLeft | Qt::AlignVCenter,
+ elided);
+ }
+ }
+ }
+}
+
+
+qint64 HeatmapView::itemAtPosition(QPoint pos)
+{
+ if (!m_data) {
+ return -1;
+ }
+
+ double t = m_viewWidth / (double)width();
+ t *= pos.x();
+ t += m_viewLeft;
+
+ qint64 time = (qint64)t;
+ qint64 index;
+
+ if (pos.y() < m_data->headerRows() * m_rowHeight) {
+ int row = pos.y() / m_rowHeight;
+ index = m_data->headerItemAt(row, time);
+ } else {
+ int row = pos.y();
+ row -= m_data->headerRows() * m_rowHeight;
+ row += m_viewBottom;
+ row /= m_rowHeight;
+ index = m_data->dataItemAt(row, time);
+ }
+
+ return index;
+}
--- /dev/null
+#ifndef HEATMAPVIEW_H
+#define HEATMAPVIEW_H
+
+#include "graphview.h"
+
+/**
+ * The heatmap iterator will only return data when there is something to draw,
+ * this allows much faster access to the data in the case where the view is
+ * zoomed out to the point of where there is multiple calls in one pixel,
+ * it automagically calculates the heat for that pixel.
+ */
+class HeatmapRowIterator {
+public:
+ virtual ~HeatmapRowIterator(){}
+
+ /* Go to the next visible heat map */
+ virtual bool next() = 0;
+
+ /* Is the current value GPU or CPU heat */
+ virtual bool isGpu() const = 0;
+
+ /* Current step (normally x coordinate) */
+ virtual int step() const = 0;
+
+ /* Current width (in steps) */
+ virtual int width() const = 0;
+
+ /* Current heat */
+ virtual float heat() const = 0;
+
+ /* Heat value for selected calls */
+ virtual float selectedHeat() const = 0;
+
+ /* Label only used when there is a single call in this heat */
+ virtual QString label() const = 0;
+};
+
+
+/**
+ * Data provider for the whole heatmap
+ */
+class HeatmapDataProvider {
+public:
+ virtual ~HeatmapDataProvider(){}
+
+ /* The start and end values (time on x-axis) for the heatmap */
+ virtual qint64 start() const = 0;
+ virtual qint64 end() const = 0;
+
+ /*
+ * Header rows (fixed at top of heatmap view)
+ */
+
+ /* Header row count */
+ virtual unsigned headerRows() const = 0;
+
+ /* Label to be used in the vertical axis */
+ virtual QString headerLabel(unsigned row) const = 0;
+
+ /* Get identifier (program no) for row */
+ virtual qint64 headerRowAt(unsigned row) const = 0;
+
+ /* Get item at row and time */
+ virtual qint64 headerItemAt(unsigned row, qint64 time) const = 0;
+
+ /* Get iterator for a row between start and end time for steps */
+ virtual HeatmapRowIterator* headerRowIterator(int row, qint64 start, qint64 end, int steps) const = 0;
+
+ /*
+ * Data rows (scrollable in heatmap view)
+ */
+
+ /* Data row count */
+ virtual unsigned dataRows() const = 0;
+
+ /* Label to be used in the vertical axis */
+ virtual QString dataLabel(unsigned row) const = 0;
+
+ /* Get identifier (program no) for row */
+ virtual qint64 dataRowAt(unsigned row) const = 0;
+
+ /* Get item at row and time */
+ virtual qint64 dataItemAt(unsigned row, qint64 time) const = 0;
+
+ /* Get iterator for a row between start and end time for steps */
+ virtual HeatmapRowIterator* dataRowIterator(int row, qint64 start, qint64 end, int steps) const = 0;
+
+ /* Handle double click on item */
+ virtual void itemDoubleClicked(qint64 index) const = 0;
+
+ /* Get mouse over tooltip for item */
+ virtual QString itemTooltip(qint64 index) const = 0;
+
+ /* Set the selection */
+ virtual void setSelectionState(SelectionState* state) = 0;
+};
+
+
+/**
+ * A not very generic heatmap for row based data
+ */
+class HeatmapView : public GraphView {
+public:
+ HeatmapView(QWidget* parent);
+
+ void setDataProvider(HeatmapDataProvider* data);
+ void setSelectionState(SelectionState* state);
+
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+
+ virtual void paintEvent(QPaintEvent *e);
+ virtual void paintRow(QPainter& painter, HeatmapRowIterator* itr);
+
+
+protected:
+ qint64 itemAtPosition(QPoint pos);
+
+protected:
+ int m_rowHeight;
+ HeatmapDataProvider* m_data;
+};
+
+#endif
--- /dev/null
+#include "histogramview.h"
+
+#include <QPen>
+#include <QBrush>
+#include <qmath.h>
+#include <QPainter>
+#include <QToolTip>
+#include <QMouseEvent>
+
+HistogramView::HistogramView(QWidget* parent) :
+ GraphView(parent),
+ m_data(NULL)
+{
+ setMouseTracking(true);
+
+ m_gradientUnselected.setColorAt(0.9, QColor(200, 200, 200));
+ m_gradientUnselected.setColorAt(0.0, QColor(220, 220, 220));
+
+ m_gradientSelected.setColorAt(0.9, QColor(0, 0, 210));
+ m_gradientSelected.setColorAt(0.0, QColor(130, 130, 255));
+}
+
+
+void HistogramView::setDataProvider(GraphDataProvider* data)
+{
+ delete m_data;
+ m_data = data;
+
+ if (m_data) {
+ m_data->setSelectionState(m_selectionState);
+ setDefaultView(0, m_data->size());
+ m_viewWidthMin = 10;
+ } else {
+ setDefaultView(0, 0);
+ }
+}
+
+
+void HistogramView::setSelectionState(SelectionState* state)
+{
+ if (m_data) {
+ m_data->setSelectionState(state);
+ }
+
+ GraphView::setSelectionState(state);
+}
+
+
+void HistogramView::setSelectedGradient(const QLinearGradient& gradient)
+{
+ m_gradientSelected = gradient;
+}
+
+
+void HistogramView::setUnelectedGradient(const QLinearGradient& gradient)
+{
+ m_gradientUnselected = gradient;
+}
+
+
+void HistogramView::mouseMoveEvent(QMouseEvent *e)
+{
+ GraphView::mouseMoveEvent(e);
+
+ if (e->buttons() || !m_data) {
+ QToolTip::hideText();
+ return;
+ }
+
+ qint64 index = itemAtPosition(e->pos());
+ qint64 time = valueAtPosition(e->pos());
+
+ if (m_data->value(index) >= time) {
+ QToolTip::showText(e->globalPos(), m_data->itemTooltip(index));
+ } else {
+ QToolTip::hideText();
+ }
+}
+
+
+void HistogramView::mouseDoubleClickEvent(QMouseEvent *e)
+{
+ if (e->button() == Qt::LeftButton) {
+ qint64 index = itemAtPosition(e->pos());
+ qint64 time = valueAtPosition(e->pos());
+
+ if (m_data->value(index) >= time) {
+ m_data->itemDoubleClicked(index);
+ return;
+ }
+ }
+
+ GraphView::mouseDoubleClickEvent(e);
+}
+
+
+void HistogramView::update()
+{
+ m_graphBottom = 0;
+ m_graphTop = 0;
+
+ if (m_data) {
+ for (qint64 i = m_viewLeft; i < m_viewRight; ++i) {
+ qint64 value = m_data->value(i);
+
+ if (value > m_graphTop) {
+ m_graphTop = value;
+ }
+ }
+ }
+
+ GraphView::update();
+}
+
+
+void HistogramView::resizeEvent(QResizeEvent *)
+{
+ m_gradientSelected.setStart(0, height());
+ m_gradientUnselected.setStart(0, height());
+}
+
+
+/* Draw the histogram
+ *
+ * When the view is zoomed such that there is more than one item occupying a single pixel
+ * the one with the highest value will be displayed.
+ */
+void HistogramView::paintEvent(QPaintEvent *)
+{
+ if (!m_data) {
+ return;
+ }
+
+ QBrush selectedBrush = QBrush(m_gradientSelected);
+ QPen selectedPen = QPen(selectedBrush, 1);
+
+ QBrush unselectedBrush = QBrush(m_gradientUnselected);
+ QPen unselectedPen = QPen(unselectedBrush, 1);
+
+ QPainter painter(this);
+ painter.fillRect(0, 0, width(), height(), Qt::white);
+
+ double dydv = height() / (double)m_graphTop;
+ double dxdv = width() / (double)(m_viewRight - m_viewLeft);
+ bool selection = m_selectionState && m_selectionState->type != SelectionState::None;
+
+ if (dxdv < 1.0) {
+ /* Less than one pixel per item */
+ qint64 longestValue = m_graphBottom;
+ qint64 longestSelected = m_graphBottom;
+ int lastX = 0;
+ double x = 0;
+
+ if (selection) {
+ painter.setPen(unselectedPen);
+ } else {
+ painter.setPen(selectedPen);
+ }
+
+ for (qint64 i = m_viewLeft; i < m_viewRight; ++i) {
+ qint64 value = m_data->value(i);
+ int ix;
+
+ if (value > longestValue) {
+ longestValue = value;
+ }
+
+ if (selection && m_data->selected(i) && value > longestSelected) {
+ longestSelected = value;
+ }
+
+ x += dxdv;
+ ix = (int)x;
+
+ if (lastX != ix) {
+ painter.drawLine(lastX, height(), lastX, height() - (longestValue * dydv));
+
+ if (selection && longestSelected > m_graphBottom) {
+ painter.setPen(selectedPen);
+ painter.drawLine(lastX, height(), lastX, height() - (longestSelected * dydv));
+ painter.setPen(unselectedPen);
+ longestSelected = m_graphBottom;
+ }
+
+ longestValue = m_graphBottom;
+ lastX = ix;
+ }
+ }
+ } else {
+ /* Draw rectangles for graph */
+ double x = 0;
+
+ for (qint64 i = m_viewLeft; i < m_viewRight; ++i, x += dxdv) {
+ qint64 value = m_data->value(i);
+ int y = qMax<int>(1, value * dydv);
+
+ if (!selection || m_data->selected(i)) {
+ painter.fillRect(x, height() - y, dxdv, y, selectedBrush);
+ } else {
+ painter.fillRect(x, height() - y, dxdv, y, unselectedBrush);
+ }
+ }
+ }
+
+ /* Draw the borders for the selection */
+ if (m_selectionState && m_selectionState->type == SelectionState::Horizontal) {
+ double dxdt = width() / (double)m_viewWidth;
+ double scroll = m_viewLeft * dxdt;
+ double left = (m_selectionState->start * dxdt) - scroll;
+ double right = (m_selectionState->end * dxdt) - scroll;
+
+ painter.setPen(Qt::green);
+
+ if (left >= 0 && left <= width()) {
+ painter.drawLine(left, 0, left, height());
+ }
+
+ if (right >= 0 && right <= width()) {
+ painter.drawLine(right, 0, right, height());
+ }
+ }
+}
+
+
+/* Find the item with the highest value at pos.x() +/- 1,
+ * the mouse must be within the bar height-wise.
+ */
+qint64 HistogramView::itemAtPosition(QPoint pos) {
+ double dvdx = m_viewWidth / (double)width();
+
+ qint64 left = qFloor(dvdx) * (pos.x() - 1) + m_viewLeft;
+ qint64 right = qCeil(dvdx) * (pos.x() + 1) + m_viewLeft;
+
+ qint64 longestIndex = 0;
+ qint64 longestValue = 0;
+
+ left = qBound<qint64>(0, left, m_data->size() - 1);
+ right = qBound<qint64>(0, right, m_data->size() - 1);
+
+ for (qint64 i = left; i <= right; ++i) {
+ if (m_data->value(i) > longestValue) {
+ longestValue = m_data->value(i);
+ longestIndex = i;
+ }
+ }
+
+ return longestIndex;
+}
+
+
+/* Return the value at position */
+qint64 HistogramView::valueAtPosition(QPoint pos) {
+ double value = m_graphTop / (double)height();
+ value *= height() - pos.y();
+ value += m_graphBottom;
+ return (qint64)value;
+}
+
--- /dev/null
+#ifndef HISTOGRAMVIEW_H
+#define HISTOGRAMVIEW_H
+
+#include "graphview.h"
+
+/**
+ * Histogram graph view.
+ *
+ * When the view is zoomed such that there is more than one item occupying
+ * a single pixel the one with the highest value will be displayed.
+ */
+class HistogramView : public GraphView {
+public:
+ HistogramView(QWidget* parent);
+
+ void setDataProvider(GraphDataProvider* data);
+ void setSelectionState(SelectionState* state);
+
+ /* Gradient colours for selected and unselected items */
+ void setSelectedGradient(const QLinearGradient& gradient);
+ void setUnelectedGradient(const QLinearGradient& gradient);
+
+ virtual void mouseMoveEvent(QMouseEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+
+ virtual void update();
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void paintEvent(QPaintEvent *e);
+
+protected:
+ qint64 itemAtPosition(QPoint pos);
+ qint64 valueAtPosition(QPoint pos);
+
+protected:
+ QLinearGradient m_gradientSelected;
+ QLinearGradient m_gradientUnselected;
+
+ GraphDataProvider* m_data;
+};
+
+#endif
--- /dev/null
+#include "timeaxiswidget.h"
+#include "profiling.h"
+
+#include <qmath.h>
+#include <QPainter>
+
+TimeAxisWidget::TimeAxisWidget(QWidget* parent) :
+ GraphAxisWidget(parent)
+{
+}
+
+void TimeAxisWidget::paintEvent(QPaintEvent *)
+{
+ /* TODO: Support selections? */
+ /* TODO: Vertical scrolling? */
+
+ QPainter painter(this);
+ painter.setPen(Qt::black);
+ painter.setBrush(Qt::lightGray);
+ painter.drawRect(0, 0, width() - 1, height() - 1);
+
+ if (m_orientation == GraphAxisWidget::Vertical) {
+ int axisHeight = height() - 1;
+ int fontHeight = painter.fontMetrics().height();
+ int ticks = axisHeight / (fontHeight * 2);
+
+ double range = m_valueMax - m_valueMin;
+ double step = range / (double)ticks;
+ double step10 = qPow(10.0, qFloor(qLn(step) / qLn(10.0)));
+ step = qFloor((step / step10) * 2) * (step10 / 2);
+
+ if (step <= 0) {
+ return;
+ }
+
+ painter.resetTransform();
+
+ for (double tick = 0; tick <= range; tick += step) {
+ int y = axisHeight - ((tick / range) * axisHeight);
+
+ painter.drawLine(width() - 8, y, width(), y);
+
+ painter.drawText(0,
+ qBound(0, y - fontHeight / 2, axisHeight - fontHeight),
+ width() - 10,
+ fontHeight,
+ Qt::AlignRight | Qt::AlignVCenter,
+ Profiling::getTimeString(tick, m_valueMax));
+ }
+ } else {
+ int axisWidth = width() - 1;
+ int fontWidth = painter.fontMetrics().width("0.000 ns");
+ int fontHeight= painter.fontMetrics().height();
+ int ticks = axisWidth / (fontWidth * 2);
+
+ double range = m_valueMax - m_valueMin;
+ double step = range / (double)ticks;
+ double step10 = qPow(10.0, qFloor(qLn(step) / qLn(10.0)));
+ step = qFloor((step / step10) * 2) * (step10 / 2);
+
+ if (step <= 0) {
+ return;
+ }
+
+ painter.resetTransform();
+
+ for (double tick = 0; tick <= range; tick += step) {
+ int x = (tick / range) * axisWidth;
+
+ painter.drawLine(x, 0, x, 8);
+
+ painter.drawText(qBound(0, x - fontWidth / 2, axisWidth - fontWidth),
+ 8,
+ fontWidth,
+ fontHeight,
+ Qt::AlignHCenter | Qt::AlignTop,
+ Profiling::getTimeString(tick, m_valueMax));
+ }
+ }
+}
--- /dev/null
+#ifndef TIMEAXISWIDGET_H
+#define TIMEAXISWIDGET_H
+
+#include "graphaxiswidget.h"
+
+/**
+ * A simple axis that draws text using getTimeString to nicely format time values
+ */
+class TimeAxisWidget : public GraphAxisWidget {
+public:
+ TimeAxisWidget(QWidget* parent = 0);
+
+ virtual void paintEvent(QPaintEvent *e);
+};
+
+#endif
int main(int argc, char **argv)
{
+ QApplication::setGraphicsSystem("raster");
QApplication app(argc, argv);
qRegisterMetaType<QList<ApiTraceFrame*> >();
#include "argumentseditor.h"
#include "imageviewer.h"
#include "jumpwidget.h"
+#include "profiledialog.h"
#include "retracer.h"
#include "searchwidget.h"
#include "settingsdialog.h"
#include "trimprocess.h"
#include "thumbnail.h"
#include "ui_retracerdialog.h"
+#include "ui_profilereplaydialog.h"
#include "vertexdatainterpreter.h"
+#include "trace_profiler.hpp"
#include <QAction>
#include <QApplication>
initConnections();
}
+MainWindow::~MainWindow()
+{
+ delete m_trace;
+ m_trace = 0;
+
+ delete m_proxyModel;
+ delete m_model;
+}
+
void MainWindow::createTrace()
{
if (!m_traceProcess->canTrace()) {
"Please wait until it finishes and try again."));
return;
}
+
QDialog dlg;
Ui_RetracerDialog dlgUi;
dlgUi.setupUi(&dlg);
dlgUi.doubleBufferingCB->setChecked(
m_retracer->isDoubleBuffered());
+
dlgUi.errorCheckCB->setChecked(
!m_retracer->isBenchmarking());
if (dlg.exec() == QDialog::Accepted) {
m_retracer->setDoubleBuffered(
dlgUi.doubleBufferingCB->isChecked());
+
m_retracer->setBenchmarking(
!dlgUi.errorCheckCB->isChecked());
- replayTrace(false, true);
+
+ m_retracer->setProfiling(false, false, false);
+
+ replayTrace(false, false);
+ }
+}
+
+void MainWindow::replayProfile()
+{
+ if (m_trace->isSaving()) {
+ QMessageBox::warning(
+ this,
+ tr("Trace Saving"),
+ tr("QApiTrace is currently saving the edited trace file. "
+ "Please wait until it finishes and try again."));
+ return;
+ }
+
+ QDialog dlg;
+ Ui_ProfileReplayDialog dlgUi;
+ dlgUi.setupUi(&dlg);
+
+ if (dlg.exec() == QDialog::Accepted) {
+ m_retracer->setProfiling(
+ dlgUi.gpuTimesCB->isChecked(),
+ dlgUi.cpuTimesCB->isChecked(),
+ dlgUi.pixelsDrawnCB->isChecked());
+
+ replayTrace(false, false);
}
}
m_retracer->quit();
m_ui.actionStop->setEnabled(false);
m_ui.actionReplay->setEnabled(true);
+ m_ui.actionProfile->setEnabled(true);
m_ui.actionLookupState->setEnabled(true);
m_ui.actionShowThumbnails->setEnabled(true);
}
if (fileName.isEmpty()) {
m_ui.actionReplay->setEnabled(false);
+ m_ui.actionProfile->setEnabled(false);
m_ui.actionLookupState->setEnabled(false);
m_ui.actionShowThumbnails->setEnabled(false);
setWindowTitle(tr("QApiTrace"));
} else {
QFileInfo info(fileName);
m_ui.actionReplay->setEnabled(true);
+ m_ui.actionProfile->setEnabled(true);
m_ui.actionLookupState->setEnabled(true);
m_ui.actionShowThumbnails->setEnabled(true);
m_ui.actionTrim->setEnabled(true);
{
m_ui.actionStop->setEnabled(false);
m_ui.actionReplay->setEnabled(true);
+ m_ui.actionProfile->setEnabled(true);
m_ui.actionLookupState->setEnabled(true);
m_ui.actionShowThumbnails->setEnabled(true);
{
m_ui.actionStop->setEnabled(false);
m_ui.actionReplay->setEnabled(true);
+ m_ui.actionProfile->setEnabled(true);
m_ui.actionLookupState->setEnabled(true);
m_ui.actionShowThumbnails->setEnabled(true);
m_stateEvent = 0;
statusBar()->showMessage(
tr("Capturing thumbnails..."));
}
+ } else if (m_retracer->isProfiling()) {
+ statusBar()->showMessage(
+ tr("Profiling draw calls in trace file..."));
} else {
statusBar()->showMessage(
tr("Replaying the trace file..."));
trimEvent();
}
-MainWindow::~MainWindow()
-{
- delete m_trace;
- m_trace = 0;
-
- delete m_proxyModel;
- delete m_model;
-}
-
static void
variantToString(const QVariant &var, QString &str)
{
m_traceProcess = new TraceProcess(this);
m_trimProcess = new TrimProcess(this);
+
+ m_profileDialog = new ProfileDialog();
}
void MainWindow::initConnections()
this, SLOT(replayError(const QString&)));
connect(m_retracer, SIGNAL(foundState(ApiTraceState*)),
this, SLOT(replayStateFound(ApiTraceState*)));
+ connect(m_retracer, SIGNAL(foundProfile(trace::Profile*)),
+ this, SLOT(replayProfileFound(trace::Profile*)));
connect(m_retracer, SIGNAL(foundThumbnails(const QList<QImage>&)),
this, SLOT(replayThumbnailsFound(const QList<QImage>&)));
connect(m_retracer, SIGNAL(retraceErrors(const QList<ApiTraceError>&)),
connect(m_ui.actionReplay, SIGNAL(triggered()),
this, SLOT(replayStart()));
+ connect(m_ui.actionProfile, SIGNAL(triggered()),
+ this, SLOT(replayProfile()));
connect(m_ui.actionStop, SIGNAL(triggered()),
this, SLOT(replayStop()));
connect(m_ui.actionLookupState, SIGNAL(triggered()),
connect(m_ui.errorsTreeWidget,
SIGNAL(itemActivated(QTreeWidgetItem*, int)),
this, SLOT(slotErrorSelected(QTreeWidgetItem*)));
+
+ connect(m_ui.actionShowProfileDialog, SIGNAL(triggered(bool)),
+ m_profileDialog, SLOT(show()));
+ connect(m_profileDialog, SIGNAL(jumpToCall(int)),
+ this, SLOT(slotJumpTo(int)));
+}
+
+void MainWindow::closeEvent(QCloseEvent * event)
+{
+ m_profileDialog->close();
+ QMainWindow::closeEvent(event);
+}
+
+void MainWindow::replayProfileFound(trace::Profile *profile)
+{
+ m_ui.actionShowProfileDialog->setEnabled(true);
+ m_profileDialog->setProfile(profile);
+ m_profileDialog->show();
+ m_profileDialog->activateWindow();
+ m_profileDialog->setFocus();
}
void MainWindow::replayStateFound(ApiTraceState *state)
QModelIndex idx = m_proxyModel->indexForCall(call);
if (idx.isValid()) {
m_ui.callView->setCurrentIndex(idx);
+ m_ui.callView->scrollTo(idx, QAbstractItemView::PositionAtTop);
break;
}
++itr;
QModelIndex idx = m_proxyModel->indexForCall(call);
if (idx.isValid()) {
m_ui.callView->setCurrentIndex(idx);
+ m_ui.callView->scrollTo(idx, QAbstractItemView::PositionAtBottom);
break;
}
} while (itr != calls.constBegin());
void MainWindow::slotJumpToResult(ApiTraceCall *call)
{
- QModelIndex index = m_proxyModel->indexForCall(call);
- if (index.isValid()) {
- m_ui.callView->setCurrentIndex(index);
+ QModelIndex idx = m_proxyModel->indexForCall(call);
+ if (idx.isValid()) {
+ activateWindow();
+ m_ui.callView->setFocus();
+ m_ui.callView->setCurrentIndex(idx);
+ m_ui.callView->scrollTo(idx, QAbstractItemView::PositionAtCenter);
} else {
statusBar()->showMessage(tr("Call has been filtered out."));
}
class ShadersSourceWidget;
class TraceProcess;
class TrimProcess;
+class ProfileDialog;
class VertexDataInterpreter;
+namespace trace { struct Profile; }
+
class MainWindow : public QMainWindow
{
Q_OBJECT
void createTrace();
void openTrace();
void replayStart();
+ void replayProfile();
void replayStop();
void replayFinished(const QString &message);
void replayStateFound(ApiTraceState *state);
+ void replayProfileFound(trace::Profile *state);
void replayThumbnailsFound(const QList<QImage> &thumbnails);
void replayError(const QString &msg);
void startedLoadingTrace();
ApiTraceFrame *currentFrame() const;
ApiTraceCall *currentCall() const;
+protected:
+ virtual void closeEvent(QCloseEvent * event);
private:
Ui_MainWindow m_ui;
ArgumentsEditor *m_argsEditor;
ApiTraceEvent *m_nonDefaultsLookupEvent;
+
+ ProfileDialog* m_profileDialog;
};
--- /dev/null
+#include "profiledialog.h"
+#include "profiletablemodel.h"
+#include <QSortFilterProxyModel>
+
+#include "graphing/histogramview.h"
+#include "graphing/timeaxiswidget.h"
+#include "graphing/frameaxiswidget.h"
+#include "graphing/heatmapverticalaxiswidget.h"
+#include "profileheatmap.h"
+
+/* Handy function to allow selection of a call in main window */
+ProfileDialog* g_profileDialog = 0;
+
+void Profiling::jumpToCall(int index)
+{
+ if (g_profileDialog) {
+ g_profileDialog->showCall(index);
+ }
+}
+
+/* Provides frame numbers based off call index */
+class FrameCallDataProvider : public FrameDataProvider {
+public:
+ FrameCallDataProvider(const trace::Profile* profile)
+ {
+ m_profile = profile;
+ }
+
+ unsigned size() const {
+ return m_profile->frames.size();
+ }
+
+ qint64 frameStart(unsigned index) const {
+ return m_profile->frames[index].calls.begin;
+ }
+
+ qint64 frameEnd(unsigned index) const {
+ return m_profile->frames[index].calls.end;
+ }
+
+private:
+ const trace::Profile* m_profile;
+};
+
+/* Provides frame numbers based off time */
+class FrameTimeDataProvider : public FrameDataProvider {
+public:
+ FrameTimeDataProvider(const trace::Profile* profile)
+ {
+ m_profile = profile;
+ }
+
+ unsigned size() const {
+ return m_profile->frames.size();
+ }
+
+ qint64 frameStart(unsigned index) const {
+ return m_profile->frames[index].cpuStart;
+ }
+
+ qint64 frameEnd(unsigned index) const {
+ return m_profile->frames[index].cpuStart + m_profile->frames[index].cpuDuration;
+ }
+
+private:
+ const trace::Profile* m_profile;
+};
+
+ProfileDialog::ProfileDialog(QWidget *parent)
+ : QDialog(parent),
+ m_profile(0)
+{
+ setupUi(this);
+ g_profileDialog = this;
+
+ /* Gradients for call duration histograms */
+ QLinearGradient cpuGradient;
+ cpuGradient.setColorAt(0.9, QColor(0, 0, 210));
+ cpuGradient.setColorAt(0.0, QColor(130, 130, 255));
+
+ QLinearGradient gpuGradient;
+ gpuGradient.setColorAt(0.9, QColor(210, 0, 0));
+ gpuGradient.setColorAt(0.0, QColor(255, 130, 130));
+
+
+ /* Setup heatmap timeline */
+ m_timeline->setLabel(new GraphLabelWidget("Frames ", m_timeline));
+ m_timeline->label()->setFlags(Qt::AlignVCenter | Qt::AlignRight);
+
+ m_timeline->setView(new HeatmapView(m_timeline));
+
+ m_timeline->setAxis(GraphWidget::AxisTop, new FrameAxisWidget(m_timeline));
+ m_timeline->setAxis(GraphWidget::AxisLeft, new HeatmapVerticalAxisWidget(m_timeline));
+ m_timeline->axis(GraphWidget::AxisLeft)->resize(80, 0);
+
+ m_timeline->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ m_timeline->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+
+ /* Setup Cpu call duration histogram */
+ m_cpuGraph->setLabel(new GraphLabelWidget("CPU", m_cpuGraph));
+
+ m_cpuGraph->setAxis(GraphWidget::AxisTop, new FrameAxisWidget(m_cpuGraph));
+ m_cpuGraph->setAxis(GraphWidget::AxisLeft, new TimeAxisWidget(m_cpuGraph));
+ m_cpuGraph->axis(GraphWidget::AxisLeft)->resize(80, 0);
+
+ HistogramView* cpuView = new HistogramView(m_cpuGraph);
+ cpuView->setSelectedGradient(cpuGradient);
+ m_cpuGraph->setView(cpuView);
+
+
+ /* Setup Gpu call duration histogram */
+ m_gpuGraph->setLabel(new GraphLabelWidget("GPU", m_gpuGraph));
+
+ m_gpuGraph->setAxis(GraphWidget::AxisTop, new FrameAxisWidget(m_gpuGraph));
+ m_gpuGraph->setAxis(GraphWidget::AxisLeft, new TimeAxisWidget(m_gpuGraph));
+ m_gpuGraph->axis(GraphWidget::AxisLeft)->resize(80, 0);
+
+ HistogramView* gpuView = new HistogramView(m_gpuGraph);
+ gpuView->setSelectedGradient(gpuGradient);
+ m_gpuGraph->setView(gpuView);
+
+
+ /* Synchronise selections */
+ connect(m_timeline, SIGNAL(selectionChanged(SelectionState)), m_cpuGraph, SLOT(setSelection(SelectionState)));
+ connect(m_timeline, SIGNAL(selectionChanged(SelectionState)), m_gpuGraph, SLOT(setSelection(SelectionState)));
+
+ connect(m_cpuGraph, SIGNAL(selectionChanged(SelectionState)), m_timeline, SLOT(setSelection(SelectionState)));
+ connect(m_cpuGraph, SIGNAL(selectionChanged(SelectionState)), m_gpuGraph, SLOT(setSelection(SelectionState)));
+
+ connect(m_gpuGraph, SIGNAL(selectionChanged(SelectionState)), m_timeline, SLOT(setSelection(SelectionState)));
+ connect(m_gpuGraph, SIGNAL(selectionChanged(SelectionState)), m_cpuGraph, SLOT(setSelection(SelectionState)));
+
+ connect(m_timeline, SIGNAL(selectionChanged(SelectionState)), this, SLOT(graphSelectionChanged(SelectionState)));
+ connect(m_cpuGraph, SIGNAL(selectionChanged(SelectionState)), this, SLOT(graphSelectionChanged(SelectionState)));
+ connect(m_gpuGraph, SIGNAL(selectionChanged(SelectionState)), this, SLOT(graphSelectionChanged(SelectionState)));
+
+
+ /* Synchronise views between cpuGraph and gpuGraph */
+ connect(m_cpuGraph, SIGNAL(horizontalViewChanged(qint64,qint64)), m_gpuGraph, SLOT(setHorizontalView(qint64,qint64)));
+ connect(m_gpuGraph, SIGNAL(horizontalViewChanged(qint64,qint64)), m_cpuGraph, SLOT(setHorizontalView(qint64,qint64)));
+}
+
+
+ProfileDialog::~ProfileDialog()
+{
+ delete m_profile;
+}
+
+
+void ProfileDialog::showCall(int call)
+{
+ emit jumpToCall(call);
+}
+
+
+void ProfileDialog::tableDoubleClicked(const QModelIndex& index)
+{
+ ProfileTableModel* model = (ProfileTableModel*)m_table->model();
+
+ if (!model) {
+ return;
+ }
+
+ const trace::Profile::Call* call = model->getJumpCall(index);
+
+ if (call) {
+ emit jumpToCall(call->no);
+ } else {
+ unsigned program = model->getProgram(index);
+
+ SelectionState state;
+ state.type = SelectionState::Vertical;
+ state.end = state.start = program;
+
+ m_timeline->setSelection(state);
+ m_cpuGraph->setSelection(state);
+ m_gpuGraph->setSelection(state);
+ }
+}
+
+
+void ProfileDialog::setProfile(trace::Profile* profile)
+{
+
+ if (profile && profile->frames.size()) {
+ HeatmapVerticalAxisWidget* programAxis;
+ FrameAxisWidget* frameAxis;
+ HistogramView* histogram;
+ HeatmapView* heatmap;
+
+
+ /* Setup data providers for Cpu graph */
+ m_cpuGraph->setProfile(profile);
+ histogram = (HistogramView*)m_cpuGraph->view();
+ frameAxis = (FrameAxisWidget*)m_cpuGraph->axis(GraphWidget::AxisTop);
+
+ histogram->setDataProvider(new CallDurationDataProvider(profile, false));
+ frameAxis->setDataProvider(new FrameCallDataProvider(profile));
+
+ /* Setup data provider for Gpu graph */
+ m_gpuGraph->setProfile(profile);
+ histogram = (HistogramView*)m_gpuGraph->view();
+ frameAxis = (FrameAxisWidget*)m_gpuGraph->axis(GraphWidget::AxisTop);
+
+ histogram->setDataProvider(new CallDurationDataProvider(profile, true));
+ frameAxis->setDataProvider(new FrameCallDataProvider(profile));
+
+ /* Setup data provider for heatmap timeline */
+ heatmap = (HeatmapView*)m_timeline->view();
+ frameAxis = (FrameAxisWidget*)m_timeline->axis(GraphWidget::AxisTop);
+ programAxis = (HeatmapVerticalAxisWidget*)m_timeline->axis(GraphWidget::AxisLeft);
+
+ heatmap->setDataProvider(new ProfileHeatmapDataProvider(profile));
+ frameAxis->setDataProvider(new FrameTimeDataProvider(profile));
+ programAxis->setDataProvider(new ProfileHeatmapDataProvider(profile));
+
+ /* Setup data model for table view */
+ ProfileTableModel* model = new ProfileTableModel(m_table);
+ model->setProfile(profile);
+
+ delete m_table->model();
+ m_table->setModel(model);
+ m_table->update(QModelIndex());
+ m_table->sortByColumn(2, Qt::DescendingOrder);
+ m_table->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
+ m_table->resizeColumnsToContents();
+
+ /* Reset selection */
+ SelectionState emptySelection;
+ emptySelection.type = SelectionState::None;
+ m_cpuGraph->setSelection(emptySelection);
+ m_gpuGraph->setSelection(emptySelection);
+ m_timeline->setSelection(emptySelection);
+ }
+
+ delete m_profile;
+ m_profile = profile;
+}
+
+
+void ProfileDialog::graphSelectionChanged(SelectionState state)
+{
+ ProfileTableModel* model = (ProfileTableModel*)m_table->model();
+
+ if (!model) {
+ return;
+ }
+
+ if (state.type == SelectionState::None) {
+ model->selectNone();
+ } else if (state.type == SelectionState::Horizontal) {
+ model->selectTime(state.start, state.end);
+ } else if (state.type == SelectionState::Vertical) {
+ model->selectProgram(state.start);
+ }
+
+ m_table->reset();
+
+ if (state.type == SelectionState::Vertical) {
+ m_table->selectRow(model->getRowIndex(state.start));
+ }
+}
+
+#include "profiledialog.moc"
--- /dev/null
+#ifndef PROFILEDIALOG_H
+#define PROFILEDIALOG_H
+
+#include "ui_profiledialog.h"
+#include <QDialog>
+
+namespace trace { struct Profile; }
+
+class ProfileDialog : public QDialog, public Ui_ProfileDialog
+{
+ Q_OBJECT
+
+public:
+ ProfileDialog(QWidget *parent = 0);
+ ~ProfileDialog();
+
+ void setProfile(trace::Profile* profile);
+ void showCall(int call);
+
+public slots:
+ void tableDoubleClicked(const QModelIndex& index);
+ void graphSelectionChanged(SelectionState state);
+
+signals:
+ void jumpToCall(int call);
+
+private:
+ trace::Profile *m_profile;
+};
+
+#endif
--- /dev/null
+#ifndef PROFILEHEATMAP_H
+#define PROFILEHEATMAP_H
+
+#include "graphing/heatmapview.h"
+#include "profiling.h"
+
+/**
+ * Data providers for a heatmap based off the trace::Profile call data
+ */
+
+class ProfileHeatmapRowIterator : public HeatmapRowIterator {
+public:
+ ProfileHeatmapRowIterator(const trace::Profile* profile, qint64 start, qint64 end, int steps, bool gpu, int program = -1) :
+ m_profile(profile),
+ m_step(-1),
+ m_stepWidth(1),
+ m_stepCount(steps),
+ m_index(0),
+ m_timeStart(start),
+ m_timeEnd(end),
+ m_useGpu(gpu),
+ m_program(program),
+ m_selected(false),
+ m_timeSelection(false),
+ m_programSelection(false)
+ {
+ m_timeWidth = m_timeEnd - m_timeStart;
+ }
+
+ virtual bool next()
+ {
+ unsigned maxIndex = m_program == -1 ? m_profile->calls.size() : m_profile->programs[m_program].calls.size();
+
+ if (m_index >= maxIndex) {
+ return false;
+ }
+
+ double dtds = m_timeWidth / (double)m_stepCount;
+
+ qint64 heatDuration = 0;
+ qint64 programHeatDuration = 0;
+ m_heat = 0.0f;
+ m_step += m_stepWidth;
+ m_stepWidth = 1;
+
+ m_selected = false;
+
+ /* Iterator through calls until step != lastStep */
+ for (; m_index < maxIndex; ++m_index)
+ {
+ const trace::Profile::Call* call;
+
+ if (m_program == -1) {
+ call = &m_profile->calls[m_index];
+ } else {
+ call = &m_profile->calls[ m_profile->programs[m_program].calls[m_index] ];
+ }
+
+ qint64 start, duration, end;
+
+ if (m_useGpu) {
+ start = call->gpuStart;
+ duration = call->gpuDuration;
+
+ if (call->pixels < 0) {
+ continue;
+ }
+ } else {
+ start = call->cpuStart;
+ duration = call->cpuDuration;
+ }
+
+ end = start + duration;
+
+ if (end < m_timeStart) {
+ continue;
+ }
+
+ if (start > m_timeEnd) {
+ m_index = m_profile->calls.size();
+ break;
+ }
+
+ double left = timeToStep(start);
+ double right = timeToStep(end);
+
+ int leftStep = left;
+ int rightStep = right;
+
+ if (leftStep > m_step) {
+ break;
+ }
+
+ if (m_programSelection && call->program == m_programSel) {
+ m_selected = true;
+ }
+
+ if (rightStep - leftStep > 1) {
+ m_label = QString::fromStdString(call->name);
+ m_step = left;
+ m_stepWidth = rightStep - leftStep;
+ heatDuration = dtds;
+ ++m_index;
+ break;
+ }
+
+ if (leftStep < m_step) {
+ qint64 rightTime = stepToTime(rightStep);
+ heatDuration += end - rightTime;
+
+ if (m_programSelection && call->program == m_programSel) {
+ programHeatDuration += end - rightTime;
+ }
+ } else if (leftStep == rightStep) {
+ heatDuration += duration;
+
+ if (m_programSelection && call->program == m_programSel) {
+ programHeatDuration += duration;
+ }
+ } else if (rightStep - leftStep == 1) {
+ qint64 rightTime = stepToTime(rightStep);
+ heatDuration += rightTime - start;
+
+ if (m_programSelection && call->program == m_programSel) {
+ programHeatDuration += rightTime - start;
+ }
+
+ break;
+ }
+ }
+
+ m_heat = heatDuration / dtds;
+ m_programHeat = programHeatDuration / dtds;
+
+ if (m_timeSelection) {
+ qint64 time = stepToTime(m_step);
+
+ if (time >= m_timeSelStart && time <= m_timeSelEnd) {
+ m_programHeat = 1.0;
+ }
+ }
+
+ if (m_programSelection && (m_program == m_programSel || (m_selected && m_stepWidth > 1))) {
+ m_programHeat = 1.0;
+ }
+
+ if (m_programHeat > 0) {
+ m_selected = true;
+ }
+
+ return true;
+ }
+
+ virtual bool isGpu() const
+ {
+ return m_useGpu;
+ }
+
+ virtual float heat() const
+ {
+ return m_heat;
+ }
+
+ virtual float selectedHeat() const
+ {
+ return m_programHeat;
+ }
+
+ virtual int step() const
+ {
+ return m_step;
+ }
+
+ virtual int width() const
+ {
+ return m_stepWidth;
+ }
+
+ virtual QString label() const
+ {
+ return m_label;
+ }
+
+ void setProgramSelection(int program)
+ {
+ m_programSelection = true;
+ m_programSel = program;
+ }
+
+ void setTimeSelection(qint64 start, qint64 end)
+ {
+ m_timeSelection = true;
+ m_timeSelStart = start;
+ m_timeSelEnd = end;
+ }
+
+private:
+ double timeToStep(qint64 time) const
+ {
+ double pos = time;
+ pos -= m_timeStart;
+ pos /= m_timeWidth;
+ pos *= m_stepCount;
+ return pos;
+ }
+
+ qint64 stepToTime(int pos) const
+ {
+ double time = pos;
+ time /= m_stepCount;
+ time *= m_timeWidth;
+ time += m_timeStart;
+ return (qint64)time;
+ }
+
+private:
+ const trace::Profile* m_profile;
+
+ int m_step;
+ int m_stepWidth;
+ int m_stepCount;
+
+ unsigned m_index;
+
+ float m_heat;
+
+ qint64 m_timeStart;
+ qint64 m_timeEnd;
+ qint64 m_timeWidth;
+
+ bool m_useGpu;
+ int m_program;
+
+ QString m_label;
+
+ bool m_selected;
+
+ bool m_timeSelection;
+ qint64 m_timeSelStart;
+ qint64 m_timeSelEnd;
+
+ bool m_programSelection;
+ int m_programSel;
+
+ float m_programHeat;
+};
+
+class ProfileHeatmapDataProvider : public HeatmapDataProvider {
+protected:
+ enum SelectionType {
+ None,
+ Time,
+ Program
+ };
+
+public:
+ ProfileHeatmapDataProvider(trace::Profile* profile) :
+ m_profile(profile),
+ m_selectionState(NULL)
+ {
+ sortRows();
+ }
+
+ virtual qint64 start() const
+ {
+ return m_profile->frames.front().cpuStart;
+ }
+
+ virtual qint64 end() const
+ {
+ return m_profile->frames.back().cpuStart + m_profile->frames.back().cpuDuration;
+ }
+
+ virtual unsigned dataRows() const
+ {
+ return m_rowPrograms.size();
+ }
+
+ virtual QString dataLabel(unsigned row) const
+ {
+ if (row >= m_rowPrograms.size()) {
+ return QString();
+ } else {
+ return QString("%1").arg(m_rowPrograms[row]);
+ }
+ }
+
+ virtual qint64 dataRowAt(unsigned row) const
+ {
+ if (row >= m_rowPrograms.size()) {
+ return 0;
+ } else {
+ return m_rowPrograms[row];
+ }
+ }
+
+ virtual HeatmapRowIterator* dataRowIterator(int row, qint64 start, qint64 end, int steps) const
+ {
+ ProfileHeatmapRowIterator* itr = new ProfileHeatmapRowIterator(m_profile, start, end, steps, true, m_rowPrograms[row]);
+
+ if (m_selectionState) {
+ if (m_selectionState->type == SelectionState::Horizontal) {
+ itr->setTimeSelection(m_selectionState->start, m_selectionState->end);
+ } else if (m_selectionState->type == SelectionState::Vertical) {
+ itr->setProgramSelection(m_selectionState->start);
+ }
+ }
+
+ return itr;
+ }
+
+ virtual unsigned headerRows() const
+ {
+ return 2;
+ }
+
+ virtual qint64 headerRowAt(unsigned row) const
+ {
+ return row;
+ }
+
+ virtual QString headerLabel(unsigned row) const
+ {
+ if (row == 0) {
+ return "CPU";
+ } else if (row == 1) {
+ return "GPU";
+ } else {
+ return QString();
+ }
+ }
+
+ virtual HeatmapRowIterator* headerRowIterator(int row, qint64 start, qint64 end, int steps) const
+ {
+ ProfileHeatmapRowIterator* itr = new ProfileHeatmapRowIterator(m_profile, start, end, steps, row != 0);
+
+ if (m_selectionState) {
+ if (m_selectionState->type == SelectionState::Horizontal) {
+ itr->setTimeSelection(m_selectionState->start, m_selectionState->end);
+ } else if (m_selectionState->type == SelectionState::Vertical) {
+ itr->setProgramSelection(m_selectionState->start);
+ }
+ }
+
+ return itr;
+ }
+
+ virtual qint64 dataItemAt(unsigned row, qint64 time) const
+ {
+ if (row >= m_rowPrograms.size()) {
+ return -1;
+ }
+
+ unsigned program = m_rowPrograms[row];
+
+ std::vector<unsigned>::const_iterator item =
+ Profiling::binarySearchTimespanIndexed
+ (m_profile->calls, m_profile->programs[program].calls.begin(), m_profile->programs[program].calls.end(), time);
+
+ if (item == m_profile->programs[program].calls.end()) {
+ return -1;
+ }
+
+ return *item;
+ }
+
+ virtual qint64 headerItemAt(unsigned row, qint64 time) const
+ {
+ if (row >= m_rowPrograms.size()) {
+ return -1;
+ }
+
+ if (row == 0) {
+ /* CPU */
+ std::vector<trace::Profile::Call>::const_iterator item =
+ Profiling::binarySearchTimespan<trace::Profile::Call,
+ &trace::Profile::Call::cpuStart,
+ &trace::Profile::Call::cpuDuration>
+ (m_profile->calls.begin(), m_profile->calls.end(), time);
+
+ if (item != m_profile->calls.end()) {
+ return item - m_profile->calls.begin();
+ }
+ } else if (row == 1) {
+ /* GPU */
+ for (unsigned i = 0; i < m_rowPrograms.size(); ++i) {
+ qint64 index = dataItemAt(i, time);
+
+ if (index != -1) {
+ return index;
+ }
+ }
+ }
+
+ return -1;
+ }
+
+ virtual void itemDoubleClicked(qint64 index) const
+ {
+ if (index < 0 || index >= m_profile->calls.size()) {
+ return;
+ }
+
+ const trace::Profile::Call& call = m_profile->calls[index];
+ Profiling::jumpToCall(call.no);
+ }
+
+ virtual QString itemTooltip(qint64 index) const
+ {
+ if (index >= m_profile->calls.size()) {
+ return QString();
+ }
+
+ const trace::Profile::Call& call = m_profile->calls[index];
+
+ QString text;
+ text = QString::fromStdString(call.name);
+
+ text += QString("\nCall: %1").arg(call.no);
+ text += QString("\nCPU Start: %1").arg(Profiling::getTimeString(call.cpuStart));
+ text += QString("\nCPU Duration: %1").arg(Profiling::getTimeString(call.cpuDuration));
+
+ if (call.pixels >= 0) {
+ text += QString("\nGPU Start: %1").arg(Profiling::getTimeString(call.gpuStart));
+ text += QString("\nGPU Duration: %1").arg(Profiling::getTimeString(call.gpuDuration));
+ text += QString("\nPixels Drawn: %1").arg(QLocale::system().toString((qlonglong)call.pixels));
+ }
+
+ return text;
+ }
+
+ virtual void setSelectionState(SelectionState* state)
+ {
+ m_selectionState = state;
+ }
+
+private:
+ void sortRows()
+ {
+ typedef QPair<quint64, unsigned> Pair;
+ std::vector<Pair> gpu;
+
+ /* Map shader to visible row */
+ for (std::vector<trace::Profile::Program>::const_iterator itr = m_profile->programs.begin(); itr != m_profile->programs.end(); ++itr) {
+ const trace::Profile::Program& program = *itr;
+ unsigned no = itr - m_profile->programs.begin();
+
+ if (program.gpuTotal > 0) {
+ gpu.push_back(Pair(program.gpuTotal, no));
+ }
+ }
+
+ /* Sort the shaders by most used gpu */
+ qSort(gpu);
+
+ /* Create row order */
+ m_rowPrograms.clear();
+
+ for (std::vector<Pair>::const_reverse_iterator itr = gpu.rbegin(); itr != gpu.rend(); ++itr) {
+ m_rowPrograms.push_back(itr->second);
+ }
+ }
+
+protected:
+ trace::Profile* m_profile;
+ std::vector<int> m_rowPrograms;
+ SelectionState* m_selectionState;
+};
+
+#endif
--- /dev/null
+#include "profiletablemodel.h"
+#include "profiledialog.h"
+#include "profiling.h"
+
+#include <QLocale>
+
+typedef trace::Profile::Call Call;
+typedef trace::Profile::Frame Frame;
+typedef trace::Profile::Program Program;
+
+enum {
+ COLUMN_PROGRAM,
+ COLUMN_USAGES,
+ COLUMN_GPU_TIME,
+ COLUMN_CPU_TIME,
+ COLUMN_PIXELS_DRAWN,
+ COLUMN_GPU_AVERAGE,
+ COLUMN_CPU_AVERAGE,
+ COLUMN_PIXELS_AVERAGE,
+ MAX_COLUMN
+};
+
+static QString columnNames[] = {
+ QString("Program"),
+ QString("Calls"),
+ QString("Total GPU Time"),
+ QString("Total CPU Time"),
+ QString("Total Pixels Drawn"),
+ QString("Avg GPU Time"),
+ QString("Avg CPU Time"),
+ QString("Avg Pixels Drawn")
+};
+
+ProfileTableModel::ProfileTableModel(QObject *parent)
+ : QAbstractTableModel(parent),
+ m_profile(0),
+ m_sortColumn(COLUMN_GPU_TIME),
+ m_sortOrder(Qt::DescendingOrder)
+{
+}
+
+
+void ProfileTableModel::setProfile(trace::Profile* profile)
+{
+ m_profile = profile;
+ m_timeMin = m_profile->frames.front().cpuStart;
+ m_timeMax = m_profile->frames.back().cpuStart + m_profile->frames.back().cpuDuration;
+ updateModel();
+}
+
+
+/**
+ * Set selection to nothing
+ */
+void ProfileTableModel::selectNone()
+{
+ m_timeMin = m_timeMax = 0;
+ updateModel();
+ sort(m_sortColumn, m_sortOrder);
+}
+
+
+/**
+ * Set selection to program
+ */
+void ProfileTableModel::selectProgram(unsigned /*program*/)
+{
+ /* We have no program based selection for table */
+ selectNone();
+}
+
+
+/**
+ * Set selection to a period of time
+ */
+void ProfileTableModel::selectTime(int64_t start, int64_t end)
+{
+ m_timeMin = start;
+ m_timeMax = end;
+
+ updateModel();
+ sort(m_sortColumn, m_sortOrder);
+}
+
+
+/**
+ * Creates the row data from trace profile
+ */
+void ProfileTableModel::updateModel()
+{
+ if (m_timeMin == m_timeMax) {
+ m_timeMin = m_profile->frames.front().cpuStart;
+ m_timeMax = m_profile->frames.back().cpuStart + m_profile->frames.back().cpuDuration;
+ }
+
+ for (QList<ProfileTableRow>::iterator itr = m_rowData.begin(); itr != m_rowData.end(); ++itr) {
+ ProfileTableRow& row = *itr;
+
+ row.uses = 0;
+ row.pixels = 0;
+ row.gpuTime = 0;
+ row.cpuTime = 0;
+ row.longestCpu = NULL;
+ row.longestGpu = NULL;
+ row.longestPixel = NULL;
+ }
+
+ for (std::vector<Program>::const_iterator itr = m_profile->programs.begin(); itr != m_profile->programs.end(); ++itr) {
+ ProfileTableRow* row = NULL;
+ const Program& program = *itr;
+
+ for (std::vector<unsigned>::const_iterator jtr = program.calls.begin(); jtr != program.calls.end(); ++jtr) {
+ const Call& call = m_profile->calls[*jtr];
+
+ if (call.cpuStart > m_timeMax) {
+ break;
+ }
+
+ if (call.cpuStart + call.cpuDuration < m_timeMin) {
+ continue;
+ }
+
+ if (!row) {
+ row = getRow(itr - m_profile->programs.begin());
+ }
+
+ row->uses++;
+ row->pixels += call.pixels;
+ row->gpuTime += call.gpuDuration;
+ row->cpuTime += call.cpuDuration;
+
+ if (!row->longestGpu || row->longestGpu->gpuDuration < call.gpuDuration) {
+ row->longestGpu = &call;
+ }
+
+ if (!row->longestCpu || row->longestCpu->cpuDuration < call.cpuDuration) {
+ row->longestCpu = &call;
+ }
+
+ if (!row->longestPixel || row->longestPixel->pixels < call.pixels) {
+ row->longestPixel = &call;
+ }
+ }
+ }
+}
+
+
+/**
+ * Get the appropriate call associated with an item in the table
+ */
+const trace::Profile::Call *ProfileTableModel::getJumpCall(const QModelIndex & index) const {
+ const ProfileTableRow& row = m_rowData[index.row()];
+
+ switch(index.column()) {
+ case COLUMN_GPU_TIME:
+ case COLUMN_GPU_AVERAGE:
+ return row.longestGpu;
+ case COLUMN_CPU_TIME:
+ case COLUMN_CPU_AVERAGE:
+ return row.longestCpu;
+ case COLUMN_PIXELS_DRAWN:
+ case COLUMN_PIXELS_AVERAGE:
+ return row.longestPixel;
+ }
+
+ return NULL;
+}
+
+
+/**
+ * Get the shader program associated with an item in the table
+ */
+unsigned ProfileTableModel::getProgram(const QModelIndex & index) const
+{
+ const ProfileTableRow& row = m_rowData[index.row()];
+ return row.program;
+}
+
+
+/**
+ * Get the row index for a shader program
+ */
+int ProfileTableModel::getRowIndex(unsigned program) const
+{
+ for (int i = 0; i < m_rowData.size(); ++i) {
+ if (m_rowData[i].program == program)
+ return i;
+ }
+
+ return -1;
+}
+
+
+/**
+ * Get the row data for a shader program
+ */
+ProfileTableRow* ProfileTableModel::getRow(unsigned program) {
+ for (QList<ProfileTableRow>::iterator itr = m_rowData.begin(); itr != m_rowData.end(); ++itr) {
+ if (itr->program == program)
+ return &*itr;
+ }
+
+ m_rowData.append(ProfileTableRow(program));
+ return &m_rowData.back();
+}
+
+
+int ProfileTableModel::rowCount(const QModelIndex & parent) const
+{
+ if (!parent.isValid()) {
+ return m_rowData.size();
+ } else {
+ return 0;
+ }
+}
+
+
+int ProfileTableModel::columnCount(const QModelIndex & /*parent*/) const
+{
+ return MAX_COLUMN;
+}
+
+
+QVariant ProfileTableModel::data(const QModelIndex &index, int role) const
+{
+ if (!index.isValid()) {
+ return QVariant();
+ }
+
+ if (role == Qt::DisplayRole) {
+ const ProfileTableRow& row = m_rowData[index.row()];
+
+ switch(index.column()) {
+ case COLUMN_PROGRAM:
+ return row.program;
+ case COLUMN_USAGES:
+ return QLocale::system().toString(row.uses);
+ case COLUMN_GPU_TIME:
+ return Profiling::getTimeString(row.gpuTime);
+ case COLUMN_CPU_TIME:
+ return Profiling::getTimeString(row.cpuTime);
+ case COLUMN_PIXELS_DRAWN:
+ return QLocale::system().toString((qlonglong)row.pixels);
+ case COLUMN_GPU_AVERAGE:
+ return Profiling::getTimeString((row.uses <= 0) ? 0 : (row.gpuTime / row.uses));
+ case COLUMN_CPU_AVERAGE:
+ return Profiling::getTimeString((row.uses <= 0) ? 0 : (row.cpuTime / row.uses));
+ case COLUMN_PIXELS_AVERAGE:
+ return QLocale::system().toString((row.uses <= 0) ? 0 : (row.pixels / row.uses));
+ }
+ } else if (role == Qt::TextAlignmentRole) {
+ return Qt::AlignRight;
+ }
+
+ return QVariant();
+}
+
+
+QVariant ProfileTableModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
+ if (section >= 0 && section < MAX_COLUMN) {
+ return columnNames[section];
+ }
+ }
+
+ return QVariant();
+}
+
+
+class ProgramSorter {
+public:
+ ProgramSorter(int column, Qt::SortOrder order)
+ : mSortColumn(column),
+ mSortOrder(order)
+ {
+ }
+
+ bool operator()(const ProfileTableRow &p1, const ProfileTableRow &p2) const
+ {
+ bool result = true;
+
+ switch(mSortColumn) {
+ case COLUMN_PROGRAM:
+ result = p1.program < p2.program;
+ break;
+ case COLUMN_USAGES:
+ result = p1.uses < p2.uses;
+ break;
+ case COLUMN_GPU_TIME:
+ result = p1.gpuTime < p2.gpuTime;
+ break;
+ case COLUMN_CPU_TIME:
+ result = p1.cpuTime < p2.cpuTime;
+ break;
+ case COLUMN_PIXELS_DRAWN:
+ result = p1.pixels < p2.pixels;
+ break;
+ case COLUMN_GPU_AVERAGE:
+ result = ((p1.uses <= 0) ? 0 : (p1.gpuTime / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.gpuTime / p2.uses));
+ break;
+ case COLUMN_CPU_AVERAGE:
+ result = ((p1.uses <= 0) ? 0 : (p1.cpuTime / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.cpuTime / p2.uses));
+ break;
+ case COLUMN_PIXELS_AVERAGE:
+ result = ((p1.uses <= 0) ? 0 : (p1.pixels / p1.uses)) < ((p2.uses <= 0) ? 0 : (p2.pixels / p2.uses));
+ break;
+ }
+
+ if (mSortOrder == Qt::DescendingOrder) {
+ return !result;
+ } else {
+ return result;
+ }
+ }
+
+private:
+ int mSortColumn;
+ Qt::SortOrder mSortOrder;
+};
+
+
+void ProfileTableModel::sort(int column, Qt::SortOrder order) {
+ m_sortColumn = column;
+ m_sortOrder = order;
+ qSort(m_rowData.begin(), m_rowData.end(), ProgramSorter(column, order));
+ emit dataChanged(createIndex(0, 0), createIndex(m_rowData.size(), MAX_COLUMN));
+}
+
+
+#include "profiletablemodel.moc"
--- /dev/null
+#ifndef PROFILETABLEMODEL_H
+#define PROFILETABLEMODEL_H
+
+#include <QAbstractTableModel>
+#include "trace_profiler.hpp"
+
+struct ProfileTableRow
+{
+ ProfileTableRow(unsigned no)
+ : program(no),
+ uses(0),
+ gpuTime(0),
+ cpuTime(0),
+ pixels(0),
+ longestGpu(0),
+ longestCpu(0),
+ longestPixel(0)
+ {
+ }
+
+ unsigned program;
+ qulonglong uses;
+ qulonglong gpuTime;
+ qulonglong cpuTime;
+ qulonglong pixels;
+
+ const trace::Profile::Call* longestGpu;
+ const trace::Profile::Call* longestCpu;
+ const trace::Profile::Call* longestPixel;
+};
+
+class ProfileTableModel : public QAbstractTableModel
+{
+ Q_OBJECT
+
+public:
+ ProfileTableModel(QObject *parent = NULL);
+
+ void setProfile(trace::Profile* profile);
+
+ void selectNone();
+ void selectProgram(unsigned program);
+ void selectTime(int64_t start, int64_t end);
+
+ int getRowIndex(unsigned program) const;
+ unsigned getProgram(const QModelIndex & index) const;
+ const trace::Profile::Call* getJumpCall(const QModelIndex & index) const;
+
+ virtual int rowCount(const QModelIndex & parent) const;
+ virtual int columnCount(const QModelIndex & parent) const;
+
+ virtual QVariant data(const QModelIndex &index, int role) const;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+
+ virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+
+private:
+ void updateModel();
+ ProfileTableRow* getRow(unsigned program);
+
+private:
+ QList<ProfileTableRow> m_rowData;
+ trace::Profile *m_profile;
+ int64_t m_timeMin;
+ int64_t m_timeMax;
+ int m_sortColumn;
+ Qt::SortOrder m_sortOrder;
+};
+
+#endif // PROFILEMODEL_H
--- /dev/null
+#ifndef PROFILING_H
+#define PROFILING_H
+
+#include <QString>
+#include <QLocale>
+#include "trace_profiler.hpp"
+
+class Profiling {
+public:
+ /**
+ * Select and show the call in main window.
+ */
+ static void jumpToCall(int index);
+
+ /**
+ * Convert a CPU / GPU time to a textual representation.
+ * This includes automatic unit selection.
+ */
+ static QString getTimeString(int64_t time, int64_t unitTime = 0)
+ {
+ QString text;
+ QString unit = " ns";
+ double unitScale = 1;
+
+ if (unitTime == 0) {
+ unitTime = time;
+ }
+
+ if (unitTime >= 60e9) {
+ int64_t mins = time / 60e9;
+ text += QString("%1 m ").arg(mins);
+
+ time -= mins * 60e9;
+ unit = " s";
+ unitScale = 1e9;
+ } else if (unitTime >= 1e9) {
+ unit = " s";
+ unitScale = 1e9;
+ } else if (unitTime >= 1e6) {
+ unit = " ms";
+ unitScale = 1e6;
+ } else if (unitTime >= 1e3) {
+ unit = QString::fromUtf8(" µs");
+ unitScale = 1e3;
+ }
+
+ /* 3 decimal places */
+ text += QString("%1").arg(time / unitScale, 0, 'f', 3);
+
+ /* Remove trailing 0 */
+ while(text.endsWith('0'))
+ text.truncate(text.length() - 1);
+
+ /* Remove trailing decimal point */
+ if (text.endsWith(QLocale::system().decimalPoint()))
+ text.truncate(text.length() - 1);
+
+ return text + unit;
+ }
+
+ template<typename val_ty, int64_t val_ty::* mem_ptr_start, int64_t val_ty::* mem_ptr_dura>
+ static typename std::vector<val_ty>::const_iterator binarySearchTimespan(
+ typename std::vector<val_ty>::const_iterator begin,
+ typename std::vector<val_ty>::const_iterator end,
+ int64_t time,
+ bool nearest = false)
+ {
+ int lower = 0;
+ int upper = end - begin;
+ int pos = (lower + upper) / 2;
+ typename std::vector<val_ty>::const_iterator itr = begin + pos;
+
+ while (!((*itr).*mem_ptr_start <= time && (*itr).*mem_ptr_start + (*itr).*mem_ptr_dura > time) && (lower <= upper)) {
+ if ((*itr).*mem_ptr_start > time) {
+ upper = pos - 1;
+ } else {
+ lower = pos + 1;
+ }
+
+ pos = (lower + upper) / 2;
+ itr = begin + pos;
+ }
+
+ if (nearest || lower <= upper) {
+ return itr;
+ } else {
+ return end;
+ }
+ }
+
+ static std::vector<unsigned>::const_iterator binarySearchTimespanIndexed(
+ const std::vector<trace::Profile::Call>& calls,
+ std::vector<unsigned>::const_iterator begin,
+ std::vector<unsigned>::const_iterator end,
+ int64_t time,
+ bool nearest = false)
+ {
+ int lower = 0;
+ int upper = end - begin - 1;
+ int pos = (lower + upper) / 2;
+ std::vector<unsigned>::const_iterator itr = begin + pos;
+
+ while (lower <= upper) {
+ const trace::Profile::Call& call = calls[*itr];
+
+ if (call.gpuStart <= time && call.gpuStart + call.gpuDuration > time) {
+ break;
+ }
+
+ if (call.gpuStart > time) {
+ upper = pos - 1;
+ } else {
+ lower = pos + 1;
+ }
+
+ pos = (lower + upper) / 2;
+ itr = begin + pos;
+ }
+
+ if (nearest || lower <= upper) {
+ return itr;
+ } else {
+ return end;
+ }
+ }
+};
+
+#endif
#include "image.hpp"
+#include "trace_profiler.hpp"
+
#include <QDebug>
#include <QVariant>
#include <QList>
m_benchmarking(false),
m_doubleBuffered(true),
m_captureState(false),
- m_captureCall(0)
+ m_captureCall(0),
+ m_profileGpu(false),
+ m_profileCpu(false),
+ m_profilePixels(false)
{
qRegisterMetaType<QList<ApiTraceError> >();
m_doubleBuffered = db;
}
+bool Retracer::isProfilingGpu() const
+{
+ return m_profileGpu;
+}
+
+bool Retracer::isProfilingCpu() const
+{
+ return m_profileCpu;
+}
+
+bool Retracer::isProfilingPixels() const
+{
+ return m_profilePixels;
+}
+
+bool Retracer::isProfiling() const
+{
+ return m_profileGpu || m_profileCpu || m_profilePixels;
+}
+
+void Retracer::setProfiling(bool gpu, bool cpu, bool pixels)
+{
+ m_profileGpu = gpu;
+ m_profileCpu = cpu;
+ m_profilePixels = pixels;
+}
+
void Retracer::setCaptureAtCallNumber(qlonglong num)
{
m_captureCall = num;
m_captureThumbnails = enable;
}
-
/**
* Starting point for the retracing thread.
*
return;
}
- if (m_doubleBuffered) {
- arguments << QLatin1String("-db");
- } else {
- arguments << QLatin1String("-sb");
- }
-
if (m_captureState) {
arguments << QLatin1String("-D");
arguments << QString::number(m_captureCall);
} else if (m_captureThumbnails) {
arguments << QLatin1String("-s"); // emit snapshots
arguments << QLatin1String("-"); // emit to stdout
- } else if (m_benchmarking) {
- arguments << QLatin1String("-b");
+ } else if (isProfiling()) {
+ if (m_profileGpu) {
+ arguments << QLatin1String("-pgpu");
+ }
+
+ if (m_profileCpu) {
+ arguments << QLatin1String("-pcpu");
+ }
+
+ if (m_profilePixels) {
+ arguments << QLatin1String("-ppd");
+ }
+ } else {
+ if (m_doubleBuffered) {
+ arguments << QLatin1String("-db");
+ } else {
+ arguments << QLatin1String("-sb");
+ }
+
+ if (m_benchmarking) {
+ arguments << QLatin1String("-b");
+ }
}
arguments << m_fileName;
QList<QImage> thumbnails;
QVariantMap parsedJson;
+ trace::Profile* profile = NULL;
process.setReadChannel(QProcess::StandardOutput);
if (process.waitForReadyRead(-1)) {
bool ok = false;
QJson::Parser jsonParser;
+
+ // Allow Nan/Infinity
+ jsonParser.allowSpecialNumbers(true);
#if 0
parsedJson = jsonParser.parse(&io, &ok).toMap();
#else
}
Q_ASSERT(process.state() != QProcess::Running);
+ } else if (isProfiling()) {
+ profile = new trace::Profile();
+
+ while (!io.atEnd()) {
+ char line[256];
+ qint64 lineLength;
+ lineLength = io.readLine(line, 256);
+
+ if (lineLength == -1)
+ break;
+
+ trace::Profiler::parseLine(line, profile);
+ }
} else {
QByteArray output;
output = process.readAllStandardOutput();
emit foundThumbnails(thumbnails);
}
+ if (isProfiling() && profile) {
+ emit foundProfile(profile);
+ }
+
if (!errors.isEmpty()) {
emit retraceErrors(errors);
}
class ApiTraceState;
+namespace trace { struct Profile; }
+
class Retracer : public QThread
{
Q_OBJECT
bool isDoubleBuffered() const;
void setDoubleBuffered(bool db);
+ bool isProfilingGpu() const;
+ bool isProfilingCpu() const;
+ bool isProfilingPixels() const;
+ bool isProfiling() const;
+ void setProfiling(bool gpu, bool cpu, bool pixels);
+
void setCaptureAtCallNumber(qlonglong num);
qlonglong captureAtCallNumber() const;
signals:
void finished(const QString &output);
void foundState(ApiTraceState *state);
+ void foundProfile(trace::Profile *profile);
void foundThumbnails(const QList<QImage> &thumbnails);
void error(const QString &msg);
void retraceErrors(const QList<ApiTraceError> &errors);
bool m_captureState;
bool m_captureThumbnails;
qlonglong m_captureCall;
+ bool m_profileGpu;
+ bool m_profileCpu;
+ bool m_profilePixels;
QProcessEnvironment m_processEnvironment;
};
<addaction name="actionGo"/>
<addaction name="actionGoFrameStart"/>
<addaction name="actionGoFrameEnd"/>
- <addaction name="separator"/>
- <addaction name="actionShowErrorsDock"/>
</widget>
<widget class="QMenu" name="menu_Trace">
<property name="title">
<string>&Trace</string>
</property>
<addaction name="actionReplay"/>
+ <addaction name="actionProfile"/>
<addaction name="actionStop"/>
<addaction name="actionLookupState"/>
<addaction name="actionShowThumbnails"/>
<addaction name="separator"/>
<addaction name="actionOptions"/>
</widget>
+ <widget class="QMenu" name="menuView">
+ <property name="title">
+ <string>&View</string>
+ </property>
+ <addaction name="actionShowErrorsDock"/>
+ <addaction name="actionShowProfileDialog"/>
+ </widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
+ <addaction name="menuView"/>
<addaction name="menu_Trace"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<bool>false</bool>
</property>
<property name="text">
- <string>Show Errors Dock</string>
+ <string>Show &Errors Dock</string>
+ </property>
+ </action>
+ <action name="actionShowProfileDialog">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Show &Profile Results</string>
+ </property>
+ </action>
+ <action name="actionProfile">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&Profile</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+P</string>
</property>
</action>
<zorder>stateDock</zorder>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ProfileDialog</class>
+ <widget class="QDialog" name="ProfileDialog">
+ <property name="windowModality">
+ <enum>Qt::NonModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1105</width>
+ <height>804</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Profile Results</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="opaqueResize">
+ <bool>false</bool>
+ </property>
+ <widget class="GraphWidget" name="m_timeline" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::WheelFocus</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="graphContainer" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>200</height>
+ </size>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="CallDurationGraph" name="m_gpuGraph" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::WheelFocus</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="CallDurationGraph" name="m_cpuGraph" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QTableView" name="m_table">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="verticalScrollMode">
+ <enum>QAbstractItemView::ScrollPerPixel</enum>
+ </property>
+ <property name="horizontalScrollMode">
+ <enum>QAbstractItemView::ScrollPerPixel</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <attribute name="verticalHeaderVisible">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>GraphWidget</class>
+ <extends>QWidget</extends>
+ <header>graphing/graphwidget.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>CallDurationGraph</class>
+ <extends>QWidget</extends>
+ <header>calldurationgraph.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>m_table</sender>
+ <signal>doubleClicked(QModelIndex)</signal>
+ <receiver>ProfileDialog</receiver>
+ <slot>tableDoubleClicked(QModelIndex)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>895</x>
+ <y>220</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>511</x>
+ <y>383</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <signal>jumpToCall(int)</signal>
+ <slot>setVerticalScrollMax(int)</slot>
+ <slot>setHorizontalScrollMax(int)</slot>
+ <slot>tableDoubleClicked(QModelIndex)</slot>
+ <slot>selectTime(int64_t,int64_t)</slot>
+ <slot>selectProgram(unsigned)</slot>
+ <slot>selectNone()</slot>
+ </slots>
+</ui>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ProfileReplayDialog</class>
+ <widget class="QDialog" name="ProfileReplayDialog">
+ <property name="windowModality">
+ <enum>Qt::ApplicationModal</enum>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>353</width>
+ <height>165</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Profile Configuration</string>
+ </property>
+ <property name="whatsThis">
+ <string>Allows setting options on the profiling process.</string>
+ </property>
+ <property name="modal">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="profileGroup">
+ <property name="title">
+ <string>Profiling</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="gpuTimesCB">
+ <property name="text">
+ <string>GPU times</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuTimesCB">
+ <property name="text">
+ <string>CPU times</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="pixelsDrawnCB">
+ <property name="text">
+ <string>Pixels drawn per call</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ProfileReplayDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>176</x>
+ <y>142</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>176</x>
+ <y>82</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ProfileReplayDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>176</x>
+ <y>142</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>176</x>
+ <y>82</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2012 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, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * AUTHORS,
+ * AND/OR THEIR SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+
+/*
+ * Auxiliary functions to compute the size of array/blob arguments.
+ */
+
+#ifndef _D3D10SIZE_HPP_
+#define _D3D10SIZE_HPP_
+
+
+/* We purposedly don't include any D3D header, so that this header can be used
+ * with all D3D versions. */
+
+#include <assert.h>
+
+#include <algorithm>
+
+
+static size_t
+_calcDataSize(DXGI_FORMAT Format, UINT Width, UINT Height, UINT RowPitch, UINT Depth = 1, UINT DepthPitch = 0) {
+ if (Width == 0 || Height == 0 || Depth == 0) {
+ return 0;
+ }
+
+ size_t BlockSize = 0;
+ UINT BlockWidth = 1;
+ UINT BlockHeight = 1;
+ switch (Format) {
+ case DXGI_FORMAT_UNKNOWN:
+ return 0;
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ BlockSize = 128;
+ break;
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ case DXGI_FORMAT_R32G32B32_UINT:
+ case DXGI_FORMAT_R32G32B32_SINT:
+ BlockSize = 96;
+ break;
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ case DXGI_FORMAT_R32G32_FLOAT:
+ case DXGI_FORMAT_R32G32_UINT:
+ case DXGI_FORMAT_R32G32_SINT:
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ BlockSize = 64;
+ break;
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ case DXGI_FORMAT_R16G16_FLOAT:
+ case DXGI_FORMAT_R16G16_UNORM:
+ case DXGI_FORMAT_R16G16_UINT:
+ case DXGI_FORMAT_R16G16_SNORM:
+ case DXGI_FORMAT_R16G16_SINT:
+ case DXGI_FORMAT_R32_TYPELESS:
+ case DXGI_FORMAT_D32_FLOAT:
+ case DXGI_FORMAT_R32_FLOAT:
+ case DXGI_FORMAT_R32_UINT:
+ case DXGI_FORMAT_R32_SINT:
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ BlockSize = 32;
+ break;
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ case DXGI_FORMAT_R8G8_UNORM:
+ case DXGI_FORMAT_R8G8_UINT:
+ case DXGI_FORMAT_R8G8_SNORM:
+ case DXGI_FORMAT_R8G8_SINT:
+ case DXGI_FORMAT_R16_TYPELESS:
+ case DXGI_FORMAT_R16_FLOAT:
+ case DXGI_FORMAT_D16_UNORM:
+ case DXGI_FORMAT_R16_UNORM:
+ case DXGI_FORMAT_R16_UINT:
+ case DXGI_FORMAT_R16_SNORM:
+ case DXGI_FORMAT_R16_SINT:
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ BlockSize = 16;
+ break;
+ case DXGI_FORMAT_R8_TYPELESS:
+ case DXGI_FORMAT_R8_UNORM:
+ case DXGI_FORMAT_R8_UINT:
+ case DXGI_FORMAT_R8_SNORM:
+ case DXGI_FORMAT_R8_SINT:
+ case DXGI_FORMAT_A8_UNORM:
+ BlockSize = 8;
+ break;
+ case DXGI_FORMAT_R1_UNORM:
+ BlockSize = 1;
+ break;
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ BlockSize = 32;
+ BlockWidth = 2;
+ break;
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC4_SNORM:
+ BlockSize = 64;
+ BlockWidth = 4;
+ BlockHeight = 4;
+ break;
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC5_SNORM:
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ case DXGI_FORMAT_BC6H_UF16:
+ case DXGI_FORMAT_BC6H_SF16:
+ case DXGI_FORMAT_BC7_TYPELESS:
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ BlockSize = 128;
+ BlockWidth = 4;
+ BlockHeight = 4;
+ break;
+ default:
+ os::log("apitrace: warning: %s: unknown format 0x%04X\n", __FUNCTION__, Format);
+ return 0;
+ }
+
+ Width = (Width + BlockWidth - 1) / BlockWidth;
+ Height = (Height + BlockHeight - 1) / BlockHeight;
+
+ size_t size = (Width * BlockSize + 7)/ 8;
+
+ if (Height > 1) {
+ size += (Height - 1) * RowPitch;
+ }
+
+ if (Depth > 1) {
+ size += (Depth - 1) * DepthPitch;
+ }
+
+ return size;
+}
+
+static size_t
+_calcMipDataSize(UINT MipLevel, DXGI_FORMAT Format, UINT Width, UINT Height, UINT RowPitch, UINT Depth = 1, UINT DepthPitch = 0) {
+ if (Width == 0 || Height == 0 || Depth == 0) {
+ return 0;
+ }
+
+ Width = std::max(Width >> MipLevel, UINT(1));
+ Height = std::max(Height >> MipLevel, UINT(1));
+ Depth = std::max(Depth >> MipLevel, UINT(1));
+
+ return _calcDataSize(Format, Width, Height, RowPitch, Depth, DepthPitch);
+}
+
+
+inline UINT
+_getNumMipLevels(UINT Width, UINT Height = 1, UINT Depth = 1) {
+ UINT MipLevels = 0;
+ do {
+ ++MipLevels;
+ Width >>= 1;
+ Height >>= 1;
+ Depth >>= 1;
+ } while (Width || Height || Depth);
+ return MipLevels;
+}
+
+inline UINT
+_getNumMipLevels(const D3D10_BUFFER_DESC *pDesc) {
+ return 1;
+}
+
+inline UINT
+_getNumMipLevels(const D3D10_TEXTURE1D_DESC *pDesc) {
+ return pDesc->MipLevels != 0 ? pDesc->MipLevels : _getNumMipLevels(pDesc->Width);
+}
+
+inline UINT
+_getNumMipLevels(const D3D10_TEXTURE2D_DESC *pDesc) {
+ return pDesc->MipLevels != 0 ? pDesc->MipLevels : _getNumMipLevels(pDesc->Width, pDesc->Height);
+}
+
+inline UINT
+_getNumMipLevels(const D3D10_TEXTURE3D_DESC *pDesc) {
+ return pDesc->MipLevels != 0 ? pDesc->MipLevels : _getNumMipLevels(pDesc->Width, pDesc->Height, pDesc->Depth);
+}
+
+inline UINT
+_getNumSubResources(const D3D10_BUFFER_DESC *pDesc) {
+ return 1;
+}
+
+inline UINT
+_getNumSubResources(const D3D10_TEXTURE1D_DESC *pDesc) {
+ return _getNumMipLevels(pDesc) * pDesc->ArraySize;
+}
+
+inline UINT
+_getNumSubResources(const D3D10_TEXTURE2D_DESC *pDesc) {
+ return _getNumMipLevels(pDesc) * pDesc->ArraySize;
+}
+
+inline UINT
+_getNumSubResources(const D3D10_TEXTURE3D_DESC *pDesc) {
+ return _getNumMipLevels(pDesc);
+}
+
+static inline size_t
+_calcSubresourceSize(const D3D10_BUFFER_DESC *pDesc, UINT Subresource, UINT RowPitch = 0, UINT SlicePitch = 0) {
+ return pDesc->ByteWidth;
+}
+
+static inline size_t
+_calcSubresourceSize(const D3D10_TEXTURE1D_DESC *pDesc, UINT Subresource, UINT RowPitch = 0, UINT SlicePitch = 0) {
+ UINT MipLevel = Subresource % _getNumMipLevels(pDesc);
+ return _calcMipDataSize(MipLevel, pDesc->Format, pDesc->Width, 1, RowPitch, 1, SlicePitch);
+}
+
+static inline size_t
+_calcSubresourceSize(const D3D10_TEXTURE2D_DESC *pDesc, UINT Subresource, UINT RowPitch, UINT SlicePitch = 0) {
+ UINT MipLevel = Subresource % _getNumMipLevels(pDesc);
+ return _calcMipDataSize(MipLevel, pDesc->Format, pDesc->Width, pDesc->Height, RowPitch, 1, SlicePitch);
+}
+
+static inline size_t
+_calcSubresourceSize(const D3D10_TEXTURE3D_DESC *pDesc, UINT Subresource, UINT RowPitch, UINT SlicePitch) {
+ UINT MipLevel = Subresource;
+ return _calcMipDataSize(MipLevel, pDesc->Format, pDesc->Width, pDesc->Height, RowPitch, pDesc->Depth, SlicePitch);
+}
+
+static inline void
+_getMapInfo(ID3D10Buffer *pResource, D3D10_MAP MapType, UINT MapFlags, void * * ppData,
+ void * & pMappedData, size_t & MappedSize) {
+ pMappedData = 0;
+ MappedSize = 0;
+
+ if (MapType == D3D10_MAP_READ) {
+ return;
+ }
+
+ D3D10_BUFFER_DESC Desc;
+ pResource->GetDesc(&Desc);
+
+ pMappedData = *ppData;
+ MappedSize = Desc.ByteWidth;
+}
+
+static inline void
+_getMapInfo(ID3D10Texture1D *pResource, UINT Subresource, D3D10_MAP MapType, UINT MapFlags, void * * ppData,
+ void * & pMappedData, size_t & MappedSize) {
+ pMappedData = 0;
+ MappedSize = 0;
+
+ if (MapType == D3D10_MAP_READ) {
+ return;
+ }
+
+ D3D10_TEXTURE1D_DESC Desc;
+ pResource->GetDesc(&Desc);
+
+ pMappedData = *ppData;
+ MappedSize = _calcSubresourceSize(&Desc, Subresource);
+}
+
+static inline void
+_getMapInfo(ID3D10Texture2D *pResource, UINT Subresource, D3D10_MAP MapType, UINT MapFlags, D3D10_MAPPED_TEXTURE2D * pMappedTex2D,
+ void * & pMappedData, size_t & MappedSize) {
+ pMappedData = 0;
+ MappedSize = 0;
+
+ if (MapType == D3D10_MAP_READ) {
+ return;
+ }
+
+ D3D10_TEXTURE2D_DESC Desc;
+ pResource->GetDesc(&Desc);
+
+ pMappedData = pMappedTex2D->pData;
+ MappedSize = _calcSubresourceSize(&Desc, Subresource, pMappedTex2D->RowPitch);
+}
+
+static inline void
+_getMapInfo(ID3D10Texture3D *pResource, UINT Subresource, D3D10_MAP MapType, UINT MapFlags, D3D10_MAPPED_TEXTURE3D * pMappedTex3D,
+ void * & pMappedData, size_t & MappedSize) {
+ pMappedData = 0;
+ MappedSize = 0;
+
+ if (MapType == D3D10_MAP_READ) {
+ return;
+ }
+
+ D3D10_TEXTURE3D_DESC Desc;
+ pResource->GetDesc(&Desc);
+
+ pMappedData = pMappedTex3D->pData;
+ MappedSize = _calcSubresourceSize(&Desc, Subresource, pMappedTex3D->RowPitch, pMappedTex3D->DepthPitch);
+}
+
+
+static inline void
+_getMapInfo(IDXGISurface *pResource, DXGI_MAPPED_RECT * pLockedRect, UINT MapFlags,
+ void * & pMappedData, size_t & MappedSize) {
+ pMappedData = 0;
+ MappedSize = 0;
+
+ if (!(MapFlags & DXGI_MAP_WRITE)) {
+ return;
+ }
+
+ DXGI_SURFACE_DESC Desc;
+ HRESULT hr = pResource->GetDesc(&Desc);
+ if (FAILED(hr)) {
+ return;
+ }
+
+ pMappedData = pLockedRect->pBits;
+ MappedSize = _calcDataSize(Desc.Format, Desc.Width, Desc.Height, pLockedRect->Pitch);
+}
+
+
+static inline size_t
+_calcSubresourceSize(ID3D10Resource *pDstResource, UINT DstSubresource, const D3D10_BOX *pDstBox, UINT SrcRowPitch, UINT SrcDepthPitch) {
+ if (pDstBox &&
+ (pDstBox->left >= pDstBox->right ||
+ pDstBox->top >= pDstBox->bottom ||
+ pDstBox->front >= pDstBox->back)) {
+ return 0;
+ }
+
+ D3D10_RESOURCE_DIMENSION Type = D3D10_RESOURCE_DIMENSION_UNKNOWN;
+ pDstResource->GetType(&Type);
+
+ DXGI_FORMAT Format;
+ UINT Width;
+ UINT Height = 1;
+ UINT Depth = 1;
+ UINT MipLevel = 0;
+
+ switch (Type) {
+ case D3D10_RESOURCE_DIMENSION_BUFFER:
+ if (pDstBox) {
+ return pDstBox->right - pDstBox->left;
+ } else {
+ D3D10_BUFFER_DESC Desc;
+ static_cast<ID3D10Buffer *>(pDstResource)->GetDesc(&Desc);
+ return Desc.ByteWidth;
+ }
+ case D3D10_RESOURCE_DIMENSION_TEXTURE1D:
+ {
+ D3D10_TEXTURE1D_DESC Desc;
+ static_cast<ID3D10Texture1D *>(pDstResource)->GetDesc(&Desc);
+ Format = Desc.Format;
+ Width = Desc.Width;
+ MipLevel = DstSubresource % Desc.MipLevels;
+ }
+ break;
+ case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
+ {
+ D3D10_TEXTURE2D_DESC Desc;
+ static_cast<ID3D10Texture2D *>(pDstResource)->GetDesc(&Desc);
+ Format = Desc.Format;
+ Width = Desc.Width;
+ Height = Desc.Height;
+ MipLevel = DstSubresource % Desc.MipLevels;
+ }
+ break;
+ case D3D10_RESOURCE_DIMENSION_TEXTURE3D:
+ {
+ D3D10_TEXTURE3D_DESC Desc;
+ static_cast<ID3D10Texture3D *>(pDstResource)->GetDesc(&Desc);
+ Format = Desc.Format;
+ Width = Desc.Width;
+ Height = Desc.Height;
+ Depth = Desc.Depth;
+ }
+ break;
+ case D3D10_RESOURCE_DIMENSION_UNKNOWN:
+ default:
+ assert(0);
+ return 0;
+ }
+
+ return _calcMipDataSize(MipLevel, Format, Width, Height, SrcRowPitch, Depth, SrcDepthPitch);
+}
+
+
+#endif /* _D3D10SIZE_HPP_ */
--- /dev/null
+/**************************************************************************
+ *
+ * Copyright 2012 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, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * AUTHORS,
+ * AND/OR THEIR SUPPLIERS 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.
+ *
+ **************************************************************************/
+
+
+/*
+ * Auxiliary functions to compute the size of array/blob arguments.
+ */
+
+#ifndef _D3D9SIZE_HPP_
+#define _D3D9SIZE_HPP_
+
+
+/* We purposedly don't include any D3D header, so that this header can be used
+ * with all D3D versions. */
+
+#include <assert.h>
+
+#include "os.hpp"
+
+
+static inline size_t
+_vertexCount(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount)
+{
+ switch (PrimitiveType) {
+ case D3DPT_POINTLIST:
+ return PrimitiveCount;
+ case D3DPT_LINELIST:
+ return PrimitiveCount*2;
+ case D3DPT_LINESTRIP:
+ return PrimitiveCount + 1;
+ case D3DPT_TRIANGLELIST:
+ return PrimitiveCount * 3;
+ case D3DPT_TRIANGLESTRIP:
+ return PrimitiveCount + 2;
+ case D3DPT_TRIANGLEFAN:
+ return PrimitiveCount + 1;
+ default:
+ os::log("apitrace: warning: %s: unknown D3DPRIMITIVETYPE %u\n", __FUNCTION__, PrimitiveType);
+ return 0;
+ }
+}
+
+
+static inline size_t
+_vertexDataSize(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, UINT VertexStride) {
+ return _vertexCount(PrimitiveType, PrimitiveCount) * VertexStride;
+}
+
+
+static inline size_t
+_indexDataSize(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, D3DFORMAT IndexDataFormat) {
+ UINT IndexStride;
+ switch (IndexDataFormat) {
+ case D3DFMT_INDEX16:
+ IndexStride = 2;
+ break;
+ case D3DFMT_INDEX32:
+ IndexStride = 4;
+ break;
+ default:
+ os::log("apitrace: warning: %s: unexpected index D3DFORMAT %u\n", __FUNCTION__, IndexDataFormat);
+ return 0;
+ }
+ return _vertexCount(PrimitiveType, PrimitiveCount) * IndexStride;
+}
+
+
+#if DIRECT3D_VERSION >= 0x0800
+
+/*
+ * Return the number of tokens for a given shader.
+ */
+static inline size_t
+_shaderSize(const DWORD *pFunction)
+{
+ DWORD dwLength = 0;
+
+ while (true) {
+ DWORD dwToken = pFunction[dwLength++];
+
+ switch (dwToken & D3DSI_OPCODE_MASK) {
+ case D3DSIO_COMMENT:
+ dwLength += (dwToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
+ break;
+
+ case D3DSIO_END:
+ if (dwToken != D3DSIO_END) {
+ os::log("apitrace: warning: %s: malformed END token\n", __FUNCTION__);
+ }
+ return dwLength * sizeof *pFunction;
+ }
+ }
+}
+
+
+static size_t
+_getLockSize(D3DFORMAT Format, UINT Width, UINT Height, INT RowPitch, UINT Depth = 1, INT SlicePitch = 0) {
+ if (Width == 0 || Height == 0 || Depth == 0) {
+ return 0;
+ }
+
+ if (RowPitch < 0) {
+ os::log("apitrace: warning: %s: negative row pitch %i\n", __FUNCTION__, RowPitch);
+ return 0;
+ }
+
+ if (SlicePitch < 0) {
+ os::log("apitrace: warning: %s: negative slice pitch %i\n", __FUNCTION__, SlicePitch);
+ return 0;
+ }
+
+ switch ((DWORD)Format) {
+ case D3DFMT_DXT1:
+ case D3DFMT_DXT2:
+ case D3DFMT_DXT3:
+ case D3DFMT_DXT4:
+ case D3DFMT_DXT5:
+ Width = (Width + 3) / 4;
+ Height = (Height + 3) / 4;
+ break;
+
+ case D3DFMT_ATI1N:
+ case D3DFMT_ATI2N:
+ /*
+ * Because these are unsupported formats, RowPitch is not set to the
+ * number of bytes between row of blocks, but instead in such way that
+ * Height * RowPitch will match the expected size.
+ */
+ break;
+
+ case D3DFMT_UYVY:
+ case D3DFMT_R8G8_B8G8:
+ case D3DFMT_YUY2:
+ case D3DFMT_G8R8_G8B8:
+ Width = (Width + 1) / 2;
+ break;
+
+ case D3DFMT_NV12:
+ return (Height + ((Height + 1) / 2)) * RowPitch;
+
+ case D3DFMT_NULL:
+ return 0;
+
+ default:
+ break;
+ }
+
+ (void)Width;
+
+ size_t size = Height * RowPitch;
+
+ if (Depth > 1) {
+ size += (Depth - 1) * SlicePitch;
+ }
+
+ return size;
+}
+
+
+#endif /* DIRECT3D_VERSION >= 0x0800 */
+
+
+#if DIRECT3D_VERSION >= 0x0900
+
+
+static inline void
+_getLockInfo(IDirect3DVertexBuffer9 *pBuffer, UINT OffsetToLock, UINT SizeToLock, void ** ppbData,
+ void * & pLockedData, size_t & LockedSize) {
+ pLockedData = *ppbData;
+ LockedSize = 0;
+
+ if (SizeToLock == 0) {
+ D3DVERTEXBUFFER_DESC Desc;
+ HRESULT hr = pBuffer->GetDesc(&Desc);
+ if (FAILED(hr)) {
+ return;
+ }
+ LockedSize = Desc.Size;
+ } else {
+ LockedSize = SizeToLock;
+ }
+}
+
+
+static inline void
+_getLockInfo(IDirect3DIndexBuffer9 *pBuffer, UINT OffsetToLock, UINT SizeToLock, void ** ppbData,
+ void * & pLockedData, size_t & LockedSize) {
+ pLockedData = *ppbData;
+ LockedSize = 0;
+
+ if (SizeToLock == 0) {
+ D3DINDEXBUFFER_DESC Desc;
+ HRESULT hr = pBuffer->GetDesc(&Desc);
+ if (FAILED(hr)) {
+ return;
+ }
+ LockedSize = Desc.Size;
+ } else {
+ LockedSize = SizeToLock;
+ }
+}
+
+
+static inline void
+_getLockInfo(IDirect3DSurface9 *pSurface, const D3DLOCKED_RECT *pLockedRect, const RECT *pRect,
+ void * & pLockedData, size_t & LockedSize) {
+ pLockedData = pLockedRect->pBits;
+ LockedSize = 0;
+
+ HRESULT hr;
+
+ D3DSURFACE_DESC Desc;
+ hr = pSurface->GetDesc(&Desc);
+ if (FAILED(hr)) {
+ return;
+ }
+
+ UINT Width;
+ UINT Height;
+ if (pRect) {
+ Width = pRect->right - pRect->left;
+ Height = pRect->bottom - pRect->top;
+ } else {
+ Width = Desc.Width;
+ Height = Desc.Height;
+ }
+
+ LockedSize = _getLockSize(Desc.Format, Width, Height, pLockedRect->Pitch);
+}
+
+
+static inline void
+_getLockInfo(IDirect3DTexture9 *pTexture, UINT Level, const D3DLOCKED_RECT *pLockedRect, const RECT *pRect,
+ void * & pLockedData, size_t & LockedSize) {
+ pLockedData = pLockedRect->pBits;
+ LockedSize = 0;
+
+ HRESULT hr;
+
+ D3DSURFACE_DESC Desc;
+ hr = pTexture->GetLevelDesc(Level, &Desc);
+ if (FAILED(hr)) {
+ return;
+ }
+
+ UINT Width;
+ UINT Height;
+ if (pRect) {
+ Width = pRect->right - pRect->left;
+ Height = pRect->bottom - pRect->top;
+ } else {
+ Width = Desc.Width;
+ Height = Desc.Height;
+ }
+
+ LockedSize = _getLockSize(Desc.Format, Width, Height, pLockedRect->Pitch);
+}
+
+
+static inline void
+_getLockInfo(IDirect3DCubeTexture9 *pTexture, D3DCUBEMAP_FACES FaceType, UINT Level, const D3DLOCKED_RECT *pLockedRect, const RECT *pRect,
+ void * & pLockedData, size_t & LockedSize) {
+ pLockedData = pLockedRect->pBits;
+ LockedSize = 0;
+
+ HRESULT hr;
+
+ (void)FaceType;
+
+ D3DSURFACE_DESC Desc;
+ hr = pTexture->GetLevelDesc(Level, &Desc);
+ if (FAILED(hr)) {
+ return;
+ }
+
+ UINT Width;
+ UINT Height;
+ if (pRect) {
+ Width = pRect->right - pRect->left;
+ Height = pRect->bottom - pRect->top;
+ } else {
+ Width = Desc.Width;
+ Height = Desc.Height;
+ }
+
+ LockedSize = _getLockSize(Desc.Format, Width, Height, pLockedRect->Pitch);
+}
+
+
+static inline void
+_getLockInfo(IDirect3DVolume9 *pVolume, const D3DLOCKED_BOX *pLockedVolume, const D3DBOX *pBox,
+ void * & pLockedData, size_t & LockedSize) {
+ pLockedData = pLockedVolume->pBits;
+ LockedSize = 0;
+
+ HRESULT hr;
+
+ D3DVOLUME_DESC Desc;
+ hr = pVolume->GetDesc(&Desc);
+ if (FAILED(hr)) {
+ return;
+ }
+
+ UINT Width;
+ UINT Height;
+ UINT Depth;
+ if (pBox) {
+ Width = pBox->Right - pBox->Left;
+ Height = pBox->Bottom - pBox->Top;
+ Depth = pBox->Back - pBox->Front;
+ } else {
+ Width = Desc.Width;
+ Height = Desc.Height;
+ Depth = Desc.Depth;
+ }
+
+ LockedSize = _getLockSize(Desc.Format, Width, Height, pLockedVolume->RowPitch, Depth, pLockedVolume->SlicePitch);
+}
+
+
+static inline void
+_getLockInfo(IDirect3DVolumeTexture9 *pTexture, UINT Level, const D3DLOCKED_BOX *pLockedVolume, const D3DBOX *pBox,
+ void * & pLockedData, size_t & LockedSize) {
+ pLockedData = pLockedVolume->pBits;
+ LockedSize = 0;
+
+ HRESULT hr;
+
+ D3DVOLUME_DESC Desc;
+ hr = pTexture->GetLevelDesc(Level, &Desc);
+ if (FAILED(hr)) {
+ return;
+ }
+
+ UINT Width;
+ UINT Height;
+ UINT Depth;
+ if (pBox) {
+ Width = pBox->Right - pBox->Left;
+ Height = pBox->Bottom - pBox->Top;
+ Depth = pBox->Back - pBox->Front;
+ } else {
+ Width = Desc.Width;
+ Height = Desc.Height;
+ Depth = Desc.Depth;
+ }
+
+ LockedSize = _getLockSize(Desc.Format, Width, Height, pLockedVolume->RowPitch, Depth, pLockedVolume->SlicePitch);
+}
+
+
+#endif /* DIRECT3D_VERSION >= 0x0900 */
+
+
+#endif /* _D3D9SIZE_HPP_ */
+++ /dev/null
-/**************************************************************************
- *
- * Copyright 2012 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, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * AUTHORS,
- * AND/OR THEIR SUPPLIERS 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.
- *
- **************************************************************************/
-
-
-/*
- * Auxiliary functions to compute the size of array/blob arguments.
- */
-
-#ifndef _D3D_SIZE_HPP_
-#define _D3D_SIZE_HPP_
-
-
-/* We purposedly don't include any D3D header, so that this header can be used
- * with all D3D versions. */
-
-#include <assert.h>
-
-#include "os.hpp"
-
-
-static inline size_t
-_vertexCount(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount)
-{
- switch (PrimitiveType) {
- case D3DPT_POINTLIST:
- return PrimitiveCount;
- case D3DPT_LINELIST:
- return PrimitiveCount*2;
- case D3DPT_LINESTRIP:
- return PrimitiveCount + 1;
- case D3DPT_TRIANGLELIST:
- return PrimitiveCount * 3;
- case D3DPT_TRIANGLESTRIP:
- return PrimitiveCount + 2;
- case D3DPT_TRIANGLEFAN:
- return PrimitiveCount + 1;
- default:
- os::log("apitrace: warning: %s: unknown D3DPRIMITIVETYPE %u\n", __FUNCTION__, PrimitiveType);
- return 0;
- }
-}
-
-
-static inline size_t
-_vertexDataSize(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, UINT VertexStride) {
- return _vertexCount(PrimitiveType, PrimitiveCount) * VertexStride;
-}
-
-
-static inline size_t
-_indexDataSize(D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, D3DFORMAT IndexDataFormat) {
- UINT IndexStride;
- switch (IndexDataFormat) {
- case D3DFMT_INDEX16:
- IndexStride = 2;
- break;
- case D3DFMT_INDEX32:
- IndexStride = 4;
- break;
- default:
- os::log("apitrace: warning: %s: unexpected index D3DFORMAT %u\n", __FUNCTION__, IndexDataFormat);
- return 0;
- }
- return _vertexCount(PrimitiveType, PrimitiveCount) * IndexStride;
-}
-
-
-#if DIRECT3D_VERSION >= 0x0800
-
-/*
- * Return the number of tokens for a given shader.
- */
-static inline size_t
-_shaderSize(const DWORD *pFunction)
-{
- DWORD dwLength = 0;
-
- while (true) {
- DWORD dwToken = pFunction[dwLength++];
-
- switch (dwToken & D3DSI_OPCODE_MASK) {
- case D3DSIO_COMMENT:
- dwLength += (dwToken & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT;
- break;
-
- case D3DSIO_END:
- if (dwToken != D3DSIO_END) {
- os::log("apitrace: warning: %s: malformed END token\n", __FUNCTION__);
- }
- return dwLength * sizeof *pFunction;
- }
- }
-}
-
-
-static size_t
-_getLockSize(D3DFORMAT Format, UINT Width, UINT Height, INT RowPitch, UINT Depth = 1, INT SlicePitch = 0) {
- if (Width == 0 || Height == 0 || Depth == 0) {
- return 0;
- }
-
- if (RowPitch < 0) {
- os::log("apitrace: warning: %s: negative row pitch %i\n", __FUNCTION__, RowPitch);
- return 0;
- }
-
- if (SlicePitch < 0) {
- os::log("apitrace: warning: %s: negative slice pitch %i\n", __FUNCTION__, SlicePitch);
- return 0;
- }
-
- switch ((DWORD)Format) {
- case D3DFMT_DXT1:
- case D3DFMT_DXT2:
- case D3DFMT_DXT3:
- case D3DFMT_DXT4:
- case D3DFMT_DXT5:
- Width = (Width + 3) / 4;
- Height = (Height + 3) / 4;
- break;
-
- case D3DFMT_ATI1N:
- case D3DFMT_ATI2N:
- /*
- * Because these are unsupported formats, RowPitch is not set to the
- * number of bytes between row of blocks, but instead in such way that
- * Height * RowPitch will match the expected size.
- */
- break;
-
- case D3DFMT_UYVY:
- case D3DFMT_R8G8_B8G8:
- case D3DFMT_YUY2:
- case D3DFMT_G8R8_G8B8:
- Width = (Width + 1) / 2;
- break;
-
- case D3DFMT_NV12:
- return (Height + ((Height + 1) / 2)) * RowPitch;
-
- case D3DFMT_NULL:
- return 0;
-
- default:
- break;
- }
-
- (void)Width;
-
- size_t size = Height * RowPitch;
-
- if (Depth > 1) {
- size += (Depth - 1) * SlicePitch;
- }
-
- return size;
-}
-
-
-#endif /* DIRECT3D_VERSION >= 0x0800 */
-
-
-#if DIRECT3D_VERSION >= 0x0900
-
-
-static inline void
-_getLockInfo(IDirect3DVertexBuffer9 *pBuffer, UINT OffsetToLock, UINT SizeToLock, void ** ppbData,
- void * & pLockedData, size_t & LockedSize) {
- pLockedData = *ppbData;
- LockedSize = 0;
-
- if (SizeToLock == 0) {
- D3DVERTEXBUFFER_DESC Desc;
- HRESULT hr = pBuffer->GetDesc(&Desc);
- if (FAILED(hr)) {
- return;
- }
- LockedSize = Desc.Size;
- } else {
- LockedSize = SizeToLock;
- }
-}
-
-
-static inline void
-_getLockInfo(IDirect3DIndexBuffer9 *pBuffer, UINT OffsetToLock, UINT SizeToLock, void ** ppbData,
- void * & pLockedData, size_t & LockedSize) {
- pLockedData = *ppbData;
- LockedSize = 0;
-
- if (SizeToLock == 0) {
- D3DINDEXBUFFER_DESC Desc;
- HRESULT hr = pBuffer->GetDesc(&Desc);
- if (FAILED(hr)) {
- return;
- }
- LockedSize = Desc.Size;
- } else {
- LockedSize = SizeToLock;
- }
-}
-
-
-static inline void
-_getLockInfo(IDirect3DSurface9 *pSurface, const D3DLOCKED_RECT *pLockedRect, const RECT *pRect,
- void * & pLockedData, size_t & LockedSize) {
- pLockedData = pLockedRect->pBits;
- LockedSize = 0;
-
- HRESULT hr;
-
- D3DSURFACE_DESC Desc;
- hr = pSurface->GetDesc(&Desc);
- if (FAILED(hr)) {
- return;
- }
-
- UINT Width;
- UINT Height;
- if (pRect) {
- Width = pRect->right - pRect->left;
- Height = pRect->bottom - pRect->top;
- } else {
- Width = Desc.Width;
- Height = Desc.Height;
- }
-
- LockedSize = _getLockSize(Desc.Format, Width, Height, pLockedRect->Pitch);
-}
-
-
-static inline void
-_getLockInfo(IDirect3DTexture9 *pTexture, UINT Level, const D3DLOCKED_RECT *pLockedRect, const RECT *pRect,
- void * & pLockedData, size_t & LockedSize) {
- pLockedData = pLockedRect->pBits;
- LockedSize = 0;
-
- HRESULT hr;
-
- D3DSURFACE_DESC Desc;
- hr = pTexture->GetLevelDesc(Level, &Desc);
- if (FAILED(hr)) {
- return;
- }
-
- UINT Width;
- UINT Height;
- if (pRect) {
- Width = pRect->right - pRect->left;
- Height = pRect->bottom - pRect->top;
- } else {
- Width = Desc.Width;
- Height = Desc.Height;
- }
-
- LockedSize = _getLockSize(Desc.Format, Width, Height, pLockedRect->Pitch);
-}
-
-
-static inline void
-_getLockInfo(IDirect3DCubeTexture9 *pTexture, D3DCUBEMAP_FACES FaceType, UINT Level, const D3DLOCKED_RECT *pLockedRect, const RECT *pRect,
- void * & pLockedData, size_t & LockedSize) {
- pLockedData = pLockedRect->pBits;
- LockedSize = 0;
-
- HRESULT hr;
-
- (void)FaceType;
-
- D3DSURFACE_DESC Desc;
- hr = pTexture->GetLevelDesc(Level, &Desc);
- if (FAILED(hr)) {
- return;
- }
-
- UINT Width;
- UINT Height;
- if (pRect) {
- Width = pRect->right - pRect->left;
- Height = pRect->bottom - pRect->top;
- } else {
- Width = Desc.Width;
- Height = Desc.Height;
- }
-
- LockedSize = _getLockSize(Desc.Format, Width, Height, pLockedRect->Pitch);
-}
-
-
-static inline void
-_getLockInfo(IDirect3DVolume9 *pVolume, const D3DLOCKED_BOX *pLockedVolume, const D3DBOX *pBox,
- void * & pLockedData, size_t & LockedSize) {
- pLockedData = pLockedVolume->pBits;
- LockedSize = 0;
-
- HRESULT hr;
-
- D3DVOLUME_DESC Desc;
- hr = pVolume->GetDesc(&Desc);
- if (FAILED(hr)) {
- return;
- }
-
- UINT Width;
- UINT Height;
- UINT Depth;
- if (pBox) {
- Width = pBox->Right - pBox->Left;
- Height = pBox->Bottom - pBox->Top;
- Depth = pBox->Back - pBox->Front;
- } else {
- Width = Desc.Width;
- Height = Desc.Height;
- Depth = Desc.Depth;
- }
-
- LockedSize = _getLockSize(Desc.Format, Width, Height, pLockedVolume->RowPitch, Depth, pLockedVolume->SlicePitch);
-}
-
-
-static inline void
-_getLockInfo(IDirect3DVolumeTexture9 *pTexture, UINT Level, const D3DLOCKED_BOX *pLockedVolume, const D3DBOX *pBox,
- void * & pLockedData, size_t & LockedSize) {
- pLockedData = pLockedVolume->pBits;
- LockedSize = 0;
-
- HRESULT hr;
-
- D3DVOLUME_DESC Desc;
- hr = pTexture->GetLevelDesc(Level, &Desc);
- if (FAILED(hr)) {
- return;
- }
-
- UINT Width;
- UINT Height;
- UINT Depth;
- if (pBox) {
- Width = pBox->Right - pBox->Left;
- Height = pBox->Bottom - pBox->Top;
- Depth = pBox->Back - pBox->Front;
- } else {
- Width = Desc.Width;
- Height = Desc.Height;
- Depth = Desc.Depth;
- }
-
- LockedSize = _getLockSize(Desc.Format, Width, Height, pLockedVolume->RowPitch, Depth, pLockedVolume->SlicePitch);
-}
-
-
-#endif /* DIRECT3D_VERSION >= 0x0900 */
-
-
-#endif /* _D3D_SIZE_HPP_ */
--- /dev/null
+/*********************************************************************
+ *
+ * Copyright 2012 Intel Corporation
+ * 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.
+ *
+ *********************************************************************/
+
+/*
+ * Auxiliary functions to compute the size of array/blob arguments.
+ */
+
+#include <string.h>
+
+#include "os_thread.hpp"
+#include "glimports.hpp"
+#include "glproc.hpp"
+#include "glsize.hpp"
+#include "eglsize.hpp"
+#include "assert.h"
+
+
+static int
+bisect_val(int min, int max, bool is_valid_val(int val))
+{
+ bool valid;
+
+ while (1) {
+ int try_val = min + (max - min + 1) / 2;
+
+ valid = is_valid_val(try_val);
+ if (min == max)
+ break;
+
+ if (valid)
+ min = try_val;
+ else
+ max = try_val - 1;
+ }
+
+ return valid ? min : -1;
+}
+
+static bool
+is_valid_width(int val)
+{
+ _glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, val, 1);
+ return _glGetError() == GL_NO_ERROR;
+}
+
+static bool
+is_valid_height(int val)
+{
+ _glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, val);
+ return _glGetError() == GL_NO_ERROR;
+}
+
+static int
+detect_size(int *width_ret, int *height_ret)
+{
+ GLint max_tex_size;
+ int width;
+ int height;
+
+ max_tex_size = 0;
+ _glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_tex_size);
+
+ width = bisect_val(1, max_tex_size, is_valid_width);
+ if (width < 0)
+ return -1;
+
+ height = bisect_val(1, max_tex_size, is_valid_height);
+ if (height < 0)
+ return -1;
+
+ *width_ret = width;
+ *height_ret = height;
+
+ return 0;
+}
+
+/* XXX */
+static inline bool
+can_unpack_subimage(void) {
+ return false;
+}
+
+static void
+_eglCreateImageKHR_get_image_size(EGLImageKHR image, image_info *info)
+{
+ GLuint fbo = 0;
+ GLuint orig_fbo = 0;
+ GLuint texture = 0;
+ GLuint orig_texture;
+ GLenum status;
+
+ _glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *)&orig_fbo);
+ _glGenFramebuffers(1, &fbo);
+ _glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ _glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *)&orig_texture);
+ _glGenTextures(1, &texture);
+ _glBindTexture(GL_TEXTURE_2D, texture);
+
+ _glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+
+ info->width = 0;
+ info->height = 0;
+
+ _glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, texture, 0);
+ status = _glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status == GL_FRAMEBUFFER_COMPLETE) {
+ if (detect_size(&info->width, &info->height) != 0)
+ os::log("%s: can't detect image size\n", __func__);
+ } else {
+ os::log("%s: error: %x\n", __func__, status);
+ }
+
+ /* Don't leak errors to the traced application. */
+ (void)_glGetError();
+
+ _glBindTexture(GL_TEXTURE_2D, orig_texture);
+ _glDeleteTextures(1, &texture);
+
+ _glBindFramebuffer(GL_FRAMEBUFFER, orig_fbo);
+ _glDeleteFramebuffers(1, &fbo);
+}
+
+static void
+get_texture_2d_image(image_info *info)
+{
+ GLuint fbo = 0;
+ GLint prev_fbo = 0;
+ GLint texture;
+ GLenum status;
+
+ _glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture);
+ if (!texture)
+ return;
+
+ _glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_fbo);
+ _glGenFramebuffers(1, &fbo);
+ _glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ _glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ texture, 0);
+ status = _glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE)
+ os::log("%s: error: %d\n", __func__, status);
+ _glReadPixels(0, 0, info->width, info->height, info->format, info->type, info->pixels);
+ /* Don't leak errors to the traced application. */
+ (void)_glGetError();
+
+ _glBindFramebuffer(GL_FRAMEBUFFER, prev_fbo);
+ _glDeleteFramebuffers(1, &fbo);
+}
+
+struct image_info *
+_EGLImageKHR_get_image_info(GLenum target, EGLImageKHR image)
+{
+ GLuint tex;
+ GLuint bound_tex;
+ struct image_info *info;
+
+ info = new image_info;
+
+ memset(info, 0, sizeof *info);
+
+ info->internalformat = GL_RGBA;
+ info->format = GL_RGBA;
+ info->type = GL_UNSIGNED_BYTE;
+
+ _eglCreateImageKHR_get_image_size(image, info);
+
+ _glGenTextures(1, &tex);
+ _glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *)&bound_tex);
+ _glBindTexture(GL_TEXTURE_2D, tex);
+ _glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+
+ info->size = _glTexImage2D_size(info->format, info->type, info->width, info->height);
+ info->pixels = malloc(info->size);
+
+ get_texture_2d_image(info);
+ _glBindTexture(GL_TEXTURE_2D, bound_tex);
+ _glDeleteBuffers(1, &tex);
+
+ return info;
+}
+
+void
+_EGLImageKHR_free_image_info(struct image_info *info)
+{
+ free(info->pixels);
+ delete info;
+}
+
+
--- /dev/null
+
+/*********************************************************************
+ *
+ * Copyright 2012 Intel Corporation
+ * 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.
+ *
+ *********************************************************************/
+
+/*
+ * Auxiliary functions to compute the size of array/blob arguments.
+ */
+#ifndef _EGLSIZE_HPP_
+#define _EGLSIZE_HPP_
+
+
+#include "glimports.hpp"
+
+
+struct image_info
+{
+ GLint internalformat;
+ GLsizei width;
+ GLsizei height;
+ GLenum format;
+ GLenum type;
+ GLsizei size;
+ GLvoid * pixels;
+};
+
+struct image_info *
+_EGLImageKHR_get_image_info(GLenum target, EGLImageKHR image);
+
+void
+_EGLImageKHR_free_image_info(struct image_info *info);
+
+
+#endif
#include <string.h>
+#include <algorithm>
+
#include "os.hpp"
#include "glimports.hpp"
return 0;
}
+ if (size == GL_BGRA) {
+ size = 4;
+ }
+
+ if (size > 4) {
+ os::log("apitrace: warning: %s: unexpected size 0x%04X\n", __FUNCTION__, size);
+ }
+
size_t elementSize = size*_gl_type_size(type);
if (!stride) {
stride = (GLsizei)elementSize;
#define _glDrawArraysEXT_count _glDrawArrays_count
+/* Forward declaration for definition in gltrace.py */
+void
+_shadow_glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
+ GLvoid *data);
+
static inline GLuint
_glDrawElementsBaseVertex_count(GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex)
{
return 0;
}
memset(temp, 0, size);
- _glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, temp);
+ _shadow_glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, offset, size, temp);
indices = temp;
} else {
if (!indices) {
}
static inline GLuint
-_glMultiDrawArrays_count(const GLint *first, const GLsizei *count, GLsizei primcount) {
+_glMultiDrawArrays_count(const GLint *first, const GLsizei *count, GLsizei drawcount) {
GLuint _count = 0;
- for (GLsizei prim = 0; prim < primcount; ++prim) {
- GLuint _count_prim = _glDrawArrays_count(first[prim], count[prim]);
- _count = std::max(_count, _count_prim);
+ for (GLsizei draw = 0; draw < drawcount; ++draw) {
+ GLuint _count_draw = _glDrawArrays_count(first[draw], count[draw]);
+ _count = std::max(_count, _count_draw);
}
return _count;
}
static inline GLuint
-_glMultiDrawElements_count(const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) {
+_glMultiDrawElements_count(const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount) {
GLuint _count = 0;
- for (GLsizei prim = 0; prim < primcount; ++prim) {
- GLuint _count_prim = _glDrawElements_count(count[prim], type, indices[prim]);
- _count = std::max(_count, _count_prim);
+ for (GLsizei draw = 0; draw < drawcount; ++draw) {
+ GLuint _count_draw = _glDrawElements_count(count[draw], type, indices[draw]);
+ _count = std::max(_count, _count_draw);
}
return _count;
}
static inline GLuint
-_glMultiDrawElementsBaseVertex_count(const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint * basevertex) {
+_glMultiDrawElementsBaseVertex_count(const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount, const GLint * basevertex) {
GLuint _count = 0;
- for (GLsizei prim = 0; prim < primcount; ++prim) {
- GLuint _count_prim = _glDrawElementsBaseVertex_count(count[prim], type, indices[prim], basevertex[prim]);
- _count = std::max(_count, _count_prim);
+ for (GLsizei draw = 0; draw < drawcount; ++draw) {
+ GLuint _count_draw = _glDrawElementsBaseVertex_count(count[draw], type, indices[draw], basevertex[draw]);
+ _count = std::max(_count, _count_draw);
}
return _count;
}
#define _glMultiDrawArraysEXT_count _glMultiDrawArrays_count
#define _glMultiDrawElementsEXT_count _glMultiDrawElements_count
-#define _glMultiModeDrawArraysIBM_count(first, count, primcount, modestride) _glMultiDrawArrays_count(first, count, primcount)
-#define _glMultiModeDrawElementsIBM_count(count, type, indices, primcount, modestride) _glMultiDrawElements_count(count, type, (const GLvoid **)indices, primcount)
+#define _glMultiModeDrawArraysIBM_count(first, count, drawcount, modestride) _glMultiDrawArrays_count(first, count, drawcount)
+#define _glMultiModeDrawElementsIBM_count(count, type, indices, drawcount, modestride) _glMultiDrawElements_count(count, type, (const GLvoid **)indices, drawcount)
static inline size_t
_gl_image_size(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, GLboolean has_unpack_subimage) {
unsigned num_channels = _gl_format_channels(format);
+ unsigned bits_per_element;
unsigned bits_per_pixel;
switch (type) {
case GL_BITMAP:
- bits_per_pixel = 1;
+ bits_per_pixel = bits_per_element = 1;
break;
case GL_BYTE:
case GL_UNSIGNED_BYTE:
- bits_per_pixel = 8 * num_channels;
+ bits_per_element = 8;
+ bits_per_pixel = bits_per_element * num_channels;
break;
case GL_SHORT:
case GL_UNSIGNED_SHORT:
case GL_HALF_FLOAT:
- bits_per_pixel = 16 * num_channels;
+ bits_per_element = 16;
+ bits_per_pixel = bits_per_element * num_channels;
break;
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
- bits_per_pixel = 32 * num_channels;
+ bits_per_element = 32;
+ bits_per_pixel = bits_per_element * num_channels;
break;
case GL_UNSIGNED_BYTE_3_3_2:
case GL_UNSIGNED_BYTE_2_3_3_REV:
- bits_per_pixel = 8;
+ bits_per_pixel = bits_per_element = 8;
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL_UNSIGNED_SHORT_5_6_5_REV:
case GL_UNSIGNED_SHORT_8_8_MESA:
case GL_UNSIGNED_SHORT_8_8_REV_MESA:
- bits_per_pixel = 16;
+ bits_per_pixel = bits_per_element = 16;
break;
case GL_UNSIGNED_INT_8_8_8_8:
case GL_UNSIGNED_INT_8_8_8_8_REV:
case GL_UNSIGNED_INT_5_9_9_9_REV:
case GL_UNSIGNED_INT_S8_S8_8_8_NV:
case GL_UNSIGNED_INT_8_8_S8_S8_REV_NV:
- bits_per_pixel = 32;
+ bits_per_pixel = bits_per_element = 32;
break;
case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
- bits_per_pixel = 64;
+ bits_per_pixel = bits_per_element = 64;
break;
default:
os::log("apitrace: warning: %s: unexpected type GLenum 0x%04X\n", __FUNCTION__, type);
- bits_per_pixel = 0;
+ bits_per_pixel = bits_per_element = 0;
break;
}
size_t row_stride = (row_length*bits_per_pixel + 7)/8;
- if ((GLint)bits_per_pixel < alignment*8 &&
- (bits_per_pixel & 7) == 0 &&
- _is_pot(bits_per_pixel)) {
+ if ((bits_per_element == 1*8 ||
+ bits_per_element == 2*8 ||
+ bits_per_element == 4*8 ||
+ bits_per_element == 8*8) &&
+ (GLint)bits_per_element < alignment*8) {
row_stride = _align(row_stride, alignment);
}
HWND
createWindow(int width, int height);
+void
+resizeWindow(HWND hWnd, int width, int height);
+
+bool
+processEvents(void);
+
} /* namespace d3dretrace */
class D3DRetracer(Retracer):
def retraceApi(self, api):
- print 'static const GUID GUID_D3DRETRACE = {0x7D71CAC9,0x7F58,0x432C,{0xA9,0x75,0xA1,0x9F,0xCF,0xCE,0xFD,0x14}};'
+ print '// Swizzling mapping for lock addresses'
+ print 'static std::map<void *, void *> _locks;'
print
self.table_name = 'd3dretrace::%s_callbacks' % api.name.lower()
if 'hFocusWindow' in method.argNames():
print r' hFocusWindow = hWnd;'
+ if method.name in ('Reset', 'ResetEx'):
+ print r' if (pPresentationParameters->Windowed) {'
+ print r' d3dretrace::resizeWindow(pPresentationParameters->hDeviceWindow, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
+ print r' }'
+
# notify frame has been completed
if method.name == 'Present':
print r' retrace::frameComplete(call);'
Retracer.invokeInterfaceMethod(self, interface, method)
+ # process events after presents
+ if method.name == 'Present':
+ print r' d3dretrace::processEvents();'
+
# check errors
if str(method.type) == 'HRESULT':
print r' if (FAILED(_result)) {'
print ' VOID *_pbData = NULL;'
print ' size_t _LockedSize = 0;'
print ' _getLockInfo(_this, %s, _pbData, _LockedSize);' % ', '.join(method.argNames()[:-1])
- print ' _this->SetPrivateData(GUID_D3DRETRACE, &_pbData, sizeof _pbData, 0);'
+ print ' _locks[_this] = _pbData;'
if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
print ' VOID *_pbData = 0;'
- print ' DWORD dwSizeOfData = sizeof _pbData;'
- print ' _this->GetPrivateData(GUID_D3DRETRACE, &_pbData, &dwSizeOfData);'
+ print ' _pbData = _locks[_this];'
print ' if (_pbData) {'
print ' retrace::delRegionByPointer(_pbData);'
print ' }'
#include <iostream>
#include "d3d9imports.hpp"
-#include "d3dsize.hpp"
+#include "d3d9size.hpp"
#include "d3dretrace.hpp"
'''
void
retrace::waitForInput(void) {
+ /* TODO */
}
void
{
MINMAXINFO *pMMI;
switch (uMsg) {
+ case WM_KEYDOWN:
+ switch (wParam) {
+ case VK_ESCAPE:
+ PostMessage(hWnd, WM_CLOSE, 0, 0);
+ break;
+ }
+ break;
case WM_GETMINMAXINFO:
// Allow to create a window bigger than the desktop
pMMI = (MINMAXINFO *)lParam;
pMMI->ptMaxTrackSize.x = 60000;
pMMI->ptMaxTrackSize.y = 60000;
break;
+ case WM_CLOSE:
+ exit(0);
+ break;
default:
break;
}
}
+void
+resizeWindow(HWND hWnd, int width, int height) {
+ RECT rClient;
+ GetClientRect(hWnd, &rClient);
+ if (width == rClient.right - rClient.left &&
+ height == rClient.bottom - rClient.top) {
+ return;
+ }
+
+ RECT rWindow;
+ GetWindowRect(hWnd, &rWindow);
+ width += (rWindow.right - rWindow.left) - rClient.right;
+ height += (rWindow.bottom - rWindow.top) - rClient.bottom;
+ SetWindowPos(hWnd, NULL, rWindow.left, rWindow.top, width, height, SWP_NOMOVE);
+}
+bool
+processEvents(void) {
+ MSG uMsg;
+ while (PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE)) {
+ if (uMsg.message == WM_QUIT) {
+ return false;
+ }
+
+ if (!TranslateAccelerator(uMsg.hwnd, NULL, &uMsg)) {
+ TranslateMessage(&uMsg);
+ DispatchMessage(&uMsg);
+ }
+ }
+ return true;
+}
+
} /* namespace d3dretrace */
**************************************************************************/
+#include <stdio.h>
+
#include <iostream>
#include "d3d9imports.hpp"
namespace d3dstate {
+typedef HRESULT
+(WINAPI *PD3DXDISASSEMBLESHADER)(
+ CONST DWORD *pShader,
+ BOOL EnableColorCode,
+ LPCSTR pComments,
+ LPD3DXBUFFER *ppDisassembly
+);
+
+
+HRESULT
+disassembleShader(const DWORD *tokens, LPD3DXBUFFER *ppDisassembly)
+{
+ static BOOL firsttime = TRUE;
+
+ /*
+ * TODO: Consider using d3dcompile_xx.dll per
+ * http://msdn.microsoft.com/en-us/library/windows/desktop/ee663275.aspx
+ */
+
+ 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) {
+ return E_FAIL;
+ }
+
+ return pfnD3DXDisassembleShader(tokens, FALSE, NULL, ppDisassembly);
+}
+
+
+template< class T >
+inline void
+dumpShader(JSONWriter &json, const char *name, T *pShader) {
+ if (!pShader) {
+ return;
+ }
+
+ HRESULT hr;
+
+ UINT SizeOfData = 0;
+
+ hr = pShader->GetFunction(NULL, &SizeOfData);
+ if (SUCCEEDED(hr)) {
+ void *pData;
+ pData = malloc(SizeOfData);
+ if (pData) {
+ hr = pShader->GetFunction(pData, &SizeOfData);
+ if (SUCCEEDED(hr)) {
+ LPD3DXBUFFER pDisassembly;
+
+ hr = disassembleShader((const DWORD *)pData, &pDisassembly);
+ if (SUCCEEDED(hr)) {
+ json.beginMember(name);
+ json.writeString((const char *)pDisassembly->GetBufferPointer() /*, pDisassembly->GetBufferSize() */);
+ json.endMember();
+ pDisassembly->Release();
+ }
+
+ }
+ free(pData);
+ }
+ }
+}
+
+static void
+dumpShaders(JSONWriter &json, IDirect3DDevice9 *pDevice)
+{
+ json.beginMember("shaders");
+
+ HRESULT hr;
+ json.beginObject();
+
+ IDirect3DVertexShader9 *pVertexShader = NULL;
+ hr = pDevice->GetVertexShader(&pVertexShader);
+ if (SUCCEEDED(hr)) {
+ dumpShader(json, "vertex", pVertexShader);
+ }
+
+ IDirect3DPixelShader9 *pPixelShader = NULL;
+ hr = pDevice->GetPixelShader(&pPixelShader);
+ if (SUCCEEDED(hr)) {
+ dumpShader(json, "pixel", pPixelShader);
+ }
+
+ json.endObject();
+ json.endMember(); // shaders
+}
+
void
dumpDevice(std::ostream &os, IDirect3DDevice9 *pDevice)
{
JSONWriter json(os);
+ dumpShaders(json, pDevice);
+
/* TODO */
}
namespace glretrace {
-
+struct Context {
+ Context(glws::Context* context)
+ : wsContext(context),
+ drawable(0),
+ activeProgram(0),
+ used(false)
+ {
+ }
+
+ ~Context();
+
+ glws::Context* wsContext;
+
+ // Bound drawable
+ glws::Drawable *drawable;
+
+ GLuint activeProgram;
+ bool used;
+
+ // Context must be current
+ inline bool
+ hasExtension(const char *extension) const {
+ return wsContext->hasExtension(extension);
+ }
+};
+
+extern bool insideList;
extern bool insideGlBeginEnd;
-extern glws::Drawable *currentDrawable;
-extern glws::Context *currentContext;
+Context *
+getCurrentContext(void);
+
+
+int
+parseAttrib(const trace::Value *attribs, int param, int default_);
+
glws::Drawable *
createDrawable(glws::Profile profile);
glws::Drawable *
createDrawable(void);
-glws::Context *
-createContext(glws::Context *shareContext, glws::Profile profile);
+glws::Drawable *
+createPbuffer(int width, int height);
+
+Context *
+createContext(Context *shareContext, glws::Profile profile);
-glws::Context *
-createContext(glws::Context *shareContext = 0);
+Context *
+createContext(Context *shareContext = 0);
bool
-makeCurrent(trace::Call &call, glws::Drawable *drawable, glws::Context *context);
+makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context);
void
extern const retrace::Entry egl_callbacks[];
void frame_complete(trace::Call &call);
+void initContext();
+
void updateDrawable(int width, int height);
+void flushQueries();
+void beginProfile(trace::Call &call, bool isDraw);
+void endProfile(trace::Call &call, bool isDraw);
+
} /* namespace glretrace */
print ' glretrace::insideGlBeginEnd = false;'
if function.name.startswith('gl') and not function.name.startswith('glX'):
- print r' if (retrace::debug && !glretrace::currentContext) {'
+ print r' if (retrace::debug && !glretrace::getCurrentContext()) {'
print r' retrace::warning(call) << "no current context\n";'
print r' }'
print r' if (pipeline) {'
print r' _pipelineHasBeenBound = true;'
print r' }'
-
+
+ profileDraw = (
+ function.name in self.draw_array_function_names or
+ function.name in self.draw_elements_function_names or
+ function.name in self.draw_indirect_function_names or
+ function.name in self.misc_draw_function_names or
+ function.name == 'glBegin'
+ )
+
+ if function.name in ('glUseProgram', 'glUseProgramObjectARB'):
+ print r' glretrace::Context *currentContext = glretrace::getCurrentContext();'
+ print r' if (currentContext) {'
+ print r' currentContext->activeProgram = call.arg(0).toUInt();'
+ print r' }'
+
+ # Only profile if not inside a list as the queries get inserted into list
+ if function.name == 'glNewList':
+ print r' glretrace::insideList = true;'
+
+ if function.name == 'glEndList':
+ print r' glretrace::insideList = false;'
+
+ if function.name != 'glEnd':
+ print r' if (!glretrace::insideList && !glretrace::insideGlBeginEnd && retrace::profiling) {'
+ if profileDraw:
+ print r' glretrace::beginProfile(call, true);'
+ else:
+ print r' glretrace::beginProfile(call, false);'
+ print r' }'
+
if function.name == 'glCreateShaderProgramv':
# When dumping state, break down glCreateShaderProgramv so that the
# shader source can be recovered.
else:
Retracer.invokeFunction(self, function)
- # Error checking
if function.name == "glBegin":
print ' glretrace::insideGlBeginEnd = true;'
- elif function.name.startswith('gl'):
+
+ print r' if (!glretrace::insideList && !glretrace::insideGlBeginEnd && retrace::profiling) {'
+ if profileDraw:
+ print r' glretrace::endProfile(call, true);'
+ else:
+ print r' glretrace::endProfile(call, false);'
+ print r' }'
+
+ # Error checking
+ if function.name.startswith('gl'):
# glGetError is not allowed inside glBegin/glEnd
- print ' if (retrace::debug && !glretrace::insideGlBeginEnd) {'
+ print ' if (retrace::debug && !glretrace::insideGlBeginEnd && glretrace::getCurrentContext()) {'
print ' glretrace::checkGlError(call);'
if function.name in ('glProgramStringARB', 'glProgramStringNV'):
print r' GLint error_position = -1;'
and 'program' not in function.argNames():
# Determine the active program for uniforms swizzling
print ' GLint program = -1;'
- print ' GLint pipeline = 0;'
- print ' if (_pipelineHasBeenBound) {'
- print ' glGetIntegerv(GL_PROGRAM_PIPELINE_BINDING, &pipeline);'
- print ' }'
- print ' if (pipeline) {'
- print ' glGetProgramPipelineiv(pipeline, GL_ACTIVE_PROGRAM, &program);'
+ print ' if (glretrace::insideList) {'
+ print ' // glUseProgram & glUseProgramObjectARB are display-list-able'
+ print r' glretrace::Context *currentContext = glretrace::getCurrentContext();'
+ print ' program = _program_map[currentContext->activeProgram];'
print ' } else {'
- print ' glGetIntegerv(GL_CURRENT_PROGRAM, &program);'
+ print ' GLint pipeline = 0;'
+ print ' if (_pipelineHasBeenBound) {'
+ print ' glGetIntegerv(GL_PROGRAM_PIPELINE_BINDING, &pipeline);'
+ print ' }'
+ print ' if (pipeline) {'
+ print ' glGetProgramPipelineiv(pipeline, GL_ACTIVE_PROGRAM, &program);'
+ print ' } else {'
+ print ' glGetIntegerv(GL_CURRENT_PROGRAM, &program);'
+ print ' }'
print ' }'
print
#include "glretrace.hpp"
+#define kCGLPFAAllRenderers 1
+#define kCGLPFADoubleBuffer 5
+#define kCGLPFAStereo 6
+#define kCGLPFAAuxBuffers 7
+#define kCGLPFAColorSize 8
+#define kCGLPFAAlphaSize 11
+#define kCGLPFADepthSize 12
+#define kCGLPFAStencilSize 13
+#define kCGLPFAAccumSize 14
+#define kCGLPFAMinimumPolicy 51
+#define kCGLPFAMaximumPolicy 52
+#define kCGLPFAOffScreen 53
+#define kCGLPFAFullScreen 54
+#define kCGLPFASampleBuffers 55
+#define kCGLPFASamples 56
+#define kCGLPFAAuxDepthStencil 57
+#define kCGLPFAColorFloat 58
+#define kCGLPFAMultisample 59
+#define kCGLPFASupersample 60
+#define kCGLPFASampleAlpha 61
+#define kCGLPFARendererID 70
+#define kCGLPFASingleRenderer 71
+#define kCGLPFANoRecovery 72
+#define kCGLPFAAccelerated 73
+#define kCGLPFAClosestPolicy 74
+#define kCGLPFARobust 75
+#define kCGLPFABackingStore 76
+#define kCGLPFAMPSafe 78
+#define kCGLPFAWindow 80
+#define kCGLPFAMultiScreen 81
+#define kCGLPFACompliant 83
+#define kCGLPFADisplayMask 84
+#define kCGLPFAPBuffer 90
+#define kCGLPFARemotePBuffer 91
+#define kCGLPFAAllowOfflineRenderers 96
+#define kCGLPFAAcceleratedCompute 97
+#define kCGLPFAOpenGLProfile 99
+#define kCGLPFAVirtualScreenCount 128
+
+#define kCGLOGLPVersion_Legacy 0x1000
+#define kCGLOGLPVersion_3_2_Core 0x3200
+
+
using namespace glretrace;
typedef std::map<unsigned long long, glws::Drawable *> DrawableMap;
-typedef std::map<unsigned long long, glws::Context *> ContextMap;
+typedef std::map<unsigned long long, Context *> ContextMap;
static DrawableMap drawable_map;
static ContextMap context_map;
-static glws::Context *sharedContext = NULL;
+static Context *sharedContext = NULL;
static glws::Drawable *
}
-static glws::Context *
+static Context *
getContext(unsigned long long ctx) {
if (ctx == 0) {
return NULL;
ContextMap::const_iterator it;
it = context_map.find(ctx);
if (it == context_map.end()) {
- glws::Context *context;
+ Context *context;
context_map[ctx] = context = glretrace::createContext(sharedContext);
if (!sharedContext) {
sharedContext = context;
}
+static void retrace_CGLChoosePixelFormat(trace::Call &call) {
+ int profile = kCGLOGLPVersion_Legacy;
+
+ const trace::Array * attribs = dynamic_cast<const trace::Array *>(&call.arg(0));
+ if (attribs) {
+ size_t i = 0;
+ while (i < attribs->values.size()) {
+ int param = attribs->values[i++]->toSInt();
+ if (param == 0) {
+ break;
+ }
+
+ switch (param) {
+ case kCGLPFAAllRenderers:
+ case kCGLPFADoubleBuffer:
+ case kCGLPFAStereo:
+ case kCGLPFAAuxBuffers:
+ case kCGLPFAMinimumPolicy:
+ case kCGLPFAMaximumPolicy:
+ case kCGLPFAOffScreen:
+ case kCGLPFAFullScreen:
+ case kCGLPFAAuxDepthStencil:
+ case kCGLPFAColorFloat:
+ case kCGLPFAMultisample:
+ case kCGLPFASupersample:
+ case kCGLPFASampleAlpha:
+ case kCGLPFASingleRenderer:
+ case kCGLPFANoRecovery:
+ case kCGLPFAAccelerated:
+ case kCGLPFAClosestPolicy:
+ case kCGLPFARobust:
+ case kCGLPFABackingStore:
+ case kCGLPFAMPSafe:
+ case kCGLPFAWindow:
+ case kCGLPFAMultiScreen:
+ case kCGLPFACompliant:
+ case kCGLPFAPBuffer:
+ case kCGLPFARemotePBuffer:
+ case kCGLPFAAllowOfflineRenderers:
+ case kCGLPFAAcceleratedCompute:
+ break;
+
+ case kCGLPFAColorSize:
+ case kCGLPFAAlphaSize:
+ case kCGLPFADepthSize:
+ case kCGLPFAStencilSize:
+ case kCGLPFAAccumSize:
+ case kCGLPFASampleBuffers:
+ case kCGLPFASamples:
+ case kCGLPFARendererID:
+ case kCGLPFADisplayMask:
+ case kCGLPFAVirtualScreenCount:
+ ++i;
+ break;
+
+ case kCGLPFAOpenGLProfile:
+ profile = attribs->values[i++]->toSInt();
+ break;
+
+ default:
+ retrace::warning(call) << "unexpected attribute " << param << "\n";
+ break;
+ }
+ }
+ }
+
+ if (profile == kCGLOGLPVersion_3_2_Core) {
+ // TODO: Do this on a per visual basis
+ retrace::coreProfile = true;
+ }
+}
+
+
+static void retrace_CGLCreateContext(trace::Call &call) {
+ unsigned long long share = call.arg(1).toUIntPtr();
+ Context *sharedContext = getContext(share);
+
+ const trace::Array *ctx_ptr = dynamic_cast<const trace::Array *>(&call.arg(2));
+ unsigned long long ctx = ctx_ptr->values[0]->toUIntPtr();
+
+ Context *context = glretrace::createContext(sharedContext);
+ context_map[ctx] = context;
+}
+
+
+static void retrace_CGLDestroyContext(trace::Call &call) {
+ unsigned long long ctx = call.arg(0).toUIntPtr();
+
+ ContextMap::iterator it;
+ it = context_map.find(ctx);
+ if (it == context_map.end()) {
+ return;
+ }
+
+ delete it->second;
+
+ context_map.erase(it);
+}
+
+
static void retrace_CGLSetCurrentContext(trace::Call &call) {
unsigned long long ctx = call.arg(0).toUIntPtr();
glws::Drawable *new_drawable = getDrawable(ctx);
- glws::Context *new_context = getContext(ctx);
+ Context *new_context = getContext(ctx);
glretrace::makeCurrent(call, new_drawable, new_context);
}
static void retrace_CGLFlushDrawable(trace::Call &call) {
- if (currentDrawable && currentContext) {
- if (retrace::doubleBuffer) {
- currentDrawable->swapBuffers();
+ unsigned long long ctx = call.arg(0).toUIntPtr();
+ Context *context = getContext(ctx);
+
+ if (context) {
+ if (context->drawable) {
+ if (retrace::doubleBuffer) {
+ context->drawable->swapBuffers();
+ } else {
+ glFlush();
+ }
+ frame_complete(call);
} else {
- glFlush();
+ if (retrace::debug) {
+ retrace::warning(call) << "context has no drawable\n";
+ }
+ }
+ }
+}
+
+
+/**
+ * We can't fully reimplement CGLTexImageIOSurface2D, as external IOSurface are
+ * no longer present. Simply emit a glTexImage2D to ensure the texture storage
+ * is present.
+ *
+ * See also:
+ * - /System/Library/Frameworks/OpenGL.framework/Headers/CGLIOSurface.h
+ */
+static void retrace_CGLTexImageIOSurface2D(trace::Call &call) {
+ if (retrace::debug) {
+ retrace::warning(call) << "external IOSurface not supported\n";
+ }
+
+ unsigned long long ctx = call.arg(0).toUIntPtr();
+ Context *context = getContext(ctx);
+
+ GLenum target;
+ target = static_cast<GLenum>((call.arg(1)).toSInt());
+
+ GLint level = 0;
+
+ GLint internalformat;
+ internalformat = static_cast<GLenum>((call.arg(2)).toSInt());
+
+ GLsizei width;
+ width = (call.arg(3)).toSInt();
+
+ GLsizei height;
+ height = (call.arg(4)).toSInt();
+
+ GLint border = 0;
+
+ GLenum format;
+ format = static_cast<GLenum>((call.arg(5)).toSInt());
+
+ GLenum type;
+ type = static_cast<GLenum>((call.arg(6)).toSInt());
+
+ GLvoid * pixels = NULL;
+
+ if (glretrace::getCurrentContext() != context) {
+ if (retrace::debug) {
+ retrace::warning(call) << "current context mismatch\n";
}
+ }
+
+ glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
- frame_complete(call);
+ if (retrace::debug && !glretrace::insideGlBeginEnd) {
+ glretrace::checkGlError(call);
}
}
const retrace::Entry glretrace::cgl_callbacks[] = {
+ {"CGLChoosePixelFormat", &retrace_CGLChoosePixelFormat},
+ {"CGLDestroyPixelFormat", &retrace::ignore},
+ {"CGLCreateContext", &retrace_CGLCreateContext},
+ {"CGLDestroyContext", &retrace_CGLDestroyContext},
{"CGLSetCurrentContext", &retrace_CGLSetCurrentContext},
{"CGLGetCurrentContext", &retrace::ignore},
{"CGLEnable", &retrace::ignore},
{"CGLSetParameter", &retrace::ignore},
{"CGLGetParameter", &retrace::ignore},
{"CGLFlushDrawable", &retrace_CGLFlushDrawable},
+ {"CGLUpdateContext", &retrace::ignore},
+ {"CGLTexImageIOSurface2D", &retrace_CGLTexImageIOSurface2D},
{NULL, NULL},
};
#include "retrace.hpp"
#include "glretrace.hpp"
#include "os.hpp"
+#include "eglsize.hpp"
#ifndef EGL_OPENGL_ES_API
#define EGL_OPENGL_ES_API 0x30A0
typedef std::map<unsigned long long, glws::Drawable *> DrawableMap;
-typedef std::map<unsigned long long, glws::Context *> ContextMap;
+typedef std::map<unsigned long long, Context *> ContextMap;
typedef std::map<unsigned long long, glws::Profile> ProfileMap;
static DrawableMap drawable_map;
static ContextMap context_map;
return (it != drawable_map.end()) ? it->second : NULL;
}
-static glws::Context *
+static Context *
getContext(unsigned long long context_ptr) {
if (context_ptr == 0) {
return NULL;
it = drawable_map.find(orig_surface);
if (it != drawable_map.end()) {
- if (it->second != currentDrawable) {
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
+ if (!currentContext || it->second != currentContext->drawable) {
// TODO: reference count
delete it->second;
}
static void retrace_eglCreateContext(trace::Call &call) {
unsigned long long orig_context = call.ret->toUIntPtr();
unsigned long long orig_config = call.arg(1).toUIntPtr();
- glws::Context *share_context = getContext(call.arg(2).toUIntPtr());
+ Context *share_context = getContext(call.arg(2).toUIntPtr());
trace::Array *attrib_array = dynamic_cast<trace::Array *>(&call.arg(3));
glws::Profile profile;
}
- glws::Context *context = glretrace::createContext(share_context, profile);
+ Context *context = glretrace::createContext(share_context, profile);
if (!context) {
const char *name;
switch (profile) {
it = context_map.find(orig_context);
if (it != context_map.end()) {
- delete it->second;
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
+ if (it->second != currentContext) {
+ // TODO: reference count
+ delete it->second;
+ }
context_map.erase(it);
}
}
static void retrace_eglMakeCurrent(trace::Call &call) {
glws::Drawable *new_drawable = getDrawable(call.arg(1).toUIntPtr());
- glws::Context *new_context = getContext(call.arg(3).toUIntPtr());
+ Context *new_context = getContext(call.arg(3).toUIntPtr());
glretrace::makeCurrent(call, new_drawable, new_context);
}
static void retrace_eglSwapBuffers(trace::Call &call) {
+ glws::Drawable *drawable = getDrawable(call.arg(1).toUIntPtr());
+
frame_complete(call);
- if (retrace::doubleBuffer && currentDrawable) {
- currentDrawable->swapBuffers();
+ if (retrace::doubleBuffer) {
+ if (drawable) {
+ drawable->swapBuffers();
+ }
} else {
glFlush();
}
{"eglSwapBuffers", &retrace_eglSwapBuffers},
//{"eglCopyBuffers", &retrace::ignore},
{"eglGetProcAddress", &retrace::ignore},
+ {"eglCreateImageKHR", &retrace::ignore},
+ {"eglDestroyImageKHR", &retrace::ignore},
+ {"glEGLImageTargetTexture2DOES", &retrace::ignore},
{NULL, NULL},
};
#include "glretrace.hpp"
+#ifndef GLX_PBUFFER_HEIGHT
+#define GLX_PBUFFER_HEIGHT 0x8040
+#endif
+
+#ifndef GLX_PBUFFER_WIDTH
+#define GLX_PBUFFER_WIDTH 0x8041
+#endif
+
+
using namespace glretrace;
typedef std::map<unsigned long, glws::Drawable *> DrawableMap;
-typedef std::map<unsigned long long, glws::Context *> ContextMap;
+typedef std::map<unsigned long long, Context *> ContextMap;
static DrawableMap drawable_map;
static ContextMap context_map;
return it->second;
}
-static glws::Context *
+static Context *
getContext(unsigned long long context_ptr) {
if (context_ptr == 0) {
return NULL;
static void retrace_glXCreateContext(trace::Call &call) {
unsigned long long orig_context = call.ret->toUIntPtr();
- glws::Context *share_context = getContext(call.arg(2).toUIntPtr());
+ Context *share_context = getContext(call.arg(2).toUIntPtr());
- glws::Context *context = glretrace::createContext(share_context);
+ Context *context = glretrace::createContext(share_context);
context_map[orig_context] = context;
}
static void retrace_glXCreateContextAttribsARB(trace::Call &call) {
unsigned long long orig_context = call.ret->toUIntPtr();
- glws::Context *share_context = getContext(call.arg(2).toUIntPtr());
+ Context *share_context = getContext(call.arg(2).toUIntPtr());
- glws::Context *context = glretrace::createContext(share_context);
+ Context *context = glretrace::createContext(share_context);
context_map[orig_context] = context;
}
static void retrace_glXMakeCurrent(trace::Call &call) {
glws::Drawable *new_drawable = getDrawable(call.arg(1).toUInt());
- glws::Context *new_context = getContext(call.arg(2).toUIntPtr());
+ Context *new_context = getContext(call.arg(2).toUIntPtr());
glretrace::makeCurrent(call, new_drawable, new_context);
}
static void retrace_glXDestroyContext(trace::Call &call) {
- glws::Context *context = getContext(call.arg(1).toUIntPtr());
+ Context *context = getContext(call.arg(1).toUIntPtr());
if (!context) {
return;
}
static void retrace_glXSwapBuffers(trace::Call &call) {
+ glws::Drawable *drawable = getDrawable(call.arg(1).toUInt());
+
frame_complete(call);
if (retrace::doubleBuffer) {
- currentDrawable->swapBuffers();
+ if (drawable) {
+ drawable->swapBuffers();
+ }
} else {
glFlush();
}
static void retrace_glXCreateNewContext(trace::Call &call) {
unsigned long long orig_context = call.ret->toUIntPtr();
- glws::Context *share_context = getContext(call.arg(3).toUIntPtr());
+ Context *share_context = getContext(call.arg(3).toUIntPtr());
- glws::Context *context = glretrace::createContext(share_context);
+ Context *context = glretrace::createContext(share_context);
context_map[orig_context] = context;
}
+static void retrace_glXCreatePbuffer(trace::Call &call) {
+ const trace::Value *attrib_list = dynamic_cast<const trace::Array *>(&call.arg(2));
+ int width = glretrace::parseAttrib(attrib_list, GLX_PBUFFER_WIDTH, 0);
+ int height = glretrace::parseAttrib(attrib_list, GLX_PBUFFER_HEIGHT, 0);
+
+ unsigned long long orig_drawable = call.ret->toUInt();
+
+ glws::Drawable *drawable = glretrace::createPbuffer(width, height);
+
+ drawable_map[orig_drawable] = drawable;
+}
+
+static void retrace_glXDestroyPbuffer(trace::Call &call) {
+ glws::Drawable *drawable = getDrawable(call.arg(1).toUInt());
+
+ if (!drawable) {
+ return;
+ }
+
+ delete drawable;
+}
+
static void retrace_glXMakeContextCurrent(trace::Call &call) {
glws::Drawable *new_drawable = getDrawable(call.arg(1).toUInt());
- glws::Context *new_context = getContext(call.arg(3).toUIntPtr());
+ Context *new_context = getContext(call.arg(3).toUIntPtr());
glretrace::makeCurrent(call, new_drawable, new_context);
}
//{"glXCreateGLXPixmap", &retrace_glXCreateGLXPixmap},
//{"glXCreateGLXPixmapWithConfigSGIX", &retrace_glXCreateGLXPixmapWithConfigSGIX},
{"glXCreateNewContext", &retrace_glXCreateNewContext},
- //{"glXCreatePbuffer", &retrace_glXCreatePbuffer},
+ {"glXCreatePbuffer", &retrace_glXCreatePbuffer},
//{"glXCreatePixmap", &retrace_glXCreatePixmap},
//{"glXCreateWindow", &retrace_glXCreateWindow},
//{"glXCushionSGI", &retrace_glXCushionSGI},
{"glXDestroyContext", &retrace_glXDestroyContext},
//{"glXDestroyGLXPbufferSGIX", &retrace_glXDestroyGLXPbufferSGIX},
//{"glXDestroyGLXPixmap", &retrace_glXDestroyGLXPixmap},
- //{"glXDestroyPbuffer", &retrace_glXDestroyPbuffer},
+ {"glXDestroyPbuffer", &retrace_glXDestroyPbuffer},
//{"glXDestroyPixmap", &retrace_glXDestroyPixmap},
//{"glXDestroyWindow", &retrace_glXDestroyWindow},
//{"glXFreeContextEXT", &retrace_glXFreeContextEXT},
{"glXGetProcAddress", &retrace::ignore},
{"glXGetSelectedEvent", &retrace::ignore},
{"glXGetSelectedEventSGIX", &retrace::ignore},
+ {"glXGetSwapIntervalMESA", &retrace::ignore},
{"glXGetSyncValuesOML", &retrace::ignore},
{"glXGetVideoSyncSGI", &retrace::ignore},
{"glXGetVisualFromFBConfig", &retrace::ignore},
#include "glproc.hpp"
#include "glstate.hpp"
#include "glretrace.hpp"
+#include "os_time.hpp"
+/* Synchronous debug output may reduce performance however,
+ * without it the callNo in the callback may be inaccurate
+ * as the callback may be called at any time.
+ */
+#define DEBUG_OUTPUT_SYNCHRONOUS 0
namespace glretrace {
+bool insideList = false;
bool insideGlBeginEnd = false;
+struct CallQuery
+{
+ GLuint ids[3];
+ unsigned call;
+ bool isDraw;
+ GLuint program;
+ const trace::FunctionSig *sig;
+ int64_t cpuStart;
+ int64_t cpuEnd;
+};
+
+static bool supportsElapsed = true;
+static bool supportsTimestamp = true;
+static bool supportsOcclusion = true;
+static bool supportsDebugOutput = true;
+
+static std::list<CallQuery> callQueries;
+
+static void APIENTRY
+debugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam);
void
checkGlError(trace::Call &call) {
GLenum error = glGetError();
- if (error == GL_NO_ERROR) {
- return;
+ while (error != GL_NO_ERROR) {
+ std::ostream & os = retrace::warning(call);
+
+ os << "glGetError(";
+ os << call.name();
+ os << ") = ";
+
+ switch (error) {
+ case GL_INVALID_ENUM:
+ os << "GL_INVALID_ENUM";
+ break;
+ case GL_INVALID_VALUE:
+ os << "GL_INVALID_VALUE";
+ break;
+ case GL_INVALID_OPERATION:
+ os << "GL_INVALID_OPERATION";
+ break;
+ case GL_STACK_OVERFLOW:
+ os << "GL_STACK_OVERFLOW";
+ break;
+ case GL_STACK_UNDERFLOW:
+ os << "GL_STACK_UNDERFLOW";
+ break;
+ case GL_OUT_OF_MEMORY:
+ os << "GL_OUT_OF_MEMORY";
+ break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ os << "GL_INVALID_FRAMEBUFFER_OPERATION";
+ break;
+ case GL_TABLE_TOO_LARGE:
+ os << "GL_TABLE_TOO_LARGE";
+ break;
+ default:
+ os << error;
+ break;
+ }
+ os << "\n";
+
+ error = glGetError();
}
+}
- std::ostream & os = retrace::warning(call);
-
- os << "glGetError(";
- os << call.name();
- os << ") = ";
-
- switch (error) {
- case GL_INVALID_ENUM:
- os << "GL_INVALID_ENUM";
- break;
- case GL_INVALID_VALUE:
- os << "GL_INVALID_VALUE";
- break;
- case GL_INVALID_OPERATION:
- os << "GL_INVALID_OPERATION";
- break;
- case GL_STACK_OVERFLOW:
- os << "GL_STACK_OVERFLOW";
- break;
- case GL_STACK_UNDERFLOW:
- os << "GL_STACK_UNDERFLOW";
- break;
- case GL_OUT_OF_MEMORY:
- os << "GL_OUT_OF_MEMORY";
- break;
- case GL_INVALID_FRAMEBUFFER_OPERATION:
- os << "GL_INVALID_FRAMEBUFFER_OPERATION";
- break;
- case GL_TABLE_TOO_LARGE:
- os << "GL_TABLE_TOO_LARGE";
- break;
- default:
- os << error;
- break;
+static void
+getCurrentTimes(int64_t& cpuTime, int64_t& gpuTime) {
+ GLuint query;
+
+ if (retrace::profilingGpuTimes && supportsTimestamp) {
+ glGenQueries(1, &query);
+ glQueryCounter(query, GL_TIMESTAMP);
+ glGetQueryObjecti64vEXT(query, GL_QUERY_RESULT, &gpuTime);
+ } else {
+ gpuTime = 0;
+ }
+
+ if (retrace::profilingCpuTimes) {
+ cpuTime = os::getTime();
+ } else {
+ cpuTime = 0;
+ }
+
+ if (retrace::profilingGpuTimes && supportsTimestamp) {
+ glDeleteQueries(1, &query);
+ }
+}
+
+static void
+completeCallQuery(CallQuery& query) {
+ /* Get call start and duration */
+ int64_t gpuStart = 0, gpuDuration = 0, cpuDuration = 0, pixels = 0;
+
+ if (query.isDraw) {
+ if (retrace::profilingGpuTimes) {
+ if (supportsTimestamp) {
+ glGetQueryObjecti64vEXT(query.ids[0], GL_QUERY_RESULT, &gpuStart);
+ }
+
+ glGetQueryObjecti64vEXT(query.ids[1], GL_QUERY_RESULT, &gpuDuration);
+ }
+
+ if (retrace::profilingPixelsDrawn) {
+ glGetQueryObjecti64vEXT(query.ids[2], GL_QUERY_RESULT, &pixels);
+ }
+
+ glDeleteQueries(3, query.ids);
+ } else {
+ pixels = -1;
+ }
+
+ if (retrace::profilingCpuTimes) {
+ cpuDuration = query.cpuEnd - query.cpuStart;
+ }
+
+ /* Add call to profile */
+ retrace::profiler.addCall(query.call, query.sig->name, query.program, pixels, gpuStart, gpuDuration, query.cpuStart, cpuDuration);
+}
+
+void
+flushQueries() {
+ for (std::list<CallQuery>::iterator itr = callQueries.begin(); itr != callQueries.end(); ++itr) {
+ completeCallQuery(*itr);
+ }
+
+ callQueries.clear();
+}
+
+void
+beginProfile(trace::Call &call, bool isDraw) {
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
+
+ /* Create call query */
+ CallQuery query;
+ query.isDraw = isDraw;
+ query.call = call.no;
+ query.sig = call.sig;
+ query.program = currentContext ? currentContext->activeProgram : 0;
+
+ /* GPU profiling only for draw calls */
+ if (isDraw) {
+ glGenQueries(3, query.ids);
+
+ if (retrace::profilingGpuTimes) {
+ if (supportsTimestamp) {
+ glQueryCounter(query.ids[0], GL_TIMESTAMP);
+ }
+
+ glBeginQuery(GL_TIME_ELAPSED, query.ids[1]);
+ }
+
+ if (retrace::profilingPixelsDrawn) {
+ glBeginQuery(GL_SAMPLES_PASSED, query.ids[2]);
+ }
+ }
+
+ callQueries.push_back(query);
+
+ /* CPU profiling for all calls */
+ if (retrace::profilingCpuTimes) {
+ callQueries.back().cpuStart = os::getTime();
+ }
+}
+
+void
+endProfile(trace::Call &call, bool isDraw) {
+ GLint64 time = os::getTime();
+
+ /* CPU profiling for all calls */
+ if (retrace::profilingCpuTimes) {
+ CallQuery& query = callQueries.back();
+ query.cpuEnd = time;
+ }
+
+ /* GPU profiling only for draw calls */
+ if (isDraw) {
+ if (retrace::profilingGpuTimes) {
+ glEndQuery(GL_TIME_ELAPSED);
+ }
+
+ if (retrace::profilingPixelsDrawn) {
+ glEndQuery(GL_SAMPLES_PASSED);
+ }
}
- os << "\n";
}
+void
+initContext() {
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
+
+ /* Ensure we have adequate extension support */
+ assert(currentContext);
+ supportsTimestamp = currentContext->hasExtension("GL_ARB_timer_query");
+ supportsElapsed = currentContext->hasExtension("GL_EXT_timer_query") || supportsTimestamp;
+ supportsOcclusion = currentContext->hasExtension("GL_ARB_occlusion_query");
+ supportsDebugOutput = currentContext->hasExtension("GL_ARB_debug_output");
+
+ /* Check for timer query support */
+ if (retrace::profilingGpuTimes) {
+ if (!supportsTimestamp && !supportsElapsed) {
+ std::cout << "Error: Cannot run profile, GL_EXT_timer_query extension is not supported." << std::endl;
+ exit(-1);
+ }
+
+ GLint bits = 0;
+ glGetQueryiv(GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS, &bits);
+
+ if (!bits) {
+ std::cout << "Error: Cannot run profile, GL_QUERY_COUNTER_BITS == 0." << std::endl;
+ exit(-1);
+ }
+ }
+
+ /* Check for occlusion query support */
+ if (retrace::profilingPixelsDrawn && !supportsOcclusion) {
+ std::cout << "Error: Cannot run profile, GL_ARB_occlusion_query extension is not supported." << std::endl;
+ exit(-1);
+ }
+
+ /* Setup debug message call back */
+ if (retrace::debug && supportsDebugOutput) {
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
+ glDebugMessageCallbackARB(&debugOutputCallback, currentContext);
+
+ if (DEBUG_OUTPUT_SYNCHRONOUS) {
+ glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+ }
+ }
+
+ /* Sync the gpu and cpu start times */
+ if (retrace::profilingCpuTimes || retrace::profilingGpuTimes) {
+ if (!retrace::profiler.hasBaseTimes()) {
+ GLint64 gpuTime, cpuTime;
+
+ getCurrentTimes(cpuTime, gpuTime);
+ retrace::profiler.setBaseCpuTime(cpuTime);
+ retrace::profiler.setBaseGpuTime(gpuTime);
+ }
+ }
+}
+
+void
+frame_complete(trace::Call &call) {
+ if (retrace::profiling) {
+ /* Complete any remaining queries */
+ flushQueries();
+
+ /* GPU time drifts due to being relative times, not absolute and can be
+ * affected by the gpu switch between processes.
+ *
+ * To attempt to compensate we resynchronise on frame end however there is
+ * still noticeable drift within a single frame which we do not account for.
+ */
+ if (retrace::profilingCpuTimes || retrace::profilingGpuTimes) {
+ int64_t cpuTime, gpuTime, error;
+
+ getCurrentTimes(cpuTime, gpuTime);
+ cpuTime = cpuTime - retrace::profiler.getBaseCpuTime();
+ gpuTime = gpuTime - retrace::profiler.getBaseGpuTime();
+ error = gpuTime - cpuTime * (1.0E9 / os::timeFrequency);
+
+ retrace::profiler.setBaseGpuTime(retrace::profiler.getBaseGpuTime() + error);
+ }
+
+ /* Indicate end of current frame */
+ retrace::profiler.addFrameEnd();
+ }
-void frame_complete(trace::Call &call) {
retrace::frameComplete(call);
- if (!currentDrawable) {
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
+ if (!currentContext) {
return;
}
- if (retrace::debug && !currentDrawable->visible) {
+ assert(currentContext->drawable);
+ if (retrace::debug && !currentContext->drawable->visible) {
retrace::warning(call) << "could not infer drawable size (glViewport never called)\n";
}
}
+static const char*
+getDebugOutputSource(GLenum source) {
+ switch(source) {
+ case GL_DEBUG_SOURCE_API_ARB:
+ return "API";
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
+ return "Window System";
+ case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
+ return "Shader Compiler";
+ case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
+ return "Third Party";
+ case GL_DEBUG_SOURCE_APPLICATION_ARB:
+ return "Application";
+ case GL_DEBUG_SOURCE_OTHER_ARB:
+ default:
+ return "";
+ }
+}
+
+static const char*
+getDebugOutputType(GLenum type) {
+ switch(type) {
+ case GL_DEBUG_TYPE_ERROR_ARB:
+ return "error";
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
+ return "deprecated behaviour";
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
+ return "undefined behaviour";
+ case GL_DEBUG_TYPE_PORTABILITY_ARB:
+ return "portability issue";
+ case GL_DEBUG_TYPE_PERFORMANCE_ARB:
+ return "performance issue";
+ case GL_DEBUG_TYPE_OTHER_ARB:
+ default:
+ return "unknown issue";
+ }
+}
+
+static const char*
+getDebugOutputSeverity(GLenum severity) {
+ switch(severity) {
+ case GL_DEBUG_SEVERITY_HIGH_ARB:
+ return "High";
+ case GL_DEBUG_SEVERITY_MEDIUM_ARB:
+ return "Medium";
+ case GL_DEBUG_SEVERITY_LOW_ARB:
+ return "Low";
+ default:
+ return "usnknown";
+ }
+}
+
+static void APIENTRY
+debugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam) {
+ std::cerr << retrace::callNo << ": ";
+ std::cerr << "glDebugOutputCallback: ";
+ std::cerr << getDebugOutputSeverity(severity) << " severity ";
+ std::cerr << getDebugOutputSource(source) << " " << getDebugOutputType(type);
+ std::cerr << " " << id;
+ std::cerr << ", " << message;
+ std::cerr << std::endl;
+}
} /* namespace glretrace */
image::Image *
retrace::getSnapshot(void) {
- if (!glretrace::currentDrawable) {
+ if (!glretrace::getCurrentContext()) {
return NULL;
}
bool
retrace::dumpState(std::ostream &os)
{
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
+
if (glretrace::insideGlBeginEnd ||
- !glretrace::currentDrawable ||
- !glretrace::currentContext) {
+ !currentContext) {
return false;
}
void
retrace::flushRendering(void) {
- glFlush();
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
+ if (currentContext) {
+ glretrace::flushQueries();
+ glFlush();
+ }
}
void
retrace::waitForInput(void) {
while (glws::processEvents()) {
+ os::sleep(100*1000);
}
}
typedef std::map<unsigned long long, glws::Drawable *> DrawableMap;
-typedef std::map<unsigned long long, glws::Context *> ContextMap;
+typedef std::map<unsigned long long, Context *> ContextMap;
static DrawableMap drawable_map;
static DrawableMap pbuffer_map;
static ContextMap context_map;
static void retrace_wglCreateContext(trace::Call &call) {
unsigned long long orig_context = call.ret->toUIntPtr();
- glws::Context *context = glretrace::createContext();
+ Context *context = glretrace::createContext();
context_map[orig_context] = context;
}
static void retrace_wglDeleteContext(trace::Call &call) {
+ unsigned long long hglrc = call.arg(0).toUIntPtr();
+
+ ContextMap::iterator it;
+ it = context_map.find(hglrc);
+ if (it == context_map.end()) {
+ return;
+ }
+
+ delete it->second;
+
+ context_map.erase(it);
}
static void retrace_wglMakeCurrent(trace::Call &call) {
glws::Drawable *new_drawable = getDrawable(call.arg(0).toUIntPtr());
- glws::Context *new_context = context_map[call.arg(1).toUIntPtr()];
+ Context *new_context = context_map[call.arg(1).toUIntPtr()];
glretrace::makeCurrent(call, new_drawable, new_context);
}
}
static void retrace_wglSwapBuffers(trace::Call &call) {
+ glws::Drawable *drawable = getDrawable(call.arg(0).toUIntPtr());
+
frame_complete(call);
if (retrace::doubleBuffer) {
- currentDrawable->swapBuffers();
+ if (drawable) {
+ drawable->swapBuffers();
+ } else {
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
+ if (currentContext) {
+ currentContext->drawable->swapBuffers();
+ }
+ }
} else {
glFlush();
}
unsigned long long hglrc1 = call.arg(0).toUIntPtr();
unsigned long long hglrc2 = call.arg(1).toUIntPtr();
- glws::Context *share_context = context_map[hglrc1];
- glws::Context *old_context = context_map[hglrc2];
+ Context *share_context = context_map[hglrc1];
+ Context *old_context = context_map[hglrc2];
- glws::Context *new_context = glretrace::createContext(share_context);
+ Context *new_context = glretrace::createContext(share_context);
if (new_context) {
+ glretrace::Context *currentContext = glretrace::getCurrentContext();
if (currentContext == old_context) {
- glretrace::makeCurrent(call, currentDrawable, new_context);
+ glretrace::makeCurrent(call, currentContext->drawable, new_context);
}
context_map[hglrc2] = new_context;
int iHeight = call.arg(3).toUInt();
unsigned long long orig_pbuffer = call.ret->toUIntPtr();
- glws::Drawable *drawable = glretrace::createDrawable();
-
- drawable->resize(iWidth, iHeight);
- drawable->show();
+ glws::Drawable *drawable = glretrace::createPbuffer(iWidth, iHeight);
pbuffer_map[orig_pbuffer] = drawable;
}
static void retrace_wglCreateContextAttribsARB(trace::Call &call) {
unsigned long long orig_context = call.ret->toUIntPtr();
- glws::Context *share_context = NULL;
+ Context *share_context = NULL;
if (call.arg(1).toPointer()) {
share_context = context_map[call.arg(1).toUIntPtr()];
}
- glws::Context *context = glretrace::createContext(share_context);
+ Context *context = glretrace::createContext(share_context);
context_map[orig_context] = context;
}
#include <string.h>
+#include "os_thread.hpp"
#include "retrace.hpp"
#include "glproc.hpp"
#include "glstate.hpp"
namespace glretrace {
-glws::Drawable *currentDrawable = NULL;
-glws::Context *currentContext = NULL;
-
-
static glws::Visual *
visuals[glws::PROFILE_MAX];
glws::Visual * & visual = visuals[profile];
if (!visual) {
visual = glws::createVisual(retrace::doubleBuffer, profile);
+ if (!visual) {
+ std::cerr << "error: failed to create OpenGL visual\n";
+ exit(1);
+ }
}
return visual;
}
}
-glws::Drawable *
-createDrawable(glws::Profile profile) {
- glws::Drawable *draw = glws::createDrawable(getVisual(profile));
+static glws::Drawable *
+createDrawableHelper(glws::Profile profile, int width = 32, int height = 32, bool pbuffer = false) {
+ glws::Visual *visual = getVisual(profile);
+ glws::Drawable *draw = glws::createDrawable(visual, width, height, pbuffer);
if (!draw) {
std::cerr << "error: failed to create OpenGL drawable\n";
exit(1);
- return NULL;
}
return draw;
}
+glws::Drawable *
+createDrawable(glws::Profile profile) {
+ return createDrawableHelper(profile);
+}
+
+
glws::Drawable *
createDrawable(void) {
- return glretrace::createDrawable(getDefaultProfile());
+ return createDrawable(getDefaultProfile());
+}
+
+
+glws::Drawable *
+createPbuffer(int width, int height) {
+ return createDrawableHelper(getDefaultProfile(), width, height, true);
}
-glws::Context *
-createContext(glws::Context *shareContext, glws::Profile profile) {
- glws::Context *ctx = glws::createContext(getVisual(profile), shareContext, profile, retrace::debug);
+Context *
+createContext(Context *shareContext, glws::Profile profile) {
+ glws::Visual *visual = getVisual(profile);
+ glws::Context *shareWsContext = shareContext ? shareContext->wsContext : NULL;
+ glws::Context *ctx = glws::createContext(visual, shareWsContext, profile, retrace::debug);
if (!ctx) {
std::cerr << "error: failed to create OpenGL context\n";
exit(1);
return NULL;
}
- return ctx;
+ return new Context(ctx);
}
-glws::Context *
-createContext(glws::Context *shareContext) {
+Context *
+createContext(Context *shareContext) {
return createContext(shareContext, getDefaultProfile());
}
+Context::~Context()
+{
+ //assert(this != getCurrentContext());
+ if (this != getCurrentContext()) {
+ delete wsContext;
+ }
+}
+
+
+static thread_specific Context *
+currentContextPtr;
+
+
bool
-makeCurrent(trace::Call &call, glws::Drawable *drawable, glws::Context *context)
+makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context)
{
+ Context *currentContext = currentContextPtr;
+ glws::Drawable *currentDrawable = currentContext ? currentContext->drawable : NULL;
+
if (drawable == currentDrawable && context == currentContext) {
return true;
}
- if (currentDrawable && currentContext) {
+ if (currentContext) {
glFlush();
if (!retrace::doubleBuffer) {
frame_complete(call);
}
}
- bool success = glws::makeCurrent(drawable, context);
+ flushQueries();
+
+ bool success = glws::makeCurrent(drawable, context ? context->wsContext : NULL);
if (!success) {
std::cerr << "error: failed to make current OpenGL context and drawable\n";
return false;
}
+ currentContextPtr = context;
+
if (drawable && context) {
- currentDrawable = drawable;
- currentContext = context;
- } else {
- currentDrawable = NULL;
- currentContext = NULL;
+ context->drawable = drawable;
+
+ if (!context->used) {
+ initContext();
+ context->used = true;
+ }
}
return true;
}
+Context *
+getCurrentContext(void) {
+ return currentContextPtr;
+}
/**
*/
void
updateDrawable(int width, int height) {
- if (!currentDrawable) {
+ Context *currentContext = getCurrentContext();
+ if (!currentContext) {
+ return;
+ }
+
+ glws::Drawable *currentDrawable = currentContext->drawable;
+ assert(currentDrawable);
+
+ if (currentDrawable->pbuffer) {
return;
}
}
+int
+parseAttrib(const trace::Value *attribs, int param, int default_ = 0) {
+ const trace::Array *attribs_ = dynamic_cast<const trace::Array *>(attribs);
+
+ if (attribs_) {
+ for (size_t i = 0; i + 1 < attribs_->values.size(); i += 2) {
+ int param_i = attribs_->values[i]->toSInt();
+ if (param_i == 0) {
+ break;
+ }
+
+ if (param_i == param) {
+ int value = attribs_->values[i + 1]->toSInt();
+ return value;
+ }
+ }
+ }
+
+ return default_;
+}
+
+
} /* namespace glretrace */
};
+/**
+ * Sames as enumToString, but with special provision to handle formatsLUMINANCE_ALPHA.
+ *
+ * OpenGL 2.1 specification states that "internalFormat may (for backwards
+ * compatibility with the 1.0 version of the GL) also take on the integer
+ * values 1, 2, 3, and 4, which are equivalent to symbolic constants LUMINANCE,
+ * LUMINANCE ALPHA, RGB, and RGBA respectively".
+ */
+const char *
+formatToString(GLenum internalFormat) {
+ switch (internalFormat) {
+ case 1:
+ return "GL_LUMINANCE";
+ case 2:
+ return "GL_LUMINANCE_ALPHA";
+ case 3:
+ return "GL_RGB";
+ case 4:
+ return "GL_RGBA";
+ default:
+ return enumToString(internalFormat);
+ }
+}
+
+
/**
* OpenGL ES does not support glGetTexLevelParameteriv, but it is possible to
* probe whether a texture has a given size by crafting a dummy glTexSubImage()
static inline bool
getActiveTextureLevelDesc(Context &context, GLenum target, GLint level, ImageDesc &desc)
{
+ assert(target != GL_TEXTURE_CUBE_MAP);
+
if (context.ES) {
return getActiveTextureLevelDescOES(context, target, level, desc);
}
json.writeNumberMember("__height__", desc.height);
json.writeNumberMember("__depth__", desc.depth);
- json.writeStringMember("__format__", enumToString(desc.internalFormat));
+ json.writeStringMember("__format__", formatToString(desc.internalFormat));
// Hardcoded for now, but we could chose types more adequate to the
// texture internal format
json.beginMember("__data__");
char *pngBuffer;
int pngBufferSize;
- image::writePixelsToBuffer(pixels, desc.width, desc.height, channels, true, &pngBuffer, &pngBufferSize);
+ image::writePixelsToBuffer(pixels, desc.width, desc.depth * desc.height, channels, true, &pngBuffer, &pngBufferSize);
json.writeBase64(pngBuffer, pngBufferSize);
free(pngBuffer);
json.endMember(); // __data__
GLint level = 0;
do {
ImageDesc desc;
- if (!getActiveTextureLevelDesc(context, target, level, desc)) {
- break;
- }
if (target == GL_TEXTURE_CUBE_MAP) {
for (int face = 0; face < 6; ++face) {
+ if (!getActiveTextureLevelDesc(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, desc)) {
+ return;
+ }
dumpActiveTextureLevel(json, context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
}
} else {
+ if (!getActiveTextureLevelDesc(context, target, level, desc)) {
+ return;
+ }
dumpActiveTextureLevel(json, context, target, level);
}
{
GLint channels = _gl_format_channels(format);
+ if (internalFormat == GL_NONE) {
+ internalFormat = format;
+ }
+
Context context;
json.beginObject();
json.writeNumberMember("__height__", height);
json.writeNumberMember("__depth__", 1);
- json.writeStringMember("__format__", enumToString(internalFormat));
+ json.writeStringMember("__format__", formatToString(internalFormat));
// Hardcoded for now, but we could chose types more adequate to the
// texture internal format
**************************************************************************/
+#include <assert.h>
+
+#include "glproc.hpp"
#include "glws.hpp"
bool
checkExtension(const char *extName, const char *extString)
{
- const char *p = extString;
- const char *q = extName;
- char c;
- do {
- c = *p++;
- if (c == '\0' || c == ' ') {
- if (q && *q == '\0') {
- return true;
- } else {
- q = extName;
- }
- } else {
- if (q && *q == c) {
- ++q;
- } else {
- q = 0;
- }
- }
- } while (c);
- return false;
+ assert(extName);
+ assert(extString);
+
+ const char *p = extString;
+ const char *q = extName;
+ char c;
+ do {
+ c = *p++;
+ if (c == '\0' || c == ' ') {
+ if (q && *q == '\0') {
+ return true;
+ } else {
+ q = extName;
+ }
+ } else {
+ if (q && *q == c) {
+ ++q;
+ } else {
+ q = 0;
+ }
+ }
+ } while (c);
+ return false;
+}
+
+
+bool
+Context::hasExtension(const char *string) {
+ if (extensions.empty()) {
+ if (profile == PROFILE_CORE) {
+ // Use glGetStringi
+ GLint num_extensions = 0;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
+ for (int i = 0; i < num_extensions; ++i) {
+ const char *extension = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i));
+ if (extension) {
+ extensions.insert(extension);
+ }
+ }
+ } else {
+ // Use glGetString
+ const char *begin = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS));
+ do {
+ const char *end = begin;
+ char c = *end;
+ while (c != '\0' && c != ' ') {
+ ++end;
+ c = *end;
+ }
+ if (end != begin) {
+ extensions.insert(std::string(begin, end));
+ }
+
+ if (c == '\0') {
+ break;
+ }
+ begin = end + 1;
+ } while(1);
+ }
+ }
+
+ return extensions.find(string) != extensions.end();
}
#define _GLWS_HPP_
+#include <assert.h>
+
#include <vector>
+#include <set>
+#include <string>
namespace glws {
const Visual *visual;
int width;
int height;
+ bool pbuffer;
bool visible;
- Drawable(const Visual *vis, int w, int h) :
+ Drawable(const Visual *vis, int w, int h, bool pb) :
visual(vis),
width(w),
height(h),
+ pbuffer(pb),
visible(false)
{}
virtual void
show(void) {
+ assert(!pbuffer);
visible = true;
}
const Visual *visual;
Profile profile;
+ std::set<std::string> extensions;
+
Context(const Visual *vis, Profile prof) :
visual(vis),
profile(prof)
{}
virtual ~Context() {}
+
+ // Context must be current
+ bool
+ hasExtension(const char *extension);
};
createVisual(bool doubleBuffer = false, Profile profile = PROFILE_COMPAT);
Drawable *
-createDrawable(const Visual *visual, int width = 32, int height = 32);
+createDrawable(const Visual *visual, int width, int height, bool pbuffer = false);
Context *
createContext(const Visual *visual, Context *shareContext = 0, Profile profile = PROFILE_COMPAT, bool debug = false);
* - http://developer.apple.com/library/mac/#samplecode/glut/Introduction/Intro.html
* - http://developer.apple.com/library/mac/#samplecode/GLEssentials/Introduction/Intro.html
* - http://www.glfw.org/
+ * - http://cocoasamurai.blogspot.co.uk/2008/04/guide-to-threading-on-leopard.html
+ * - http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/Introduction/Introduction.html
*/
+#include "glproc.hpp"
+
#include <stdlib.h>
#include <iostream>
+#include <dlfcn.h>
+
#include <Cocoa/Cocoa.h>
#include "glws.hpp"
+/**
+ * Dummy thread to force Cocoa to enter multithreading mode.
+ */
+@interface DummyThread : NSObject
+ + (void)enterMultiThreaded;
+ + (void)dummyThreadMethod:(id)unused;
+@end
+
+@implementation DummyThread
+ + (void)dummyThreadMethod:(id)unused {
+ (void)unused;
+ }
+
+ + (void)enterMultiThreaded {
+ [NSThread detachNewThreadSelector:@selector(dummyThreadMethod:)
+ toTarget:self
+ withObject:nil];
+ }
+@end
+
+
namespace glws {
-NSAutoreleasePool *autoreleasePool = nil;
+static __thread NSAutoreleasePool *
+autoreleasePool = nil;
class CocoaVisual : public Visual
{
public:
NSWindow *window;
+ NSOpenGLView *view;
NSOpenGLContext *currentContext;
- CocoaDrawable(const Visual *vis, int w, int h) :
- Drawable(vis, w, h),
+ CocoaDrawable(const Visual *vis, int w, int h, bool pbuffer) :
+ Drawable(vis, w, h, pbuffer),
currentContext(nil)
{
NSOpenGLPixelFormat *pixelFormat = static_cast<const CocoaVisual *>(visual)->pixelFormat;
defer:NO];
assert(window != nil);
- NSOpenGLView *view = [[NSOpenGLView alloc]
- initWithFrame:winRect
- pixelFormat:pixelFormat];
+ view = [[NSOpenGLView alloc]
+ initWithFrame:winRect
+ pixelFormat:pixelFormat];
assert(view != nil);
[window setContentView:view];
if (currentContext != nil) {
[currentContext update];
[window makeKeyAndOrderFront:nil];
- [currentContext setView:[window contentView]];
+ [currentContext setView:view];
[currentContext makeCurrentContext];
}
};
+static inline void
+initThread(void) {
+ if (autoreleasePool == nil) {
+ autoreleasePool = [[NSAutoreleasePool alloc] init];
+ }
+}
+
void
init(void) {
- [NSApplication sharedApplication];
+ // Prevent glproc to load system's OpenGL, so that we can trace glretrace.
+ _libGlHandle = dlopen("OpenGL", RTLD_LOCAL | RTLD_NOW | RTLD_FIRST);
- autoreleasePool = [[NSAutoreleasePool alloc] init];
+ initThread();
+
+ [DummyThread enterMultiThreaded];
+
+ bool isMultiThreaded = [NSThread isMultiThreaded];
+ if (!isMultiThreaded) {
+ std::cerr << "error: failed to enable Cocoa multi-threading\n";
+ exit(1);
+ }
+
+ [NSApplication sharedApplication];
[NSApp finishLaunching];
}
Visual *
createVisual(bool doubleBuffer, Profile profile) {
+
+ initThread();
+
if (profile != PROFILE_COMPAT &&
profile != PROFILE_CORE) {
return nil;
return NULL;
#endif
}
+
+ // Use Apple software rendering for debugging purposes.
+ if (0) {
+ attribs.add(NSOpenGLPFARendererID, 0x00020200); // kCGLRendererGenericID
+ }
+
attribs.end();
NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc]
}
Drawable *
-createDrawable(const Visual *visual, int width, int height)
+createDrawable(const Visual *visual, int width, int height, bool pbuffer)
{
- return new CocoaDrawable(visual, width, height);
+ initThread();
+
+ return new CocoaDrawable(visual, width, height, pbuffer);
}
Context *
createContext(const Visual *visual, Context *shareContext, Profile profile, bool debug)
{
+ initThread();
+
NSOpenGLPixelFormat *pixelFormat = static_cast<const CocoaVisual *>(visual)->pixelFormat;
NSOpenGLContext *share_context = nil;
NSOpenGLContext *context;
bool
makeCurrent(Drawable *drawable, Context *context)
{
+ initThread();
+
if (!drawable || !context) {
[NSOpenGLContext clearCurrentContext];
} else {
bool
processEvents(void) {
- NSEvent* event;
+ initThread();
+ NSEvent* event;
do {
event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast]
EGLSurface surface;
EGLint api;
- EglDrawable(const Visual *vis, int w, int h) :
- Drawable(vis, w, h), api(EGL_OPENGL_ES_API)
+ EglDrawable(const Visual *vis, int w, int h, bool pbuffer) :
+ Drawable(vis, w, h, pbuffer),
+ api(EGL_OPENGL_ES_API)
{
XVisualInfo *visinfo = static_cast<const EglVisual *>(visual)->visinfo;
eglWaitNative(EGL_CORE_NATIVE_ENGINE);
}
+ void
+ recreate(void) {
+ EGLContext currentContext = eglGetCurrentContext();
+ EGLSurface currentDrawSurface = eglGetCurrentSurface(EGL_DRAW);
+ EGLSurface currentReadSurface = eglGetCurrentSurface(EGL_DRAW);
+ bool rebindDrawSurface = currentDrawSurface == surface;
+ bool rebindReadSurface = currentReadSurface == surface;
+
+ if (rebindDrawSurface || rebindReadSurface) {
+ eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ }
+
+ eglDestroySurface(eglDisplay, surface);
+
+ EGLConfig config = static_cast<const EglVisual *>(visual)->config;
+ surface = eglCreateWindowSurface(eglDisplay, config, (EGLNativeWindowType)window, NULL);
+
+ if (rebindDrawSurface || rebindReadSurface) {
+ eglMakeCurrent(eglDisplay, surface, surface, currentContext);
+ }
+ }
+
void
resize(int w, int h) {
if (w == width && h == height) {
waitForEvent(ConfigureNotify);
eglWaitNative(EGL_CORE_NATIVE_ENGINE);
+
+ /*
+ * Some implementations won't update the backbuffer unless we recreate
+ * the EGL surface.
+ */
+
+ int eglWidth;
+ int eglHeight;
+
+ eglQuerySurface(eglDisplay, surface, EGL_WIDTH, &eglWidth);
+ eglQuerySurface(eglDisplay, surface, EGL_HEIGHT, &eglHeight);
+
+ if (eglWidth != width || eglHeight != height) {
+ recreate();
+
+ eglQuerySurface(eglDisplay, surface, EGL_WIDTH, &eglWidth);
+ eglQuerySurface(eglDisplay, surface, EGL_HEIGHT, &eglHeight);
+ }
+
+ assert(eglWidth == width);
+ assert(eglHeight == height);
}
void show(void) {
}
Drawable *
-createDrawable(const Visual *visual, int width, int height)
+createDrawable(const Visual *visual, int width, int height, bool pbuffer)
{
- return new EglDrawable(visual, width, height);
+ return new EglDrawable(visual, width, height, pbuffer);
}
Context *
};
-static void describeEvent(const XEvent &event) {
+static void
+processEvent(XEvent &event) {
if (0) {
switch (event.type) {
case ConfigureNotify:
}
std::cerr << " " << event.xany.window << "\n";
}
+
+ switch (event.type) {
+ case KeyPress:
+ {
+ char buffer[32];
+ KeySym keysym;
+ XLookupString(&event.xkey, buffer, sizeof buffer - 1, &keysym, NULL);
+ if (keysym == XK_Escape) {
+ exit(0);
+ }
+ }
+ break;
+ }
}
class GlxDrawable : public Drawable
public:
Window window;
- GlxDrawable(const Visual *vis, int w, int h) :
- Drawable(vis, w, h)
+ GlxDrawable(const Visual *vis, int w, int h, bool pbuffer) :
+ Drawable(vis, w, h, pbuffer)
{
XVisualInfo *visinfo = static_cast<const GlxVisual *>(visual)->visinfo;
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap(display, root, visinfo->visual, AllocNone);
- attr.event_mask = StructureNotifyMask;
+ attr.event_mask = StructureNotifyMask | KeyPressMask;
unsigned long mask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
glXWaitX();
}
+ void processKeys(void) {
+ XEvent event;
+ while (XCheckWindowEvent(display, window, StructureNotifyMask | KeyPressMask, &event)) {
+ processEvent(event);
+ }
+ }
+
void waitForEvent(int type) {
XEvent event;
do {
- XWindowEvent(display, window, StructureNotifyMask, &event);
- describeEvent(event);
+ XWindowEvent(display, window, StructureNotifyMask | KeyPressMask, &event);
+ processEvent(event);
} while (event.type != type);
}
void swapBuffers(void) {
glXSwapBuffers(display, window);
+
+ processKeys();
}
};
void
init(void) {
+ XInitThreads();
+
display = XOpenDisplay(NULL);
if (!display) {
std::cerr << "error: unable to open display " << XDisplayName(NULL) << "\n";
}
Drawable *
-createDrawable(const Visual *visual, int width, int height)
+createDrawable(const Visual *visual, int width, int height, bool pbuffer)
{
- return new GlxDrawable(visual, width, height);
+ return new GlxDrawable(visual, width, height, pbuffer);
}
Context *
while (XPending(display) > 0) {
XEvent event;
XNextEvent(display, &event);
- describeEvent(event);
+ processEvent(event);
}
return true;
}
PIXELFORMATDESCRIPTOR pfd;
int iPixelFormat;
- WglDrawable(const Visual *vis, int width, int height) :
- Drawable(vis, width, height)
+ WglDrawable(const Visual *vis, int width, int height, bool pbuffer) :
+ Drawable(vis, width, height, pbuffer)
{
static bool first = TRUE;
RECT rect;
wglDeleteContext(hglrc);
}
}
+
+ bool
+ create(WglDrawable *wglDrawable) {
+ if (!hglrc) {
+ hglrc = wglCreateContext(wglDrawable->hDC);
+ if (!hglrc) {
+ std::cerr << "error: wglCreateContext failed\n";
+ exit(1);
+ return false;
+ }
+ if (shareContext) {
+ if (shareContext->create(wglDrawable)) {
+ BOOL bRet;
+ bRet = wglShareLists(shareContext->hglrc,
+ hglrc);
+ if (!bRet) {
+ std::cerr
+ << "warning: wglShareLists failed: "
+ << std::hex << GetLastError() << std::dec
+ << "\n";
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
};
Visual *
createVisual(bool doubleBuffer, Profile profile) {
- if (profile != PROFILE_COMPAT) {
+ if (profile != PROFILE_COMPAT &&
+ profile != PROFILE_CORE) {
return NULL;
}
}
Drawable *
-createDrawable(const Visual *visual, int width, int height)
+createDrawable(const Visual *visual, int width, int height, bool pbuffer)
{
- return new WglDrawable(visual, width, height);
+ return new WglDrawable(visual, width, height, pbuffer);
}
Context *
createContext(const Visual *visual, Context *shareContext, Profile profile, bool debug)
{
- if (profile != PROFILE_COMPAT) {
+ if (profile != PROFILE_COMPAT &&
+ profile != PROFILE_CORE) {
return NULL;
}
+ if (profile == PROFILE_CORE) {
+ std::cerr << "warning: ignoring OpenGL core profile request\n";
+ }
+
return new WglContext(visual, profile, static_cast<WglContext *>(shareContext));
}
WglDrawable *wglDrawable = static_cast<WglDrawable *>(drawable);
WglContext *wglContext = static_cast<WglContext *>(context);
- if (!wglContext->hglrc) {
- wglContext->hglrc = wglCreateContext(wglDrawable->hDC);
- if (!wglContext->hglrc) {
- std::cerr << "error: wglCreateContext failed\n";
- exit(1);
- return false;
- }
- if (wglContext->shareContext) {
- BOOL bRet;
- bRet = wglShareLists(wglContext->shareContext->hglrc,
- wglContext->hglrc);
- if (!bRet) {
- std::cerr << "warning: wglShareLists failed\n";
- }
- }
- }
+ wglContext->create(wglDrawable);
return wglMakeCurrent(wglDrawable->hDC, wglContext->hglrc);
}
#include <stddef.h>
#include <wchar.h>
+#ifdef _MSC_VER
+# include <float.h>
+# define isfinite _finite
+# define isnan _isnan
+#else
+# include <math.h> // isfinite, isnan
+#endif
+
#include <iomanip>
#include <limits>
#include <ostream>
template<class T>
inline void writeNumber(T n) {
- if (n != n) {
- // NaN
- writeNull();
+ separator();
+ if (isnan(n)) {
+ // NaN is non-standard but widely supported
+ os << "NaN";
+ } else if (!isfinite(n)) {
+ // Infinite is non-standard but widely supported
+ if (n < 0) {
+ os << '-';
+ }
+ os << "Infinity";
} else {
- separator();
os << std::dec << std::setprecision(std::numeric_limits<T>::digits10 + 1) << n;
- value = true;
- space = ' ';
}
+ value = true;
+ space = ' ';
}
inline void writeStringMember(const char *name, const char *s) {
static void dumpCall(trace::Call &call) {
if (verbosity >= 0 && !call_dumped) {
+ std::cout << std::hex << call.thread_id << std::dec << " ";
std::cout << call;
std::cout.flush();
call_dumped = true;
void Retracer::retrace(trace::Call &call) {
call_dumped = false;
- if (verbosity >= 1) {
- if (verbosity >= 2 ||
- !(call.flags & trace::CALL_FLAG_VERBOSE)) {
- dumpCall(call);
- }
- }
-
Callback callback = 0;
trace::Id id = call.sig->id;
assert(callback);
assert(callbacks[id] == callback);
- if (retrace::profiling) {
- long long startTime = os::getTime();
- callback(call);
- long long stopTime = os::getTime();
- float timeInterval = (stopTime - startTime) * (1.0E6 / os::timeFrequency);
-
- std::cout
- << call.no << " "
- << "[" << timeInterval << " usec] "
- ;
- trace::dump(call, std::cout, trace::DUMP_FLAG_NO_CALL_NO | trace::DUMP_FLAG_NO_COLOR);
- } else {
- callback(call);
+ if (verbosity >= 1) {
+ if (verbosity >= 2 ||
+ (!(call.flags & trace::CALL_FLAG_VERBOSE) &&
+ callback != &ignore)) {
+ dumpCall(call);
+ }
}
+
+ callback(call);
}
#include "trace_model.hpp"
#include "trace_parser.hpp"
+#include "trace_profiler.hpp"
namespace image {
extern trace::Parser parser;
+extern trace::Profiler profiler;
/**
* Add profiling data to the dump when retracing.
*/
extern bool profiling;
+extern bool profilingCpuTimes;
+extern bool profilingGpuTimes;
+extern bool profilingPixelsDrawn;
/**
* State dumping.
extern bool doubleBuffer;
extern bool coreProfile;
+extern unsigned frameNo;
+extern unsigned callNo;
+
std::ostream &warning(trace::Call &call);
#include "os_binary.hpp"
#include "os_time.hpp"
+#include "os_thread.hpp"
#include "image.hpp"
#include "trace_callset.hpp"
#include "trace_dump.hpp"
static unsigned dumpStateCallNo = ~0;
+retrace::Retracer retracer;
+
namespace retrace {
trace::Parser parser;
+trace::Profiler profiler;
int verbosity = 0;
bool debug = true;
-bool profiling = false;
bool dumpingState = false;
-
bool doubleBuffer = true;
bool coreProfile = false;
+bool profiling = false;
+bool profilingGpuTimes = false;
+bool profilingCpuTimes = false;
+bool profilingPixelsDrawn = false;
-static unsigned frameNo = 0;
+unsigned frameNo = 0;
+unsigned callNo = 0;
void
}
+/**
+ * Take/compare snapshots.
+ */
static void
takeSnapshot(unsigned call_no) {
assert(snapshotPrefix || comparePrefix);
}
+/**
+ * Retrace one call.
+ *
+ * Take snapshots before/after retracing (as appropriate) and dispatch it to
+ * the respective handler.
+ */
static void
-mainLoop() {
- retrace::Retracer retracer;
+retraceCall(trace::Call *call) {
+ bool swapRenderTarget = call->flags &
+ trace::CALL_FLAG_SWAP_RENDERTARGET;
+ bool doSnapshot = snapshotFrequency.contains(*call) ||
+ compareFrequency.contains(*call);
+
+ // For calls which cause rendertargets to be swaped, we take the
+ // snapshot _before_ swapping the rendertargets.
+ if (doSnapshot && swapRenderTarget) {
+ if (call->flags & trace::CALL_FLAG_END_FRAME) {
+ // For swapbuffers/presents we still use this
+ // call number, spite not have been executed yet.
+ takeSnapshot(call->no);
+ } else {
+ // Whereas for ordinate fbo/rendertarget changes we
+ // use the previous call's number.
+ takeSnapshot(call->no - 1);
+ }
+ }
- addCallbacks(retracer);
+ callNo = call->no;
+ retracer.retrace(*call);
- long long startTime = 0;
- frameNo = 0;
+ if (doSnapshot && !swapRenderTarget)
+ takeSnapshot(call->no);
- startTime = os::getTime();
- trace::Call *call;
+ if (call->no >= dumpStateCallNo &&
+ dumpState(std::cout)) {
+ exit(0);
+ }
+}
- while ((call = retrace::parser.parse_call())) {
- bool swapRenderTarget = call->flags & trace::CALL_FLAG_SWAP_RENDERTARGET;
- bool doSnapshot =
- snapshotFrequency.contains(*call) ||
- compareFrequency.contains(*call)
- ;
-
- // For calls which cause rendertargets to be swaped, we take the
- // snapshot _before_ swapping the rendertargets.
- if (doSnapshot && swapRenderTarget) {
- if (call->flags & trace::CALL_FLAG_END_FRAME) {
- // For swapbuffers/presents we still use this call number,
- // spite not have been executed yet.
- takeSnapshot(call->no);
- } else {
- // Whereas for ordinate fbo/rendertarget changes we use the
- // previous call's number.
- takeSnapshot(call->no - 1);
+
+class RelayRunner;
+
+
+/**
+ * Implement multi-threading by mimicking a relay race.
+ */
+class RelayRace
+{
+private:
+ /**
+ * Runners indexed by the leg they run (i.e, the thread_ids from the
+ * trace).
+ */
+ std::vector<RelayRunner*> runners;
+
+public:
+ RelayRace();
+
+ ~RelayRace();
+
+ RelayRunner *
+ getRunner(unsigned leg);
+
+ inline RelayRunner *
+ getForeRunner() {
+ return getRunner(0);
+ }
+
+ void
+ run(void);
+
+ void
+ passBaton(trace::Call *call);
+
+ void
+ finishLine();
+
+ void
+ stopRunners();
+};
+
+
+/**
+ * Each runner is a thread.
+ *
+ * The fore runner doesn't have its own thread, but instead uses the thread
+ * where the race started.
+ */
+class RelayRunner
+{
+private:
+ friend class RelayRace;
+
+ RelayRace *race;
+
+ unsigned leg;
+
+ os::mutex mutex;
+ os::condition_variable wake_cond;
+
+ /**
+ * There are protected by the mutex.
+ */
+ bool finished;
+ trace::Call *baton;
+
+ os::thread thread;
+
+ static void *
+ runnerThread(RelayRunner *_this);
+
+public:
+ RelayRunner(RelayRace *race, unsigned _leg) :
+ race(race),
+ leg(_leg),
+ finished(false),
+ baton(0)
+ {
+ /* The fore runner does not need a new thread */
+ if (leg) {
+ thread = os::thread(runnerThread, this);
+ }
+ }
+
+ /**
+ * Thread main loop.
+ */
+ void
+ runRace(void) {
+ os::unique_lock<os::mutex> lock(mutex);
+
+ while (1) {
+ while (!finished && !baton) {
+ wake_cond.wait(lock);
+ }
+
+ if (finished) {
+ break;
}
+
+ assert(baton);
+ trace::Call *call = baton;
+ baton = 0;
+
+ runLeg(call);
}
- retracer.retrace(*call);
+ if (0) std::cerr << "leg " << leg << " actually finishing\n";
- if (doSnapshot && !swapRenderTarget) {
- takeSnapshot(call->no);
+ if (leg == 0) {
+ race->stopRunners();
}
+ }
- if (call->no >= dumpStateCallNo &&
- dumpState(std::cout)) {
- exit(0);
+ /**
+ * Interpret successive calls.
+ */
+ void
+ runLeg(trace::Call *call) {
+ /* Consume successive calls for this thread. */
+ do {
+ assert(call);
+ assert(call->thread_id == leg);
+ retraceCall(call);
+ delete call;
+ call = parser.parse_call();
+ } while (call && call->thread_id == leg);
+
+ if (call) {
+ /* Pass the baton */
+ assert(call->thread_id != leg);
+ flushRendering();
+ race->passBaton(call);
+ } else {
+ /* Reached the finish line */
+ if (0) std::cerr << "finished on leg " << leg << "\n";
+ if (leg) {
+ /* Notify the fore runner */
+ race->finishLine();
+ } else {
+ /* We are the fore runner */
+ finished = true;
+ }
}
+ }
- delete call;
+ /**
+ * Called by other threads when relinquishing the baton.
+ */
+ void
+ receiveBaton(trace::Call *call) {
+ assert (call->thread_id == leg);
+
+ mutex.lock();
+ baton = call;
+ mutex.unlock();
+
+ wake_cond.signal();
}
- // Reached the end of trace
- flushRendering();
+ /**
+ * Called by the fore runner when the race is over.
+ */
+ void
+ finishRace() {
+ if (0) std::cerr << "notify finish to leg " << leg << "\n";
+
+ mutex.lock();
+ finished = true;
+ mutex.unlock();
+
+ wake_cond.signal();
+ }
+};
+
+
+void *
+RelayRunner::runnerThread(RelayRunner *_this) {
+ _this->runRace();
+ return 0;
+}
+
+
+RelayRace::RelayRace() {
+ runners.push_back(new RelayRunner(this, 0));
+}
+
+
+RelayRace::~RelayRace() {
+ assert(runners.size() >= 1);
+ std::vector<RelayRunner*>::const_iterator it;
+ for (it = runners.begin(); it != runners.end(); ++it) {
+ RelayRunner* runner = *it;
+ if (runner) {
+ delete runner;
+ }
+ }
+}
+
+
+/**
+ * Get (or instantiate) a runner for the specified leg.
+ */
+RelayRunner *
+RelayRace::getRunner(unsigned leg) {
+ RelayRunner *runner;
+
+ if (leg >= runners.size()) {
+ runners.resize(leg + 1);
+ runner = 0;
+ } else {
+ runner = runners[leg];
+ }
+ if (!runner) {
+ runner = new RelayRunner(this, leg);
+ runners[leg] = runner;
+ }
+ return runner;
+}
+
+
+/**
+ * Start the race.
+ */
+void
+RelayRace::run(void) {
+ trace::Call *call;
+ call = parser.parse_call();
+ if (!call) {
+ /* Nothing to do */
+ return;
+ }
+
+ RelayRunner *foreRunner = getForeRunner();
+ if (call->thread_id == 0) {
+ /* We are the forerunner thread, so no need to pass baton */
+ foreRunner->baton = call;
+ } else {
+ passBaton(call);
+ }
+
+ /* Start the forerunner thread */
+ foreRunner->runRace();
+}
+
+
+/**
+ * Pass the baton (i.e., the call) to the appropriate thread.
+ */
+void
+RelayRace::passBaton(trace::Call *call) {
+ if (0) std::cerr << "switching to thread " << call->thread_id << "\n";
+ RelayRunner *runner = getRunner(call->thread_id);
+ runner->receiveBaton(call);
+}
+
+
+/**
+ * Called when a runner other than the forerunner reaches the finish line.
+ *
+ * Only the fore runner can finish the race, so inform him that the race is
+ * finished.
+ */
+void
+RelayRace::finishLine(void) {
+ RelayRunner *foreRunner = getForeRunner();
+ foreRunner->finishRace();
+}
+
+
+/**
+ * Called by the fore runner after finish line to stop all other runners.
+ */
+void
+RelayRace::stopRunners(void) {
+ std::vector<RelayRunner*>::const_iterator it;
+ for (it = runners.begin() + 1; it != runners.end(); ++it) {
+ RelayRunner* runner = *it;
+ if (runner) {
+ runner->finishRace();
+ }
+ }
+}
+
+
+static void
+mainLoop() {
+ addCallbacks(retracer);
+
+ long long startTime = 0;
+ frameNo = 0;
+
+ startTime = os::getTime();
+
+ RelayRace race;
+ race.run();
long long endTime = os::getTime();
float timeInterval = (endTime - startTime) * (1.0 / os::timeFrequency);
"Replay TRACE.\n"
"\n"
" -b benchmark mode (no error checking or warning messages)\n"
- " -p profiling mode (run whole trace, dump profiling info)\n"
+ " -pcpu cpu profiling (cpu times per call)\n"
+ " -pgpu gpu profiling (gpu times per draw call)\n"
+ " -ppd pixels drawn profiling (pixels drawn per draw call)\n"
" -c PREFIX compare against snapshots\n"
" -C CALLSET calls to compare (default is every frame)\n"
" -core use core profile\n"
} else if (!strcmp(arg, "-b")) {
retrace::debug = false;
retrace::verbosity = -1;
- } else if (!strcmp(arg, "-p")) {
- retrace::debug = false;
- retrace::profiling = true;
- retrace::verbosity = -1;
} else if (!strcmp(arg, "-c")) {
comparePrefix = argv[++i];
if (compareFrequency.empty()) {
++retrace::verbosity;
} else if (!strcmp(arg, "-w")) {
waitOnFinish = true;
+ } else if (arg[1] == 'p') {
+ retrace::debug = false;
+ retrace::profiling = true;
+ retrace::verbosity = -1;
+
+ if (!strcmp(arg, "-pcpu")) {
+ retrace::profilingCpuTimes = true;
+ } else if (!strcmp(arg, "-pgpu")) {
+ retrace::profilingGpuTimes = true;
+ } else if (!strcmp(arg, "-ppd")) {
+ retrace::profilingPixelsDrawn = true;
+ }
} else {
std::cerr << "error: unknown option " << arg << "\n";
usage(argv[0]);
}
retrace::setUp();
+ if (retrace::profiling) {
+ retrace::profiler.setup(retrace::profilingCpuTimes, retrace::profilingGpuTimes, retrace::profilingPixelsDrawn);
+ }
for ( ; i < argc; ++i) {
if (!retrace::parser.open(argv[i])) {
}
}
+#ifndef NDEBUG
+ if (it != regionMap.end()) {
+ assert(contains(it, address) || it->first > address);
+ }
+#endif
+
return it;
}
upperBound(unsigned long long address) {
RegionMap::iterator it = regionMap.upper_bound(address);
+#ifndef NDEBUG
+ if (it != regionMap.end()) {
+ assert(it->first >= address);
+ }
+#endif
+
return it;
}
#ifndef NDEBUG
RegionMap::iterator start = lowerBound(address);
- RegionMap::iterator stop = upperBound(address + size);
+ RegionMap::iterator stop = upperBound(address + size - 1);
if (0) {
// Forget all regions that intersect this new one.
regionMap.erase(start, stop);
--- /dev/null
+#!/usr/bin/env python
+##########################################################################
+#
+# Copyright 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.
+#
+##########################################################################/
+
+
+import sys
+
+
+def process(stream):
+ times = {}
+
+ # call no gpu_start gpu_dura cpu_start cpu_dura pixels program name
+
+ for line in stream:
+ words = line.split(' ')
+
+ if line.startswith('#'):
+ continue
+
+ if words[0] == 'call':
+ id = long(words[1])
+ duration = long(words[3])
+ shader = long(words[7])
+ func = words[8]
+
+ if times.has_key(shader):
+ times[shader]['draws'] += 1
+ times[shader]['duration'] += duration
+
+ if duration > times[shader]['longestDuration']:
+ times[shader]['longest'] = id
+ times[shader]['longestDuration'] = duration
+ else:
+ times[shader] = {'draws': 1, 'duration': duration, 'longest': id, 'longestDuration': duration}
+
+ times = sorted(times.items(), key=lambda x: x[1]['duration'], reverse=True)
+
+ print '+------------+--------------+--------------------+--------------+-------------+'
+ print '| Shader[id] | Draws [#] | Duration [ns] v | Per Call[ns] | Longest[id] |'
+ print '+------------+--------------+--------------------+--------------+-------------+'
+
+ for shader in times:
+ id = str(shader[0]).rjust(10)
+ draw = str(shader[1]['draws']).rjust(12)
+ dura = str(shader[1]['duration']).rjust(18)
+ perCall = str(shader[1]['duration'] / shader[1]['draws']).rjust(12)
+ longest = str(shader[1]['longest']).rjust(11)
+ print "| %s | %s | %s | %s | %s |" % (id, draw, dura, perCall, longest)
+
+ print '+------------+--------------+--------------------+--------------+-------------+'
+
+
+def main():
+ if len(sys.argv) > 1:
+ for arg in sys.argv[1:]:
+ process(open(arg, 'rt'))
+ else:
+ process(sys.stdin)
+
+
+if __name__ == '__main__':
+ main()
magic = stream.readline()
if not magic:
return None, None
- assert magic.rstrip() == 'P6'
+ magic = magic.rstrip()
+ if magic == 'P5':
+ channels = 1
+ mode = 'L'
+ elif magic == 'P6':
+ channels = 3
+ mode = 'RGB'
+ else:
+ raise Exception('Unsupported magic `%s`' % magic)
comment = ''
line = stream.readline()
while line.startswith('#'):
width, height = map(int, line.strip().split())
maximum = int(stream.readline().strip())
assert maximum == 255
- data = stream.read(height * width * 3)
- image = Image.frombuffer('RGB', (width, height), data, 'raw', 'RGB', 0, 1)
+ data = stream.read(height * width * channels)
+ image = Image.frombuffer(mode, (width, height), data, 'raw', mode, 0, 1)
return image, comment
def diff(ref_trace, src_trace):
+ isatty = sys.stdout.isatty()
+
ref_dumper = Dumper(ref_trace, options.ref_calls)
src_dumper = Dumper(src_trace, options.src_calls)
diff_args = [
'diff',
'--speed-large-files',
+ ]
+ if isatty:
+ diff_args += [
'--old-line-format=' + start_delete + '%l' + end_delete + '\n',
'--new-line-format=' + start_insert + '%l' + end_insert + '\n',
]
'wdiff',
#'--terminal',
'--avoid-wraps',
+ ]
+ if isatty:
+ diff_args += [
'--start-delete=' + start_delete,
'--end-delete=' + end_delete,
'--start-insert=' + start_insert,
src_dumper.dump.wait()
less = None
- if sys.stdout.isatty():
+ if isatty:
less = subprocess.Popen(
args = ['less', '-FRXn'],
stdin = subprocess.PIPE
return 'blob(%u)' % self.size
def __eq__(self, other):
- return self.size == other.size and self.hash == other.hash
+ return isinstance(other, Blob) and self.size == other.size and self.hash == other.hash
def __hash__(self):
return self.hash
class Counter(Unpickler):
- def __init__(self, stream, quiet):
+ def __init__(self, stream, verbose = False):
Unpickler.__init__(self, stream)
- self.quiet = quiet
- self.calls = 0
+ self.verbose = verbose
+ self.numCalls = 0
+ self.functionFrequencies = {}
+
+ def parse(self):
+ Unpickler.parse(self)
+
+ functionFrequencies = self.functionFrequencies.items()
+ functionFrequencies.sort(lambda (name1, freq1), (name2, freq2): cmp(freq1, freq2))
+ for name, frequency in functionFrequencies:
+ sys.stdout.write('%8u %s\n' % (frequency, name))
def handleCall(self, call):
- if not self.quiet:
+ if self.verbose:
sys.stdout.write(str(call))
sys.stdout.write('\n')
- self.calls += 1
+ self.numCalls += 1
+ try:
+ self.functionFrequencies[call.functionName] += 1
+ except KeyError:
+ self.functionFrequencies[call.functionName] = 1
def main():
optparser = optparse.OptionParser(
- usage="\n\tapitrace pickle trace. %prog [options]")
+ usage="\n\tapitrace pickle <trace> | %prog [options]")
+ optparser.add_option(
+ '-p', '--profile',
+ action="store_true", dest="profile", default=False,
+ help="profile call parsing")
optparser.add_option(
- '-q', '--quiet',
- action="store_true", dest="quiet", default=False,
- help="don't dump calls to stdout")
+ '-v', '--verbose',
+ action="store_true", dest="verbose", default=False,
+ help="dump calls to stdout")
(options, args) = optparser.parse_args(sys.argv[1:])
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
startTime = time.time()
- parser = Counter(sys.stdin, options.quiet)
+ parser = Counter(sys.stdin, options.verbose)
parser.parse()
stopTime = time.time()
duration = stopTime - startTime
- sys.stderr.write('%u calls, %.03f secs, %u calls/sec\n' % (parser.calls, duration, parser.calls/duration))
+
+ if options.profile:
+ sys.stderr.write('Processed %u calls in %.03f secs, at %u calls/sec\n' % (parser.numCalls, duration, parser.numCalls/duration))
if __name__ == '__main__':
Function(CGLError, "CGLLockContext", [(CGLContextObj, "ctx")]),
Function(CGLError, "CGLUnlockContext", [(CGLContextObj, "ctx")]),
Function(Void, "CGLGetVersion", [Out(Pointer(GLint), "majorvers"), Out(Pointer(GLint), "minorvers")]),
- Function(Const(CString), "CGLErrorString", [(CGLError, "error")]),
+ Function(ConstCString, "CGLErrorString", [(CGLError, "error")]),
# CGLIOSurface.h, OpenGL framework
Function(CGLError, "CGLTexImageIOSurface2D", [(CGLContextObj, "ctx"), (GLenum, "target"), (GLenum, "internal_format"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"), (GLenum, "type"), (IOSurfaceRef, "ioSurface"), (GLuint, "plane")]),
])
D3D10_SUBRESOURCE_DATA = Struct("D3D10_SUBRESOURCE_DATA", [
- (OpaquePointer(Const(Void)), "pSysMem"),
+ (Blob(Const(Void), "_calcSubresourceSize(pDesc, {i}, {self}.SysMemPitch, {self}.SysMemSlicePitch)"), "pSysMem"),
(UINT, "SysMemPitch"),
(UINT, "SysMemSlicePitch"),
])
Method(Void, "RSSetScissorRects", [(UINT, "NumRects"), (Array(Const(D3D10_RECT), "NumRects"), "pRects")]),
Method(Void, "CopySubresourceRegion", [(ObjPointer(ID3D10Resource), "pDstResource"), (UINT, "DstSubresource"), (UINT, "DstX"), (UINT, "DstY"), (UINT, "DstZ"), (ObjPointer(ID3D10Resource), "pSrcResource"), (UINT, "SrcSubresource"), (Pointer(Const(D3D10_BOX)), "pSrcBox")]),
Method(Void, "CopyResource", [(ObjPointer(ID3D10Resource), "pDstResource"), (ObjPointer(ID3D10Resource), "pSrcResource")]),
- Method(Void, "UpdateSubresource", [(ObjPointer(ID3D10Resource), "pDstResource"), (UINT, "DstSubresource"), (Pointer(Const(D3D10_BOX)), "pDstBox"), (OpaquePointer(Const(Void)), "pSrcData"), (UINT, "SrcRowPitch"), (UINT, "SrcDepthPitch")]),
+ Method(Void, "UpdateSubresource", [(ObjPointer(ID3D10Resource), "pDstResource"), (UINT, "DstSubresource"), (Pointer(Const(D3D10_BOX)), "pDstBox"), (Blob(Const(Void), "_calcSubresourceSize(pDstResource, DstSubresource, pDstBox, SrcRowPitch, SrcDepthPitch)"), "pSrcData"), (UINT, "SrcRowPitch"), (UINT, "SrcDepthPitch")]),
Method(Void, "ClearRenderTargetView", [(ObjPointer(ID3D10RenderTargetView), "pRenderTargetView"), (Array(Const(FLOAT), 4), "ColorRGBA")]),
Method(Void, "ClearDepthStencilView", [(ObjPointer(ID3D10DepthStencilView), "pDepthStencilView"), (D3D10_CLEAR_FLAG, "ClearFlags"), (FLOAT, "Depth"), (UINT8, "Stencil")]),
Method(Void, "GenerateMips", [(ObjPointer(ID3D10ShaderResourceView), "pShaderResourceView")]),
Method(HRESULT, "SetPrivateDataInterface", [(REFGUID, "guid"), (OpaquePointer(Const(IUnknown)), "pData")], sideeffects=False),
Method(Void, "ClearState", []),
Method(Void, "Flush", []),
- Method(HRESULT, "CreateBuffer", [(Pointer(Const(D3D10_BUFFER_DESC)), "pDesc"), (Pointer(Const(D3D10_SUBRESOURCE_DATA)), "pInitialData"), Out(Pointer(ObjPointer(ID3D10Buffer)), "ppBuffer")]),
- Method(HRESULT, "CreateTexture1D", [(Pointer(Const(D3D10_TEXTURE1D_DESC)), "pDesc"), (Pointer(Const(D3D10_SUBRESOURCE_DATA)), "pInitialData"), Out(Pointer(ObjPointer(ID3D10Texture1D)), "ppTexture1D")]),
- Method(HRESULT, "CreateTexture2D", [(Pointer(Const(D3D10_TEXTURE2D_DESC)), "pDesc"), (Pointer(Const(D3D10_SUBRESOURCE_DATA)), "pInitialData"), Out(Pointer(ObjPointer(ID3D10Texture2D)), "ppTexture2D")]),
- Method(HRESULT, "CreateTexture3D", [(Pointer(Const(D3D10_TEXTURE3D_DESC)), "pDesc"), (Pointer(Const(D3D10_SUBRESOURCE_DATA)), "pInitialData"), Out(Pointer(ObjPointer(ID3D10Texture3D)), "ppTexture3D")]),
+ Method(HRESULT, "CreateBuffer", [(Pointer(Const(D3D10_BUFFER_DESC)), "pDesc"), (Array(Const(D3D10_SUBRESOURCE_DATA), "1"), "pInitialData"), Out(Pointer(ObjPointer(ID3D10Buffer)), "ppBuffer")]),
+ Method(HRESULT, "CreateTexture1D", [(Pointer(Const(D3D10_TEXTURE1D_DESC)), "pDesc"), (Array(Const(D3D10_SUBRESOURCE_DATA), "_getNumSubResources(pDesc)"), "pInitialData"), Out(Pointer(ObjPointer(ID3D10Texture1D)), "ppTexture1D")]),
+ Method(HRESULT, "CreateTexture2D", [(Pointer(Const(D3D10_TEXTURE2D_DESC)), "pDesc"), (Array(Const(D3D10_SUBRESOURCE_DATA), "_getNumSubResources(pDesc)"), "pInitialData"), Out(Pointer(ObjPointer(ID3D10Texture2D)), "ppTexture2D")]),
+ Method(HRESULT, "CreateTexture3D", [(Pointer(Const(D3D10_TEXTURE3D_DESC)), "pDesc"), (Array(Const(D3D10_SUBRESOURCE_DATA), "_getNumSubResources(pDesc)"), "pInitialData"), Out(Pointer(ObjPointer(ID3D10Texture3D)), "ppTexture3D")]),
Method(HRESULT, "CreateShaderResourceView", [(ObjPointer(ID3D10Resource), "pResource"), (Pointer(Const(D3D10_SHADER_RESOURCE_VIEW_DESC)), "pDesc"), Out(Pointer(ObjPointer(ID3D10ShaderResourceView)), "ppSRView")]),
Method(HRESULT, "CreateRenderTargetView", [(ObjPointer(ID3D10Resource), "pResource"), (Pointer(Const(D3D10_RENDER_TARGET_VIEW_DESC)), "pDesc"), Out(Pointer(ObjPointer(ID3D10RenderTargetView)), "ppRTView")]),
Method(HRESULT, "CreateDepthStencilView", [(ObjPointer(ID3D10Resource), "pResource"), (Pointer(Const(D3D10_DEPTH_STENCIL_VIEW_DESC)), "pDesc"), Out(Pointer(ObjPointer(ID3D10DepthStencilView)), "ppDepthStencilView")]),
(D3D10_MESSAGE_CATEGORY, "Category"),
(D3D10_MESSAGE_SEVERITY, "Severity"),
(D3D10_MESSAGE_ID, "ID"),
- (Const(CString), "pDescription"),
+ (ConstCString, "pDescription"),
(SIZE_T, "DescriptionByteLength"),
])
dxgi = API('dxgi')
dxgi.addFunctions([
- StdFunction(HRESULT, "CreateDXGIFactory", [(REFIID, "riid"), (Pointer(ObjPointer(Void)), "ppFactory")]),
- StdFunction(HRESULT, "CreateDXGIFactory1", [(REFIID, "riid"), (Pointer(ObjPointer(Void)), "ppFactory")]),
+ StdFunction(HRESULT, "CreateDXGIFactory", [(REFIID, "riid"), Out(Pointer(ObjPointer(Void)), "ppFactory")]),
+ StdFunction(HRESULT, "CreateDXGIFactory1", [(REFIID, "riid"), Out(Pointer(ObjPointer(Void)), "ppFactory")]),
])
Function(EGLBoolean, "eglInitialize", [(EGLDisplay, "dpy"), Out(Pointer(EGLint), "major"), Out(Pointer(EGLint), "minor")]),
Function(EGLBoolean, "eglTerminate", [(EGLDisplay, "dpy")]),
- Function(Const(String("char *")), "eglQueryString", [(EGLDisplay, "dpy"), (EGLName, "name")], sideeffects=False),
+ Function(ConstCString, "eglQueryString", [(EGLDisplay, "dpy"), (EGLName, "name")], sideeffects=False),
Function(EGLBoolean, "eglGetConfigs", [(EGLDisplay, "dpy"), (Array(EGLConfig, "config_size"), "configs"), (EGLint, "config_size"), Out(Pointer(EGLint), "num_config")]),
Function(EGLBoolean, "eglChooseConfig", [(EGLDisplay, "dpy"), (EGLAttribList, "attrib_list"), (Array(EGLConfig, "config_size"), "configs"), (EGLint, "config_size"), Out(Pointer(EGLint), "num_config")]),
Function(EGLBoolean, "eglSwapBuffers", [(EGLDisplay, "dpy"), (EGLSurface, "surface")]),
Function(EGLBoolean, "eglCopyBuffers", [(EGLDisplay, "dpy"), (EGLSurface, "surface"), (EGLNativePixmapType, "target")]),
- Function(EGLProc, "eglGetProcAddress", [(Const(CString), "procname")]),
+ Function(EGLProc, "eglGetProcAddress", [(ConstCString, "procname")]),
# EGL_KHR_lock_surface
Function(EGLBoolean, "eglLockSurfaceKHR", [(EGLDisplay, "display"), (EGLSurface, "surface"), (EGLAttribList, "attrib_list")]),
GlFunction(Void, "glTexImage2D", [(GLenum, "target"), (GLint, "level"), (GLenum_int, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLint, "border"), (GLenum, "format"), (GLenum, "type"), (Blob(Const(GLvoid), "_glTexImage2D_size(format, type, width, height)"), "pixels")]),
GlFunction(Void, "glDrawBuffer", [(GLenum, "mode")]),
GlFunction(Void, "glClear", [(GLbitfield_attrib, "mask")]),
- GlFunction(Void, "glClearColor", [(GLclampf, "red"), (GLclampf, "green"), (GLclampf, "blue"), (GLclampf, "alpha")]),
+ GlFunction(Void, "glClearColor", [(GLfloat, "red"), (GLfloat, "green"), (GLfloat, "blue"), (GLfloat, "alpha")]),
GlFunction(Void, "glClearStencil", [(GLint, "s")]),
- GlFunction(Void, "glClearDepth", [(GLclampd, "depth")]),
+ GlFunction(Void, "glClearDepth", [(GLdouble, "depth")]),
GlFunction(Void, "glStencilMask", [(GLuint, "mask")]),
GlFunction(Void, "glColorMask", [(GLboolean, "red"), (GLboolean, "green"), (GLboolean, "blue"), (GLboolean, "alpha")]),
GlFunction(Void, "glDepthMask", [(GLboolean, "flag")]),
GlFunction(GLenum_error, "glGetError", [], sideeffects=False),
GlFunction(Void, "glGetFloatv", [(GLenum, "pname"), Out(Array(GLfloat, "_gl_param_size(pname)"), "params")], sideeffects=False),
GlFunction(Void, "glGetIntegerv", [(GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
- GlFunction(String("const GLubyte *"), "glGetString", [(GLenum, "name")], sideeffects=False),
+ GlFunction(String(Const(GLubyte)), "glGetString", [(GLenum, "name")], sideeffects=False),
GlFunction(Void, "glGetTexImage", [(GLenum, "target"), (GLint, "level"), (GLenum, "format"), (GLenum, "type"), Out(GLpointer, "pixels")]),
GlFunction(Void, "glGetTexParameterfv", [(GLenum, "target"), (GLenum, "pname"), Out(Array(GLfloat, "_gl_param_size(pname)"), "params")], sideeffects=False),
GlFunction(Void, "glGetTexParameteriv", [(GLenum, "target"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
GlFunction(Void, "glGetTexLevelParameterfv", [(GLenum, "target"), (GLint, "level"), (GLenum, "pname"), Out(Array(GLfloat, "_gl_param_size(pname)"), "params")], sideeffects=False),
GlFunction(Void, "glGetTexLevelParameteriv", [(GLenum, "target"), (GLint, "level"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
GlFunction(GLboolean, "glIsEnabled", [(GLenum, "cap")], sideeffects=False),
- GlFunction(Void, "glDepthRange", [(GLclampd, "zNear"), (GLclampd, "zFar")]),
+ GlFunction(Void, "glDepthRange", [(GLdouble, "zNear"), (GLdouble, "zFar")]),
GlFunction(Void, "glViewport", [(GLint, "x"), (GLint, "y"), (GLsizei, "width"), (GLsizei, "height")]),
# GL_VERSION_1_0_DEPRECATED
GlFunction(Void, "glEvalPoint1", [(GLint, "i")]),
GlFunction(Void, "glEvalMesh2", [(GLenum, "mode"), (GLint, "i1"), (GLint, "i2"), (GLint, "j1"), (GLint, "j2")]),
GlFunction(Void, "glEvalPoint2", [(GLint, "i"), (GLint, "j")]),
- GlFunction(Void, "glAlphaFunc", [(GLenum, "func"), (GLclampf, "ref")]),
+ GlFunction(Void, "glAlphaFunc", [(GLenum, "func"), (GLfloat, "ref")]),
GlFunction(Void, "glPixelZoom", [(GLfloat, "xfactor"), (GLfloat, "yfactor")]),
GlFunction(Void, "glPixelTransferf", [(GLenum, "pname"), (GLfloat, "param")]),
GlFunction(Void, "glPixelTransferi", [(GLenum, "pname"), (GLint, "param")]),
# GL_VERSION_1_1_DEPRECATED
GlFunction(Void, "glArrayElement", [(GLint, "i")]),
- GlFunction(Void, "glColorPointer", [(GLint, "size"), (GLenum, "type"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
+ GlFunction(Void, "glColorPointer", [(size_bgra, "size"), (GLenum, "type"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
GlFunction(Void, "glDisableClientState", [(GLenum, "array")]),
GlFunction(Void, "glEdgeFlagPointer", [(GLsizei, "stride"), (GLpointerConst, "pointer")]),
GlFunction(Void, "glEnableClientState", [(GLenum, "array")]),
GlFunction(Void, "glPushClientAttrib", [(GLbitfield_client_attrib, "mask")]),
# GL_VERSION_1_2
- GlFunction(Void, "glBlendColor", [(GLclampf, "red"), (GLclampf, "green"), (GLclampf, "blue"), (GLclampf, "alpha")]),
+ GlFunction(Void, "glBlendColor", [(GLfloat, "red"), (GLfloat, "green"), (GLfloat, "blue"), (GLfloat, "alpha")]),
GlFunction(Void, "glBlendEquation", [(GLenum, "mode")]),
GlFunction(Void, "glDrawRangeElements", [(GLenum_mode, "mode"), (GLuint, "start"), (GLuint, "end"), (GLsizei, "count"), (GLenum, "type"), (GLpointerConst, "indices")]),
GlFunction(Void, "glTexImage3D", [(GLenum, "target"), (GLint, "level"), (GLenum_int, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLsizei, "depth"), (GLint, "border"), (GLenum, "format"), (GLenum, "type"), (Blob(Const(GLvoid), "_glTexImage3D_size(format, type, width, height, depth)"), "pixels")]),
# GL_VERSION_1_3
GlFunction(Void, "glActiveTexture", [(GLenum, "texture")]),
- GlFunction(Void, "glSampleCoverage", [(GLclampf, "value"), (GLboolean, "invert")]),
+ GlFunction(Void, "glSampleCoverage", [(GLfloat, "value"), (GLboolean, "invert")]),
GlFunction(Void, "glCompressedTexImage3D", [(GLenum, "target"), (GLint, "level"), (GLenum, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLsizei, "depth"), (GLint, "border"), (GLsizei, "imageSize"), (Blob(Const(GLvoid), "imageSize"), "data")]),
GlFunction(Void, "glCompressedTexImage2D", [(GLenum, "target"), (GLint, "level"), (GLenum, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLint, "border"), (GLsizei, "imageSize"), (Blob(Const(GLvoid), "imageSize"), "data")]),
GlFunction(Void, "glCompressedTexImage1D", [(GLenum, "target"), (GLint, "level"), (GLenum, "internalformat"), (GLsizei, "width"), (GLint, "border"), (GLsizei, "imageSize"), (Blob(Const(GLvoid), "imageSize"), "data")]),
# GL_VERSION_1_4
GlFunction(Void, "glBlendFuncSeparate", [(GLenum, "sfactorRGB"), (GLenum, "dfactorRGB"), (GLenum, "sfactorAlpha"), (GLenum, "dfactorAlpha")]),
- GlFunction(Void, "glMultiDrawArrays", [(GLenum_mode, "mode"), (Array(Const(GLint), "primcount"), "first"), (Array(Const(GLsizei), "primcount"), "count"), (GLsizei, "primcount")]),
- GlFunction(Void, "glMultiDrawElements", [(GLenum_mode, "mode"), (Array(Const(GLsizei), "primcount"), "count"), (GLenum, "type"), (Array(GLpointerConst, "primcount"), "indices"), (GLsizei, "primcount")]),
+ GlFunction(Void, "glMultiDrawArrays", [(GLenum_mode, "mode"), (Array(Const(GLint), "drawcount"), "first"), (Array(Const(GLsizei), "drawcount"), "count"), (GLsizei, "drawcount")]),
+ GlFunction(Void, "glMultiDrawElements", [(GLenum_mode, "mode"), (Array(Const(GLsizei), "drawcount"), "count"), (GLenum, "type"), (Array(Const(GLpointerConst), "drawcount"), "indices"), (GLsizei, "drawcount")]),
GlFunction(Void, "glPointParameterf", [(GLenum, "pname"), (GLfloat, "param")]),
GlFunction(Void, "glPointParameterfv", [(GLenum, "pname"), (Array(Const(GLfloat), "_gl_param_size(pname)"), "params")]),
GlFunction(Void, "glPointParameteri", [(GLenum, "pname"), (GLint, "param")]),
GlFunction(Void, "glSecondaryColor3uiv", [(Array(Const(GLuint), 3), "v")]),
GlFunction(Void, "glSecondaryColor3us", [(GLushort, "red"), (GLushort, "green"), (GLushort, "blue")]),
GlFunction(Void, "glSecondaryColor3usv", [(Array(Const(GLushort), 3), "v")]),
- GlFunction(Void, "glSecondaryColorPointer", [(GLint, "size"), (GLenum, "type"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
+ GlFunction(Void, "glSecondaryColorPointer", [(size_bgra, "size"), (GLenum, "type"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
GlFunction(Void, "glWindowPos2d", [(GLdouble, "x"), (GLdouble, "y")]),
GlFunction(Void, "glWindowPos2dv", [(Array(Const(GLdouble), 2), "v")]),
GlFunction(Void, "glWindowPos2f", [(GLfloat, "x"), (GLfloat, "y")]),
GlFunction(Void, "glStencilFuncSeparate", [(GLenum, "face"), (GLenum, "func"), (GLint, "ref"), (GLuint, "mask")]),
GlFunction(Void, "glStencilMaskSeparate", [(GLenum, "face"), (GLuint, "mask")]),
GlFunction(Void, "glAttachShader", [(GLprogram, "program"), (GLshader, "shader")]),
- GlFunction(Void, "glBindAttribLocation", [(GLprogram, "program"), (GLuint, "index"), (Const(GLstring), "name")]),
+ GlFunction(Void, "glBindAttribLocation", [(GLprogram, "program"), (GLuint, "index"), (GLstringConst, "name")]),
GlFunction(Void, "glCompileShader", [(GLshader, "shader")]),
GlFunction(GLprogram, "glCreateProgram", []),
GlFunction(GLshader, "glCreateShader", [(GLenum, "type")]),
GlFunction(Void, "glGetActiveAttrib", [(GLprogram, "program"), (GLuint, "index"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Pointer(GLint), "size"), Out(Pointer(GLenum), "type"), Out(GLstring, "name")], sideeffects=False),
GlFunction(Void, "glGetActiveUniform", [(GLprogram, "program"), (GLuint, "index"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Pointer(GLint), "size"), Out(Pointer(GLenum), "type"), Out(GLstring, "name")], sideeffects=False),
GlFunction(Void, "glGetAttachedShaders", [(GLprogram, "program"), (GLsizei, "maxCount"), Out(Pointer(GLsizei), "count"), Out(Array(GLuint, "(count ? *count : maxCount)"), "obj")], sideeffects=False),
- GlFunction(GLint, "glGetAttribLocation", [(GLprogram, "program"), (Const(GLstring), "name")]),
+ GlFunction(GLint, "glGetAttribLocation", [(GLprogram, "program"), (GLstringConst, "name")]),
GlFunction(Void, "glGetProgramiv", [(GLprogram, "program"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
GlFunction(Void, "glGetProgramInfoLog", [(GLprogram, "program"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(GLstring, "infoLog")], sideeffects=False),
GlFunction(Void, "glGetShaderiv", [(GLshader, "shader"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
GlFunction(Void, "glGetShaderInfoLog", [(GLshader, "shader"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(GLstring, "infoLog")], sideeffects=False),
- GlFunction(Void, "glGetShaderSource", [(GLshader, "shader"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(String("GLchar *", "*length"), "source")], sideeffects=False),
- GlFunction(GLlocation, "glGetUniformLocation", [(GLprogram, "program"), (Const(GLstring), "name")]),
+ GlFunction(Void, "glGetShaderSource", [(GLshader, "shader"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(String(GLchar, "*length"), "source")], sideeffects=False),
+ GlFunction(GLlocation, "glGetUniformLocation", [(GLprogram, "program"), (GLstringConst, "name")]),
GlFunction(Void, "glGetUniformfv", [(GLprogram, "program"), (GLlocation, "location"), Out(OpaquePointer(GLfloat), "params")], sideeffects=False),
GlFunction(Void, "glGetUniformiv", [(GLprogram, "program"), (GLlocation, "location"), Out(OpaquePointer(GLint), "params")], sideeffects=False),
GlFunction(Void, "glGetVertexAttribdv", [(GLuint, "index"), (GLenum, "pname"), Out(Array(GLdouble, "_gl_param_size(pname)"), "params")], sideeffects=False),
GlFunction(GLboolean, "glIsProgram", [(GLprogram, "program")], sideeffects=False),
GlFunction(GLboolean, "glIsShader", [(GLshader, "shader")], sideeffects=False),
GlFunction(Void, "glLinkProgram", [(GLprogram, "program")]),
- GlFunction(Void, "glShaderSource", [(GLshader, "shader"), (GLsizei, "count"), (Const(Array(Const(GLstringARB), "count")), "string"), (Array(Const(GLint), "count"), "length")]),
+ GlFunction(Void, "glShaderSource", [(GLshader, "shader"), (GLsizei, "count"), (Array(Const(GLstringConstARB), "count"), "string"), (Array(Const(GLint), "count"), "length")]),
GlFunction(Void, "glUseProgram", [(GLprogram, "program")]),
GlFunction(Void, "glUniform1f", [(GLlocation, "location"), (GLfloat, "v0")]),
GlFunction(Void, "glUniform2f", [(GLlocation, "location"), (GLfloat, "v0"), (GLfloat, "v1")]),
GlFunction(Void, "glVertexAttrib4ubv", [(GLuint, "index"), (Array(Const(GLubyte), 4), "v")]),
GlFunction(Void, "glVertexAttrib4uiv", [(GLuint, "index"), (Array(Const(GLuint), 4), "v")]),
GlFunction(Void, "glVertexAttrib4usv", [(GLuint, "index"), (Array(Const(GLushort), 4), "v")]),
- GlFunction(Void, "glVertexAttribPointer", [(GLuint, "index"), (GLint, "size"), (GLenum, "type"), (GLboolean, "normalized"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
+ GlFunction(Void, "glVertexAttribPointer", [(GLuint, "index"), (size_bgra, "size"), (GLenum, "type"), (GLboolean, "normalized"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
# GL_VERSION_2_1
GlFunction(Void, "glUniformMatrix2x3fv", [(GLlocation, "location"), (GLsizei, "count"), (GLboolean, "transpose"), (Array(Const(GLfloat), "count*2*3"), "value")]),
GlFunction(Void, "glEndTransformFeedback", []),
GlFunction(Void, "glBindBufferRange", [(GLenum, "target"), (GLuint, "index"), (GLbuffer, "buffer"), (GLintptr, "offset"), (GLsizeiptr, "size")]),
GlFunction(Void, "glBindBufferBase", [(GLenum, "target"), (GLuint, "index"), (GLbuffer, "buffer")]),
- GlFunction(Void, "glTransformFeedbackVaryings", [(GLprogram, "program"), (GLsizei, "count"), (Const(Array(Const(GLstring), "count")), "varyings"), (GLenum, "bufferMode")]),
+ GlFunction(Void, "glTransformFeedbackVaryings", [(GLprogram, "program"), (GLsizei, "count"), (Array(Const(GLstringConst), "count"), "varyings"), (GLenum, "bufferMode")]),
GlFunction(Void, "glGetTransformFeedbackVarying", [(GLprogram, "program"), (GLuint, "index"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Pointer(GLsizei), "size"), Out(Pointer(GLenum), "type"), Out(GLstring, "name")], sideeffects=False),
GlFunction(Void, "glClampColor", [(GLenum, "target"), (GLenum, "clamp")]),
GlFunction(Void, "glBeginConditionalRender", [(GLuint, "id"), (GLenum, "mode")]),
GlFunction(Void, "glVertexAttribI4ubv", [(GLuint, "index"), (Array(Const(GLubyte), 4), "v")]),
GlFunction(Void, "glVertexAttribI4usv", [(GLuint, "index"), (Array(Const(GLushort), 4), "v")]),
GlFunction(Void, "glGetUniformuiv", [(GLprogram, "program"), (GLlocation, "location"), Out(OpaqueArray(GLuint, "_glGetUniformuiv_size(program, location)"), "params")], sideeffects=False),
- GlFunction(Void, "glBindFragDataLocation", [(GLprogram, "program"), (GLuint, "color"), (Const(GLstring), "name")]),
- GlFunction(GLlocation, "glGetFragDataLocation", [(GLprogram, "program"), (Const(GLstring), "name")]),
+ GlFunction(Void, "glBindFragDataLocation", [(GLprogram, "program"), (GLuint, "color"), (GLstringConst, "name")]),
+ GlFunction(GLlocation, "glGetFragDataLocation", [(GLprogram, "program"), (GLstringConst, "name")]),
GlFunction(Void, "glUniform1ui", [(GLlocation, "location"), (GLuint, "v0")]),
GlFunction(Void, "glUniform2ui", [(GLlocation, "location"), (GLuint, "v0"), (GLuint, "v1")]),
GlFunction(Void, "glUniform3ui", [(GLlocation, "location"), (GLuint, "v0"), (GLuint, "v1"), (GLuint, "v2")]),
GlFunction(Void, "glClearBufferuiv", [(GLenum, "buffer"), (GLint, "drawbuffer"), (Array(Const(GLuint), "_glClearBuffer_size(buffer)"), "value")]),
GlFunction(Void, "glClearBufferfv", [(GLenum, "buffer"), (GLint, "drawbuffer"), (Array(Const(GLfloat), "_glClearBuffer_size(buffer)"), "value")]),
GlFunction(Void, "glClearBufferfi", [(GLenum, "buffer"), (GLint, "drawbuffer"), (GLfloat, "depth"), (GLint, "stencil")]),
- GlFunction(String("const GLubyte *"), "glGetStringi", [(GLenum, "name"), (GLuint, "index")], sideeffects=False),
+ GlFunction(String(Const(GLubyte)), "glGetStringi", [(GLenum, "name"), (GLuint, "index")], sideeffects=False),
# GL_VERSION_3_1
GlFunction(Void, "glDrawArraysInstanced", [(GLenum_mode, "mode"), (GLint, "first"), (GLsizei, "count"), (GLsizei, "primcount")]),
GlFunction(Void, "glVertexAttribDivisor", [(GLuint, "index"), (GLuint, "divisor")]),
# GL_VERSION_4_0
- GlFunction(Void, "glMinSampleShading", [(GLclampf, "value")]),
+ GlFunction(Void, "glMinSampleShading", [(GLfloat, "value")]),
GlFunction(Void, "glBlendEquationi", [(GLuint, "buf"), (GLenum, "mode")]),
GlFunction(Void, "glBlendEquationSeparatei", [(GLuint, "buf"), (GLenum, "modeRGB"), (GLenum, "modeAlpha")]),
GlFunction(Void, "glBlendFunci", [(GLuint, "buf"), (GLenum, "src"), (GLenum, "dst")]),
GlFunction(Void, "glMultTransposeMatrixdARB", [(Array(Const(GLdouble), 16), "m")]),
# GL_ARB_multisample
- GlFunction(Void, "glSampleCoverageARB", [(GLclampf, "value"), (GLboolean, "invert")]),
+ GlFunction(Void, "glSampleCoverageARB", [(GLfloat, "value"), (GLboolean, "invert")]),
# GL_ARB_texture_compression
GlFunction(Void, "glCompressedTexImage3DARB", [(GLenum, "target"), (GLint, "level"), (GLenum, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLsizei, "depth"), (GLint, "border"), (GLsizei, "imageSize"), (Blob(Const(GLvoid), "imageSize"), "data")]),
GlFunction(Void, "glVertexAttrib4ubvARB", [(GLuint, "index"), (Array(Const(GLubyte), 4), "v")]),
GlFunction(Void, "glVertexAttrib4uivARB", [(GLuint, "index"), (Array(Const(GLuint), 4), "v")]),
GlFunction(Void, "glVertexAttrib4usvARB", [(GLuint, "index"), (Array(Const(GLushort), 4), "v")]),
- GlFunction(Void, "glVertexAttribPointerARB", [(GLuint, "index"), (GLint, "size"), (GLenum, "type"), (GLboolean, "normalized"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
+ GlFunction(Void, "glVertexAttribPointerARB", [(GLuint, "index"), (size_bgra, "size"), (GLenum, "type"), (GLboolean, "normalized"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
GlFunction(Void, "glEnableVertexAttribArrayARB", [(GLuint, "index")]),
GlFunction(Void, "glDisableVertexAttribArrayARB", [(GLuint, "index")]),
- GlFunction(Void, "glProgramStringARB", [(GLenum, "target"), (GLenum, "format"), (GLsizei, "len"), (String("const void *", "len"), "string")]),
+ GlFunction(Void, "glProgramStringARB", [(GLenum, "target"), (GLenum, "format"), (GLsizei, "len"), (String(Const(Void), "len"), "string")]),
GlFunction(Void, "glBindProgramARB", [(GLenum, "target"), (GLprogramARB, "program")]),
GlFunction(Void, "glDeleteProgramsARB", [(GLsizei, "n"), (Array(Const(GLprogramARB), "n"), "programs")]),
GlFunction(Void, "glGenProgramsARB", [(GLsizei, "n"), Out(Array(GLprogramARB, "n"), "programs")]),
GlFunction(GLhandleARB, "glGetHandleARB", [(GLenum, "pname")], sideeffects=False),
GlFunction(Void, "glDetachObjectARB", [(GLhandleARB, "containerObj"), (GLhandleARB, "attachedObj")]),
GlFunction(GLhandleARB, "glCreateShaderObjectARB", [(GLenum, "shaderType")]),
- GlFunction(Void, "glShaderSourceARB", [(GLhandleARB, "shaderObj"), (GLsizei, "count"), (Const(Array(Const(GLstringARB), "count")), "string"), (Array(Const(GLint), "count"), "length")]),
+ GlFunction(Void, "glShaderSourceARB", [(GLhandleARB, "shaderObj"), (GLsizei, "count"), (Const(Array(GLstringConstARB, "count")), "string"), (Array(Const(GLint), "count"), "length")]),
GlFunction(Void, "glCompileShaderARB", [(GLhandleARB, "shaderObj")]),
GlFunction(GLhandleARB, "glCreateProgramObjectARB", []),
GlFunction(Void, "glAttachObjectARB", [(GLhandleARB, "containerObj"), (GLhandleARB, "obj")]),
GlFunction(Void, "glGetObjectParameterivARB", [(GLhandleARB, "obj"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
GlFunction(Void, "glGetInfoLogARB", [(GLhandleARB, "obj"), (GLsizei, "maxLength"), Out(Pointer(GLsizei), "length"), Out(GLstringARB, "infoLog")], sideeffects=False),
GlFunction(Void, "glGetAttachedObjectsARB", [(GLhandleARB, "containerObj"), (GLsizei, "maxCount"), Out(Pointer(GLsizei), "count"), Out(Array(GLhandleARB, "(count ? *count : maxCount)"), "obj")], sideeffects=False),
- GlFunction(GLlocationARB, "glGetUniformLocationARB", [(GLhandleARB, "programObj"), (Const(GLstringARB), "name")]),
+ GlFunction(GLlocationARB, "glGetUniformLocationARB", [(GLhandleARB, "programObj"), (GLstringConstARB, "name")]),
GlFunction(Void, "glGetActiveUniformARB", [(GLhandleARB, "programObj"), (GLuint, "index"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Pointer(GLint), "size"), Out(Pointer(GLenum), "type"), Out(GLstringARB, "name")], sideeffects=False),
GlFunction(Void, "glGetUniformfvARB", [(GLhandleARB, "programObj"), (GLlocationARB, "location"), Out(OpaquePointer(GLfloat), "params")], sideeffects=False),
GlFunction(Void, "glGetUniformivARB", [(GLhandleARB, "programObj"), (GLlocationARB, "location"), Out(OpaquePointer(GLint), "params")], sideeffects=False),
GlFunction(Void, "glGetShaderSourceARB", [(GLhandleARB, "obj"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(GLstringARB, "source")], sideeffects=False),
# GL_ARB_vertex_shader
- GlFunction(Void, "glBindAttribLocationARB", [(GLhandleARB, "programObj"), (GLuint, "index"), (Const(GLstringARB), "name")]),
+ GlFunction(Void, "glBindAttribLocationARB", [(GLhandleARB, "programObj"), (GLuint, "index"), (GLstringConstARB, "name")]),
GlFunction(Void, "glGetActiveAttribARB", [(GLhandleARB, "programObj"), (GLuint, "index"), (GLsizei, "maxLength"), Out(Pointer(GLsizei), "length"), Out(Pointer(GLint), "size"), Out(Pointer(GLenum), "type"), Out(GLstringARB, "name")], sideeffects=False),
- GlFunction(GLint, "glGetAttribLocationARB", [(GLhandleARB, "programObj"), (Const(GLstringARB), "name")]),
+ GlFunction(GLint, "glGetAttribLocationARB", [(GLhandleARB, "programObj"), (GLstringConstARB, "name")]),
# GL_ARB_draw_buffers
GlFunction(Void, "glDrawBuffersARB", [(GLsizei, "n"), (Array(Const(GLenum), "n"), "bufs")]),
GlFunction(GLboolean, "glIsVertexArray", [(GLarray, "array")], sideeffects=False),
# GL_ARB_uniform_buffer_object
- GlFunction(Void, "glGetUniformIndices", [(GLprogram, "program"), (GLsizei, "uniformCount"), (Array(Const(GLstring), "uniformCount"), "uniformNames"), Out(Array(GLuint, "uniformCount"), "uniformIndices")], sideeffects=False),
+ GlFunction(Void, "glGetUniformIndices", [(GLprogram, "program"), (GLsizei, "uniformCount"), (Array(Const(GLstringConst), "uniformCount"), "uniformNames"), Out(Array(GLuint, "uniformCount"), "uniformIndices")], sideeffects=False),
GlFunction(Void, "glGetActiveUniformsiv", [(GLprogram, "program"), (GLsizei, "uniformCount"), (Array(Const(GLuint), "uniformCount"), "uniformIndices"), (GLenum, "pname"), Out(OpaqueArray(GLint, "_glGetActiveUniformsiv_size(pname)"), "params")], sideeffects=False),
GlFunction(Void, "glGetActiveUniformName", [(GLprogram, "program"), (GLuint, "uniformIndex"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Array(GLchar, "bufSize"), "uniformName")], sideeffects=False),
- GlFunction(GLuint, "glGetUniformBlockIndex", [(GLprogram, "program"), (Const(GLstring), "uniformBlockName")]),
+ GlFunction(GLuint, "glGetUniformBlockIndex", [(GLprogram, "program"), (GLstringConst, "uniformBlockName")]),
GlFunction(Void, "glGetActiveUniformBlockiv", [(GLprogram, "program"), (GLuint, "uniformBlockIndex"), (GLenum, "pname"), Out(OpaqueArray(GLint, "_glGetActiveUniformBlockiv_size(pname)"), "params")], sideeffects=False),
GlFunction(Void, "glGetActiveUniformBlockName", [(GLprogram, "program"), (GLuint, "uniformBlockIndex"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Array(GLchar, "bufSize"), "uniformBlockName")], sideeffects=False),
GlFunction(Void, "glUniformBlockBinding", [(GLprogram, "program"), (GLuint, "uniformBlockIndex"), (GLuint, "uniformBlockBinding")]),
GlFunction(Void, "glDrawElementsBaseVertex", [(GLenum_mode, "mode"), (GLsizei, "count"), (GLenum, "type"), (GLpointerConst, "indices"), (GLint, "basevertex")]),
GlFunction(Void, "glDrawRangeElementsBaseVertex", [(GLenum_mode, "mode"), (GLuint, "start"), (GLuint, "end"), (GLsizei, "count"), (GLenum, "type"), (GLpointerConst, "indices"), (GLint, "basevertex")]),
GlFunction(Void, "glDrawElementsInstancedBaseVertex", [(GLenum_mode, "mode"), (GLsizei, "count"), (GLenum, "type"), (GLpointerConst, "indices"), (GLsizei, "primcount"), (GLint, "basevertex")]),
- GlFunction(Void, "glMultiDrawElementsBaseVertex", [(GLenum_mode, "mode"), (Array(Const(GLsizei), "primcount"), "count"), (GLenum, "type"), (Array(GLpointerConst, "primcount"), "indices"), (GLsizei, "primcount"), (Array(Const(GLint), "primcount"), "basevertex")]),
+ GlFunction(Void, "glMultiDrawElementsBaseVertex", [(GLenum_mode, "mode"), (Array(Const(GLsizei), "drawcount"), "count"), (GLenum, "type"), (Array(Const(GLpointerConst), "drawcount"), "indices"), (GLsizei, "drawcount"), (Array(Const(GLint), "drawcount"), "basevertex")]),
# GL_ARB_provoking_vertex
GlFunction(Void, "glProvokingVertex", [(GLenum, "mode")]),
GlFunction(Void, "glBlendFuncSeparateiARB", [(GLuint, "buf"), (GLenum, "srcRGB"), (GLenum, "dstRGB"), (GLenum, "srcAlpha"), (GLenum, "dstAlpha")]),
# GL_ARB_sample_shading
- GlFunction(Void, "glMinSampleShadingARB", [(GLclampf, "value")]),
+ GlFunction(Void, "glMinSampleShadingARB", [(GLfloat, "value")]),
# GL_ARB_shading_language_include
- GlFunction(Void, "glNamedStringARB", [(GLenum, "type"), (GLint, "namelen"), (Const(String('GLchar *', "namelen")), "name"), (GLint, "stringlen"), (Const(String('GLchar *', "stringlen")), "string")]),
- GlFunction(Void, "glDeleteNamedStringARB", [(GLint, "namelen"), (Const(String('GLchar *', "namelen")), "name")]),
- GlFunction(Void, "glCompileShaderIncludeARB", [(GLshader, "shader"), (GLsizei, "count"), (Array(String("const GLchar *"), "count"), "path"), (Array(Const(GLint), "count"), "length")]),
- GlFunction(GLboolean, "glIsNamedStringARB", [(GLint, "namelen"), (Const(String('GLchar *', "namelen")), "name")], sideeffects=False),
- GlFunction(Void, "glGetNamedStringARB", [(GLint, "namelen"), (Const(String('GLchar *', "namelen")), "name"), (GLsizei, "bufSize"), Out(Pointer(GLint), "stringlen"), Out(Array(GLchar, "bufSize"), "string")], sideeffects=False),
- GlFunction(Void, "glGetNamedStringivARB", [(GLint, "namelen"), (Const(String('GLchar *', "namelen")), "name"), (GLenum, "pname"), Out(OpaqueArray(GLint, "_glGetNamedStringivARB_size(pname)"), "params")], sideeffects=False),
+ GlFunction(Void, "glNamedStringARB", [(GLenum, "type"), (GLint, "namelen"), (String(Const(GLchar), "namelen"), "name"), (GLint, "stringlen"), (String(Const(GLchar), "stringlen"), "string")]),
+ GlFunction(Void, "glDeleteNamedStringARB", [(GLint, "namelen"), (String(Const(GLchar), "namelen"), "name")]),
+ GlFunction(Void, "glCompileShaderIncludeARB", [(GLshader, "shader"), (GLsizei, "count"), (Array(String(Const(GLchar)), "count"), "path"), (Array(Const(GLint), "count"), "length")]),
+ GlFunction(GLboolean, "glIsNamedStringARB", [(GLint, "namelen"), (String(Const(GLchar), "namelen"), "name")], sideeffects=False),
+ GlFunction(Void, "glGetNamedStringARB", [(GLint, "namelen"), (String(Const(GLchar), "namelen"), "name"), (GLsizei, "bufSize"), Out(Pointer(GLint), "stringlen"), Out(Array(GLchar, "bufSize"), "string")], sideeffects=False),
+ GlFunction(Void, "glGetNamedStringivARB", [(GLint, "namelen"), (String(Const(GLchar), "namelen"), "name"), (GLenum, "pname"), Out(OpaqueArray(GLint, "_glGetNamedStringivARB_size(pname)"), "params")], sideeffects=False),
# GL_ARB_blend_func_extended
- GlFunction(Void, "glBindFragDataLocationIndexed", [(GLprogram, "program"), (GLuint, "colorNumber"), (GLuint, "index"), (Const(GLstring), "name")]),
- GlFunction(GLint, "glGetFragDataIndex", [(GLprogram, "program"), (Const(GLstring), "name")], sideeffects=False),
+ GlFunction(Void, "glBindFragDataLocationIndexed", [(GLprogram, "program"), (GLuint, "colorNumber"), (GLuint, "index"), (GLstringConst, "name")]),
+ GlFunction(GLint, "glGetFragDataIndex", [(GLprogram, "program"), (GLstringConst, "name")], sideeffects=False),
# GL_ARB_sampler_objects
GlFunction(Void, "glGenSamplers", [(GLsizei, "count"), Out(Array(GLsampler, "count"), "samplers")]),
GlFunction(Void, "glGetUniformdv", [(GLprogram, "program"), (GLlocation, "location"), Out(OpaqueArray(GLdouble, "_glGetUniformdv_size(location)"), "params")], sideeffects=False),
# GL_ARB_shader_subroutine
- GlFunction(GLlocation, "glGetSubroutineUniformLocation", [(GLprogram, "program"), (GLenum, "shadertype"), (Const(GLstring), "name")]),
- GlFunction(GLuint, "glGetSubroutineIndex", [(GLprogram, "program"), (GLenum, "shadertype"), (Const(GLstring), "name")]),
+ GlFunction(GLlocation, "glGetSubroutineUniformLocation", [(GLprogram, "program"), (GLenum, "shadertype"), (GLstringConst, "name")]),
+ GlFunction(GLuint, "glGetSubroutineIndex", [(GLprogram, "program"), (GLenum, "shadertype"), (GLstringConst, "name")]),
GlFunction(Void, "glGetActiveSubroutineUniformiv", [(GLprogram, "program"), (GLenum, "shadertype"), (GLuint, "index"), (GLenum, "pname"), Out(OpaqueArray(GLint, "_glGetActiveSubroutineUniformiv_size(pname)"), "values")], sideeffects=False),
GlFunction(Void, "glGetActiveSubroutineUniformName", [(GLprogram, "program"), (GLenum, "shadertype"), (GLuint, "index"), (GLsizei, "bufsize"), Out(Pointer(GLsizei), "length"), Out(Array(GLchar, "bufsize"), "name")], sideeffects=False),
GlFunction(Void, "glGetActiveSubroutineName", [(GLprogram, "program"), (GLenum, "shadertype"), (GLuint, "index"), (GLsizei, "bufsize"), Out(Pointer(GLsizei), "length"), Out(Array(GLchar, "bufsize"), "name")], sideeffects=False),
GlFunction(Void, "glReleaseShaderCompiler", []),
GlFunction(Void, "glShaderBinary", [(GLsizei, "count"), (Array(Const(GLuint), "count"), "shaders"), (GLenum, "binaryformat"), (Blob(Const(GLvoid), "length"), "binary"), (GLsizei, "length")]),
GlFunction(Void, "glGetShaderPrecisionFormat", [(GLenum, "shadertype"), (GLenum, "precisiontype"), Out(Array(GLint, 2), "range"), Out(Array(GLint, 2), "precision")], sideeffects=False),
- GlFunction(Void, "glDepthRangef", [(GLclampf, "n"), (GLclampf, "f")]),
- GlFunction(Void, "glClearDepthf", [(GLclampf, "d")]),
+ GlFunction(Void, "glDepthRangef", [(GLfloat, "n"), (GLfloat, "f")]),
+ GlFunction(Void, "glClearDepthf", [(GLfloat, "d")]),
# GL_ARB_get_program_binary
GlFunction(Void, "glGetProgramBinary", [(GLprogram, "program"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Pointer(GLenum), "binaryFormat"), Out(OpaqueArray(GLvoid, "_glGetProgramBinary_size(length)"), "binary")], sideeffects=False),
# GL_ARB_separate_shader_objects
GlFunction(Void, "glUseProgramStages", [(GLpipeline, "pipeline"), (GLbitfield_shader, "stages"), (GLprogram, "program")]),
GlFunction(Void, "glActiveShaderProgram", [(GLpipeline, "pipeline"), (GLprogram, "program")]),
- GlFunction(GLprogram, "glCreateShaderProgramv", [(GLenum, "type"), (GLsizei, "count"), (Const(Array(Const(GLstring), "count")), "strings")]),
+ GlFunction(GLprogram, "glCreateShaderProgramv", [(GLenum, "type"), (GLsizei, "count"), (Array(Const(GLstringConst), "count"), "strings")]),
GlFunction(Void, "glBindProgramPipeline", [(GLpipeline, "pipeline")]),
GlFunction(Void, "glDeleteProgramPipelines", [(GLsizei, "n"), (Array(Const(GLuint), "n"), "pipelines")]),
GlFunction(Void, "glGenProgramPipelines", [(GLsizei, "n"), Out(Array(GLpipeline, "n"), "pipelines")]),
GlFunction(Void, "glScissorArrayv", [(GLuint, "first"), (GLsizei, "count"), (Array(Const(GLint), "count*4"), "v")]),
GlFunction(Void, "glScissorIndexed", [(GLuint, "index"), (GLint, "left"), (GLint, "bottom"), (GLsizei, "width"), (GLsizei, "height")]),
GlFunction(Void, "glScissorIndexedv", [(GLuint, "index"), (Array(Const(GLint), 4), "v")]),
- GlFunction(Void, "glDepthRangeArrayv", [(GLuint, "first"), (GLsizei, "count"), (Array(Const(GLclampd), "count*2"), "v")]),
- GlFunction(Void, "glDepthRangeIndexed", [(GLuint, "index"), (GLclampd, "n"), (GLclampd, "f")]),
+ GlFunction(Void, "glDepthRangeArrayv", [(GLuint, "first"), (GLsizei, "count"), (Array(Const(GLdouble), "count*2"), "v")]),
+ GlFunction(Void, "glDepthRangeIndexed", [(GLuint, "index"), (GLdouble, "n"), (GLdouble, "f")]),
GlFunction(Void, "glGetFloati_v", [(GLenum, "target"), (GLuint, "index"), Out(Array(GLfloat, "_gl_param_size(target)"), "data")], sideeffects=False),
GlFunction(Void, "glGetDoublei_v", [(GLenum, "target"), (GLuint, "index"), Out(Array(GLdouble, "_gl_param_size(target)"), "data")], sideeffects=False),
# GL_ARB_debug_output
GlFunction(Void, "glDebugMessageControlARB", [(GLenum, "source"), (GLenum, "type"), (GLenum, "severity"), (GLsizei, "count"), (Array(Const(GLuint), "count"), "ids"), (GLboolean, "enabled")], sideeffects=False),
- GlFunction(Void, "glDebugMessageInsertARB", [(GLenum, "source"), (GLenum, "type"), (GLuint, "id"), (GLenum, "severity"), (GLsizei, "length"), (Const(String("GLchar *", "length")), "buf")], sideeffects=False),
+ GlFunction(Void, "glDebugMessageInsertARB", [(GLenum, "source"), (GLenum, "type"), (GLuint, "id"), (GLenum, "severity"), (GLsizei, "length"), (String(Const(GLchar), "length"), "buf")], sideeffects=False),
GlFunction(Void, "glDebugMessageCallbackARB", [(GLDEBUGPROCARB, "callback"), (GLpointerConst, "userParam")], sideeffects=False),
GlFunction(GLuint, "glGetDebugMessageLogARB", [(GLuint, "count"), (GLsizei, "bufsize"), Out(Array(GLenum, "count"), "sources"), Out(Array(GLenum, "count"), "types"), Out(Array(GLuint, "count"), "ids"), Out(Array(GLenum, "count"), "severities"), Out(Array(GLsizei, "count"), "lengths"), Out(GLstring, "messageLog")], sideeffects=False),
GlFunction(Void, "glTextureStorage2DEXT", [(GLtexture, "texture"), (GLenum, "target"), (GLsizei, "levels"), (GLenum, "internalformat"), (GLsizei, "width"), (GLsizei, "height")]),
GlFunction(Void, "glTextureStorage3DEXT", [(GLtexture, "texture"), (GLenum, "target"), (GLsizei, "levels"), (GLenum, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLsizei, "depth")]),
+ # GL_KHR_debug
+ GlFunction(Void, "glDebugMessageControl", [(GLenum, "source"), (GLenum, "type"), (GLenum, "severity"), (GLsizei, "count"), (Array(Const(GLuint), "count"), "ids"), (GLboolean, "enabled")], sideeffects=False),
+ GlFunction(Void, "glDebugMessageInsert", [(GLenum, "source"), (GLenum, "type"), (GLuint, "id"), (GLenum, "severity"), (GLsizei, "length"), (OpaqueArray(Const(GLchar), "_glDebugMessageInsert_size(buf, length)"), "buf")], sideeffects=False),
+ GlFunction(Void, "glDebugMessageCallback", [(GLDEBUGPROC, "callback"), (OpaquePointer(Const(Void)), "userParam")], sideeffects=False),
+ GlFunction(GLuint, "glGetDebugMessageLog", [(GLuint, "count"), (GLsizei, "bufsize"), Out(OpaqueArray(GLenum, "_glGetDebugMessageLog_size(count)"), "sources"), Out(OpaqueArray(GLenum, "_glGetDebugMessageLog_size(count)"), "types"), Out(OpaqueArray(GLuint, "_glGetDebugMessageLog_size(count)"), "ids"), Out(OpaqueArray(GLenum, "_glGetDebugMessageLog_size(count)"), "severities"), Out(OpaqueArray(GLsizei, "_glGetDebugMessageLog_size(count)"), "lengths"), Out(OpaqueArray(GLchar, "_glGetDebugMessageLog_size(bufsize)"), "messageLog")], sideeffects=False),
+ GlFunction(Void, "glPushDebugGroup", [(GLenum, "source"), (GLuint, "id"), (GLsizei, "length"), (OpaqueArray(Const(GLchar), "_glPushDebugGroup_size(message, length)"), "message")], sideeffects=False),
+ GlFunction(Void, "glPopDebugGroup", [], sideeffects=False),
+ GlFunction(Void, "glObjectLabel", [(GLenum, "identifier"), (GLuint, "name"), (GLsizei, "length"), (OpaqueArray(Const(GLchar), "_glObjectLabel_size(label, length)"), "label")], sideeffects=False),
+ GlFunction(Void, "glGetObjectLabel", [(GLenum, "identifier"), (GLuint, "name"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Array(GLchar, "bufSize"), "label")], sideeffects=False),
+ GlFunction(Void, "glObjectPtrLabel", [(OpaquePointer(Const(Void)), "ptr"), (GLsizei, "length"), (OpaqueArray(Const(GLchar), "_glObjectPtrLabel_size(label, length)"), "label")], sideeffects=False),
+ GlFunction(Void, "glGetObjectPtrLabel", [(OpaquePointer(Const(Void)), "ptr"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Array(GLchar, "bufSize"), "label")], sideeffects=False),
+
+ # GL_ARB_clear_buffer_object
+ GlFunction(Void, "glClearBufferData", [(GLenum, "target"), (GLenum, "internalformat"), (GLenum, "format"), (GLenum, "type"), (OpaqueArray(Const(Void), "_glClearBufferData_size(format, type)"), "data")]),
+ GlFunction(Void, "glClearBufferSubData", [(GLenum, "target"), (GLenum, "internalformat"), (GLintptr, "offset"), (GLsizeiptr, "size"), (GLenum, "format"), (GLenum, "type"), (OpaqueArray(Const(Void), "_glClearBufferSubData_size(format, type)"), "data")]),
+ GlFunction(Void, "glClearNamedBufferDataEXT", [(GLbuffer, "buffer"), (GLenum, "internalformat"), (GLenum, "format"), (GLenum, "type"), (OpaqueArray(Const(Void), "_glClearNamedBufferDataEXT_size(format, type)"), "data")]),
+ GlFunction(Void, "glClearNamedBufferSubDataEXT", [(GLbuffer, "buffer"), (GLenum, "internalformat"), (GLenum, "format"), (GLenum, "type"), (GLsizeiptr, "offset"), (GLsizeiptr, "size"), (OpaqueArray(Const(Void), "_glClearNamedBufferSubDataEXT_size(format, type)"), "data")]),
+
+ # GL_ARB_compute_shader
+ GlFunction(Void, "glDispatchCompute", [(GLuint, "num_groups_x"), (GLuint, "num_groups_y"), (GLuint, "num_groups_z")]),
+ GlFunction(Void, "glDispatchComputeIndirect", [(GLintptr, "indirect")]),
+
+ # GL_ARB_copy_image
+ GlFunction(Void, "glCopyImageSubData", [(GLuint, "srcName"), (GLenum, "srcTarget"), (GLint, "srcLevel"), (GLint, "srcX"), (GLint, "srcY"), (GLint, "srcZ"), (GLuint, "dstName"), (GLenum, "dstTarget"), (GLint, "dstLevel"), (GLint, "dstX"), (GLint, "dstY"), (GLint, "dstZ"), (GLsizei, "srcWidth"), (GLsizei, "srcHeight"), (GLsizei, "srcDepth")]),
+
+ # GL_ARB_framebuffer_no_attachments
+ GlFunction(Void, "glFramebufferParameteri", [(GLenum, "target"), (GLenum, "pname"), (GLint, "param")]),
+ GlFunction(Void, "glGetFramebufferParameteriv", [(GLenum, "target"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
+ GlFunction(Void, "glNamedFramebufferParameteriEXT", [(GLuint, "framebuffer"), (GLenum, "pname"), (GLint, "param")]),
+ GlFunction(Void, "glGetNamedFramebufferParameterivEXT", [(GLuint, "framebuffer"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
+
+ # GL_ARB_internalformat_query2
+ GlFunction(Void, "glGetInternalformati64v", [(GLenum, "target"), (GLenum, "internalformat"), (GLenum, "pname"), (GLsizei, "bufSize"), Out(Array(GLint64, "bufSize"), "params")], sideeffects=False),
+
+ # GL_ARB_invalidate_subdata
+ GlFunction(Void, "glInvalidateTexSubImage", [(GLtexture, "texture"), (GLint, "level"), (GLint, "xoffset"), (GLint, "yoffset"), (GLint, "zoffset"), (GLsizei, "width"), (GLsizei, "height"), (GLsizei, "depth")]),
+ GlFunction(Void, "glInvalidateTexImage", [(GLtexture, "texture"), (GLint, "level")]),
+ GlFunction(Void, "glInvalidateBufferSubData", [(GLuint, "buffer"), (GLintptr, "offset"), (GLsizeiptr, "length")]),
+ GlFunction(Void, "glInvalidateBufferData", [(GLbuffer, "buffer")]),
+ GlFunction(Void, "glInvalidateFramebuffer", [(GLenum, "target"), (GLsizei, "numAttachments"), (Array(Const(GLenum), "numAttachments"), "attachments")]),
+ GlFunction(Void, "glInvalidateSubFramebuffer", [(GLenum, "target"), (GLsizei, "numAttachments"), (Array(Const(GLenum), "numAttachments"), "attachments"), (GLint, "x"), (GLint, "y"), (GLsizei, "width"), (GLsizei, "height")]),
+
+ # GL_ARB_multi_draw_indirect
+ GlFunction(Void, "glMultiDrawArraysIndirect", [(GLenum, "mode"), (OpaqueArray(Const(Void), "_glMultiDrawArraysIndirect_size(drawcount, stride)"), "indirect"), (GLsizei, "drawcount"), (GLsizei, "stride")]),
+ GlFunction(Void, "glMultiDrawElementsIndirect", [(GLenum, "mode"), (GLenum, "type"), (OpaqueArray(Const(Void), "_glMultiDrawElementsIndirect_size(drawcount, stride)"), "indirect"), (GLsizei, "drawcount"), (GLsizei, "stride")]),
+
+ # GL_ARB_program_interface_query
+ GlFunction(Void, "glGetProgramInterfaceiv", [(GLprogram, "program"), (GLenum, "programInterface"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
+ GlFunction(GLuint, "glGetProgramResourceIndex", [(GLprogram, "program"), (GLenum, "programInterface"), (OpaqueArray(Const(GLchar), "_glGetProgramResourceIndex_size(name)"), "name")], sideeffects=False),
+ GlFunction(Void, "glGetProgramResourceName", [(GLprogram, "program"), (GLenum, "programInterface"), (GLuint, "index"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Array(GLchar, "bufSize"), "name")], sideeffects=False),
+ GlFunction(Void, "glGetProgramResourceiv", [(GLprogram, "program"), (GLenum, "programInterface"), (GLuint, "index"), (GLsizei, "propCount"), (Array(Const(GLenum), "propCount"), "props"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Array(GLint, "bufSize"), "params")], sideeffects=False),
+ GlFunction(GLlocation, "glGetProgramResourceLocation", [(GLprogram, "program"), (GLenum, "programInterface"), (GLstringConst, "name")], sideeffects=False),
+ GlFunction(GLlocation, "glGetProgramResourceLocationIndex", [(GLprogram, "program"), (GLenum, "programInterface"), (GLstringConst, "name")], sideeffects=False),
+
+ # GL_ARB_shader_storage_buffer_object
+ GlFunction(Void, "glShaderStorageBlockBinding", [(GLprogram, "program"), (GLuint, "storageBlockIndex"), (GLuint, "storageBlockBinding")]),
+
+ # GL_ARB_texture_buffer_range
+ GlFunction(Void, "glTexBufferRange", [(GLenum, "target"), (GLenum, "internalformat"), (GLuint, "buffer"), (GLintptr, "offset"), (GLsizeiptr, "size")]),
+ GlFunction(Void, "glTextureBufferRangeEXT", [(GLtexture, "texture"), (GLenum, "target"), (GLenum, "internalformat"), (GLuint, "buffer"), (GLintptr, "offset"), (GLsizeiptr, "size")]),
+
+ # GL_ARB_texture_storage_multisample
+ GlFunction(Void, "glTexStorage2DMultisample", [(GLenum, "target"), (GLsizei, "samples"), (GLenum, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLboolean, "fixedsamplelocations")]),
+ GlFunction(Void, "glTexStorage3DMultisample", [(GLenum, "target"), (GLsizei, "samples"), (GLenum, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLsizei, "depth"), (GLboolean, "fixedsamplelocations")]),
+ GlFunction(Void, "glTextureStorage2DMultisampleEXT", [(GLtexture, "texture"), (GLenum, "target"), (GLsizei, "samples"), (GLenum, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLboolean, "fixedsamplelocations")]),
+ GlFunction(Void, "glTextureStorage3DMultisampleEXT", [(GLtexture, "texture"), (GLenum, "target"), (GLsizei, "samples"), (GLenum, "internalformat"), (GLsizei, "width"), (GLsizei, "height"), (GLsizei, "depth"), (GLboolean, "fixedsamplelocations")]),
+
+ # GL_ARB_texture_view
+ GlFunction(Void, "glTextureView", [(GLtexture, "texture"), (GLenum, "target"), (GLtexture, "origtexture"), (GLenum, "internalformat"), (GLuint, "minlevel"), (GLuint, "numlevels"), (GLuint, "minlayer"), (GLuint, "numlayers")]),
+
+ # GL_ARB_vertex_attrib_binding
+ GlFunction(Void, "glBindVertexBuffer", [(GLuint, "bindingindex"), (GLbuffer, "buffer"), (GLintptr, "offset"), (GLsizei, "stride")]),
+ GlFunction(Void, "glVertexAttribFormat", [(GLuint, "attribindex"), (GLint, "size"), (GLenum, "type"), (GLboolean, "normalized"), (GLuint, "relativeoffset")]),
+ GlFunction(Void, "glVertexAttribIFormat", [(GLuint, "attribindex"), (GLint, "size"), (GLenum, "type"), (GLuint, "relativeoffset")]),
+ GlFunction(Void, "glVertexAttribLFormat", [(GLuint, "attribindex"), (GLint, "size"), (GLenum, "type"), (GLuint, "relativeoffset")]),
+ GlFunction(Void, "glVertexAttribBinding", [(GLuint, "attribindex"), (GLuint, "bindingindex")]),
+ GlFunction(Void, "glVertexBindingDivisor", [(GLuint, "bindingindex"), (GLuint, "divisor")]),
+ GlFunction(Void, "glVertexArrayBindVertexBufferEXT", [(GLarray, "vaobj"), (GLuint, "bindingindex"), (GLbuffer, "buffer"), (GLintptr, "offset"), (GLsizei, "stride")]),
+ GlFunction(Void, "glVertexArrayVertexAttribFormatEXT", [(GLarray, "vaobj"), (GLuint, "attribindex"), (GLint, "size"), (GLenum, "type"), (GLboolean, "normalized"), (GLuint, "relativeoffset")]),
+ GlFunction(Void, "glVertexArrayVertexAttribIFormatEXT", [(GLarray, "vaobj"), (GLuint, "attribindex"), (GLint, "size"), (GLenum, "type"), (GLuint, "relativeoffset")]),
+ GlFunction(Void, "glVertexArrayVertexAttribLFormatEXT", [(GLarray, "vaobj"), (GLuint, "attribindex"), (GLint, "size"), (GLenum, "type"), (GLuint, "relativeoffset")]),
+ GlFunction(Void, "glVertexArrayVertexAttribBindingEXT", [(GLarray, "vaobj"), (GLuint, "attribindex"), (GLuint, "bindingindex")]),
+ GlFunction(Void, "glVertexArrayVertexBindingDivisorEXT", [(GLarray, "vaobj"), (GLuint, "bindingindex"), (GLuint, "divisor")]),
+
# GL_EXT_blend_color
- GlFunction(Void, "glBlendColorEXT", [(GLclampf, "red"), (GLclampf, "green"), (GLclampf, "blue"), (GLclampf, "alpha")]),
+ GlFunction(Void, "glBlendColorEXT", [(GLfloat, "red"), (GLfloat, "green"), (GLfloat, "blue"), (GLfloat, "alpha")]),
# GL_EXT_polygon_offset
GlFunction(Void, "glPolygonOffsetEXT", [(GLfloat, "factor"), (GLfloat, "bias")]),
# GL_EXT_vertex_array
GlFunction(Void, "glArrayElementEXT", [(GLint, "i")]),
- GlFunction(Void, "glColorPointerEXT", [(GLint, "size"), (GLenum, "type"), (GLsizei, "stride"), (GLsizei, "count"), (GLpointerConst, "pointer")]),
+ GlFunction(Void, "glColorPointerEXT", [(size_bgra, "size"), (GLenum, "type"), (GLsizei, "stride"), (GLsizei, "count"), (GLpointerConst, "pointer")]),
GlFunction(Void, "glDrawArraysEXT", [(GLenum_mode, "mode"), (GLint, "first"), (GLsizei, "count")]),
GlFunction(Void, "glEdgeFlagPointerEXT", [(GLsizei, "stride"), (GLsizei, "count"), (OpaquePointer(Const(GLboolean)), "pointer")]),
GlFunction(Void, "glGetPointervEXT", [(GLenum, "pname"), Out(Pointer(GLpointer), "params")], sideeffects=False),
# GL_INTEL_parallel_arrays
GlFunction(Void, "glVertexPointervINTEL", [(GLint, "size"), (GLenum, "type"), (OpaqueArray(GLpointerConst, "size"), "pointer")]),
GlFunction(Void, "glNormalPointervINTEL", [(GLenum, "type"), (OpaqueArray(GLpointerConst, "size"), "pointer")]),
- GlFunction(Void, "glColorPointervINTEL", [(GLint, "size"), (GLenum, "type"), (OpaqueArray(GLpointerConst, "size"), "pointer")]),
+ GlFunction(Void, "glColorPointervINTEL", [(size_bgra, "size"), (GLenum, "type"), (OpaqueArray(GLpointerConst, "size"), "pointer")]),
GlFunction(Void, "glTexCoordPointervINTEL", [(GLint, "size"), (GLenum, "type"), (OpaqueArray(GLpointerConst, "size"), "pointer")]),
# GL_EXT_pixel_transform
GlFunction(Void, "glSecondaryColor3uivEXT", [(Array(Const(GLuint), 3), "v")]),
GlFunction(Void, "glSecondaryColor3usEXT", [(GLushort, "red"), (GLushort, "green"), (GLushort, "blue")]),
GlFunction(Void, "glSecondaryColor3usvEXT", [(Array(Const(GLushort), 3), "v")]),
- GlFunction(Void, "glSecondaryColorPointerEXT", [(GLint, "size"), (GLenum, "type"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
+ GlFunction(Void, "glSecondaryColorPointerEXT", [(size_bgra, "size"), (GLenum, "type"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
# GL_EXT_texture_perturb_normal
GlFunction(Void, "glTextureNormalEXT", [(GLenum, "mode")]),
GlFunction(Void, "glMultiModeDrawElementsIBM", [(Array(Const(GLenum), "primcount"), "mode"), (Array(Const(GLsizei), "primcount"), "count"), (GLenum, "type"), (Array(Const(GLpointerConst), "primcount"), "indices"), (GLsizei, "primcount"), (GLint, "modestride")]),
# GL_IBM_vertex_array_lists
- GlFunction(Void, "glColorPointerListIBM", [(GLint, "size"), (GLenum, "type"), (GLint, "stride"), (OpaquePointer(GLpointerConst), "pointer"), (GLint, "ptrstride")]),
- GlFunction(Void, "glSecondaryColorPointerListIBM", [(GLint, "size"), (GLenum, "type"), (GLint, "stride"), (OpaquePointer(GLpointerConst), "pointer"), (GLint, "ptrstride")]),
+ GlFunction(Void, "glColorPointerListIBM", [(size_bgra, "size"), (GLenum, "type"), (GLint, "stride"), (OpaquePointer(GLpointerConst), "pointer"), (GLint, "ptrstride")]),
+ GlFunction(Void, "glSecondaryColorPointerListIBM", [(size_bgra, "size"), (GLenum, "type"), (GLint, "stride"), (OpaquePointer(GLpointerConst), "pointer"), (GLint, "ptrstride")]),
GlFunction(Void, "glEdgeFlagPointerListIBM", [(GLint, "stride"), (OpaquePointer(Opaque("const GLboolean *")), "pointer"), (GLint, "ptrstride")]),
GlFunction(Void, "glFogCoordPointerListIBM", [(GLenum, "type"), (GLint, "stride"), (OpaquePointer(GLpointerConst), "pointer"), (GLint, "ptrstride")]),
GlFunction(Void, "glIndexPointerListIBM", [(GLenum, "type"), (GLint, "stride"), (OpaquePointer(GLpointerConst), "pointer"), (GLint, "ptrstride")]),
GlFunction(Void, "glIglooInterfaceSGIX", [(GLenum, "pname"), (OpaqueBlob(Const(GLvoid), "_glIglooInterfaceSGIX_size(pname)"), "params")]),
# GL_NV_fence
- GlFunction(Void, "glDeleteFencesNV", [(GLsizei, "n"), (Array(Const(GLuint), "n"), "fences")]),
- GlFunction(Void, "glGenFencesNV", [(GLsizei, "n"), Out(Array(GLuint, "n"), "fences")]),
- GlFunction(GLboolean, "glIsFenceNV", [(GLuint, "fence")], sideeffects=False),
- GlFunction(GLboolean, "glTestFenceNV", [(GLuint, "fence")]),
- GlFunction(Void, "glGetFenceivNV", [(GLuint, "fence"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
- GlFunction(Void, "glFinishFenceNV", [(GLuint, "fence")]),
- GlFunction(Void, "glSetFenceNV", [(GLuint, "fence"), (GLenum, "condition")]),
+ GlFunction(Void, "glDeleteFencesNV", [(GLsizei, "n"), (Array(Const(GLfence), "n"), "fences")]),
+ GlFunction(Void, "glGenFencesNV", [(GLsizei, "n"), Out(Array(GLfence, "n"), "fences")]),
+ GlFunction(GLboolean, "glIsFenceNV", [(GLfence, "fence")], sideeffects=False),
+ GlFunction(GLboolean, "glTestFenceNV", [(GLfence, "fence")]),
+ GlFunction(Void, "glGetFenceivNV", [(GLfence, "fence"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
+ GlFunction(Void, "glFinishFenceNV", [(GLfence, "fence")]),
+ GlFunction(Void, "glSetFenceNV", [(GLfence, "fence"), (GLenum, "condition")]),
# GL_NV_evaluators
GlFunction(Void, "glMapControlPointsNV", [(GLenum, "target"), (GLuint, "index"), (GLenum, "type"), (GLsizei, "ustride"), (GLsizei, "vstride"), (GLint, "uorder"), (GLint, "vorder"), (GLboolean, "packed"), (OpaqueBlob(Const(GLvoid), "_glMapControlPointsNV_size(target, uorder, vorder)"), "points")]),
GlFunction(Void, "glGetVertexAttribivNV", [(GLuint, "index"), (GLenum, "pname"), Out(Array(GLint, "_gl_param_size(pname)"), "params")], sideeffects=False),
GlFunction(Void, "glGetVertexAttribPointervNV", [(GLuint, "index"), (GLenum, "pname"), Out(Pointer(GLpointer), "pointer")], sideeffects=False),
GlFunction(GLboolean, "glIsProgramNV", [(GLprogramARB, "program")], sideeffects=False),
- GlFunction(Void, "glLoadProgramNV", [(GLenum, "target"), (GLprogramARB, "id"), (GLsizei, "len"), (String("const GLubyte *", "len"), "program")]),
+ GlFunction(Void, "glLoadProgramNV", [(GLenum, "target"), (GLprogramARB, "id"), (GLsizei, "len"), (String(Const(GLubyte), "len"), "program")]),
GlFunction(Void, "glProgramParameter4dNV", [(GLenum, "target"), (GLuint, "index"), (GLdouble, "x"), (GLdouble, "y"), (GLdouble, "z"), (GLdouble, "w")]),
GlFunction(Void, "glProgramParameter4dvNV", [(GLenum, "target"), (GLuint, "index"), (Array(Const(GLdouble), 4), "v")]),
GlFunction(Void, "glProgramParameter4fNV", [(GLenum, "target"), (GLuint, "index"), (GLfloat, "x"), (GLfloat, "y"), (GLfloat, "z"), (GLfloat, "w")]),
GlFunction(Void, "glProgramParameters4fvNV", [(GLenum, "target"), (GLuint, "index"), (GLsizei, "count"), (Array(Const(GLfloat), "count*4"), "v")]),
GlFunction(Void, "glRequestResidentProgramsNV", [(GLsizei, "n"), (Array(Const(GLprogramARB), "n"), "programs")]),
GlFunction(Void, "glTrackMatrixNV", [(GLenum, "target"), (GLuint, "address"), (GLenum, "matrix"), (GLenum, "transform")]),
- GlFunction(Void, "glVertexAttribPointerNV", [(GLuint, "index"), (GLint, "size"), (GLenum, "type"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
+ GlFunction(Void, "glVertexAttribPointerNV", [(GLuint, "index"), (size_bgra, "size"), (GLenum, "type"), (GLsizei, "stride"), (GLpointerConst, "pointer")]),
GlFunction(Void, "glVertexAttrib1dNV", [(GLuint, "index"), (GLdouble, "x")]),
GlFunction(Void, "glVertexAttrib1dvNV", [(GLuint, "index"), (Pointer(Const(GLdouble)), "v")]),
GlFunction(Void, "glVertexAttrib1fNV", [(GLuint, "index"), (GLfloat, "x")]),
GlFunction(Void, "glMultiDrawRangeElementArrayAPPLE", [(GLenum_mode, "mode"), (GLuint, "start"), (GLuint, "end"), (Array(Const(GLint), "primcount"), "first"), (Array(Const(GLsizei), "primcount"), "count"), (GLsizei, "primcount")]),
# GL_APPLE_fence
- GlFunction(Void, "glGenFencesAPPLE", [(GLsizei, "n"), Out(Array(GLuint, "n"), "fences")]),
- GlFunction(Void, "glDeleteFencesAPPLE", [(GLsizei, "n"), (Array(Const(GLuint), "n"), "fences")]),
- GlFunction(Void, "glSetFenceAPPLE", [(GLuint, "fence")]),
- GlFunction(GLboolean, "glIsFenceAPPLE", [(GLuint, "fence")], sideeffects=False),
- GlFunction(GLboolean, "glTestFenceAPPLE", [(GLuint, "fence")]),
- GlFunction(Void, "glFinishFenceAPPLE", [(GLuint, "fence")]),
- GlFunction(GLboolean, "glTestObjectAPPLE", [(GLenum, "object"), (GLuint, "name")]),
- GlFunction(Void, "glFinishObjectAPPLE", [(GLenum, "object"), (GLint, "name")]),
+ GlFunction(Void, "glGenFencesAPPLE", [(GLsizei, "n"), Out(Array(GLfence, "n"), "fences")]),
+ GlFunction(Void, "glDeleteFencesAPPLE", [(GLsizei, "n"), (Array(Const(GLfence), "n"), "fences")]),
+ GlFunction(Void, "glSetFenceAPPLE", [(GLfence, "fence")]),
+ GlFunction(GLboolean, "glIsFenceAPPLE", [(GLfence, "fence")], sideeffects=False),
+ GlFunction(GLboolean, "glTestFenceAPPLE", [(GLfence, "fence")]),
+ GlFunction(Void, "glFinishFenceAPPLE", [(GLfence, "fence")]),
+ GlFunction(GLboolean, "glTestObjectAPPLE", [(GLenum, "object"), (GLuint, "name")]), # XXX: name needs swizzling
+ GlFunction(Void, "glFinishObjectAPPLE", [(GLenum, "object"), (GLint, "name")]), # XXX: name needs swizzling
# GL_APPLE_vertex_array_object
- GlFunction(Void, "glBindVertexArrayAPPLE", [(GLuint, "array")]),
- GlFunction(Void, "glDeleteVertexArraysAPPLE", [(GLsizei, "n"), (Array(Const(GLuint), "n"), "arrays")]),
- GlFunction(Void, "glGenVertexArraysAPPLE", [(GLsizei, "n"), Out(Array(GLuint, "n"), "arrays")]),
- GlFunction(GLboolean, "glIsVertexArrayAPPLE", [(GLuint, "array")], sideeffects=False),
+ GlFunction(Void, "glBindVertexArrayAPPLE", [(GLarrayAPPLE, "array")]),
+ GlFunction(Void, "glDeleteVertexArraysAPPLE", [(GLsizei, "n"), (Array(Const(GLarrayAPPLE), "n"), "arrays")]),
+ GlFunction(Void, "glGenVertexArraysAPPLE", [(GLsizei, "n"), Out(Array(GLarrayAPPLE, "n"), "arrays")]),
+ GlFunction(GLboolean, "glIsVertexArrayAPPLE", [(GLarrayAPPLE, "array")], sideeffects=False),
# GL_APPLE_vertex_array_range
GlFunction(Void, "glVertexArrayRangeAPPLE", [(GLsizei, "length"), (GLpointer, "pointer")]),
GlFunction(Void, "glDrawBuffersATI", [(GLsizei, "n"), (Array(Const(GLenum), "n"), "bufs")]),
# GL_NV_fragment_program
- GlFunction(Void, "glProgramNamedParameter4fNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String("const GLubyte *", "len"), "name"), (GLfloat, "x"), (GLfloat, "y"), (GLfloat, "z"), (GLfloat, "w")]),
- GlFunction(Void, "glProgramNamedParameter4dNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String("const GLubyte *", "len"), "name"), (GLdouble, "x"), (GLdouble, "y"), (GLdouble, "z"), (GLdouble, "w")]),
- GlFunction(Void, "glProgramNamedParameter4fvNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String("const GLubyte *", "len"), "name"), (Array(Const(GLfloat), 4), "v")]),
- GlFunction(Void, "glProgramNamedParameter4dvNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String("const GLubyte *", "len"), "name"), (Array(Const(GLdouble), 4), "v")]),
- GlFunction(Void, "glGetProgramNamedParameterdvNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String("const GLubyte *", "len"), "name"), Out(Array(GLdouble, 4), "params")], sideeffects=False),
- GlFunction(Void, "glGetProgramNamedParameterfvNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String("const GLubyte *", "len"), "name"), Out(Array(GLfloat, 4), "params")], sideeffects=False),
+ GlFunction(Void, "glProgramNamedParameter4fNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String(Const(GLubyte), "len"), "name"), (GLfloat, "x"), (GLfloat, "y"), (GLfloat, "z"), (GLfloat, "w")]),
+ GlFunction(Void, "glProgramNamedParameter4dNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String(Const(GLubyte), "len"), "name"), (GLdouble, "x"), (GLdouble, "y"), (GLdouble, "z"), (GLdouble, "w")]),
+ GlFunction(Void, "glProgramNamedParameter4fvNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String(Const(GLubyte), "len"), "name"), (Array(Const(GLfloat), 4), "v")]),
+ GlFunction(Void, "glProgramNamedParameter4dvNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String(Const(GLubyte), "len"), "name"), (Array(Const(GLdouble), 4), "v")]),
+ GlFunction(Void, "glGetProgramNamedParameterdvNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String(Const(GLubyte), "len"), "name"), Out(Array(GLdouble, 4), "params")], sideeffects=False),
+ GlFunction(Void, "glGetProgramNamedParameterfvNV", [(GLprogramARB, "id"), (GLsizei, "len"), (String(Const(GLubyte), "len"), "name"), Out(Array(GLfloat, 4), "params")], sideeffects=False),
# GL_NV_half_float
GlFunction(Void, "glVertex2hNV", [(GLhalfNV, "x"), (GLhalfNV, "y")]),
GlFunction(Void, "glVertexAttribs4hvNV", [(GLuint, "index"), (GLsizei, "n"), (Array(Const(GLhalfNV), "n"), "v")]),
# GL_NV_pixel_data_range
- GlFunction(Void, "glPixelDataRangeNV", [(GLenum, "target"), (GLsizei, "length"), (OpaqueBlob(GLvoid, "length"), "pointer")]),
+ GlFunction(Void, "glPixelDataRangeNV", [(GLenum, "target"), (GLsizei, "length"), (OpaqueBlob(Const(GLvoid), "length"), "pointer")]),
GlFunction(Void, "glFlushPixelDataRangeNV", [(GLenum, "target")]),
# GL_NV_primitive_restart
GlFunction(Void, "glGenerateMipmapEXT", [(GLenum, "target")]),
# GL_GREMEDY_string_marker
- GlFunction(Void, "glStringMarkerGREMEDY", [(GLsizei, "len"), (Const(String("GLvoid *", "len ? len : strlen((const char *)string)")), "string")], sideeffects=False),
+ GlFunction(Void, "glStringMarkerGREMEDY", [(GLsizei, "len"), (String(Const(GLvoid), "len ? len : strlen((const char *)string)"), "string")], sideeffects=False),
# GL_EXT_stencil_clear_tag
GlFunction(Void, "glStencilClearTagEXT", [(GLsizei, "stencilTagBits"), (GLuint, "stencilClearTag")]),
# GL_EXT_gpu_shader4
GlFunction(Void, "glGetUniformuivEXT", [(GLprogram, "program"), (GLlocation, "location"), Out(OpaqueArray(GLuint, "_glGetUniformuivEXT_size(program, location)"), "params")], sideeffects=False),
- GlFunction(Void, "glBindFragDataLocationEXT", [(GLprogram, "program"), (GLuint, "color"), (Const(GLstring), "name")]),
- GlFunction(GLlocation, "glGetFragDataLocationEXT", [(GLprogram, "program"), (Const(GLstring), "name")]),
+ GlFunction(Void, "glBindFragDataLocationEXT", [(GLprogram, "program"), (GLuint, "color"), (GLstringConst, "name")]),
+ GlFunction(GLlocation, "glGetFragDataLocationEXT", [(GLprogram, "program"), (GLstringConst, "name")]),
GlFunction(Void, "glUniform1uiEXT", [(GLlocation, "location"), (GLuint, "v0")]),
GlFunction(Void, "glUniform2uiEXT", [(GLlocation, "location"), (GLuint, "v0"), (GLuint, "v1")]),
GlFunction(Void, "glUniform3uiEXT", [(GLlocation, "location"), (GLuint, "v0"), (GLuint, "v1"), (GLuint, "v2")]),
GlFunction(Void, "glBindBufferOffsetNV", [(GLenum, "target"), (GLuint, "index"), (GLbuffer, "buffer"), (GLintptr, "offset")]),
GlFunction(Void, "glBindBufferBaseNV", [(GLenum, "target"), (GLuint, "index"), (GLbuffer, "buffer")]),
GlFunction(Void, "glTransformFeedbackVaryingsNV", [(GLprogram, "program"), (GLsizei, "count"), (Array(Const(GLint), "count"), "locations"), (GLenum, "bufferMode")]),
- GlFunction(Void, "glActiveVaryingNV", [(GLprogram, "program"), (Const(GLstring), "name")]),
- GlFunction(GLlocation, "glGetVaryingLocationNV", [(GLprogram, "program"), (Const(GLstring), "name")]),
+ GlFunction(Void, "glActiveVaryingNV", [(GLprogram, "program"), (GLstringConst, "name")]),
+ GlFunction(GLlocation, "glGetVaryingLocationNV", [(GLprogram, "program"), (GLstringConst, "name")]),
GlFunction(Void, "glGetActiveVaryingNV", [(GLprogram, "program"), (GLuint, "index"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Pointer(GLsizei), "size"), Out(Pointer(GLenum), "type"), Out(GLstring, "name")], sideeffects=False),
GlFunction(Void, "glGetTransformFeedbackVaryingNV", [(GLprogram, "program"), (GLuint, "index"), Out(Pointer(GLlocation), "location")], sideeffects=False),
GlFunction(Void, "glTransformFeedbackStreamAttribsNV", [(GLsizei, "count"), (Array(Const(GLint), "count"), "attribs"), (GLsizei, "nbuffers"), (Array(Const(GLint), "nbuffers"), "bufstreams"), (GLenum, "bufferMode")]),
GlFunction(Void, "glBindBufferRangeEXT", [(GLenum, "target"), (GLuint, "index"), (GLbuffer, "buffer"), (GLintptr, "offset"), (GLsizeiptr, "size")]),
GlFunction(Void, "glBindBufferOffsetEXT", [(GLenum, "target"), (GLuint, "index"), (GLbuffer, "buffer"), (GLintptr, "offset")]),
GlFunction(Void, "glBindBufferBaseEXT", [(GLenum, "target"), (GLuint, "index"), (GLbuffer, "buffer")]),
- GlFunction(Void, "glTransformFeedbackVaryingsEXT", [(GLprogram, "program"), (GLsizei, "count"), (Const(Array(Const(GLstring), "count")), "varyings"), (GLenum, "bufferMode")]),
+ GlFunction(Void, "glTransformFeedbackVaryingsEXT", [(GLprogram, "program"), (GLsizei, "count"), (Const(Array(GLstringConst, "count")), "varyings"), (GLenum, "bufferMode")]),
GlFunction(Void, "glGetTransformFeedbackVaryingEXT", [(GLprogram, "program"), (GLuint, "index"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(Pointer(GLsizei), "size"), Out(Pointer(GLenum), "type"), Out(GLstring, "name")], sideeffects=False),
# GL_EXT_direct_state_access
GlFunction(Void, "glCompressedMultiTexSubImage2DEXT", [(GLenum, "texunit"), (GLenum, "target"), (GLint, "level"), (GLint, "xoffset"), (GLint, "yoffset"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"), (GLsizei, "imageSize"), (Blob(Const(GLvoid), "imageSize"), "bits")]),
GlFunction(Void, "glCompressedMultiTexSubImage1DEXT", [(GLenum, "texunit"), (GLenum, "target"), (GLint, "level"), (GLint, "xoffset"), (GLsizei, "width"), (GLenum, "format"), (GLsizei, "imageSize"), (Blob(Const(GLvoid), "imageSize"), "bits")]),
GlFunction(Void, "glGetCompressedMultiTexImageEXT", [(GLenum, "texunit"), (GLenum, "target"), (GLint, "lod"), Out(OpaqueBlob(GLvoid, "_glGetCompressedMultiTexImageEXT_size(target, lod)"), "img")], sideeffects=False),
- GlFunction(Void, "glNamedProgramStringEXT", [(GLprogram, "program"), (GLenum, "target"), (GLenum, "format"), (GLsizei, "len"), (Const(String("GLvoid *", "len")), "string")]),
+ GlFunction(Void, "glNamedProgramStringEXT", [(GLprogram, "program"), (GLenum, "target"), (GLenum, "format"), (GLsizei, "len"), (String(Const(GLvoid), "len"), "string")]),
GlFunction(Void, "glNamedProgramLocalParameter4dEXT", [(GLprogram, "program"), (GLenum, "target"), (GLuint, "index"), (GLdouble, "x"), (GLdouble, "y"), (GLdouble, "z"), (GLdouble, "w")]),
GlFunction(Void, "glNamedProgramLocalParameter4dvEXT", [(GLprogram, "program"), (GLenum, "target"), (GLuint, "index"), (Array(Const(GLdouble), 4), "params")]),
GlFunction(Void, "glNamedProgramLocalParameter4fEXT", [(GLprogram, "program"), (GLenum, "target"), (GLuint, "index"), (GLfloat, "x"), (GLfloat, "y"), (GLfloat, "z"), (GLfloat, "w")]),
# GL_EXT_separate_shader_objects
GlFunction(Void, "glUseShaderProgramEXT", [(GLenum, "type"), (GLprogram, "program")]),
GlFunction(Void, "glActiveProgramEXT", [(GLprogram, "program")]),
- GlFunction(GLprogram, "glCreateShaderProgramEXT", [(GLenum, "type"), (Const(GLstring), "string")]),
+ GlFunction(GLprogram, "glCreateShaderProgramEXT", [(GLenum, "type"), (GLstringConst, "string")]),
# GL_NV_shader_buffer_load
GlFunction(Void, "glMakeBufferResidentNV", [(GLenum, "target"), (GLenum, "access")]),
GlFunction(Void, "glReadBufferNV", [(GLenum, "mode")]),
# GL_EXT_debug_label
- GlFunction(Void, "glLabelObjectEXT", [(GLenum, "type"), (GLuint, "object"), (GLsizei, "length"), (Const(GLstring), "label")]),
+ GlFunction(Void, "glLabelObjectEXT", [(GLenum, "type"), (GLuint, "object"), (GLsizei, "length"), (GLstringConst, "label")]),
GlFunction(Void, "glGetObjectLabelEXT", [(GLenum, "type"), (GLuint, "object"), (GLsizei, "bufSize"), Out(Pointer(GLsizei), "length"), Out(GLstring, "label")], sideeffects=False),
# GL_EXT_debug_marker
- GlFunction(Void, "glInsertEventMarkerEXT", [(GLsizei, "length"), (Const(String("GLchar *", "length ? length : strlen(marker)")), "marker")], sideeffects=False),
- GlFunction(Void, "glPushGroupMarkerEXT", [(GLsizei, "length"), (Const(String("GLchar *", "length ? length : strlen(marker)")), "marker")], sideeffects=False),
+ GlFunction(Void, "glInsertEventMarkerEXT", [(GLsizei, "length"), (String(Const(GLchar), "length ? length : strlen(marker)"), "marker")], sideeffects=False),
+ GlFunction(Void, "glPushGroupMarkerEXT", [(GLsizei, "length"), (String(Const(GLchar), "length ? length : strlen(marker)"), "marker")], sideeffects=False),
GlFunction(Void, "glPopGroupMarkerEXT", [], sideeffects=False),
# GL_EXT_occlusion_query_boolean
# GL_EXT_separate_shader_objects
GlFunction(Void, "glUseProgramStagesEXT", [(GLpipeline, "pipeline"), (GLbitfield_shader, "stages"), (GLprogram, "program")]),
GlFunction(Void, "glActiveShaderProgramEXT", [(GLpipeline, "pipeline"), (GLprogram, "program")]),
- GlFunction(GLprogram, "glCreateShaderProgramvEXT", [(GLenum, "type"), (GLsizei, "count"), (Const(Array(Const(GLstring), "count")), "strings")]),
+ GlFunction(GLprogram, "glCreateShaderProgramvEXT", [(GLenum, "type"), (GLsizei, "count"), (Const(Array(GLstringConst, "count")), "strings")]),
GlFunction(Void, "glBindProgramPipelineEXT", [(GLpipeline, "pipeline")]),
GlFunction(Void, "glDeleteProgramPipelinesEXT", [(GLsizei, "n"), (Array(Const(GLuint), "n"), "pipelines")]),
GlFunction(Void, "glGenProgramPipelinesEXT", [(GLsizei, "n"), Out(Array(GLpipeline, "n"), "pipelines")]),
("", X, 1, "GL_RG32UI"), # 0x823C
("", X, 1, "GL_SYNC_CL_EVENT_ARB"), # 0x8240
("", X, 1, "GL_SYNC_CL_EVENT_COMPLETE_ARB"), # 0x8241
- ("glGet", B, 1, "GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB"), # 0x8242
- ("glGet", I, 1, "GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB"), # 0x8243
- ("glGet", P, 1, "GL_DEBUG_CALLBACK_FUNCTION_ARB"), # 0x8244
- ("glGet", P, 1, "GL_DEBUG_CALLBACK_USER_PARAM_ARB"), # 0x8245
- ("", X, 1, "GL_DEBUG_SOURCE_API_ARB"), # 0x8246
- ("", X, 1, "GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB"), # 0x8247
- ("", X, 1, "GL_DEBUG_SOURCE_SHADER_COMPILER_ARB"), # 0x8248
- ("", X, 1, "GL_DEBUG_SOURCE_THIRD_PARTY_ARB"), # 0x8249
- ("", X, 1, "GL_DEBUG_SOURCE_APPLICATION_ARB"), # 0x824A
- ("", X, 1, "GL_DEBUG_SOURCE_OTHER_ARB"), # 0x824B
- ("", X, 1, "GL_DEBUG_TYPE_ERROR_ARB"), # 0x824C
- ("", X, 1, "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB"), # 0x824D
- ("", X, 1, "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB"), # 0x824E
- ("", X, 1, "GL_DEBUG_TYPE_PORTABILITY_ARB"), # 0x824F
- ("", X, 1, "GL_DEBUG_TYPE_PERFORMANCE_ARB"), # 0x8250
- ("", X, 1, "GL_DEBUG_TYPE_OTHER_ARB"), # 0x8251
+ ("glGet", B, 1, "GL_DEBUG_OUTPUT_SYNCHRONOUS"), # 0x8242
+ ("glGet", I, 1, "GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH"), # 0x8243
+ ("glGet", P, 1, "GL_DEBUG_CALLBACK_FUNCTION"), # 0x8244
+ ("glGet", P, 1, "GL_DEBUG_CALLBACK_USER_PARAM"), # 0x8245
+ ("", X, 1, "GL_DEBUG_SOURCE_API"), # 0x8246
+ ("", X, 1, "GL_DEBUG_SOURCE_WINDOW_SYSTEM"), # 0x8247
+ ("", X, 1, "GL_DEBUG_SOURCE_SHADER_COMPILER"), # 0x8248
+ ("", X, 1, "GL_DEBUG_SOURCE_THIRD_PARTY"), # 0x8249
+ ("", X, 1, "GL_DEBUG_SOURCE_APPLICATION"), # 0x824A
+ ("", X, 1, "GL_DEBUG_SOURCE_OTHER"), # 0x824B
+ ("", X, 1, "GL_DEBUG_TYPE_ERROR"), # 0x824C
+ ("", X, 1, "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR"), # 0x824D
+ ("", X, 1, "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR"), # 0x824E
+ ("", X, 1, "GL_DEBUG_TYPE_PORTABILITY"), # 0x824F
+ ("", X, 1, "GL_DEBUG_TYPE_PERFORMANCE"), # 0x8250
+ ("", X, 1, "GL_DEBUG_TYPE_OTHER"), # 0x8251
("", X, 1, "GL_LOSE_CONTEXT_ON_RESET_ARB"), # 0x8252
("", X, 1, "GL_GUILTY_CONTEXT_RESET_ARB"), # 0x8253
("", X, 1, "GL_INNOCENT_CONTEXT_RESET_ARB"), # 0x8254
("glGet", E, 1, "GL_VIEWPORT_INDEX_PROVOKING_VERTEX"), # 0x825F
("", X, 1, "GL_UNDEFINED_VERTEX"), # 0x8260
("", X, 1, "GL_NO_RESET_NOTIFICATION_ARB"), # 0x8261
+ ("glGet", I, 1, "GL_MAX_COMPUTE_SHARED_MEMORY_SIZE"), # 0x8262
+ ("glGet", I, 1, "GL_MAX_COMPUTE_UNIFORM_COMPONENTS"), # 0x8263
+ ("glGet", I, 1, "GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS"), # 0x8264
+ ("glGet", I, 1, "GL_MAX_COMPUTE_ATOMIC_COUNTERS"), # 0x8265
+ ("glGet", I, 1, "GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS"), # 0x8266
+ ("", X, 1, "GL_COMPUTE_LOCAL_WORK_SIZE"), # 0x8267
+ ("", X, 1, "GL_DEBUG_TYPE_MARKER"), # 0x8268
+ ("", X, 1, "GL_DEBUG_TYPE_PUSH_GROUP"), # 0x8269
+ ("", X, 1, "GL_DEBUG_TYPE_POP_GROUP"), # 0x826A
+ ("", X, 1, "GL_DEBUG_SEVERITY_NOTIFICATION"), # 0x826B
+ ("", X, 1, "GL_MAX_DEBUG_GROUP_STACK_DEPTH"), # 0x826C
+ ("", X, 1, "GL_DEBUG_GROUP_STACK_DEPTH"), # 0x826D
+ ("glGet", I, 1, "GL_MAX_UNIFORM_LOCATIONS"), # 0x826E
+ ("", X, 1, "GL_INTERNALFORMAT_SUPPORTED"), # 0x826F
+ ("", X, 1, "GL_INTERNALFORMAT_PREFERRED"), # 0x8270
+ ("", X, 1, "GL_INTERNALFORMAT_RED_SIZE"), # 0x8271
+ ("", X, 1, "GL_INTERNALFORMAT_GREEN_SIZE"), # 0x8272
+ ("", X, 1, "GL_INTERNALFORMAT_BLUE_SIZE"), # 0x8273
+ ("", X, 1, "GL_INTERNALFORMAT_ALPHA_SIZE"), # 0x8274
+ ("", X, 1, "GL_INTERNALFORMAT_DEPTH_SIZE"), # 0x8275
+ ("", X, 1, "GL_INTERNALFORMAT_STENCIL_SIZE"), # 0x8276
+ ("", X, 1, "GL_INTERNALFORMAT_SHARED_SIZE"), # 0x8277
+ ("", X, 1, "GL_INTERNALFORMAT_RED_TYPE"), # 0x8278
+ ("", X, 1, "GL_INTERNALFORMAT_GREEN_TYPE"), # 0x8279
+ ("", X, 1, "GL_INTERNALFORMAT_BLUE_TYPE"), # 0x827A
+ ("", X, 1, "GL_INTERNALFORMAT_ALPHA_TYPE"), # 0x827B
+ ("", X, 1, "GL_INTERNALFORMAT_DEPTH_TYPE"), # 0x827C
+ ("", X, 1, "GL_INTERNALFORMAT_STENCIL_TYPE"), # 0x827D
+ ("", X, 1, "GL_MAX_WIDTH"), # 0x827E
+ ("", X, 1, "GL_MAX_HEIGHT"), # 0x827F
+ ("", X, 1, "GL_MAX_DEPTH"), # 0x8280
+ ("", X, 1, "GL_MAX_LAYERS"), # 0x8281
+ ("", X, 1, "GL_MAX_COMBINED_DIMENSIONS"), # 0x8282
+ ("", X, 1, "GL_COLOR_COMPONENTS"), # 0x8283
+ ("", X, 1, "GL_DEPTH_COMPONENTS"), # 0x8284
+ ("", X, 1, "GL_STENCIL_COMPONENTS"), # 0x8285
+ ("", X, 1, "GL_COLOR_RENDERABLE"), # 0x8286
+ ("", X, 1, "GL_DEPTH_RENDERABLE"), # 0x8287
+ ("", X, 1, "GL_STENCIL_RENDERABLE"), # 0x8288
+ ("", X, 1, "GL_FRAMEBUFFER_RENDERABLE"), # 0x8289
+ ("", X, 1, "GL_FRAMEBUFFER_RENDERABLE_LAYERED"), # 0x828A
+ ("", X, 1, "GL_FRAMEBUFFER_BLEND"), # 0x828B
+ ("", X, 1, "GL_READ_PIXELS"), # 0x828C
+ ("", X, 1, "GL_READ_PIXELS_FORMAT"), # 0x828D
+ ("", X, 1, "GL_READ_PIXELS_TYPE"), # 0x828E
+ ("", X, 1, "GL_TEXTURE_IMAGE_FORMAT"), # 0x828F
+ ("", X, 1, "GL_TEXTURE_IMAGE_TYPE"), # 0x8290
+ ("", X, 1, "GL_GET_TEXTURE_IMAGE_FORMAT"), # 0x8291
+ ("", X, 1, "GL_GET_TEXTURE_IMAGE_TYPE"), # 0x8292
+ ("", X, 1, "GL_MIPMAP"), # 0x8293
+ ("", X, 1, "GL_MANUAL_GENERATE_MIPMAP"), # 0x8294
+ ("", X, 1, "GL_AUTO_GENERATE_MIPMAP"), # 0x8295
+ ("", X, 1, "GL_COLOR_ENCODING"), # 0x8296
+ ("", X, 1, "GL_SRGB_READ"), # 0x8297
+ ("", X, 1, "GL_SRGB_WRITE"), # 0x8298
+ ("", X, 1, "GL_SRGB_DECODE_ARB"), # 0x8299
+ ("", X, 1, "GL_FILTER"), # 0x829A
+ ("", X, 1, "GL_VERTEX_TEXTURE"), # 0x829B
+ ("", X, 1, "GL_TESS_CONTROL_TEXTURE"), # 0x829C
+ ("", X, 1, "GL_TESS_EVALUATION_TEXTURE"), # 0x829D
+ ("", X, 1, "GL_GEOMETRY_TEXTURE"), # 0x829E
+ ("", X, 1, "GL_FRAGMENT_TEXTURE"), # 0x829F
+ ("", X, 1, "GL_COMPUTE_TEXTURE"), # 0x82A0
+ ("", X, 1, "GL_TEXTURE_SHADOW"), # 0x82A1
+ ("", X, 1, "GL_TEXTURE_GATHER"), # 0x82A2
+ ("", X, 1, "GL_TEXTURE_GATHER_SHADOW"), # 0x82A3
+ ("", X, 1, "GL_SHADER_IMAGE_LOAD"), # 0x82A4
+ ("", X, 1, "GL_SHADER_IMAGE_STORE"), # 0x82A5
+ ("", X, 1, "GL_SHADER_IMAGE_ATOMIC"), # 0x82A6
+ ("", X, 1, "GL_IMAGE_TEXEL_SIZE"), # 0x82A7
+ ("", X, 1, "GL_IMAGE_COMPATIBILITY_CLASS"), # 0x82A8
+ ("", X, 1, "GL_IMAGE_PIXEL_FORMAT"), # 0x82A9
+ ("", X, 1, "GL_IMAGE_PIXEL_TYPE"), # 0x82AA
+ ("", X, 1, "GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST"), # 0x82AC
+ ("", X, 1, "GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST"), # 0x82AD
+ ("", X, 1, "GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE"), # 0x82AE
+ ("", X, 1, "GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE"), # 0x82AF
+ ("", X, 1, "GL_TEXTURE_COMPRESSED_BLOCK_WIDTH"), # 0x82B1
+ ("", X, 1, "GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT"), # 0x82B2
+ ("", X, 1, "GL_TEXTURE_COMPRESSED_BLOCK_SIZE"), # 0x82B3
+ ("", X, 1, "GL_CLEAR_BUFFER"), # 0x82B4
+ ("", X, 1, "GL_TEXTURE_VIEW"), # 0x82B5
+ ("", X, 1, "GL_VIEW_COMPATIBILITY_CLASS"), # 0x82B6
+ ("", X, 1, "GL_FULL_SUPPORT"), # 0x82B7
+ ("", X, 1, "GL_CAVEAT_SUPPORT"), # 0x82B8
+ ("", X, 1, "GL_IMAGE_CLASS_4_X_32"), # 0x82B9
+ ("", X, 1, "GL_IMAGE_CLASS_2_X_32"), # 0x82BA
+ ("", X, 1, "GL_IMAGE_CLASS_1_X_32"), # 0x82BB
+ ("", X, 1, "GL_IMAGE_CLASS_4_X_16"), # 0x82BC
+ ("", X, 1, "GL_IMAGE_CLASS_2_X_16"), # 0x82BD
+ ("", X, 1, "GL_IMAGE_CLASS_1_X_16"), # 0x82BE
+ ("", X, 1, "GL_IMAGE_CLASS_4_X_8"), # 0x82BF
+ ("", X, 1, "GL_IMAGE_CLASS_2_X_8"), # 0x82C0
+ ("", X, 1, "GL_IMAGE_CLASS_1_X_8"), # 0x82C1
+ ("", X, 1, "GL_IMAGE_CLASS_11_11_10"), # 0x82C2
+ ("", X, 1, "GL_IMAGE_CLASS_10_10_10_2"), # 0x82C3
+ ("", X, 1, "GL_VIEW_CLASS_128_BITS"), # 0x82C4
+ ("", X, 1, "GL_VIEW_CLASS_96_BITS"), # 0x82C5
+ ("", X, 1, "GL_VIEW_CLASS_64_BITS"), # 0x82C6
+ ("", X, 1, "GL_VIEW_CLASS_48_BITS"), # 0x82C7
+ ("", X, 1, "GL_VIEW_CLASS_32_BITS"), # 0x82C8
+ ("", X, 1, "GL_VIEW_CLASS_24_BITS"), # 0x82C9
+ ("", X, 1, "GL_VIEW_CLASS_16_BITS"), # 0x82CA
+ ("", X, 1, "GL_VIEW_CLASS_8_BITS"), # 0x82CB
+ ("", X, 1, "GL_VIEW_CLASS_S3TC_DXT1_RGB"), # 0x82CC
+ ("", X, 1, "GL_VIEW_CLASS_S3TC_DXT1_RGBA"), # 0x82CD
+ ("", X, 1, "GL_VIEW_CLASS_S3TC_DXT3_RGBA"), # 0x82CE
+ ("", X, 1, "GL_VIEW_CLASS_S3TC_DXT5_RGBA"), # 0x82CF
+ ("", X, 1, "GL_VIEW_CLASS_RGTC1_RED"), # 0x82D0
+ ("", X, 1, "GL_VIEW_CLASS_RGTC2_RG"), # 0x82D1
+ ("", X, 1, "GL_VIEW_CLASS_BPTC_UNORM"), # 0x82D2
+ ("", X, 1, "GL_VIEW_CLASS_BPTC_FLOAT"), # 0x82D3
+ ("", I, 1, "GL_VERTEX_ATTRIB_BINDING"), # 0x82D4
+ ("", I, 1, "GL_VERTEX_ATTRIB_RELATIVE_OFFSET"), # 0x82D5
+ ("", I, 1, "GL_VERTEX_BINDING_DIVISOR"), # 0x82D6
+ ("", I, 1, "GL_VERTEX_BINDING_OFFSET"), # 0x82D7
+ ("", I, 1, "GL_VERTEX_BINDING_STRIDE"), # 0x82D8
+ ("", I, 1, "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET"), # 0x82D9
+ ("", I, 1, "GL_MAX_VERTEX_ATTRIB_BINDINGS"), # 0x82DA
+ ("glGetTexParameter", I, 1, "GL_TEXTURE_VIEW_MIN_LEVEL"), # 0x82DB
+ ("glGetTexParameter", I, 1, "GL_TEXTURE_VIEW_NUM_LEVELS"), # 0x82DC
+ ("glGetTexParameter", I, 1, "GL_TEXTURE_VIEW_MIN_LAYER"), # 0x82DD
+ ("glGetTexParameter", I, 1, "GL_TEXTURE_VIEW_NUM_LAYERS"), # 0x82DE
+ ("glGetTexParameter", I, 1, "GL_TEXTURE_IMMUTABLE_LEVELS"), # 0x82DF
+ ("", X, 1, "GL_BUFFER"), # 0x82E0
+ ("", X, 1, "GL_SHADER"), # 0x82E1
+ ("", X, 1, "GL_PROGRAM"), # 0x82E2
+ ("", X, 1, "GL_QUERY"), # 0x82E3
+ ("", X, 1, "GL_PROGRAM_PIPELINE"), # 0x82E4
+ ("", X, 1, "GL_SAMPLER"), # 0x82E6
+ ("", X, 1, "GL_DISPLAY_LIST"), # 0x82E7
+ ("", X, 1, "GL_MAX_LABEL_LENGTH"), # 0x82E8
+ ("", X, 1, "GL_NUM_SHADING_LANGUAGE_VERSIONS"), # 0x82E9
("", X, 1, "GL_DEPTH_PASS_INSTRUMENT_SGIX"), # 0x8310
("", X, 1, "GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX"), # 0x8311
("", X, 1, "GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX"), # 0x8312
("glGet", I, 1, "GL_PIXEL_PACK_BUFFER_BINDING"), # 0x88ED
("glGet", I, 1, "GL_PIXEL_UNPACK_BUFFER_BINDING"), # 0x88EF
("", X, 1, "GL_DEPTH24_STENCIL8"), # 0x88F0
- ("", X, 1, "GL_TEXTURE_STENCIL_SIZE"), # 0x88F1
+ ("glGetTexLevelParameter", I, 1, "GL_TEXTURE_STENCIL_SIZE"), # 0x88F1
("", X, 1, "GL_STENCIL_TAG_BITS_EXT"), # 0x88F2
("", X, 1, "GL_STENCIL_CLEAR_TAG_VALUE_EXT"), # 0x88F3
("glGetProgramARB", I, 1, "GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV"), # 0x88F4
("", X, 1, "GL_TRANSFORM_FEEDBACK_RECORD_NV"), # 0x8C86
("", X, 1, "GL_PRIMITIVES_GENERATED"), # 0x8C87
("", X, 1, "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN"), # 0x8C88
- ("", X, 1, "GL_RASTERIZER_DISCARD"), # 0x8C89
+ ("glGet", B, 1, "GL_RASTERIZER_DISCARD"), # 0x8C89
("", X, 1, "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS"), # 0x8C8A
("", X, 1, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS"), # 0x8C8B
("", X, 1, "GL_INTERLEAVED_ATTRIBS"), # 0x8C8C
#("", X, 1, "GL_SAMPLER_EXTERNAL_OES"), # 0x8D66
#("", X, 1, "GL_TEXTURE_BINDING_EXTERNAL_OES"), # 0x8D67
#("", X, 1, "GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES"), # 0x8D68
+ ("", B, 1, "GL_PRIMITIVE_RESTART_FIXED_INDEX"), # 0x8D69
+ ("", X, 1, "GL_ANY_SAMPLES_PASSED_CONSERVATIVE"), # 0x8D6A
+ ("glGet", I, 1, "GL_MAX_ELEMENT_INDEX"), # 0x8D6B
+ #("", X, 1, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT"), # 0x8D6C
("", X, 1, "GL_RGBA32UI"), # 0x8D70
("", X, 1, "GL_RGB32UI"), # 0x8D71
("", X, 1, "GL_ALPHA32UI_EXT"), # 0x8D72
("", X, 1, "GL_MAX_IMAGE_SAMPLES"), # 0x906D
("", X, 1, "GL_IMAGE_BINDING_FORMAT"), # 0x906E
("", X, 1, "GL_RGB10_A2UI"), # 0x906F
+ ("", X, 1, "GL_PATH_FORMAT_SVG_NV"), # 0x9070
+ ("", X, 1, "GL_PATH_FORMAT_PS_NV"), # 0x9071
+ ("", X, 1, "GL_STANDARD_FONT_NAME_NV"), # 0x9072
+ ("", X, 1, "GL_SYSTEM_FONT_NAME_NV"), # 0x9073
+ ("", X, 1, "GL_FILE_NAME_NV"), # 0x9074
+ ("", X, 1, "GL_PATH_STROKE_WIDTH_NV"), # 0x9075
+ ("", X, 1, "GL_PATH_END_CAPS_NV"), # 0x9076
+ ("", X, 1, "GL_PATH_INITIAL_END_CAP_NV"), # 0x9077
+ ("", X, 1, "GL_PATH_TERMINAL_END_CAP_NV"), # 0x9078
+ ("", X, 1, "GL_PATH_JOIN_STYLE_NV"), # 0x9079
+ ("", X, 1, "GL_PATH_MITER_LIMIT_NV"), # 0x907A
+ ("", X, 1, "GL_PATH_DASH_CAPS_NV"), # 0x907B
+ ("", X, 1, "GL_PATH_INITIAL_DASH_CAP_NV"), # 0x907C
+ ("", X, 1, "GL_PATH_TERMINAL_DASH_CAP_NV"), # 0x907D
+ ("", X, 1, "GL_PATH_DASH_OFFSET_NV"), # 0x907E
+ ("", X, 1, "GL_PATH_CLIENT_LENGTH_NV"), # 0x907F
+ ("", X, 1, "GL_PATH_FILL_MODE_NV"), # 0x9080
+ ("", X, 1, "GL_PATH_FILL_MASK_NV"), # 0x9081
+ ("", X, 1, "GL_PATH_FILL_COVER_MODE_NV"), # 0x9082
+ ("", X, 1, "GL_PATH_STROKE_COVER_MODE_NV"), # 0x9083
+ ("", X, 1, "GL_PATH_STROKE_MASK_NV"), # 0x9084
+ ("", X, 1, "GL_PATH_SAMPLE_QUALITY_NV"), # 0x9085
+ ("", X, 1, "GL_PATH_STROKE_BOUND_NV"), # 0x9086
+ ("", X, 1, "GL_PATH_STROKE_OVERSAMPLE_COUNT_NV"), # 0x9087
+ ("", X, 1, "GL_COUNT_UP_NV"), # 0x9088
+ ("", X, 1, "GL_COUNT_DOWN_NV"), # 0x9089
+ ("", X, 1, "GL_PATH_OBJECT_BOUNDING_BOX_NV"), # 0x908A
+ ("", X, 1, "GL_CONVEX_HULL_NV"), # 0x908B
+ ("", X, 1, "GL_MULTI_HULLS_NV"), # 0x908C
+ ("", X, 1, "GL_BOUNDING_BOX_NV"), # 0x908D
+ ("", X, 1, "GL_TRANSLATE_X_NV"), # 0x908E
+ ("", X, 1, "GL_TRANSLATE_Y_NV"), # 0x908F
+ ("", X, 1, "GL_TRANSLATE_2D_NV"), # 0x9090
+ ("", X, 1, "GL_TRANSLATE_3D_NV"), # 0x9091
+ ("", X, 1, "GL_AFFINE_2D_NV"), # 0x9092
+ ("", X, 1, "GL_PROJECTIVE_2D_NV"), # 0x9093
+ ("", X, 1, "GL_AFFINE_3D_NV"), # 0x9094
+ ("", X, 1, "GL_PROJECTIVE_3D_NV"), # 0x9095
+ ("", X, 1, "GL_TRANSPOSE_AFFINE_2D_NV"), # 0x9096
+ ("", X, 1, "GL_TRANSPOSE_PROJECTIVE_2D_NV"), # 0x9097
+ ("", X, 1, "GL_TRANSPOSE_AFFINE_3D_NV"), # 0x9098
+ ("", X, 1, "GL_TRANSPOSE_PROJECTIVE_3D_NV"), # 0x9099
+ ("", X, 1, "GL_UTF8_NV"), # 0x909A
+ ("", X, 1, "GL_UTF16_NV"), # 0x909B
+ ("", X, 1, "GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV"), # 0x909C
+ ("", X, 1, "GL_PATH_COMMAND_COUNT_NV"), # 0x909D
+ ("", X, 1, "GL_PATH_COORD_COUNT_NV"), # 0x909E
+ ("", X, 1, "GL_PATH_DASH_ARRAY_COUNT_NV"), # 0x909F
+ ("", X, 1, "GL_PATH_COMPUTED_LENGTH_NV"), # 0x90A0
+ ("", X, 1, "GL_PATH_FILL_BOUNDING_BOX_NV"), # 0x90A1
+ ("", X, 1, "GL_PATH_STROKE_BOUNDING_BOX_NV"), # 0x90A2
+ ("", X, 1, "GL_SQUARE_NV"), # 0x90A3
+ ("", X, 1, "GL_ROUND_NV"), # 0x90A4
+ ("", X, 1, "GL_TRIANGULAR_NV"), # 0x90A5
+ ("", X, 1, "GL_BEVEL_NV"), # 0x90A6
+ ("", X, 1, "GL_MITER_REVERT_NV"), # 0x90A7
+ ("", X, 1, "GL_MITER_TRUNCATE_NV"), # 0x90A8
+ ("", X, 1, "GL_SKIP_MISSING_GLYPH_NV"), # 0x90A9
+ ("", X, 1, "GL_USE_MISSING_GLYPH_NV"), # 0x90AA
+ ("", X, 1, "GL_PATH_ERROR_POSITION_NV"), # 0x90AB
+ ("", X, 1, "GL_PATH_FOG_GEN_MODE_NV"), # 0x90AC
+ ("", X, 1, "GL_ACCUM_ADJACENT_PAIRS_NV"), # 0x90AD
+ ("", X, 1, "GL_ADJACENT_PAIRS_NV"), # 0x90AE
+ ("", X, 1, "GL_FIRST_TO_REST_NV"), # 0x90AF
+ ("", X, 1, "GL_PATH_GEN_MODE_NV"), # 0x90B0
+ ("", X, 1, "GL_PATH_GEN_COEFF_NV"), # 0x90B1
+ ("", X, 1, "GL_PATH_GEN_COLOR_FORMAT_NV"), # 0x90B2
+ ("", X, 1, "GL_PATH_GEN_COMPONENTS_NV"), # 0x90B3
+ ("", X, 1, "GL_PATH_DASH_OFFSET_RESET_NV"), # 0x90B4
+ ("", X, 1, "GL_MOVE_TO_RESETS_NV"), # 0x90B5
+ ("", X, 1, "GL_MOVE_TO_CONTINUES_NV"), # 0x90B6
+ ("", X, 1, "GL_PATH_STENCIL_FUNC_NV"), # 0x90B7
+ ("", X, 1, "GL_PATH_STENCIL_REF_NV"), # 0x90B8
+ ("", X, 1, "GL_PATH_STENCIL_VALUE_MASK_NV"), # 0x90B9
("", X, 1, "GL_SCALED_RESOLVE_FASTEST_EXT"), # 0x90BA
("", X, 1, "GL_SCALED_RESOLVE_NICEST_EXT"), # 0x90BB
("", X, 1, "GL_MIN_MAP_BUFFER_ALIGNMENT"), # 0x90BC
+ ("", X, 1, "GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV"), # 0x90BD
+ ("", X, 1, "GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV"), # 0x90BE
+ ("", X, 1, "GL_PATH_COVER_DEPTH_FUNC_NV"), # 0x90BF
("", X, 1, "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE"), # 0x90C7
("", X, 1, "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE"), # 0x90C8
("", X, 1, "GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS"), # 0x90C9
("", X, 1, "GL_MAX_GEOMETRY_IMAGE_UNIFORMS"), # 0x90CD
("", X, 1, "GL_MAX_FRAGMENT_IMAGE_UNIFORMS"), # 0x90CE
("", X, 1, "GL_MAX_COMBINED_IMAGE_UNIFORMS"), # 0x90CF
+ ("", I, 1, "GL_SHADER_STORAGE_BUFFER"), # 0x90D2
+ ("", I, 1, "GL_SHADER_STORAGE_BUFFER_BINDING"), # 0x90D3
+ ("", I, 1, "GL_SHADER_STORAGE_BUFFER_START"), # 0x90D4
+ ("", I, 1, "GL_SHADER_STORAGE_BUFFER_SIZE"), # 0x90D5
+ ("", I, 1, "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS"), # 0x90D6
+ ("", I, 1, "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS"), # 0x90D7
+ ("", I, 1, "GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS"), # 0x90D8
+ ("", I, 1, "GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS"), # 0x90D9
+ ("", I, 1, "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS"), # 0x90DA
+ ("glGet", I, 1, "GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS"), # 0x90DB
+ ("", I, 1, "GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS"), # 0x90DC
+ ("", I, 1, "GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS"), # 0x90DD
+ ("", I, 1, "GL_MAX_SHADER_STORAGE_BLOCK_SIZE"), # 0x90DE
+ ("", X, 1, "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT"), # 0x90DF
("", X, 1, "GL_SYNC_X11_FENCE_EXT"), # 0x90E1
+ ("glGetTexParameter", E, 1, "GL_DEPTH_STENCIL_TEXTURE_MODE"), # 0x90EA
+ ("glGet", I, 1, "GL_MAX_COMPUTE_LOCAL_INVOCATIONS"), # 0x90EB
+ ("", X, 1, "GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER"), # 0x90EC
+ ("", X, 1, "GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER"), # 0x90ED
+ ("", X, 1, "GL_DISPATCH_INDIRECT_BUFFER"), # 0x90EE
+ ("glGet", I, 1, "GL_DISPATCH_INDIRECT_BUFFER_BINDING"), # 0x90EF
("", X, 1, "GL_TEXTURE_2D_MULTISAMPLE"), # 0x9100
("", X, 1, "GL_PROXY_TEXTURE_2D_MULTISAMPLE"), # 0x9101
("", X, 1, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY"), # 0x9102
#("", X, 1, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG"), # 0x9134
#("", X, 1, "GL_MAX_SAMPLES_IMG"), # 0x9135
#("", X, 1, "GL_TEXTURE_SAMPLES_IMG"), # 0x9136
- ("glGet", I, 1, "GL_MAX_DEBUG_MESSAGE_LENGTH_ARB"), # 0x9143
- ("glGet", I, 1, "GL_MAX_DEBUG_LOGGED_MESSAGES_ARB"), # 0x9144
- ("glGet", I, 1, "GL_DEBUG_LOGGED_MESSAGES_ARB"), # 0x9145
- ("", X, 1, "GL_DEBUG_SEVERITY_HIGH_ARB"), # 0x9146
- ("", X, 1, "GL_DEBUG_SEVERITY_MEDIUM_ARB"), # 0x9147
- ("", X, 1, "GL_DEBUG_SEVERITY_LOW_ARB"), # 0x9148
+ ("glGet", I, 1, "GL_MAX_DEBUG_MESSAGE_LENGTH"), # 0x9143
+ ("glGet", I, 1, "GL_MAX_DEBUG_LOGGED_MESSAGES"), # 0x9144
+ ("glGet", I, 1, "GL_DEBUG_LOGGED_MESSAGES"), # 0x9145
+ ("", X, 1, "GL_DEBUG_SEVERITY_HIGH"), # 0x9146
+ ("", X, 1, "GL_DEBUG_SEVERITY_MEDIUM"), # 0x9147
+ ("", X, 1, "GL_DEBUG_SEVERITY_LOW"), # 0x9148
("", X, 1, "GL_DEBUG_CATEGORY_API_ERROR_AMD"), # 0x9149
("", X, 1, "GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD"), # 0x914A
("", X, 1, "GL_DEBUG_CATEGORY_DEPRECATION_AMD"), # 0x914B
("", X, 1, "GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD"), # 0x914E
("", X, 1, "GL_DEBUG_CATEGORY_APPLICATION_AMD"), # 0x914F
("", X, 1, "GL_DEBUG_CATEGORY_OTHER_AMD"), # 0x9150
- ("", X, 1, "GL_DATA_BUFFER_AMD"), # 0x9151
+ ("", X, 1, "GL_BUFFER_OBJECT_EXT"), # 0x9151
("", X, 1, "GL_PERFORMANCE_MONITOR_AMD"), # 0x9152
- ("", X, 1, "GL_QUERY_OBJECT_AMD"), # 0x9153
- ("", X, 1, "GL_VERTEX_ARRAY_OBJECT_AMD"), # 0x9154
+ ("", X, 1, "GL_QUERY_OBJECT_EXT"), # 0x9153
+ ("", X, 1, "GL_VERTEX_ARRAY_OBJECT_EXT"), # 0x9154
("", X, 1, "GL_SAMPLER_OBJECT_AMD"), # 0x9155
- #("", X, 1, "GL_SHADER_BINARY_DMP"), # 0x9250
+ ("", X, 1, "GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD"), # 0x9160
+ ("", X, 1, "GL_QUERY_BUFFER_AMD"), # 0x9192
+ ("", X, 1, "GL_QUERY_BUFFER_BINDING_AMD"), # 0x9193
+ ("", X, 1, "GL_QUERY_RESULT_NO_WAIT_AMD"), # 0x9194
+ ("glGetTexLevelParameter", I, 1, "GL_TEXTURE_BUFFER_OFFSET"), # 0x919D
+ ("glGetTexLevelParameter", I, 1, "GL_TEXTURE_BUFFER_SIZE"), # 0x919E
+ ("glGet", I, 1, "GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT"), # 0x919F
+ ("", X, 1, "GL_COMPUTE_SHADER"), # 0x91B9
+ ("glGet", I, 1, "GL_MAX_COMPUTE_UNIFORM_BLOCKS"), # 0x91BB
+ ("glGet", I, 1, "GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS"), # 0x91BC
+ ("glGet", I, 1, "GL_MAX_COMPUTE_IMAGE_UNIFORMS"), # 0x91BD
+ ("glGet", I, 3, "GL_MAX_COMPUTE_WORK_GROUP_COUNT"), # 0x91BE
+ ("glGet", I, 3, "GL_MAX_COMPUTE_WORK_GROUP_SIZE"), # 0x91BF
+ ("", X, 1, "GL_SHADER_BINARY_DMP"), # 0x9250
+ #("", X, 1, "GL_GCCSO_SHADER_BINARY_FJ"), # 0x9260
+ ("", X, 1, "GL_COMPRESSED_R11_EAC"), # 0x9270
+ ("", X, 1, "GL_COMPRESSED_SIGNED_R11_EAC"), # 0x9271
+ ("", X, 1, "GL_COMPRESSED_RG11_EAC"), # 0x9272
+ ("", X, 1, "GL_COMPRESSED_SIGNED_RG11_EAC"), # 0x9273
+ ("", X, 1, "GL_COMPRESSED_RGB8_ETC2"), # 0x9274
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ETC2"), # 0x9275
+ ("", X, 1, "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"), # 0x9276
+ ("", X, 1, "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"), # 0x9277
+ ("", X, 1, "GL_COMPRESSED_RGBA8_ETC2_EAC"), # 0x9278
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"), # 0x9279
("", X, 1, "GL_ATOMIC_COUNTER_BUFFER"), # 0x92C0
("", X, 1, "GL_ATOMIC_COUNTER_BUFFER_BINDING"), # 0x92C1
("", X, 1, "GL_ATOMIC_COUNTER_BUFFER_START"), # 0x92C2
("", X, 1, "GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX"), # 0x92DA
("", X, 1, "GL_UNSIGNED_INT_ATOMIC_COUNTER"), # 0x92DB
("", X, 1, "GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS"), # 0x92DC
+ ("glGet", B, 1, "GL_DEBUG_OUTPUT"), # 0x92E0
+ ("", X, 1, "GL_UNIFORM"), # 0x92E1
+ ("", X, 1, "GL_UNIFORM_BLOCK"), # 0x92E2
+ ("", X, 1, "GL_PROGRAM_INPUT"), # 0x92E3
+ ("", X, 1, "GL_PROGRAM_OUTPUT"), # 0x92E4
+ ("", X, 1, "GL_BUFFER_VARIABLE"), # 0x92E5
+ ("", X, 1, "GL_SHADER_STORAGE_BLOCK"), # 0x92E6
+ ("", X, 1, "GL_IS_PER_PATCH"), # 0x92E7
+ ("", X, 1, "GL_VERTEX_SUBROUTINE"), # 0x92E8
+ ("", X, 1, "GL_TESS_CONTROL_SUBROUTINE"), # 0x92E9
+ ("", X, 1, "GL_TESS_EVALUATION_SUBROUTINE"), # 0x92EA
+ ("", X, 1, "GL_GEOMETRY_SUBROUTINE"), # 0x92EB
+ ("", X, 1, "GL_FRAGMENT_SUBROUTINE"), # 0x92EC
+ ("", X, 1, "GL_COMPUTE_SUBROUTINE"), # 0x92ED
+ ("", X, 1, "GL_VERTEX_SUBROUTINE_UNIFORM"), # 0x92EE
+ ("", X, 1, "GL_TESS_CONTROL_SUBROUTINE_UNIFORM"), # 0x92EF
+ ("", X, 1, "GL_TESS_EVALUATION_SUBROUTINE_UNIFORM"), # 0x92F0
+ ("", X, 1, "GL_GEOMETRY_SUBROUTINE_UNIFORM"), # 0x92F1
+ ("", X, 1, "GL_FRAGMENT_SUBROUTINE_UNIFORM"), # 0x92F2
+ ("", X, 1, "GL_COMPUTE_SUBROUTINE_UNIFORM"), # 0x92F3
+ ("", X, 1, "GL_TRANSFORM_FEEDBACK_VARYING"), # 0x92F4
+ ("", X, 1, "GL_ACTIVE_RESOURCES"), # 0x92F5
+ ("", X, 1, "GL_MAX_NAME_LENGTH"), # 0x92F6
+ ("", X, 1, "GL_MAX_NUM_ACTIVE_VARIABLES"), # 0x92F7
+ ("", X, 1, "GL_MAX_NUM_COMPATIBLE_SUBROUTINES"), # 0x92F8
+ ("", X, 1, "GL_NAME_LENGTH"), # 0x92F9
+ ("", X, 1, "GL_TYPE"), # 0x92FA
+ ("", X, 1, "GL_ARRAY_SIZE"), # 0x92FB
+ ("", X, 1, "GL_OFFSET"), # 0x92FC
+ ("", X, 1, "GL_BLOCK_INDEX"), # 0x92FD
+ ("", X, 1, "GL_ARRAY_STRIDE"), # 0x92FE
+ ("", X, 1, "GL_MATRIX_STRIDE"), # 0x92FF
+ ("", X, 1, "GL_IS_ROW_MAJOR"), # 0x9300
+ ("", X, 1, "GL_ATOMIC_COUNTER_BUFFER_INDEX"), # 0x9301
+ ("", X, 1, "GL_BUFFER_BINDING"), # 0x9302
+ ("", X, 1, "GL_BUFFER_DATA_SIZE"), # 0x9303
+ ("", X, 1, "GL_NUM_ACTIVE_VARIABLES"), # 0x9304
+ ("", X, 1, "GL_ACTIVE_VARIABLES"), # 0x9305
+ ("", X, 1, "GL_REFERENCED_BY_VERTEX_SHADER"), # 0x9306
+ ("", X, 1, "GL_REFERENCED_BY_TESS_CONTROL_SHADER"), # 0x9307
+ ("", X, 1, "GL_REFERENCED_BY_TESS_EVALUATION_SHADER"), # 0x9308
+ ("", X, 1, "GL_REFERENCED_BY_GEOMETRY_SHADER"), # 0x9309
+ ("", X, 1, "GL_REFERENCED_BY_FRAGMENT_SHADER"), # 0x930A
+ ("", X, 1, "GL_REFERENCED_BY_COMPUTE_SHADER"), # 0x930B
+ ("", X, 1, "GL_TOP_LEVEL_ARRAY_SIZE"), # 0x930C
+ ("", X, 1, "GL_TOP_LEVEL_ARRAY_STRIDE"), # 0x930D
+ ("", X, 1, "GL_LOCATION"), # 0x930E
+ ("", X, 1, "GL_LOCATION_INDEX"), # 0x930F
+ ("", I, 1, "GL_FRAMEBUFFER_DEFAULT_WIDTH"), # 0x9310
+ ("", I, 1, "GL_FRAMEBUFFER_DEFAULT_HEIGHT"), # 0x9311
+ ("", I, 1, "GL_FRAMEBUFFER_DEFAULT_LAYERS"), # 0x9312
+ ("", I, 1, "GL_FRAMEBUFFER_DEFAULT_SAMPLES"), # 0x9313
+ ("", B, 1, "GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS"), # 0x9314
+ ("glGet", I, 1, "GL_MAX_FRAMEBUFFER_WIDTH"), # 0x9315
+ ("glGet", I, 1, "GL_MAX_FRAMEBUFFER_HEIGHT"), # 0x9316
+ ("glGet", I, 1, "GL_MAX_FRAMEBUFFER_LAYERS"), # 0x9317
+ ("glGet", I, 1, "GL_MAX_FRAMEBUFFER_SAMPLES"), # 0x9318
("", X, 1, "GL_NUM_SAMPLE_COUNTS"), # 0x9380
+ ("", X, 1, "GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE"), # 0x93A0
+ ("", X, 1, "GL_TEXTURE_USAGE_ANGLE"), # 0x93A2
+ ("", X, 1, "GL_FRAMEBUFFER_ATTACHMENT_ANGLE"), # 0x93A3
+ ("", X, 1, "GL_PACK_REVERSE_ROW_ORDER_ANGLE"), # 0x93A4
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_4x4_KHR"), # 0x93B0
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_5x4_KHR"), # 0x93B1
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_5x5_KHR"), # 0x93B2
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_6x5_KHR"), # 0x93B3
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_6x6_KHR"), # 0x93B4
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_8x5_KHR"), # 0x93B5
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_8x6_KHR"), # 0x93B6
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_8x8_KHR"), # 0x93B7
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_10x5_KHR"), # 0x93B8
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_10x6_KHR"), # 0x93B9
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_10x8_KHR"), # 0x93BA
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_10x10_KHR"), # 0x93BB
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_12x10_KHR"), # 0x93BC
+ ("", X, 1, "GL_COMPRESSED_RGBA_ASTC_12x12_KHR"), # 0x93BD
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"), # 0x93D0
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"), # 0x93D1
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"), # 0x93D2
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"), # 0x93D3
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"), # 0x93D4
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"), # 0x93D5
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"), # 0x93D6
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"), # 0x93D7
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"), # 0x93D8
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"), # 0x93D9
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"), # 0x93DA
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"), # 0x93DB
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"), # 0x93DC
+ ("", X, 1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"), # 0x93DD
+ #("", X, 1, "GL_RESTART_PATH_NV"), # 0xF0
+ #("", X, 1, "GL_DUP_FIRST_CUBIC_CURVE_TO_NV"), # 0xF2
+ #("", X, 1, "GL_DUP_LAST_CUBIC_CURVE_TO_NV"), # 0xF4
+ #("", X, 1, "GL_RECT_NV"), # 0xF6
+ #("", X, 1, "GL_CIRCULAR_CCW_ARC_TO_NV"), # 0xF8
+ #("", X, 1, "GL_CIRCULAR_CW_ARC_TO_NV"), # 0xFA
+ #("", X, 1, "GL_CIRCULAR_TANGENT_ARC_TO_NV"), # 0xFC
+ #("", X, 1, "GL_ARC_TO_NV"), # 0xFE
+ #("", X, 1, "GL_TIMEOUT_IGNORED"), # 0xFFFFFFFFFFFFFFFFull
("", X, 1, "GL_INVALID_INDEX"), # 0xFFFFFFFFu
]
GLclampf = Alias("GLclampf", Float)
GLdouble = Alias("GLdouble", Double)
GLclampd = Alias("GLclampd", Double)
-GLchar = Alias("GLchar", SChar)
-GLstring = String("GLchar *")
+GLchar = Alias("GLchar", Char)
GLcharARB = Alias("GLcharARB", SChar)
-GLstringARB = String("GLcharARB *")
GLintptrARB = Alias("GLintptrARB", Int)
GLsizeiptrARB = Alias("GLsizeiptrARB", Int)
GLhandleARB = Handle("handleARB", Alias("GLhandleARB", UInt))
GLhalfNV = Alias("GLhalfNV", UShort)
GLint64EXT = Alias("GLint64EXT", Int64)
GLuint64EXT = Alias("GLuint64EXT", UInt64)
+GLDEBUGPROC = Opaque("GLDEBUGPROC")
GLDEBUGPROCARB = Opaque("GLDEBUGPROCARB")
GLDEBUGPROCAMD = Opaque("GLDEBUGPROCAMD")
+GLstring = String(GLchar)
+GLstringConst = String(Const(GLchar))
+GLstringARB = String(GLcharARB)
+GLstringConstARB = String(Const(GLcharARB))
+
GLpointer = OpaquePointer(GLvoid)
GLpointerConst = OpaquePointer(Const(GLvoid))
GLlocation = Handle("location", GLint, key=('program', GLhandleARB))
GLlocationARB = Handle("location", GLint, key=('programObj', GLhandleARB))
+contextKey = ('reinterpret_cast<uintptr_t>(glretrace::getCurrentContext())', UIntPtr)
+
GLprogramARB = Handle("programARB", GLuint)
GLframebuffer = Handle("framebuffer", GLuint)
GLrenderbuffer = Handle("renderbuffer", GLuint)
GLfragmentShaderATI = Handle("fragmentShaderATI", GLuint)
-GLarray = Handle("array", GLuint)
+GLarray = Handle("array", GLuint, key=contextKey) # per-context
+GLarrayAPPLE = Handle("arrayAPPLE", GLuint) # shared
GLregion = Handle("region", GLuint)
GLpipeline = Handle("pipeline", GLuint)
GLsampler = Handle("sampler", GLuint)
GLfeedback = Handle("feedback", GLuint)
+GLfence = Handle("fence", GLuint)
# GL mappings are pointers to linear memory regions.
#
"GL_GEOMETRY_SHADER_BIT", # 0x00000004
"GL_TESS_CONTROL_SHADER_BIT", # 0x00000008
"GL_TESS_EVALUATION_SHADER_BIT", # 0x00000010
+ "GL_COMPUTE_SHADER_BIT", # 0x00000020
])
GLbitfield_access = Flags(GLbitfield, [
"GL_ATOMIC_COUNTER_BARRIER_BIT", # 0x00001000
])
+# GL_ARB_vertex_array_bgra
+size_bgra = FakeEnum(GLint, [
+ "GL_BGRA",
+])
Function(Void, "glXUseXFont", [(Font, "font"), (Int, "first"), (Int, "count"), (Int, "list")]),
# GLX 1.1 and later
- Function((Const(String("char *"))), "glXQueryExtensionsString", [(Display, "dpy"), (Int, "screen")]),
- Function((Const(String("char *"))), "glXQueryServerString", [(Display, "dpy"), (Int, "screen"), (GLXname, "name")]),
- Function((Const(String("char *"))), "glXGetClientString", [(Display, "dpy"), (GLXname, "name")]),
+ Function((ConstCString), "glXQueryExtensionsString", [(Display, "dpy"), (Int, "screen")], sideeffects=False),
+ Function((ConstCString), "glXQueryServerString", [(Display, "dpy"), (Int, "screen"), (GLXname, "name")], sideeffects=False),
+ Function((ConstCString), "glXGetClientString", [(Display, "dpy"), (GLXname, "name")], sideeffects=False),
# GLX 1.2 and later
Function(Display, "glXGetCurrentDisplay", [], sideeffects=False),
# GLX_MESA_swap_control
Function(Int, "glXSwapIntervalMESA", [(UInt, "interval")]),
- Function(Int, "glXGetSwapIntervalMESA", []),
+ Function(Int, "glXGetSwapIntervalMESA", [], sideeffects=False),
# GLX_OML_sync_control
Function(Bool, "glXGetSyncValuesOML", [(Display, "dpy"), (GLXDrawable, "drawable"), (OpaquePointer(Int64), "ust"), (OpaquePointer(Int64), "msc"), (OpaquePointer(Int64), "sbc")]),
Function(Void, "glXFreeMemoryNV", [(OpaquePointer(Void), "pointer")]),
# Must be last
- Function(PROC, "glXGetProcAddressARB", [(Alias("const GLubyte *", CString), "procName")]),
- Function(PROC, "glXGetProcAddress", [(Alias("const GLubyte *", CString), "procName")]),
+ Function(PROC, "glXGetProcAddressARB", [(String(Const(GLubyte)), "procName")]),
+ Function(PROC, "glXGetProcAddress", [(String(Const(GLubyte)), "procName")]),
])
try:
int(length)
except ValueError:
- length = "%s" % length
+ length = '"%s"' % length
arg_type = '%s(%s, %s)' % (constructor, base_type, length)
else:
- length = length.replace("COMPSIZE", "_%s_size" % function_name)
- length = length.replace("/", ", ")
- arg_type = 'Opaque%s(%s, %s)' % (constructor, base_type, length)
+ if length == "COMPSIZE(pname)":
+ length = "_gl_param_size(pname)"
+ arg_type = '%s(%s, "%s")' % (constructor, base_type, length)
+ else:
+ length = length.replace("COMPSIZE", "_%s_size" % function_name)
+ length = length.replace("/", ", ")
+ arg_type = 'Opaque%s(%s, "%s")' % (constructor, base_type, length)
else:
assert False
return visitor.visitLiteral(self, *args, **kwargs)
+Bool = Literal("bool", "Bool")
+SChar = Literal("signed char", "SInt")
+UChar = Literal("unsigned char", "UInt")
+Short = Literal("short", "SInt")
+Int = Literal("int", "SInt")
+Long = Literal("long", "SInt")
+LongLong = Literal("long long", "SInt")
+UShort = Literal("unsigned short", "UInt")
+UInt = Literal("unsigned int", "UInt")
+ULong = Literal("unsigned long", "UInt")
+ULongLong = Literal("unsigned long long", "UInt")
+Float = Literal("float", "Float")
+Double = Literal("double", "Double")
+SizeT = Literal("size_t", "UInt")
+
+Char = Literal("char", "SInt")
+WChar = Literal("wchar_t", "SInt")
+
+Int8 = Literal("int8_t", "SInt")
+UInt8 = Literal("uint8_t", "UInt")
+Int16 = Literal("int16_t", "SInt")
+UInt16 = Literal("uint16_t", "UInt")
+Int32 = Literal("int32_t", "SInt")
+UInt32 = Literal("uint32_t", "UInt")
+Int64 = Literal("int64_t", "SInt")
+UInt64 = Literal("uint64_t", "UInt")
+
+IntPtr = Literal("intptr_t", "SInt")
+UIntPtr = Literal("uintptr_t", "UInt")
+
class Const(Type):
def __init__(self, type):
# While "const foo" and "foo const" are synonymous, "const foo *" and
# "foo * const" are not quite the same, and some compilers do enforce
# strict const correctness.
- if isinstance(type, String) or type is WString:
- # For strings we never intend to say a const pointer to chars, but
- # rather a point to const chars.
- expr = "const " + type.expr
- elif type.expr.startswith("const ") or '*' in type.expr:
+ if type.expr.startswith("const ") or '*' in type.expr:
expr = type.expr + " const"
else:
# The most legible
class String(Type):
+ '''Human-legible character string.'''
- def __init__(self, expr = "char *", length = None, kind = 'String'):
- Type.__init__(self, expr)
+ def __init__(self, type = Char, length = None, wide = False):
+ assert isinstance(type, Type)
+ Type.__init__(self, type.expr + ' *')
+ self.type = type
self.length = length
- self.kind = kind
+ self.wide = wide
def visit(self, visitor, *args, **kwargs):
return visitor.visitString(self, *args, **kwargs)
return literal
def visitString(self, string):
- return string
+ string_type = self.visit(string.type)
+ if string_type is string.type:
+ return string
+ else:
+ return String(string_type, string.length, string.wide)
def visitConst(self, const):
const_type = self.visit(const.type)
class MutableRebuilder(Rebuilder):
'''Type visitor which derives a mutable type.'''
+ def visitString(self, string):
+ return string
+
def visitConst(self, const):
# Strip out const qualifier
return const.type
return None
-Bool = Literal("bool", "Bool")
-SChar = Literal("signed char", "SInt")
-UChar = Literal("unsigned char", "UInt")
-Short = Literal("short", "SInt")
-Int = Literal("int", "SInt")
-Long = Literal("long", "SInt")
-LongLong = Literal("long long", "SInt")
-UShort = Literal("unsigned short", "UInt")
-UInt = Literal("unsigned int", "UInt")
-ULong = Literal("unsigned long", "UInt")
-ULongLong = Literal("unsigned long long", "UInt")
-Float = Literal("float", "Float")
-Double = Literal("double", "Double")
-SizeT = Literal("size_t", "UInt")
-
# C string (i.e., zero terminated)
-CString = String()
-WString = String("wchar_t *", kind="WString")
-
-Int8 = Literal("int8_t", "SInt")
-UInt8 = Literal("uint8_t", "UInt")
-Int16 = Literal("int16_t", "SInt")
-UInt16 = Literal("uint16_t", "UInt")
-Int32 = Literal("int32_t", "SInt")
-UInt32 = Literal("uint32_t", "UInt")
-Int64 = Literal("int64_t", "SInt")
-UInt64 = Literal("uint64_t", "UInt")
+CString = String(Char)
+WString = String(WChar, wide=True)
+ConstCString = String(Const(Char))
+ConstWString = String(Const(WChar), wide=True)
StdFunction(BOOL, "wglRestoreBufferRegionARB", [(HANDLE, "hRegion"), (Int, "x"), (Int, "y"), (Int, "width"), (Int, "height"), (Int, "xSrc"), (Int, "ySrc")]),
# WGL_ARB_extensions_string
- StdFunction(Const(CString), "wglGetExtensionsStringARB", [(HDC, "hdc")], sideeffects=False),
+ StdFunction(ConstCString, "wglGetExtensionsStringARB", [(HDC, "hdc")], sideeffects=False),
# WGL_ARB_pixel_format
StdFunction(BOOL, "wglGetPixelFormatAttribivARB", [(HDC, "hdc"), (Int, "iPixelFormat"), (Int, "iLayerPlane"), (UINT, "nAttributes"), (Array(WGLenum, "nAttributes"), "piAttributes"), Out(Array(Int, "nAttributes"), "piValues")], sideeffects=False),
StdFunction(HGLRC, "wglCreateContextAttribsARB", [(HDC, "hDC"), (HGLRC, "hShareContext"), (Array(Const(WGLenum), "_AttribPairList_size(attribList)"), "attribList")]),
# WGL_EXT_extensions_string
- StdFunction(Const(CString), "wglGetExtensionsStringEXT", [], sideeffects=False),
+ StdFunction(ConstCString, "wglGetExtensionsStringEXT", [], sideeffects=False),
# WGL_EXT_make_current_read
StdFunction(BOOL, "wglMakeContextCurrentEXT", [(HDC, "hDrawDC"), (HDC, "hReadDC"), (HGLRC, "hglrc")]),
LPBOOL = Pointer(BOOL)
LPSTR = CString
-LPCSTR = Const(CString)
+LPCSTR = ConstCString
LPWSTR = WString
-LPCWSTR = Const(WString)
+LPCWSTR = ConstWString
LARGE_INTEGER = Struct("LARGE_INTEGER", [
(LONGLONG, 'QuadPart'),
/* Header file version number */
/* Current version at http://www.khronos.org/registry/egl/ */
-/* $Revision: 16996 $ on $Date: 2012-02-29 18:38:19 -0800 (Wed, 29 Feb 2012) $ */
-#define EGL_EGLEXT_VERSION 11
+/* $Revision: 18699 $ on $Date: 2012-07-31 03:04:59 -0700 (Tue, 31 Jul 2012) $ */
+#define EGL_EGLEXT_VERSION 14
#ifndef EGL_KHR_config_attribs
#define EGL_KHR_config_attribs 1
typedef void* EGLSyncNV;
typedef khronos_utime_nanoseconds_t EGLTimeNV;
#ifdef EGL_EGLEXT_PROTOTYPES
-EGLSyncNV eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
-EGLBoolean eglDestroySyncNV (EGLSyncNV sync);
-EGLBoolean eglFenceNV (EGLSyncNV sync);
-EGLint eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
-EGLBoolean eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
-EGLBoolean eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
+EGLAPI EGLSyncNV EGLAPIENTRY eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncNV (EGLSyncNV sync);
+EGLAPI EGLBoolean EGLAPIENTRY eglFenceNV (EGLSyncNV sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
#endif
-#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
+#if KHRONOS_SUPPORT_INT64 /* EGLuint64NV requires 64-bit uint support */
#ifndef EGL_NV_system_time
#define EGL_NV_system_time 1
#endif
#endif
+#if KHRONOS_SUPPORT_INT64 /* EGLuint64KHR requires 64-bit uint support */
+#ifndef EGL_KHR_stream
+#define EGL_KHR_stream 1
+typedef void* EGLStreamKHR;
+typedef khronos_uint64_t EGLuint64KHR;
+#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0)
+#define EGL_CONSUMER_LATENCY_USEC_KHR 0x3210
+#define EGL_PRODUCER_FRAME_KHR 0x3212
+#define EGL_CONSUMER_FRAME_KHR 0x3213
+#define EGL_STREAM_STATE_KHR 0x3214
+#define EGL_STREAM_STATE_CREATED_KHR 0x3215
+#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
+#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
+#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define EGL_BAD_STREAM_KHR 0x321B
+#define EGL_BAD_STATE_KHR 0x321C
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamAttribKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamu64KHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC)(EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#endif
+#endif
+
+#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
+#ifndef EGL_KHR_stream_consumer_gltexture
+#define EGL_KHR_stream_consumer_gltexture 1
+#define EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR 0x321E
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+#endif
+
+#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
+#ifndef EGL_KHR_stream_producer_eglsurface
+#define EGL_KHR_stream_producer_eglsurface 1
+#define EGL_STREAM_BIT_KHR 0x0800
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSurface EGLAPIENTRY eglCreateStreamProducerSurfaceKHR(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC)(EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif
+#endif
+
+#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
+#ifndef EGL_KHR_stream_producer_aldatalocator
+#define EGL_KHR_stream_producer_aldatalocator 1
+#endif
+#endif
+
+#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
+#ifndef EGL_KHR_stream_fifo
+#define EGL_KHR_stream_fifo 1
+/* reuse EGLTimeKHR */
+#define EGL_STREAM_FIFO_LENGTH_KHR 0x31FC
+#define EGL_STREAM_TIME_NOW_KHR 0x31FD
+#define EGL_STREAM_TIME_CONSUMER_KHR 0x31FE
+#define EGL_STREAM_TIME_PRODUCER_KHR 0x31FF
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglQueryStreamTimeKHR(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+#endif
+#endif
+
#ifndef EGL_EXT_create_context_robustness
#define EGL_EXT_create_context_robustness 1
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
/* reuse EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE */
#endif
+#ifndef EGL_KHR_create_context
+#define EGL_KHR_create_context 1
+#define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION
+#define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
+#define EGL_CONTEXT_FLAGS_KHR 0x30FC
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR 0x30FD
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR 0x31BD
+#define EGL_NO_RESET_NOTIFICATION_KHR 0x31BE
+#define EGL_LOSE_CONTEXT_ON_RESET_KHR 0x31BF
+#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR 0x00000004
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR 0x00000002
+#endif
+
+#ifndef EGL_KHR_surfaceless_context
+#define EGL_KHR_surfaceless_context 1
+/* No tokens/entry points, just relaxes an error condition */
+#endif
+
+#ifdef EGL_KHR_stream /* Requires KHR_stream extension */
+#ifndef EGL_KHR_stream_cross_process_fd
+#define EGL_KHR_stream_cross_process_fd 1
+typedef int EGLNativeFileDescriptorKHR;
+#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1))
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLNativeFileDescriptorKHR EGLAPIENTRY eglGetStreamFileDescriptorKHR(EGLDisplay dpy, EGLStreamKHR stream);
+EGLAPI EGLStreamKHR EGLAPIENTRY eglCreateStreamFromFileDescriptorKHR(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMTIMEKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLTimeKHR *value);
+typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC)(EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif
+#endif
+
#ifdef __cplusplus
}
#endif
*/
/* Header file version number, required by OpenGL ABI for Linux */
-/* glext.h last updated $Date: 2012-03-05 02:52:51 -0800 (Mon, 05 Mar 2012) $ */
+/* glext.h last updated $Date: 2012-08-06 02:01:01 -0700 (Mon, 06 Aug 2012) $ */
/* Current version at http://www.opengl.org/registry/ */
-#define GL_GLEXT_VERSION 76
+#define GL_GLEXT_VERSION 83
/* Function declaration macros - to move into glplatform.h */
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
/* reuse GL_MAX_VERTEX_UNIFORM_VECTORS */
/* reuse GL_MAX_VARYING_VECTORS */
/* reuse GL_MAX_FRAGMENT_UNIFORM_VECTORS */
+/* reuse GL_RGB565 */
/* Reuse tokens from ARB_get_program_binary */
/* reuse GL_PROGRAM_BINARY_RETRIEVABLE_HINT */
/* reuse GL_PROGRAM_BINARY_LENGTH */
/* reuse GL_TEXTURE_IMMUTABLE_FORMAT */
#endif
+#ifndef GL_VERSION_4_3
+#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
+#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E
+/* Reuse tokens from ARB_arrays_of_arrays (none, GLSL only) */
+/* Reuse tokens from ARB_fragment_layer_viewport (none, GLSL only) */
+/* Reuse tokens from ARB_shader_image_size (none, GLSL only) */
+/* Reuse tokens from ARB_ES3_compatibility */
+/* reuse GL_COMPRESSED_RGB8_ETC2 */
+/* reuse GL_COMPRESSED_SRGB8_ETC2 */
+/* reuse GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 */
+/* reuse GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 */
+/* reuse GL_COMPRESSED_RGBA8_ETC2_EAC */
+/* reuse GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC */
+/* reuse GL_COMPRESSED_R11_EAC */
+/* reuse GL_COMPRESSED_SIGNED_R11_EAC */
+/* reuse GL_COMPRESSED_RG11_EAC */
+/* reuse GL_COMPRESSED_SIGNED_RG11_EAC */
+/* reuse GL_PRIMITIVE_RESTART_FIXED_INDEX */
+/* reuse GL_ANY_SAMPLES_PASSED_CONSERVATIVE */
+/* reuse GL_MAX_ELEMENT_INDEX */
+/* Reuse tokens from ARB_clear_buffer_object (none) */
+/* Reuse tokens from ARB_compute_shader */
+/* reuse GL_COMPUTE_SHADER */
+/* reuse GL_MAX_COMPUTE_UNIFORM_BLOCKS */
+/* reuse GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS */
+/* reuse GL_MAX_COMPUTE_IMAGE_UNIFORMS */
+/* reuse GL_MAX_COMPUTE_SHARED_MEMORY_SIZE */
+/* reuse GL_MAX_COMPUTE_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS */
+/* reuse GL_MAX_COMPUTE_ATOMIC_COUNTERS */
+/* reuse GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS */
+/* reuse GL_MAX_COMPUTE_LOCAL_INVOCATIONS */
+/* reuse GL_MAX_COMPUTE_WORK_GROUP_COUNT */
+/* reuse GL_MAX_COMPUTE_WORK_GROUP_SIZE */
+/* reuse GL_COMPUTE_LOCAL_WORK_SIZE */
+/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER */
+/* reuse GL_DISPATCH_INDIRECT_BUFFER */
+/* reuse GL_DISPATCH_INDIRECT_BUFFER_BINDING */
+/* Reuse tokens from ARB_copy_image (none) */
+/* Reuse tokens from KHR_debug */
+/* reuse GL_DEBUG_OUTPUT_SYNCHRONOUS */
+/* reuse GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH */
+/* reuse GL_DEBUG_CALLBACK_FUNCTION */
+/* reuse GL_DEBUG_CALLBACK_USER_PARAM */
+/* reuse GL_DEBUG_SOURCE_API */
+/* reuse GL_DEBUG_SOURCE_WINDOW_SYSTEM */
+/* reuse GL_DEBUG_SOURCE_SHADER_COMPILER */
+/* reuse GL_DEBUG_SOURCE_THIRD_PARTY */
+/* reuse GL_DEBUG_SOURCE_APPLICATION */
+/* reuse GL_DEBUG_SOURCE_OTHER */
+/* reuse GL_DEBUG_TYPE_ERROR */
+/* reuse GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR */
+/* reuse GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR */
+/* reuse GL_DEBUG_TYPE_PORTABILITY */
+/* reuse GL_DEBUG_TYPE_PERFORMANCE */
+/* reuse GL_DEBUG_TYPE_OTHER */
+/* reuse GL_MAX_DEBUG_MESSAGE_LENGTH */
+/* reuse GL_MAX_DEBUG_LOGGED_MESSAGES */
+/* reuse GL_DEBUG_LOGGED_MESSAGES */
+/* reuse GL_DEBUG_SEVERITY_HIGH */
+/* reuse GL_DEBUG_SEVERITY_MEDIUM */
+/* reuse GL_DEBUG_SEVERITY_LOW */
+/* reuse GL_DEBUG_TYPE_MARKER */
+/* reuse GL_DEBUG_TYPE_PUSH_GROUP */
+/* reuse GL_DEBUG_TYPE_POP_GROUP */
+/* reuse GL_DEBUG_SEVERITY_NOTIFICATION */
+/* reuse GL_MAX_DEBUG_GROUP_STACK_DEPTH */
+/* reuse GL_DEBUG_GROUP_STACK_DEPTH */
+/* reuse GL_BUFFER */
+/* reuse GL_SHADER */
+/* reuse GL_PROGRAM */
+/* reuse GL_QUERY */
+/* reuse GL_PROGRAM_PIPELINE */
+/* reuse GL_SAMPLER */
+/* reuse GL_DISPLAY_LIST */
+/* reuse GL_MAX_LABEL_LENGTH */
+/* reuse GL_DEBUG_OUTPUT */
+/* reuse GL_CONTEXT_FLAG_DEBUG_BIT */
+/* reuse GL_STACK_UNDERFLOW */
+/* reuse GL_STACK_OVERFLOW */
+/* Reuse tokens from ARB_explicit_uniform_location */
+/* reuse GL_MAX_UNIFORM_LOCATIONS */
+/* Reuse tokens from ARB_framebuffer_no_attachments */
+/* reuse GL_FRAMEBUFFER_DEFAULT_WIDTH */
+/* reuse GL_FRAMEBUFFER_DEFAULT_HEIGHT */
+/* reuse GL_FRAMEBUFFER_DEFAULT_LAYERS */
+/* reuse GL_FRAMEBUFFER_DEFAULT_SAMPLES */
+/* reuse GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS */
+/* reuse GL_MAX_FRAMEBUFFER_WIDTH */
+/* reuse GL_MAX_FRAMEBUFFER_HEIGHT */
+/* reuse GL_MAX_FRAMEBUFFER_LAYERS */
+/* reuse GL_MAX_FRAMEBUFFER_SAMPLES */
+/* Reuse tokens from ARB_internalformat_query2 */
+/* reuse GL_INTERNALFORMAT_SUPPORTED */
+/* reuse GL_INTERNALFORMAT_PREFERRED */
+/* reuse GL_INTERNALFORMAT_RED_SIZE */
+/* reuse GL_INTERNALFORMAT_GREEN_SIZE */
+/* reuse GL_INTERNALFORMAT_BLUE_SIZE */
+/* reuse GL_INTERNALFORMAT_ALPHA_SIZE */
+/* reuse GL_INTERNALFORMAT_DEPTH_SIZE */
+/* reuse GL_INTERNALFORMAT_STENCIL_SIZE */
+/* reuse GL_INTERNALFORMAT_SHARED_SIZE */
+/* reuse GL_INTERNALFORMAT_RED_TYPE */
+/* reuse GL_INTERNALFORMAT_GREEN_TYPE */
+/* reuse GL_INTERNALFORMAT_BLUE_TYPE */
+/* reuse GL_INTERNALFORMAT_ALPHA_TYPE */
+/* reuse GL_INTERNALFORMAT_DEPTH_TYPE */
+/* reuse GL_INTERNALFORMAT_STENCIL_TYPE */
+/* reuse GL_MAX_WIDTH */
+/* reuse GL_MAX_HEIGHT */
+/* reuse GL_MAX_DEPTH */
+/* reuse GL_MAX_LAYERS */
+/* reuse GL_MAX_COMBINED_DIMENSIONS */
+/* reuse GL_COLOR_COMPONENTS */
+/* reuse GL_DEPTH_COMPONENTS */
+/* reuse GL_STENCIL_COMPONENTS */
+/* reuse GL_COLOR_RENDERABLE */
+/* reuse GL_DEPTH_RENDERABLE */
+/* reuse GL_STENCIL_RENDERABLE */
+/* reuse GL_FRAMEBUFFER_RENDERABLE */
+/* reuse GL_FRAMEBUFFER_RENDERABLE_LAYERED */
+/* reuse GL_FRAMEBUFFER_BLEND */
+/* reuse GL_READ_PIXELS */
+/* reuse GL_READ_PIXELS_FORMAT */
+/* reuse GL_READ_PIXELS_TYPE */
+/* reuse GL_TEXTURE_IMAGE_FORMAT */
+/* reuse GL_TEXTURE_IMAGE_TYPE */
+/* reuse GL_GET_TEXTURE_IMAGE_FORMAT */
+/* reuse GL_GET_TEXTURE_IMAGE_TYPE */
+/* reuse GL_MIPMAP */
+/* reuse GL_MANUAL_GENERATE_MIPMAP */
+/* reuse GL_AUTO_GENERATE_MIPMAP */
+/* reuse GL_COLOR_ENCODING */
+/* reuse GL_SRGB_READ */
+/* reuse GL_SRGB_WRITE */
+/* reuse GL_FILTER */
+/* reuse GL_VERTEX_TEXTURE */
+/* reuse GL_TESS_CONTROL_TEXTURE */
+/* reuse GL_TESS_EVALUATION_TEXTURE */
+/* reuse GL_GEOMETRY_TEXTURE */
+/* reuse GL_FRAGMENT_TEXTURE */
+/* reuse GL_COMPUTE_TEXTURE */
+/* reuse GL_TEXTURE_SHADOW */
+/* reuse GL_TEXTURE_GATHER */
+/* reuse GL_TEXTURE_GATHER_SHADOW */
+/* reuse GL_SHADER_IMAGE_LOAD */
+/* reuse GL_SHADER_IMAGE_STORE */
+/* reuse GL_SHADER_IMAGE_ATOMIC */
+/* reuse GL_IMAGE_TEXEL_SIZE */
+/* reuse GL_IMAGE_COMPATIBILITY_CLASS */
+/* reuse GL_IMAGE_PIXEL_FORMAT */
+/* reuse GL_IMAGE_PIXEL_TYPE */
+/* reuse GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST */
+/* reuse GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST */
+/* reuse GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE */
+/* reuse GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE */
+/* reuse GL_TEXTURE_COMPRESSED_BLOCK_WIDTH */
+/* reuse GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT */
+/* reuse GL_TEXTURE_COMPRESSED_BLOCK_SIZE */
+/* reuse GL_CLEAR_BUFFER */
+/* reuse GL_TEXTURE_VIEW */
+/* reuse GL_VIEW_COMPATIBILITY_CLASS */
+/* reuse GL_FULL_SUPPORT */
+/* reuse GL_CAVEAT_SUPPORT */
+/* reuse GL_IMAGE_CLASS_4_X_32 */
+/* reuse GL_IMAGE_CLASS_2_X_32 */
+/* reuse GL_IMAGE_CLASS_1_X_32 */
+/* reuse GL_IMAGE_CLASS_4_X_16 */
+/* reuse GL_IMAGE_CLASS_2_X_16 */
+/* reuse GL_IMAGE_CLASS_1_X_16 */
+/* reuse GL_IMAGE_CLASS_4_X_8 */
+/* reuse GL_IMAGE_CLASS_2_X_8 */
+/* reuse GL_IMAGE_CLASS_1_X_8 */
+/* reuse GL_IMAGE_CLASS_11_11_10 */
+/* reuse GL_IMAGE_CLASS_10_10_10_2 */
+/* reuse GL_VIEW_CLASS_128_BITS */
+/* reuse GL_VIEW_CLASS_96_BITS */
+/* reuse GL_VIEW_CLASS_64_BITS */
+/* reuse GL_VIEW_CLASS_48_BITS */
+/* reuse GL_VIEW_CLASS_32_BITS */
+/* reuse GL_VIEW_CLASS_24_BITS */
+/* reuse GL_VIEW_CLASS_16_BITS */
+/* reuse GL_VIEW_CLASS_8_BITS */
+/* reuse GL_VIEW_CLASS_S3TC_DXT1_RGB */
+/* reuse GL_VIEW_CLASS_S3TC_DXT1_RGBA */
+/* reuse GL_VIEW_CLASS_S3TC_DXT3_RGBA */
+/* reuse GL_VIEW_CLASS_S3TC_DXT5_RGBA */
+/* reuse GL_VIEW_CLASS_RGTC1_RED */
+/* reuse GL_VIEW_CLASS_RGTC2_RG */
+/* reuse GL_VIEW_CLASS_BPTC_UNORM */
+/* reuse GL_VIEW_CLASS_BPTC_FLOAT */
+/* Reuse tokens from ARB_invalidate_subdata (none) */
+/* Reuse tokens from ARB_multi_draw_indirect (none) */
+/* Reuse tokens from ARB_program_interface_query */
+/* reuse GL_UNIFORM */
+/* reuse GL_UNIFORM_BLOCK */
+/* reuse GL_PROGRAM_INPUT */
+/* reuse GL_PROGRAM_OUTPUT */
+/* reuse GL_BUFFER_VARIABLE */
+/* reuse GL_SHADER_STORAGE_BLOCK */
+/* reuse GL_VERTEX_SUBROUTINE */
+/* reuse GL_TESS_CONTROL_SUBROUTINE */
+/* reuse GL_TESS_EVALUATION_SUBROUTINE */
+/* reuse GL_GEOMETRY_SUBROUTINE */
+/* reuse GL_FRAGMENT_SUBROUTINE */
+/* reuse GL_COMPUTE_SUBROUTINE */
+/* reuse GL_VERTEX_SUBROUTINE_UNIFORM */
+/* reuse GL_TESS_CONTROL_SUBROUTINE_UNIFORM */
+/* reuse GL_TESS_EVALUATION_SUBROUTINE_UNIFORM */
+/* reuse GL_GEOMETRY_SUBROUTINE_UNIFORM */
+/* reuse GL_FRAGMENT_SUBROUTINE_UNIFORM */
+/* reuse GL_COMPUTE_SUBROUTINE_UNIFORM */
+/* reuse GL_TRANSFORM_FEEDBACK_VARYING */
+/* reuse GL_ACTIVE_RESOURCES */
+/* reuse GL_MAX_NAME_LENGTH */
+/* reuse GL_MAX_NUM_ACTIVE_VARIABLES */
+/* reuse GL_MAX_NUM_COMPATIBLE_SUBROUTINES */
+/* reuse GL_NAME_LENGTH */
+/* reuse GL_TYPE */
+/* reuse GL_ARRAY_SIZE */
+/* reuse GL_OFFSET */
+/* reuse GL_BLOCK_INDEX */
+/* reuse GL_ARRAY_STRIDE */
+/* reuse GL_MATRIX_STRIDE */
+/* reuse GL_IS_ROW_MAJOR */
+/* reuse GL_ATOMIC_COUNTER_BUFFER_INDEX */
+/* reuse GL_BUFFER_BINDING */
+/* reuse GL_BUFFER_DATA_SIZE */
+/* reuse GL_NUM_ACTIVE_VARIABLES */
+/* reuse GL_ACTIVE_VARIABLES */
+/* reuse GL_REFERENCED_BY_VERTEX_SHADER */
+/* reuse GL_REFERENCED_BY_TESS_CONTROL_SHADER */
+/* reuse GL_REFERENCED_BY_TESS_EVALUATION_SHADER */
+/* reuse GL_REFERENCED_BY_GEOMETRY_SHADER */
+/* reuse GL_REFERENCED_BY_FRAGMENT_SHADER */
+/* reuse GL_REFERENCED_BY_COMPUTE_SHADER */
+/* reuse GL_TOP_LEVEL_ARRAY_SIZE */
+/* reuse GL_TOP_LEVEL_ARRAY_STRIDE */
+/* reuse GL_LOCATION */
+/* reuse GL_LOCATION_INDEX */
+/* reuse GL_IS_PER_PATCH */
+/* Reuse tokens from ARB_robust_buffer_access_behavior (none) */
+/* Reuse tokens from ARB_shader_storage_buffer_object */
+/* reuse GL_SHADER_STORAGE_BUFFER */
+/* reuse GL_SHADER_STORAGE_BUFFER_BINDING */
+/* reuse GL_SHADER_STORAGE_BUFFER_START */
+/* reuse GL_SHADER_STORAGE_BUFFER_SIZE */
+/* reuse GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS */
+/* reuse GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS */
+/* reuse GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS */
+/* reuse GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS */
+/* reuse GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS */
+/* reuse GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS */
+/* reuse GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS */
+/* reuse GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS */
+/* reuse GL_MAX_SHADER_STORAGE_BLOCK_SIZE */
+/* reuse GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT */
+/* reuse GL_SHADER_STORAGE_BARRIER_BIT */
+/* reuse GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES */
+/* Reuse tokens from ARB_stencil_texturing */
+/* reuse GL_DEPTH_STENCIL_TEXTURE_MODE */
+/* Reuse tokens from ARB_texture_buffer_range */
+/* reuse GL_TEXTURE_BUFFER_OFFSET */
+/* reuse GL_TEXTURE_BUFFER_SIZE */
+/* reuse GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT */
+/* Reuse tokens from ARB_texture_query_levels (none) */
+/* Reuse tokens from ARB_texture_storage_multisample (none) */
+/* Reuse tokens from ARB_texture_view */
+/* reuse GL_TEXTURE_VIEW_MIN_LEVEL */
+/* reuse GL_TEXTURE_VIEW_NUM_LEVELS */
+/* reuse GL_TEXTURE_VIEW_MIN_LAYER */
+/* reuse GL_TEXTURE_VIEW_NUM_LAYERS */
+/* reuse GL_TEXTURE_IMMUTABLE_LEVELS */
+/* Reuse tokens from ARB_vertex_attrib_binding */
+/* reuse GL_VERTEX_ATTRIB_BINDING */
+/* reuse GL_VERTEX_ATTRIB_RELATIVE_OFFSET */
+/* reuse GL_VERTEX_BINDING_DIVISOR */
+/* reuse GL_VERTEX_BINDING_OFFSET */
+/* reuse GL_VERTEX_BINDING_STRIDE */
+/* reuse GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET */
+/* reuse GL_MAX_VERTEX_ATTRIB_BINDINGS */
+#endif
+
#ifndef GL_ARB_multitexture
#define GL_TEXTURE0_ARB 0x84C0
#define GL_TEXTURE1_ARB 0x84C1
#endif
#ifndef GL_ARB_copy_buffer
-#define GL_COPY_READ_BUFFER 0x8F36
-#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_COPY_READ_BUFFER_BINDING 0x8F36
+#define GL_COPY_READ_BUFFER GL_COPY_READ_BUFFER_BINDING
+#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
+#define GL_COPY_WRITE_BUFFER GL_COPY_WRITE_BUFFER_BINDING
#endif
#ifndef GL_ARB_shader_texture_lod
#ifndef GL_ARB_transform_feedback2
#define GL_TRANSFORM_FEEDBACK 0x8E22
-#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23
-#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED GL_TRANSFORM_FEEDBACK_PAUSED
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE GL_TRANSFORM_FEEDBACK_ACTIVE
#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
#endif
#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB
#define GL_MAX_VARYING_VECTORS 0x8DFC
#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD
+#define GL_RGB565 0x8D62
#endif
#ifndef GL_ARB_get_program_binary
#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
#endif
+#ifndef GL_KHR_texture_compression_astc_ldr
+#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
+#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
+#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
+#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
+#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
+#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
+#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
+#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
+#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
+#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
+#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
+#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
+#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
+#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
+#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
+#endif
+
+#ifndef GL_KHR_debug
+#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
+#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
+#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
+#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
+#define GL_DEBUG_SOURCE_API 0x8246
+#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
+#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
+#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
+#define GL_DEBUG_SOURCE_APPLICATION 0x824A
+#define GL_DEBUG_SOURCE_OTHER 0x824B
+#define GL_DEBUG_TYPE_ERROR 0x824C
+#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
+#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
+#define GL_DEBUG_TYPE_PORTABILITY 0x824F
+#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
+#define GL_DEBUG_TYPE_OTHER 0x8251
+#define GL_DEBUG_TYPE_MARKER 0x8268
+#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
+#define GL_DEBUG_TYPE_POP_GROUP 0x826A
+#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
+#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
+#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
+#define GL_BUFFER 0x82E0
+#define GL_SHADER 0x82E1
+#define GL_PROGRAM 0x82E2
+#define GL_QUERY 0x82E3
+#define GL_PROGRAM_PIPELINE 0x82E4
+#define GL_SAMPLER 0x82E6
+#define GL_DISPLAY_LIST 0x82E7
+#define GL_MAX_LABEL_LENGTH 0x82E8
+#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
+#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
+#define GL_DEBUG_LOGGED_MESSAGES 0x9145
+#define GL_DEBUG_SEVERITY_HIGH 0x9146
+#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
+#define GL_DEBUG_SEVERITY_LOW 0x9148
+#define GL_DEBUG_OUTPUT 0x92E0
+#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
+/* reuse GL_STACK_UNDERFLOW */
+/* reuse GL_STACK_OVERFLOW */
+#endif
+
+#ifndef GL_ARB_arrays_of_arrays
+#endif
+
+#ifndef GL_ARB_clear_buffer_object
+#endif
+
+#ifndef GL_ARB_compute_shader
+#define GL_COMPUTE_SHADER 0x91B9
+#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
+#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
+#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
+#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
+#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
+#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
+#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
+#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
+#define GL_MAX_COMPUTE_LOCAL_INVOCATIONS 0x90EB
+#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
+#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
+#define GL_COMPUTE_LOCAL_WORK_SIZE 0x8267
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
+#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
+#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
+#define GL_COMPUTE_SHADER_BIT 0x00000020
+#endif
+
+#ifndef GL_ARB_copy_image
+#endif
+
+#ifndef GL_ARB_debug_group
+/* reuse GL_DEBUG_TYPE_MARKER */
+/* reuse GL_DEBUG_TYPE_PUSH_GROUP */
+/* reuse GL_DEBUG_TYPE_POP_GROUP */
+/* reuse GL_DEBUG_SEVERITY_NOTIFICATION */
+/* reuse GL_MAX_DEBUG_GROUP_STACK_DEPTH */
+/* reuse GL_DEBUG_GROUP_STACK_DEPTH */
+/* reuse GL_STACK_UNDERFLOW */
+/* reuse GL_STACK_OVERFLOW */
+#endif
+
+#ifndef GL_ARB_debug_label
+/* reuse GL_BUFFER */
+/* reuse GL_SHADER */
+/* reuse GL_PROGRAM */
+/* reuse GL_QUERY */
+/* reuse GL_PROGRAM_PIPELINE */
+/* reuse GL_SAMPLER */
+/* DISPLAY_LIST used in compatibility profile only */
+/* reuse GL_DISPLAY_LIST */
+/* reuse GL_MAX_LABEL_LENGTH */
+/* reuse GL_VERTEX_ARRAY */
+#endif
+
+#ifndef GL_ARB_debug_output2
+/* reuse GL_CONTEXT_FLAG_DEBUG_BIT */
+/* reuse GL_DEBUG_OUTPUT */
+#endif
+
+#ifndef GL_ARB_ES3_compatibility
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#endif
+
+#ifndef GL_ARB_explicit_uniform_location
+#define GL_MAX_UNIFORM_LOCATIONS 0x826E
+#endif
+
+#ifndef GL_ARB_fragment_layer_viewport
+#endif
+
+#ifndef GL_ARB_framebuffer_no_attachments
+#define GL_FRAMEBUFFER_DEFAULT_WIDTH 0x9310
+#define GL_FRAMEBUFFER_DEFAULT_HEIGHT 0x9311
+#define GL_FRAMEBUFFER_DEFAULT_LAYERS 0x9312
+#define GL_FRAMEBUFFER_DEFAULT_SAMPLES 0x9313
+#define GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS 0x9314
+#define GL_MAX_FRAMEBUFFER_WIDTH 0x9315
+#define GL_MAX_FRAMEBUFFER_HEIGHT 0x9316
+#define GL_MAX_FRAMEBUFFER_LAYERS 0x9317
+#define GL_MAX_FRAMEBUFFER_SAMPLES 0x9318
+#endif
+
+#ifndef GL_ARB_internalformat_query2
+/* reuse GL_IMAGE_FORMAT_COMPATIBILITY_TYPE */
+/* reuse GL_NUM_SAMPLE_COUNTS */
+/* reuse GL_RENDERBUFFER */
+/* reuse GL_SAMPLES */
+/* reuse GL_TEXTURE_1D */
+/* reuse GL_TEXTURE_1D_ARRAY */
+/* reuse GL_TEXTURE_2D */
+/* reuse GL_TEXTURE_2D_ARRAY */
+/* reuse GL_TEXTURE_3D */
+/* reuse GL_TEXTURE_CUBE_MAP */
+/* reuse GL_TEXTURE_CUBE_MAP_ARRAY */
+/* reuse GL_TEXTURE_RECTANGLE */
+/* reuse GL_TEXTURE_BUFFER */
+/* reuse GL_TEXTURE_2D_MULTISAMPLE */
+/* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_TEXTURE_COMPRESSED */
+#define GL_INTERNALFORMAT_SUPPORTED 0x826F
+#define GL_INTERNALFORMAT_PREFERRED 0x8270
+#define GL_INTERNALFORMAT_RED_SIZE 0x8271
+#define GL_INTERNALFORMAT_GREEN_SIZE 0x8272
+#define GL_INTERNALFORMAT_BLUE_SIZE 0x8273
+#define GL_INTERNALFORMAT_ALPHA_SIZE 0x8274
+#define GL_INTERNALFORMAT_DEPTH_SIZE 0x8275
+#define GL_INTERNALFORMAT_STENCIL_SIZE 0x8276
+#define GL_INTERNALFORMAT_SHARED_SIZE 0x8277
+#define GL_INTERNALFORMAT_RED_TYPE 0x8278
+#define GL_INTERNALFORMAT_GREEN_TYPE 0x8279
+#define GL_INTERNALFORMAT_BLUE_TYPE 0x827A
+#define GL_INTERNALFORMAT_ALPHA_TYPE 0x827B
+#define GL_INTERNALFORMAT_DEPTH_TYPE 0x827C
+#define GL_INTERNALFORMAT_STENCIL_TYPE 0x827D
+#define GL_MAX_WIDTH 0x827E
+#define GL_MAX_HEIGHT 0x827F
+#define GL_MAX_DEPTH 0x8280
+#define GL_MAX_LAYERS 0x8281
+#define GL_MAX_COMBINED_DIMENSIONS 0x8282
+#define GL_COLOR_COMPONENTS 0x8283
+#define GL_DEPTH_COMPONENTS 0x8284
+#define GL_STENCIL_COMPONENTS 0x8285
+#define GL_COLOR_RENDERABLE 0x8286
+#define GL_DEPTH_RENDERABLE 0x8287
+#define GL_STENCIL_RENDERABLE 0x8288
+#define GL_FRAMEBUFFER_RENDERABLE 0x8289
+#define GL_FRAMEBUFFER_RENDERABLE_LAYERED 0x828A
+#define GL_FRAMEBUFFER_BLEND 0x828B
+#define GL_READ_PIXELS 0x828C
+#define GL_READ_PIXELS_FORMAT 0x828D
+#define GL_READ_PIXELS_TYPE 0x828E
+#define GL_TEXTURE_IMAGE_FORMAT 0x828F
+#define GL_TEXTURE_IMAGE_TYPE 0x8290
+#define GL_GET_TEXTURE_IMAGE_FORMAT 0x8291
+#define GL_GET_TEXTURE_IMAGE_TYPE 0x8292
+#define GL_MIPMAP 0x8293
+#define GL_MANUAL_GENERATE_MIPMAP 0x8294
+#define GL_AUTO_GENERATE_MIPMAP 0x8295
+#define GL_COLOR_ENCODING 0x8296
+#define GL_SRGB_READ 0x8297
+#define GL_SRGB_WRITE 0x8298
+#define GL_SRGB_DECODE_ARB 0x8299
+#define GL_FILTER 0x829A
+#define GL_VERTEX_TEXTURE 0x829B
+#define GL_TESS_CONTROL_TEXTURE 0x829C
+#define GL_TESS_EVALUATION_TEXTURE 0x829D
+#define GL_GEOMETRY_TEXTURE 0x829E
+#define GL_FRAGMENT_TEXTURE 0x829F
+#define GL_COMPUTE_TEXTURE 0x82A0
+#define GL_TEXTURE_SHADOW 0x82A1
+#define GL_TEXTURE_GATHER 0x82A2
+#define GL_TEXTURE_GATHER_SHADOW 0x82A3
+#define GL_SHADER_IMAGE_LOAD 0x82A4
+#define GL_SHADER_IMAGE_STORE 0x82A5
+#define GL_SHADER_IMAGE_ATOMIC 0x82A6
+#define GL_IMAGE_TEXEL_SIZE 0x82A7
+#define GL_IMAGE_COMPATIBILITY_CLASS 0x82A8
+#define GL_IMAGE_PIXEL_FORMAT 0x82A9
+#define GL_IMAGE_PIXEL_TYPE 0x82AA
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST 0x82AC
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST 0x82AD
+#define GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE 0x82AE
+#define GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE 0x82AF
+#define GL_TEXTURE_COMPRESSED_BLOCK_WIDTH 0x82B1
+#define GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT 0x82B2
+#define GL_TEXTURE_COMPRESSED_BLOCK_SIZE 0x82B3
+#define GL_CLEAR_BUFFER 0x82B4
+#define GL_TEXTURE_VIEW 0x82B5
+#define GL_VIEW_COMPATIBILITY_CLASS 0x82B6
+#define GL_FULL_SUPPORT 0x82B7
+#define GL_CAVEAT_SUPPORT 0x82B8
+#define GL_IMAGE_CLASS_4_X_32 0x82B9
+#define GL_IMAGE_CLASS_2_X_32 0x82BA
+#define GL_IMAGE_CLASS_1_X_32 0x82BB
+#define GL_IMAGE_CLASS_4_X_16 0x82BC
+#define GL_IMAGE_CLASS_2_X_16 0x82BD
+#define GL_IMAGE_CLASS_1_X_16 0x82BE
+#define GL_IMAGE_CLASS_4_X_8 0x82BF
+#define GL_IMAGE_CLASS_2_X_8 0x82C0
+#define GL_IMAGE_CLASS_1_X_8 0x82C1
+#define GL_IMAGE_CLASS_11_11_10 0x82C2
+#define GL_IMAGE_CLASS_10_10_10_2 0x82C3
+#define GL_VIEW_CLASS_128_BITS 0x82C4
+#define GL_VIEW_CLASS_96_BITS 0x82C5
+#define GL_VIEW_CLASS_64_BITS 0x82C6
+#define GL_VIEW_CLASS_48_BITS 0x82C7
+#define GL_VIEW_CLASS_32_BITS 0x82C8
+#define GL_VIEW_CLASS_24_BITS 0x82C9
+#define GL_VIEW_CLASS_16_BITS 0x82CA
+#define GL_VIEW_CLASS_8_BITS 0x82CB
+#define GL_VIEW_CLASS_S3TC_DXT1_RGB 0x82CC
+#define GL_VIEW_CLASS_S3TC_DXT1_RGBA 0x82CD
+#define GL_VIEW_CLASS_S3TC_DXT3_RGBA 0x82CE
+#define GL_VIEW_CLASS_S3TC_DXT5_RGBA 0x82CF
+#define GL_VIEW_CLASS_RGTC1_RED 0x82D0
+#define GL_VIEW_CLASS_RGTC2_RG 0x82D1
+#define GL_VIEW_CLASS_BPTC_UNORM 0x82D2
+#define GL_VIEW_CLASS_BPTC_FLOAT 0x82D3
+#endif
+
+#ifndef GL_ARB_invalidate_subdata
+#endif
+
+#ifndef GL_ARB_multi_draw_indirect
+#endif
+
+#ifndef GL_ARB_program_interface_query
+#define GL_UNIFORM 0x92E1
+#define GL_UNIFORM_BLOCK 0x92E2
+#define GL_PROGRAM_INPUT 0x92E3
+#define GL_PROGRAM_OUTPUT 0x92E4
+#define GL_BUFFER_VARIABLE 0x92E5
+#define GL_SHADER_STORAGE_BLOCK 0x92E6
+/* reuse GL_ATOMIC_COUNTER_BUFFER */
+#define GL_VERTEX_SUBROUTINE 0x92E8
+#define GL_TESS_CONTROL_SUBROUTINE 0x92E9
+#define GL_TESS_EVALUATION_SUBROUTINE 0x92EA
+#define GL_GEOMETRY_SUBROUTINE 0x92EB
+#define GL_FRAGMENT_SUBROUTINE 0x92EC
+#define GL_COMPUTE_SUBROUTINE 0x92ED
+#define GL_VERTEX_SUBROUTINE_UNIFORM 0x92EE
+#define GL_TESS_CONTROL_SUBROUTINE_UNIFORM 0x92EF
+#define GL_TESS_EVALUATION_SUBROUTINE_UNIFORM 0x92F0
+#define GL_GEOMETRY_SUBROUTINE_UNIFORM 0x92F1
+#define GL_FRAGMENT_SUBROUTINE_UNIFORM 0x92F2
+#define GL_COMPUTE_SUBROUTINE_UNIFORM 0x92F3
+#define GL_TRANSFORM_FEEDBACK_VARYING 0x92F4
+#define GL_ACTIVE_RESOURCES 0x92F5
+#define GL_MAX_NAME_LENGTH 0x92F6
+#define GL_MAX_NUM_ACTIVE_VARIABLES 0x92F7
+#define GL_MAX_NUM_COMPATIBLE_SUBROUTINES 0x92F8
+#define GL_NAME_LENGTH 0x92F9
+#define GL_TYPE 0x92FA
+#define GL_ARRAY_SIZE 0x92FB
+#define GL_OFFSET 0x92FC
+#define GL_BLOCK_INDEX 0x92FD
+#define GL_ARRAY_STRIDE 0x92FE
+#define GL_MATRIX_STRIDE 0x92FF
+#define GL_IS_ROW_MAJOR 0x9300
+#define GL_ATOMIC_COUNTER_BUFFER_INDEX 0x9301
+#define GL_BUFFER_BINDING 0x9302
+#define GL_BUFFER_DATA_SIZE 0x9303
+#define GL_NUM_ACTIVE_VARIABLES 0x9304
+#define GL_ACTIVE_VARIABLES 0x9305
+#define GL_REFERENCED_BY_VERTEX_SHADER 0x9306
+#define GL_REFERENCED_BY_TESS_CONTROL_SHADER 0x9307
+#define GL_REFERENCED_BY_TESS_EVALUATION_SHADER 0x9308
+#define GL_REFERENCED_BY_GEOMETRY_SHADER 0x9309
+#define GL_REFERENCED_BY_FRAGMENT_SHADER 0x930A
+#define GL_REFERENCED_BY_COMPUTE_SHADER 0x930B
+#define GL_TOP_LEVEL_ARRAY_SIZE 0x930C
+#define GL_TOP_LEVEL_ARRAY_STRIDE 0x930D
+#define GL_LOCATION 0x930E
+#define GL_LOCATION_INDEX 0x930F
+#define GL_IS_PER_PATCH 0x92E7
+/* reuse GL_NUM_COMPATIBLE_SUBROUTINES */
+/* reuse GL_COMPATIBLE_SUBROUTINES */
+#endif
+
+#ifndef GL_ARB_robust_buffer_access_behavior
+#endif
+
+#ifndef GL_ARB_shader_image_size
+#endif
+
+#ifndef GL_ARB_shader_storage_buffer_object
+#define GL_SHADER_STORAGE_BUFFER 0x90D2
+#define GL_SHADER_STORAGE_BUFFER_BINDING 0x90D3
+#define GL_SHADER_STORAGE_BUFFER_START 0x90D4
+#define GL_SHADER_STORAGE_BUFFER_SIZE 0x90D5
+#define GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS 0x90D6
+#define GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS 0x90D7
+#define GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS 0x90D8
+#define GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS 0x90D9
+#define GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS 0x90DA
+#define GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS 0x90DB
+#define GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS 0x90DC
+#define GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS 0x90DD
+#define GL_MAX_SHADER_STORAGE_BLOCK_SIZE 0x90DE
+#define GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 0x90DF
+#define GL_SHADER_STORAGE_BARRIER_BIT 0x2000
+#define GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS
+/* reuse GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS */
+#endif
+
+#ifndef GL_ARB_stencil_texturing
+#define GL_DEPTH_STENCIL_TEXTURE_MODE 0x90EA
+#endif
+
+#ifndef GL_ARB_texture_buffer_range
+#define GL_TEXTURE_BUFFER_OFFSET 0x919D
+#define GL_TEXTURE_BUFFER_SIZE 0x919E
+#define GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT 0x919F
+#endif
+
+#ifndef GL_ARB_texture_query_levels
+#endif
+
+#ifndef GL_ARB_texture_storage_multisample
+#endif
+
+#ifndef GL_ARB_texture_view
+#define GL_TEXTURE_VIEW_MIN_LEVEL 0x82DB
+#define GL_TEXTURE_VIEW_NUM_LEVELS 0x82DC
+#define GL_TEXTURE_VIEW_MIN_LAYER 0x82DD
+#define GL_TEXTURE_VIEW_NUM_LAYERS 0x82DE
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+#endif
+
+#ifndef GL_ARB_vertex_attrib_binding
+#define GL_VERTEX_ATTRIB_BINDING 0x82D4
+#define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
+#define GL_VERTEX_BINDING_DIVISOR 0x82D6
+#define GL_VERTEX_BINDING_OFFSET 0x82D7
+#define GL_VERTEX_BINDING_STRIDE 0x82D8
+#define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9
+#define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA
+#endif
+
+#ifndef GL_ARB_robustness_isolation
+#endif
+
#ifndef GL_EXT_abgr
#define GL_ABGR_EXT 0x8000
#endif
#define GL_STENCIL_BACK_OP_VALUE_AMD 0x874D
#endif
+#ifndef GL_AMD_vertex_shader_viewport_index
+#endif
+
+#ifndef GL_AMD_vertex_shader_layer
+#endif
+
+#ifndef GL_NV_bindless_texture
+#endif
+
+#ifndef GL_NV_shader_atomic_float
+#endif
+
+#ifndef GL_AMD_query_buffer_object
+#define GL_QUERY_BUFFER_AMD 0x9192
+#define GL_QUERY_BUFFER_BINDING_AMD 0x9193
+#define GL_QUERY_RESULT_NO_WAIT_AMD 0x9194
+#endif
+
/*************************************************************/
typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
#endif
+#ifndef GL_KHR_debug
+typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
+#endif
+
#ifndef GL_NV_vdpau_interop
typedef GLintptr GLvdpauSurfaceNV;
#endif
#ifndef GL_VERSION_1_2
#define GL_VERSION_1_2 1
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GLAPI void APIENTRY glBlendColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
GLAPI void APIENTRY glBlendEquation (GLenum mode);
GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
#endif /* GL_GLEXT_PROTOTYPES */
-typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
#define GL_VERSION_1_3 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glActiveTexture (GLenum texture);
-GLAPI void APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glSampleCoverage (GLfloat value, GLboolean invert);
GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, GLvoid *img);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
-typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLfloat value, GLboolean invert);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
#define GL_VERSION_1_4 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
-GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
-GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);
+GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount);
GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param);
GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params);
GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param);
GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
-typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
-typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount);
typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);
typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param);
GLAPI GLboolean APIENTRY glIsProgram (GLuint program);
GLAPI GLboolean APIENTRY glIsShader (GLuint shader);
GLAPI void APIENTRY glLinkProgram (GLuint program);
-GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length);
GLAPI void APIENTRY glUseProgram (GLuint program);
GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0);
GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
-typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* const *string, const GLint *length);
typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
GLAPI void APIENTRY glEndTransformFeedback (void);
GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer);
-GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* const *varyings, GLenum bufferMode);
GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp);
GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode);
typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void);
typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer);
-typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* const *varyings, GLenum bufferMode);
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp);
typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode);
/* ARB_copy_buffer */
/* ARB_uniform_buffer_object */
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
-GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount);
GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer);
GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index);
#endif /* GL_GLEXT_PROTOTYPES */
-typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
-typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount);
typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer);
typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index);
#endif
/* ARB_transform_feedback2 */
/* ARB_transform_feedback3 */
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glMinSampleShading (GLclampf value);
+GLAPI void APIENTRY glMinSampleShading (GLfloat value);
GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode);
GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst);
GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
#endif /* GL_GLEXT_PROTOTYPES */
-typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLclampf value);
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLfloat value);
typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);
typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);
/* ARB_texture_storage */
#endif
+#ifndef GL_VERSION_4_3
+#define GL_VERSION_4_3 1
+/* OpenGL 4.3 reuses entry points from these extensions: */
+/* ARB_arrays_of_arrays (no entry points, GLSL only) */
+/* ARB_fragment_layer_viewport (no entry points, GLSL only) */
+/* ARB_shader_image_size (no entry points, GLSL only) */
+/* ARB_ES3_compatibility (no entry points) */
+/* ARB_clear_buffer_object */
+/* ARB_compute_shader */
+/* ARB_copy_image */
+/* ARB_debug_group */
+/* ARB_debug_label */
+/* KHR_debug (ARB_debug_output promoted to KHR without suffixes) */
+/* ARB_debug_output2 (no entry points) */
+/* ARB_explicit_uniform_location (no entry points) */
+/* ARB_framebuffer_no_attachments */
+/* ARB_internalformat_query2 */
+/* ARB_invalidate_subdata */
+/* ARB_multi_draw_indirect */
+/* ARB_program_interface_query */
+/* ARB_robust_buffer_access_behavior (no entry points) */
+/* ARB_shader_storage_buffer_object */
+/* ARB_stencil_texturing (no entry points) */
+/* ARB_texture_buffer_range */
+/* ARB_texture_query_levels (no entry points) */
+/* ARB_texture_storage_multisample */
+/* ARB_texture_view */
+/* ARB_vertex_attrib_binding */
+#endif
+
#ifndef GL_ARB_multitexture
#define GL_ARB_multitexture 1
#ifdef GL_GLEXT_PROTOTYPES
#ifndef GL_ARB_multisample
#define GL_ARB_multisample 1
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glSampleCoverageARB (GLclampf value, GLboolean invert);
+GLAPI void APIENTRY glSampleCoverageARB (GLfloat value, GLboolean invert);
#endif /* GL_GLEXT_PROTOTYPES */
-typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLfloat value, GLboolean invert);
#endif
#ifndef GL_ARB_texture_env_add
#ifndef GL_ARB_uniform_buffer_object
#define GL_ARB_uniform_buffer_object 1
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices);
+GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint *uniformIndices);
GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);
GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName);
GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName);
GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
#endif /* GL_GLEXT_PROTOTYPES */
-typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices);
+typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint *uniformIndices);
typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName);
typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName);
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
-GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
-GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount, GLint basevertex);
+GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount, const GLint *basevertex);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
-typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
-typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instancecount, GLint basevertex);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei drawcount, const GLint *basevertex);
#endif
#ifndef GL_ARB_fragment_coord_conventions
#ifndef GL_ARB_sample_shading
#define GL_ARB_sample_shading 1
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glMinSampleShadingARB (GLclampf value);
+GLAPI void APIENTRY glMinSampleShadingARB (GLfloat value);
#endif /* GL_GLEXT_PROTOTYPES */
-typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value);
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLfloat value);
#endif
#ifndef GL_ARB_texture_cube_map_array
GLAPI void APIENTRY glReleaseShaderCompiler (void);
GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length);
GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
-GLAPI void APIENTRY glDepthRangef (GLclampf n, GLclampf f);
-GLAPI void APIENTRY glClearDepthf (GLclampf d);
+GLAPI void APIENTRY glDepthRangef (GLfloat n, GLfloat f);
+GLAPI void APIENTRY glClearDepthf (GLfloat d);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void);
typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length);
typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision);
-typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f);
-typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLclampf d);
+typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLfloat n, GLfloat f);
+typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLfloat d);
#endif
#ifndef GL_ARB_get_program_binary
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program);
GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program);
-GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar* *strings);
+GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar* const *strings);
GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline);
GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines);
GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program);
typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program);
-typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* *strings);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* const *strings);
typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline);
typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines);
typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines);
GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v);
GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v);
-GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLclampd *v);
-GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLclampd n, GLclampd f);
+GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLdouble *v);
+GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLdouble n, GLdouble f);
GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data);
GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v);
typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height);
typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v);
-typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd *v);
-typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f);
+typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLdouble n, GLdouble f);
typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);
typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);
#endif
#ifndef GL_ARB_base_instance
#define GL_ARB_base_instance 1
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance);
-GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance);
-GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance);
+GLAPI void APIENTRY glDrawArraysInstancedBaseInstance (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+GLAPI void APIENTRY glDrawElementsInstancedBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
+GLAPI void APIENTRY glDrawElementsInstancedBaseVertexBaseInstance (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
#endif /* GL_GLEXT_PROTOTYPES */
-typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount, GLuint baseinstance);
-typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLuint baseinstance);
-typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount, GLint basevertex, GLuint baseinstance);
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
#endif
#ifndef GL_ARB_shading_language_420pack
#ifndef GL_ARB_transform_feedback_instanced
#define GL_ARB_transform_feedback_instanced 1
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei primcount);
-GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei primcount);
+GLAPI void APIENTRY glDrawTransformFeedbackInstanced (GLenum mode, GLuint id, GLsizei instancecount);
+GLAPI void APIENTRY glDrawTransformFeedbackStreamInstanced (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount);
#endif /* GL_GLEXT_PROTOTYPES */
-typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei primcount);
-typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) (GLenum mode, GLuint id, GLsizei instancecount);
+typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) (GLenum mode, GLuint id, GLuint stream, GLsizei instancecount);
#endif
#ifndef GL_ARB_compressed_texture_pixel_storage
typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
#endif
+#ifndef GL_KHR_texture_compression_astc_ldr
+#define GL_KHR_texture_compression_astc_ldr 1
+#endif
+
+#ifndef GL_KHR_debug
+#define GL_KHR_debug 1
+/* KHR_debug also reuses entry points from ARB_debug_group and ARB_debug_label */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam);
+GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message);
+GLAPI void APIENTRY glPopDebugGroup (void);
+GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label);
+GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
+typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
+typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
+typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);
+typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void);
+typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
+typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
+typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label);
+typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
+#endif
+
+#ifndef GL_ARB_arrays_of_arrays
+#define GL_ARB_arrays_of_arrays 1
+#endif
+
+#ifndef GL_ARB_clear_buffer_object
+#define GL_ARB_clear_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClearBufferData (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data);
+GLAPI void APIENTRY glClearBufferSubData (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);
+GLAPI void APIENTRY glClearNamedBufferDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);
+GLAPI void APIENTRY glClearNamedBufferSubDataEXT (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, GLsizeiptr offset, GLsizeiptr size, const void *data);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLEARBUFFERDATAPROC) (GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data);
+typedef void (APIENTRYP PFNGLCLEARBUFFERSUBDATAPROC) (GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data);
+typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data);
+typedef void (APIENTRYP PFNGLCLEARNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, GLsizeiptr offset, GLsizeiptr size, const void *data);
+#endif
+
+#ifndef GL_ARB_compute_shader
+#define GL_ARB_compute_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
+typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect);
+#endif
+
+#ifndef GL_ARB_copy_image
+#define GL_ARB_copy_image 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyImageSubData (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATAPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+#endif
+
+#ifndef GL_ARB_debug_group
+#define GL_ARB_debug_group 1
+/* ARB_debug_group reuses entry points from KHR_debug */
+#endif
+
+#ifndef GL_ARB_debug_label
+#define GL_ARB_debug_label 1
+/* ARB_debug_label reuses entry points from KHR_debug */
+#endif
+
+#ifndef GL_ARB_debug_output2
+#define GL_ARB_debug_output2 1
+#endif
+
+#ifndef GL_ARB_ES3_compatibility
+#define GL_ARB_ES3_compatibility 1
+#endif
+
+#ifndef GL_ARB_explicit_uniform_location
+#define GL_ARB_explicit_uniform_location 1
+#endif
+
+#ifndef GL_ARB_fragment_layer_viewport
+#define GL_ARB_fragment_layer_viewport 1
+#endif
+
+#ifndef GL_ARB_framebuffer_no_attachments
+#define GL_ARB_framebuffer_no_attachments 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFramebufferParameteri (GLenum target, GLenum pname, GLint param);
+GLAPI void APIENTRY glGetFramebufferParameteriv (GLenum target, GLenum pname, GLint *params);
+GLAPI void APIENTRY glNamedFramebufferParameteriEXT (GLuint framebuffer, GLenum pname, GLint param);
+GLAPI void APIENTRY glGetNamedFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAMEBUFFERPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERPARAMETERIEXTPROC) (GLuint framebuffer, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_ARB_internalformat_query2
+#define GL_ARB_internalformat_query2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetInternalformati64v (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETINTERNALFORMATI64VPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params);
+#endif
+
+#ifndef GL_ARB_invalidate_subdata
+#define GL_ARB_invalidate_subdata 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glInvalidateTexSubImage (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
+GLAPI void APIENTRY glInvalidateTexImage (GLuint texture, GLint level);
+GLAPI void APIENTRY glInvalidateBufferSubData (GLuint buffer, GLintptr offset, GLsizeiptr length);
+GLAPI void APIENTRY glInvalidateBufferData (GLuint buffer);
+GLAPI void APIENTRY glInvalidateFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+GLAPI void APIENTRY glInvalidateSubFramebuffer (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLINVALIDATETEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth);
+typedef void (APIENTRYP PFNGLINVALIDATETEXIMAGEPROC) (GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLINVALIDATEBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length);
+typedef void (APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLINVALIDATEFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+typedef void (APIENTRYP PFNGLINVALIDATESUBFRAMEBUFFERPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_ARB_multi_draw_indirect
+#define GL_ARB_multi_draw_indirect 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiDrawArraysIndirect (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+GLAPI void APIENTRY glMultiDrawElementsIndirect (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTPROC) (GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride);
+#endif
+
+#ifndef GL_ARB_program_interface_query
+#define GL_ARB_program_interface_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetProgramInterfaceiv (GLuint program, GLenum programInterface, GLenum pname, GLint *params);
+GLAPI GLuint APIENTRY glGetProgramResourceIndex (GLuint program, GLenum programInterface, const GLchar *name);
+GLAPI void APIENTRY glGetProgramResourceName (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
+GLAPI void APIENTRY glGetProgramResourceiv (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
+GLAPI GLint APIENTRY glGetProgramResourceLocation (GLuint program, GLenum programInterface, const GLchar *name);
+GLAPI GLint APIENTRY glGetProgramResourceLocationIndex (GLuint program, GLenum programInterface, const GLchar *name);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETPROGRAMINTERFACEIVPROC) (GLuint program, GLenum programInterface, GLenum pname, GLint *params);
+typedef GLuint (APIENTRYP PFNGLGETPROGRAMRESOURCEINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCENAMEPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name);
+typedef void (APIENTRYP PFNGLGETPROGRAMRESOURCEIVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params);
+typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONPROC) (GLuint program, GLenum programInterface, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) (GLuint program, GLenum programInterface, const GLchar *name);
+#endif
+
+#ifndef GL_ARB_robust_buffer_access_behavior
+#define GL_ARB_robust_buffer_access_behavior 1
+#endif
+
+#ifndef GL_ARB_shader_image_size
+#define GL_ARB_shader_image_size 1
+#endif
+
+#ifndef GL_ARB_shader_storage_buffer_object
+#define GL_ARB_shader_storage_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glShaderStorageBlockBinding (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSHADERSTORAGEBLOCKBINDINGPROC) (GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding);
+#endif
+
+#ifndef GL_ARB_stencil_texturing
+#define GL_ARB_stencil_texturing 1
+#endif
+
+#ifndef GL_ARB_texture_buffer_range
+#define GL_ARB_texture_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBufferRange (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GLAPI void APIENTRY glTextureBufferRangeEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUFFERRANGEPROC) (GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLTEXTUREBUFFERRANGEEXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size);
+#endif
+
+#ifndef GL_ARB_texture_query_levels
+#define GL_ARB_texture_query_levels 1
+#endif
+
+#ifndef GL_ARB_texture_storage_multisample
+#define GL_ARB_texture_storage_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexStorage2DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glTexStorage3DMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glTextureStorage2DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+GLAPI void APIENTRY glTextureStorage3DMultisampleEXT (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXSTORAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLTEXSTORAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DMULTISAMPLEEXTPROC) (GLuint texture, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+#endif
+
+#ifndef GL_ARB_texture_view
+#define GL_ARB_texture_view 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureView (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTUREVIEWPROC) (GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers);
+#endif
+
+#ifndef GL_ARB_vertex_attrib_binding
+#define GL_ARB_vertex_attrib_binding 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindVertexBuffer (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+GLAPI void APIENTRY glVertexAttribFormat (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+GLAPI void APIENTRY glVertexAttribIFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+GLAPI void APIENTRY glVertexAttribLFormat (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+GLAPI void APIENTRY glVertexAttribBinding (GLuint attribindex, GLuint bindingindex);
+GLAPI void APIENTRY glVertexBindingDivisor (GLuint bindingindex, GLuint divisor);
+GLAPI void APIENTRY glVertexArrayBindVertexBufferEXT (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+GLAPI void APIENTRY glVertexArrayVertexAttribFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+GLAPI void APIENTRY glVertexArrayVertexAttribIFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+GLAPI void APIENTRY glVertexArrayVertexAttribLFormatEXT (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+GLAPI void APIENTRY glVertexArrayVertexAttribBindingEXT (GLuint vaobj, GLuint attribindex, GLuint bindingindex);
+GLAPI void APIENTRY glVertexArrayVertexBindingDivisorEXT (GLuint vaobj, GLuint bindingindex, GLuint divisor);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex);
+typedef void (APIENTRYP PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor);
+typedef void (APIENTRYP PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride);
+typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset);
+typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset);
+typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex);
+typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor);
+#endif
+
+#ifndef GL_ARB_robustness_isolation
+#define GL_ARB_robustness_isolation 1
+#endif
+
#ifndef GL_EXT_abgr
#define GL_EXT_abgr 1
#endif
#ifndef GL_EXT_blend_color
#define GL_EXT_blend_color 1
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glBlendColorEXT (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+GLAPI void APIENTRY glBlendColorEXT (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
#endif /* GL_GLEXT_PROTOTYPES */
-typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
#endif
#ifndef GL_EXT_polygon_offset
#ifndef GL_NV_pixel_data_range
#define GL_NV_pixel_data_range 1
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, GLvoid *pointer);
+GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, const GLvoid *pointer);
GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target);
#endif /* GL_GLEXT_PROTOTYPES */
-typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, const GLvoid *pointer);
typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target);
#endif
typedef void (APIENTRYP PFNGLSTENCILOPVALUEAMDPROC) (GLenum face, GLuint value);
#endif
+#ifndef GL_AMD_vertex_shader_viewport_index
+#define GL_AMD_vertex_shader_viewport_index 1
+#endif
+
+#ifndef GL_AMD_vertex_shader_layer
+#define GL_AMD_vertex_shader_layer 1
+#endif
+
+#ifndef GL_NV_bindless_texture
+#define GL_NV_bindless_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint64 APIENTRY glGetTextureHandleNV (GLuint texture);
+GLAPI GLuint64 APIENTRY glGetTextureSamplerHandleNV (GLuint texture, GLuint sampler);
+GLAPI void APIENTRY glMakeTextureHandleResidentNV (GLuint64 handle);
+GLAPI void APIENTRY glMakeTextureHandleNonResidentNV (GLuint64 handle);
+GLAPI GLuint64 APIENTRY glGetImageHandleNV (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+GLAPI void APIENTRY glMakeImageHandleResidentNV (GLuint64 handle, GLenum access);
+GLAPI void APIENTRY glMakeImageHandleNonResidentNV (GLuint64 handle);
+GLAPI void APIENTRY glUniformHandleui64NV (GLint location, GLuint64 value);
+GLAPI void APIENTRY glUniformHandleui64vNV (GLint location, GLsizei count, const GLuint64 *value);
+GLAPI void APIENTRY glProgramUniformHandleui64NV (GLuint program, GLint location, GLuint64 value);
+GLAPI void APIENTRY glProgramUniformHandleui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+GLAPI GLboolean APIENTRY glIsTextureHandleResidentNV (GLuint64 handle);
+GLAPI GLboolean APIENTRY glIsImageHandleResidentNV (GLuint64 handle);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLENVPROC) (GLuint texture);
+typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLENVPROC) (GLuint texture, GLuint sampler);
+typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLENVPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
+typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle, GLenum access);
+typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTNVPROC) (GLuint64 handle);
+typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64NVPROC) (GLint location, GLuint64 value);
+typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VNVPROC) (GLint location, GLsizei count, const GLuint64 *value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64NVPROC) (GLuint program, GLint location, GLuint64 value);
+typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
+typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTNVPROC) (GLuint64 handle);
+typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTNVPROC) (GLuint64 handle);
+#endif
+
+#ifndef GL_NV_shader_atomic_float
+#define GL_NV_shader_atomic_float 1
+#endif
+
+#ifndef GL_AMD_query_buffer_object
+#define GL_AMD_query_buffer_object 1
+#endif
+
#ifdef __cplusplus
}
#ifndef __gles_glext_h_
#define __gles_glext_h_
-/* $Revision: 16481 $ on $Date:: 2012-01-04 10:43:56 -0800 #$ */
+/* $Revision: 18482 $ on $Date:: 2012-07-11 18:08:18 -0700 #$ */
#ifdef __cplusplus
extern "C" {
#define GL_DEPTH24_STENCIL8_OES 0x88F0
#endif
+/* GL_OES_required_internalformat */
+/* No new tokens introduced by this extension. */
+
/* GL_OES_rgb8_rgba8 */
#ifndef GL_OES_rgb8_rgba8
#define GL_RGB8_OES 0x8051
/* GL_EXT_multisampled_render_to_texture */
#ifndef GL_EXT_multisampled_render_to_texture
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
-#define GL_RENDERBUFFER_SAMPLES_EXT 0x9133
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x9134
-#define GL_MAX_SAMPLES_EXT 0x9135
+/* reuse values from GL_EXT_framebuffer_multisample (desktop extension) */
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
#endif
/* GL_EXT_multi_draw_arrays */
#define GL_OES_packed_depth_stencil 1
#endif
+/* GL_OES_required_internalformat */
+#ifndef GL_OES_required_internalformat
+#define GL_OES_required_internalformat 1
+#endif
+
/* GL_OES_query_matrix */
#ifndef GL_OES_query_matrix
#define GL_OES_query_matrix 1
GL_API void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
GL_API void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
#endif
-typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
-typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
#endif
/*------------------------------------------------------------------------*
#ifndef __gl2ext_h_
#define __gl2ext_h_
-/* $Revision: 16994 $ on $Date:: 2012-02-29 18:29:34 -0800 #$ */
+/* $Revision: 18481 $ on $Date:: 2012-07-11 18:07:26 -0700 #$ */
#ifdef __cplusplus
extern "C" {
#define GL_DEPTH24_STENCIL8_OES 0x88F0
#endif
+/* GL_OES_required_internalformat */
+/* No new tokens introduced by this extension. */
+
/* GL_OES_rgb8_rgba8 */
#ifndef GL_OES_rgb8_rgba8
#define GL_RGB8_OES 0x8051
/* GL_EXT_multisampled_render_to_texture */
#ifndef GL_EXT_multisampled_render_to_texture
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C
-#define GL_RENDERBUFFER_SAMPLES_EXT 0x9133
-#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x9134
-#define GL_MAX_SAMPLES_EXT 0x9135
+/* reuse values from GL_EXT_framebuffer_multisample (desktop extension) */
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
#endif
/* GL_EXT_multi_draw_arrays */
#define GL_SHADER_BINARY_DMP 0x9250
#endif
+/*------------------------------------------------------------------------*
+ * FJ extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_FJ_shader_binary_GCCSO */
+#ifndef GL_FJ_shader_binary_GCCSO
+#define GCCSO_SHADER_BINARY_FJ 0x9260
+#endif
+
/*------------------------------------------------------------------------*
* IMG extension tokens
*------------------------------------------------------------------------*/
#define GL_OES_packed_depth_stencil 1
#endif
+/* GL_OES_required_internalformat */
+#ifndef GL_OES_required_internalformat
+#define GL_OES_required_internalformat 1
+#endif
+
/* GL_OES_rgb8_rgba8 */
#ifndef GL_OES_rgb8_rgba8
#define GL_OES_rgb8_rgba8 1
#define GL_DMP_shader_binary 1
#endif
+/*------------------------------------------------------------------------*
+ * FJ extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_FJ_shader_binary_GCCSO */
+#ifndef GL_FJ_shader_binary_GCCSO
+#define GL_FJ_shader_binary_GCCSO 1
+#endif
+
/*------------------------------------------------------------------------*
* IMG extension functions
*------------------------------------------------------------------------*/
GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
#endif
-typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
-typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMGPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMGPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
#endif
/*------------------------------------------------------------------------*
-add_definitions (-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII -DQT_NO_DEBUG_OUTPUT)
+add_definitions (
+ -DQT_NO_CAST_FROM_ASCII
+ -DQT_NO_CAST_TO_ASCII
+ -DQT_NO_DEBUG_OUTPUT
+)
set (QT_DONT_USE_QTGUI TRUE)
set (qjson_MOC_HDRS
parserrunnable.h
- serializerrunnable.h
+ #serializerrunnable.h
)
qt4_wrap_cpp (qjson_MOC_SRCS ${qjson_MOC_HDRS})
-set (qjson_SRCS parser.cpp qobjecthelper.cpp json_scanner.cpp json_parser.cc parserrunnable.cpp serializer.cpp serializerrunnable.cpp)
+set (qjson_SRCS
+ parser.cpp
+ qobjecthelper.cpp
+ json_scanner.cpp
+ json_parser.cc
+ parserrunnable.cpp
+ #serializer.cpp
+ #serializerrunnable.cpp
+)
add_library (qjson_bundled STATIC ${qjson_SRCS} ${qjson_MOC_SRCS})
+++ /dev/null
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL. It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
- This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it. You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
- When we speak of free software, we are referring to freedom of use,
-not price. Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
- To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights. These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
- For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you. You must make sure that they, too, receive or can get the source
-code. If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it. And you must show them these terms so they know their rights.
-
- We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
- To protect each distributor, we want to make it very clear that
-there is no warranty for the free library. Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-\f
- Finally, software patents pose a constant threat to the existence of
-any free program. We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder. Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
- Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License. This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License. We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
- When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library. The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom. The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
- We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License. It also provides other free software developers Less
-of an advantage over competing non-free programs. These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries. However, the Lesser license provides advantages in certain
-special circumstances.
-
- For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard. To achieve this, non-free programs must be
-allowed to use the library. A more frequent case is that a free
-library does the same job as widely used non-free libraries. In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
- In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software. For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
- Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
- The precise terms and conditions for copying, distribution and
-modification follow. Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library". The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-\f
- GNU LESSER GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
- A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
- The "Library", below, refers to any such software library or work
-which has been distributed under these terms. A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language. (Hereinafter, translation is
-included without limitation in the term "modification".)
-
- "Source code" for a work means the preferred form of the work for
-making modifications to it. For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
- Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it). Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
- 1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
- You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-\f
- 2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) The modified work must itself be a software library.
-
- b) You must cause the files modified to carry prominent notices
- stating that you changed the files and the date of any change.
-
- c) You must cause the whole of the work to be licensed at no
- charge to all third parties under the terms of this License.
-
- d) If a facility in the modified Library refers to a function or a
- table of data to be supplied by an application program that uses
- the facility, other than as an argument passed when the facility
- is invoked, then you must make a good faith effort to ensure that,
- in the event an application does not supply such function or
- table, the facility still operates, and performs whatever part of
- its purpose remains meaningful.
-
- (For example, a function in a library to compute square roots has
- a purpose that is entirely well-defined independent of the
- application. Therefore, Subsection 2d requires that any
- application-supplied function or table used by this function must
- be optional: if the application does not supply it, the square
- root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library. To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License. (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.) Do not make any other change in
-these notices.
-\f
- Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
- This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
- 4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
- If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library". Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
- However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library". The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
- When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library. The
-threshold for this to be true is not precisely defined by law.
-
- If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work. (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
- Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-\f
- 6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
- You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License. You must supply a copy of this License. If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License. Also, you must do one
-of these things:
-
- a) Accompany the work with the complete corresponding
- machine-readable source code for the Library including whatever
- changes were used in the work (which must be distributed under
- Sections 1 and 2 above); and, if the work is an executable linked
- with the Library, with the complete machine-readable "work that
- uses the Library", as object code and/or source code, so that the
- user can modify the Library and then relink to produce a modified
- executable containing the modified Library. (It is understood
- that the user who changes the contents of definitions files in the
- Library will not necessarily be able to recompile the application
- to use the modified definitions.)
-
- b) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (1) uses at run time a
- copy of the library already present on the user's computer system,
- rather than copying library functions into the executable, and (2)
- will operate properly with a modified version of the library, if
- the user installs one, as long as the modified version is
- interface-compatible with the version that the work was made with.
-
- c) Accompany the work with a written offer, valid for at
- least three years, to give the same user the materials
- specified in Subsection 6a, above, for a charge no more
- than the cost of performing this distribution.
-
- d) If distribution of the work is made by offering access to copy
- from a designated place, offer equivalent access to copy the above
- specified materials from the same place.
-
- e) Verify that the user has already received a copy of these
- materials or that you have already sent this user a copy.
-
- For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it. However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
- It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system. Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-\f
- 7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
- a) Accompany the combined library with a copy of the same work
- based on the Library, uncombined with any other library
- facilities. This must be distributed under the terms of the
- Sections above.
-
- b) Give prominent notice with the combined library of the fact
- that part of it is a work based on the Library, and explaining
- where to find the accompanying uncombined form of the same work.
-
- 8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License. Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License. However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
- 9. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Library or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
- 10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-\f
- 11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all. For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded. In such case, this License incorporates the limitation as if
-written in the body of this License.
-
- 13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation. If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-\f
- 14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission. For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this. Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
- NO WARRANTY
-
- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
- END OF TERMS AND CONDITIONS
-\f
- How to Apply These Terms to Your New Libraries
-
- If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change. You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
- To apply these terms, attach the following notices to the library. It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
- <one line to give the library's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the
- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
- <signature of Ty Coon>, 1 April 1990
- Ty Coon, President of Vice
-
-That's all there is to it!
-
-
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1, as published by the Free Software Foundation.
+
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
-QJson version 0.5.0
+QJson
-------------------------------------------------
-Date: April 3rd, 2009
Website: http://qjson.sourceforge.net/
Mailing List: https://lists.sourceforge.net/mailman/listinfo/qjson-devel
License
-------
- This library is licensed under the Lesser GNU General Public License. See
- the COPYING file for more information.
+ This library is licensed under the Lesser GNU General Public License version 2.1.
+ See the COPYING.lib file for more information.
Description
-----------
#line 43 "json_parser.cc"
#ifndef YY_
-# if defined YYENABLE_NLS && YYENABLE_NLS
+# if YYENABLE_NLS
# if ENABLE_NLS
# include <libintl.h> /* FIXME: INFRINGES ON USER NAME SPACE */
# define YY_(msgid) dgettext ("bison-runtime", msgid)
switch (yyn)
{
case 2:
-#line 80 "json_parser.yy"
+#line 84 "json_parser.yy"
{
driver->m_result = (yysemantic_stack_[(1) - (1)]);
qjsonDebug() << "json_parser - parsing finished";
break;
case 3:
-#line 85 "json_parser.yy"
- {(yyval) = (yysemantic_stack_[(1) - (1)]); ;}
+#line 89 "json_parser.yy"
+ { (yyval) = (yysemantic_stack_[(1) - (1)]); ;}
break;
case 4:
-#line 86 "json_parser.yy"
- {(yyval) = (yysemantic_stack_[(1) - (1)]); ;}
- break;
-
- case 5:
-#line 88 "json_parser.yy"
+#line 91 "json_parser.yy"
{
qCritical()<< "json_parser - syntax error found, "
- << "forcing abort";
+ << "forcing abort, Line" << (yyloc).begin.line << "Column" << (yyloc).begin.column;
YYABORT;
;}
break;
- case 7:
-#line 95 "json_parser.yy"
+ case 6:
+#line 98 "json_parser.yy"
{ (yyval) = (yysemantic_stack_[(3) - (2)]); ;}
break;
- case 8:
-#line 97 "json_parser.yy"
+ case 7:
+#line 100 "json_parser.yy"
{ (yyval) = QVariant (QVariantMap()); ;}
break;
- case 9:
-#line 98 "json_parser.yy"
+ case 8:
+#line 101 "json_parser.yy"
{
QVariantMap members = (yysemantic_stack_[(2) - (2)]).toMap();
(yysemantic_stack_[(2) - (2)]) = QVariant(); // Allow reuse of map
;}
break;
- case 10:
-#line 104 "json_parser.yy"
+ case 9:
+#line 107 "json_parser.yy"
{ (yyval) = QVariant (QVariantMap()); ;}
break;
- case 11:
-#line 105 "json_parser.yy"
+ case 10:
+#line 108 "json_parser.yy"
{
QVariantMap members = (yysemantic_stack_[(3) - (3)]).toMap();
(yysemantic_stack_[(3) - (3)]) = QVariant(); // Allow reuse of map
;}
break;
- case 12:
-#line 111 "json_parser.yy"
+ case 11:
+#line 114 "json_parser.yy"
{
QVariantMap pair;
pair.insert ((yysemantic_stack_[(3) - (1)]).toString(), QVariant((yysemantic_stack_[(3) - (3)])));
;}
break;
- case 13:
-#line 117 "json_parser.yy"
+ case 12:
+#line 120 "json_parser.yy"
{ (yyval) = (yysemantic_stack_[(3) - (2)]); ;}
break;
- case 14:
-#line 119 "json_parser.yy"
+ case 13:
+#line 122 "json_parser.yy"
{ (yyval) = QVariant (QVariantList()); ;}
break;
- case 15:
-#line 120 "json_parser.yy"
+ case 14:
+#line 123 "json_parser.yy"
{
QVariantList members = (yysemantic_stack_[(2) - (2)]).toList();
(yysemantic_stack_[(2) - (2)]) = QVariant(); // Allow reuse of list
;}
break;
- case 16:
-#line 127 "json_parser.yy"
+ case 15:
+#line 130 "json_parser.yy"
{ (yyval) = QVariant (QVariantList()); ;}
break;
- case 17:
-#line 128 "json_parser.yy"
+ case 16:
+#line 131 "json_parser.yy"
{
QVariantList members = (yysemantic_stack_[(3) - (3)]).toList();
(yysemantic_stack_[(3) - (3)]) = QVariant(); // Allow reuse of list
;}
break;
+ case 17:
+#line 138 "json_parser.yy"
+ { (yyval) = (yysemantic_stack_[(1) - (1)]); ;}
+ break;
+
case 18:
-#line 135 "json_parser.yy"
+#line 139 "json_parser.yy"
{ (yyval) = (yysemantic_stack_[(1) - (1)]); ;}
break;
case 19:
-#line 136 "json_parser.yy"
+#line 140 "json_parser.yy"
{ (yyval) = (yysemantic_stack_[(1) - (1)]); ;}
break;
case 20:
-#line 137 "json_parser.yy"
+#line 141 "json_parser.yy"
{ (yyval) = (yysemantic_stack_[(1) - (1)]); ;}
break;
case 21:
-#line 138 "json_parser.yy"
- { (yyval) = (yysemantic_stack_[(1) - (1)]); ;}
- break;
-
- case 22:
-#line 139 "json_parser.yy"
+#line 142 "json_parser.yy"
{ (yyval) = QVariant (true); ;}
break;
- case 23:
-#line 140 "json_parser.yy"
+ case 22:
+#line 143 "json_parser.yy"
{ (yyval) = QVariant (false); ;}
break;
- case 24:
-#line 141 "json_parser.yy"
+ case 23:
+#line 144 "json_parser.yy"
{
QVariant null_variant;
(yyval) = null_variant;
;}
break;
+ case 24:
+#line 149 "json_parser.yy"
+ { (yyval) = QVariant(QVariant::Double); (yyval).setValue( -std::numeric_limits<double>::infinity() ); ;}
+ break;
+
case 25:
-#line 146 "json_parser.yy"
+#line 150 "json_parser.yy"
+ { (yyval) = QVariant(QVariant::Double); (yyval).setValue( std::numeric_limits<double>::infinity() ); ;}
+ break;
+
+ case 26:
+#line 151 "json_parser.yy"
+ { (yyval) = QVariant(QVariant::Double); (yyval).setValue( std::numeric_limits<double>::quiet_NaN() ); ;}
+ break;
+
+ case 28:
+#line 154 "json_parser.yy"
{
if ((yysemantic_stack_[(1) - (1)]).toByteArray().startsWith('-')) {
(yyval) = QVariant (QVariant::LongLong);
;}
break;
- case 26:
-#line 156 "json_parser.yy"
+ case 29:
+#line 164 "json_parser.yy"
{
const QByteArray value = (yysemantic_stack_[(2) - (1)]).toByteArray() + (yysemantic_stack_[(2) - (2)]).toByteArray();
(yyval) = QVariant(QVariant::Double);
;}
break;
- case 27:
-#line 161 "json_parser.yy"
+ case 30:
+#line 169 "json_parser.yy"
{ (yyval) = QVariant ((yysemantic_stack_[(2) - (1)]).toByteArray() + (yysemantic_stack_[(2) - (2)]).toByteArray()); ;}
break;
- case 28:
-#line 162 "json_parser.yy"
+ case 31:
+#line 170 "json_parser.yy"
{
const QByteArray value = (yysemantic_stack_[(3) - (1)]).toByteArray() + (yysemantic_stack_[(3) - (2)]).toByteArray() + (yysemantic_stack_[(3) - (3)]).toByteArray();
(yyval) = QVariant (value);
;}
break;
- case 29:
-#line 167 "json_parser.yy"
+ case 32:
+#line 175 "json_parser.yy"
{ (yyval) = QVariant ((yysemantic_stack_[(2) - (1)]).toByteArray() + (yysemantic_stack_[(2) - (2)]).toByteArray()); ;}
break;
- case 30:
-#line 168 "json_parser.yy"
+ case 33:
+#line 176 "json_parser.yy"
{ (yyval) = QVariant (QByteArray("-") + (yysemantic_stack_[(3) - (2)]).toByteArray() + (yysemantic_stack_[(3) - (3)]).toByteArray()); ;}
break;
- case 31:
-#line 170 "json_parser.yy"
+ case 34:
+#line 178 "json_parser.yy"
{ (yyval) = QVariant (QByteArray("")); ;}
break;
- case 32:
-#line 171 "json_parser.yy"
+ case 35:
+#line 179 "json_parser.yy"
{
(yyval) = QVariant((yysemantic_stack_[(2) - (1)]).toByteArray() + (yysemantic_stack_[(2) - (2)]).toByteArray());
;}
break;
- case 33:
-#line 175 "json_parser.yy"
+ case 36:
+#line 183 "json_parser.yy"
{
(yyval) = QVariant(QByteArray(".") + (yysemantic_stack_[(2) - (2)]).toByteArray());
;}
break;
- case 34:
-#line 179 "json_parser.yy"
+ case 37:
+#line 187 "json_parser.yy"
{ (yyval) = QVariant((yysemantic_stack_[(2) - (1)]).toByteArray() + (yysemantic_stack_[(2) - (2)]).toByteArray()); ;}
break;
- case 35:
-#line 181 "json_parser.yy"
+ case 38:
+#line 189 "json_parser.yy"
{ (yyval) = (yysemantic_stack_[(3) - (2)]); ;}
break;
- case 36:
-#line 183 "json_parser.yy"
+ case 39:
+#line 191 "json_parser.yy"
{ (yyval) = QVariant (QString(QLatin1String(""))); ;}
break;
- case 37:
-#line 184 "json_parser.yy"
+ case 40:
+#line 192 "json_parser.yy"
{
(yyval) = (yysemantic_stack_[(1) - (1)]);
;}
/* Line 675 of lalr1.cc. */
-#line 618 "json_parser.cc"
+#line 628 "json_parser.cc"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc);
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
- const signed char json_parser::yypact_ninf_ = -18;
+ const signed char json_parser::yypact_ninf_ = -21;
const signed char
json_parser::yypact_[] =
{
- 5, -18, -18, 1, -2, 19, -18, -18, -18, 2,
- 20, 17, 21, 16, 18, -18, -18, -18, -18, -18,
- 24, 23, -18, -8, -18, -18, -18, 15, -18, 1,
- -18, -2, 18, 18, -18, -18, -2, -18, 18, 18,
- 22, -18, -18, 17, -18, -18, -18, 23, -18, -18,
- -18, -18, -18
+ 3, -21, -21, -6, 31, -10, 0, -21, -21, -21,
+ 6, -21, -21, 25, -21, -21, -21, -21, -21, -21,
+ -5, -21, 22, 19, 21, 23, 24, 0, -21, 0,
+ -21, -21, 13, -21, 0, 0, 29, -21, -21, -6,
+ -21, 31, -21, 31, -21, -21, -21, -21, -21, -21,
+ -21, 19, -21, 24, -21, -21
};
/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
const unsigned char
json_parser::yydefact_[] =
{
- 0, 6, 5, 8, 14, 0, 2, 3, 4, 36,
- 0, 10, 0, 0, 31, 22, 23, 24, 20, 21,
- 0, 16, 19, 25, 18, 1, 37, 0, 7, 0,
- 9, 0, 31, 31, 29, 13, 0, 15, 31, 31,
- 26, 27, 35, 10, 12, 30, 32, 16, 33, 34,
- 28, 11, 17
+ 0, 5, 4, 7, 13, 0, 34, 21, 22, 23,
+ 39, 25, 26, 0, 2, 19, 20, 3, 18, 27,
+ 28, 17, 0, 9, 0, 0, 15, 34, 24, 34,
+ 32, 40, 0, 1, 34, 34, 29, 30, 6, 0,
+ 8, 0, 12, 0, 14, 33, 35, 38, 36, 37,
+ 31, 9, 11, 15, 10, 16
};
/* YYPGOTO[NTERM-NUM]. */
const signed char
json_parser::yypgoto_[] =
{
- -18, -18, -18, 33, -18, -7, 6, 37, -18, -9,
- -13, -18, -18, -17, -18, -1, -3, -18
+ -21, -21, -21, -21, -21, -20, 4, -21, -21, -18,
+ -4, -21, -21, -21, -14, -21, -3, -1, -21
};
/* YYDEFGOTO[NTERM-NUM]. */
const signed char
json_parser::yydefgoto_[] =
{
- -1, 5, 6, 18, 10, 30, 11, 19, 20, 37,
- 21, 22, 23, 34, 40, 41, 24, 27
+ -1, 13, 14, 15, 22, 40, 23, 16, 25, 44,
+ 17, 18, 19, 20, 30, 36, 37, 21, 32
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
const unsigned char
json_parser::yytable_[] =
{
- 12, 3, 38, 4, 39, 1, 2, 13, 3, 14,
- 4, 15, 16, 17, 9, 45, 46, 9, 44, 25,
- 26, 48, 49, 47, 28, 29, 12, 32, 31, 33,
- 35, 36, 42, 7, 39, 43, 51, 8, 52, 50
+ 26, 27, 24, 1, 2, 34, 3, 35, 4, 28,
+ 10, 29, 5, 45, 6, 46, 7, 8, 9, 10,
+ 48, 49, 11, 12, 31, 33, 38, 39, 41, 42,
+ 47, 54, 43, 50, 3, 55, 4, 52, 24, 53,
+ 5, 35, 6, 51, 7, 8, 9, 10, 0, 0,
+ 11, 12
};
/* YYCHECK. */
- const unsigned char
+ const signed char
json_parser::yycheck_[] =
{
- 3, 3, 10, 5, 12, 0, 1, 9, 3, 11,
- 5, 13, 14, 15, 16, 32, 33, 16, 31, 0,
- 18, 38, 39, 36, 4, 8, 29, 11, 7, 11,
- 6, 8, 17, 0, 12, 29, 43, 0, 47, 40
+ 4, 11, 3, 0, 1, 10, 3, 12, 5, 19,
+ 16, 11, 9, 27, 11, 29, 13, 14, 15, 16,
+ 34, 35, 19, 20, 18, 0, 4, 8, 7, 6,
+ 17, 51, 8, 36, 3, 53, 5, 41, 39, 43,
+ 9, 12, 11, 39, 13, 14, 15, 16, -1, -1,
+ 19, 20
};
/* STOS_[STATE-NUM] -- The (internal number of the) accessing
const unsigned char
json_parser::yystos_[] =
{
- 0, 0, 1, 3, 5, 20, 21, 22, 26, 16,
- 23, 25, 35, 9, 11, 13, 14, 15, 22, 26,
- 27, 29, 30, 31, 35, 0, 18, 36, 4, 8,
- 24, 7, 11, 11, 32, 6, 8, 28, 10, 12,
- 33, 34, 17, 25, 29, 32, 32, 29, 32, 32,
- 34, 24, 28
+ 0, 0, 1, 3, 5, 9, 11, 13, 14, 15,
+ 16, 19, 20, 22, 23, 24, 28, 31, 32, 33,
+ 34, 38, 25, 27, 38, 29, 31, 11, 19, 11,
+ 35, 18, 39, 0, 10, 12, 36, 37, 4, 8,
+ 26, 7, 6, 8, 30, 35, 35, 17, 35, 35,
+ 37, 27, 31, 31, 26, 30
};
#if YYDEBUG
json_parser::yytoken_number_[] =
{
0, 256, 257, 1, 2, 3, 4, 5, 6, 7,
- 8, 9, 10, 11, 12, 13, 14, 15, 16
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18
};
#endif
const unsigned char
json_parser::yyr1_[] =
{
- 0, 19, 20, 21, 21, 21, 21, 22, 23, 23,
- 24, 24, 25, 26, 27, 27, 28, 28, 29, 29,
- 29, 29, 29, 29, 29, 30, 30, 30, 30, 31,
- 31, 32, 32, 33, 34, 35, 36, 36
+ 0, 21, 22, 23, 23, 23, 24, 25, 25, 26,
+ 26, 27, 28, 29, 29, 30, 30, 31, 31, 31,
+ 31, 31, 31, 31, 32, 32, 32, 32, 33, 33,
+ 33, 33, 34, 34, 35, 35, 36, 37, 38, 39,
+ 39
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
const unsigned char
json_parser::yyr2_[] =
{
- 0, 2, 1, 1, 1, 1, 1, 3, 0, 2,
- 0, 3, 3, 3, 0, 2, 0, 3, 1, 1,
- 1, 1, 1, 1, 1, 1, 2, 2, 3, 2,
- 3, 0, 2, 2, 2, 3, 0, 1
+ 0, 2, 1, 1, 1, 1, 3, 0, 2, 0,
+ 3, 3, 3, 0, 2, 0, 3, 1, 1, 1,
+ 1, 1, 1, 1, 2, 1, 1, 1, 1, 2,
+ 2, 3, 2, 3, 0, 2, 2, 2, 3, 0,
+ 1
};
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
"\"]\"", "\":\"", "\",\"", "\"-\"", "\".\"", "\"digit\"",
"\"exponential\"", "\"true\"", "\"false\"", "\"null\"",
"\"open quotation mark\"", "\"close quotation mark\"", "\"string\"",
- "$accept", "start", "data", "object", "members", "r_members", "pair",
- "array", "values", "r_values", "value", "number", "int", "digits",
- "fract", "exp", "string", "string_arg", 0
+ "\"Infinity\"", "\"NaN\"", "$accept", "start", "data", "object",
+ "members", "r_members", "pair", "array", "values", "r_values", "value",
+ "special_or_number", "number", "int", "digits", "fract", "exp", "string",
+ "string_arg", 0
};
#endif
const json_parser::rhs_number_type
json_parser::yyrhs_[] =
{
- 20, 0, -1, 21, -1, 22, -1, 26, -1, 1,
- -1, 0, -1, 3, 23, 4, -1, -1, 25, 24,
- -1, -1, 8, 25, 24, -1, 35, 7, 29, -1,
- 5, 27, 6, -1, -1, 29, 28, -1, -1, 8,
- 29, 28, -1, 35, -1, 30, -1, 22, -1, 26,
- -1, 13, -1, 14, -1, 15, -1, 31, -1, 31,
- 33, -1, 31, 34, -1, 31, 33, 34, -1, 11,
- 32, -1, 9, 11, 32, -1, -1, 11, 32, -1,
- 10, 32, -1, 12, 32, -1, 16, 36, 17, -1,
- -1, 18, -1
+ 22, 0, -1, 23, -1, 31, -1, 1, -1, 0,
+ -1, 3, 25, 4, -1, -1, 27, 26, -1, -1,
+ 8, 27, 26, -1, 38, 7, 31, -1, 5, 29,
+ 6, -1, -1, 31, 30, -1, -1, 8, 31, 30,
+ -1, 38, -1, 32, -1, 24, -1, 28, -1, 13,
+ -1, 14, -1, 15, -1, 9, 19, -1, 19, -1,
+ 20, -1, 33, -1, 34, -1, 34, 36, -1, 34,
+ 37, -1, 34, 36, 37, -1, 11, 35, -1, 9,
+ 11, 35, -1, -1, 11, 35, -1, 10, 35, -1,
+ 12, 35, -1, 16, 39, 17, -1, -1, 18, -1
};
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
const unsigned char
json_parser::yyprhs_[] =
{
- 0, 0, 3, 5, 7, 9, 11, 13, 17, 18,
- 21, 22, 26, 30, 34, 35, 38, 39, 43, 45,
- 47, 49, 51, 53, 55, 57, 59, 62, 65, 69,
- 72, 76, 77, 80, 83, 86, 90, 91
+ 0, 0, 3, 5, 7, 9, 11, 15, 16, 19,
+ 20, 24, 28, 32, 33, 36, 37, 41, 43, 45,
+ 47, 49, 51, 53, 55, 58, 60, 62, 64, 66,
+ 69, 72, 76, 79, 83, 84, 87, 90, 93, 97,
+ 98
};
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
const unsigned char
json_parser::yyrline_[] =
{
- 0, 80, 80, 85, 86, 87, 93, 95, 97, 98,
- 104, 105, 111, 117, 119, 120, 127, 128, 135, 136,
- 137, 138, 139, 140, 141, 146, 156, 161, 162, 167,
- 168, 170, 171, 175, 179, 181, 183, 184
+ 0, 84, 84, 89, 90, 96, 98, 100, 101, 107,
+ 108, 114, 120, 122, 123, 130, 131, 138, 139, 140,
+ 141, 142, 143, 144, 149, 150, 151, 152, 154, 164,
+ 169, 170, 175, 176, 178, 179, 183, 187, 189, 191,
+ 192
};
// Print the state stack on the debug stream.
translate_table[] =
{
0, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 17, 18, 2, 2, 2,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
}
const int json_parser::yyeof_ = 0;
- const int json_parser::yylast_ = 39;
- const int json_parser::yynnts_ = 18;
+ const int json_parser::yylast_ = 51;
+ const int json_parser::yynnts_ = 19;
const int json_parser::yyempty_ = -2;
- const int json_parser::yyfinal_ = 25;
+ const int json_parser::yyfinal_ = 33;
const int json_parser::yyterror_ = 1;
const int json_parser::yyerrcode_ = 256;
- const int json_parser::yyntokens_ = 19;
+ const int json_parser::yyntokens_ = 21;
const unsigned int json_parser::yyuser_token_number_max_ = 257;
const json_parser::token_number_type json_parser::yyundef_token_ = 2;
} // namespace yy
-#line 188 "json_parser.yy"
+#line 196 "json_parser.yy"
int yy::yylex(YYSTYPE *yylval, yy::location *yylloc, QJson::ParserPrivate* driver)
#include <QtCore/QString>
#include <QtCore/QVariant>
+ #include <limits>
+
class JSonScanner;
namespace QJson {
#define YYERROR_VERBOSE 1
-/* Line 303 of lalr1.cc. */
-#line 73 "json_parser.hh"
+/* Line 35 of lalr1.cc. */
+#line 75 "json_parser.hh"
#include "location.hh"
NULL_VAL = 13,
QUOTMARKOPEN = 14,
QUOTMARKCLOSE = 15,
- STRING = 16
+ STRING = 16,
+ INFINITY_VAL = 17,
+ NAN_VAL = 18
};
};
static const unsigned char yytable_[];
static const signed char yytable_ninf_;
- static const unsigned char yycheck_[];
+ static const signed char yycheck_[];
/// For a state, its accessing symbol.
static const unsigned char yystos_[];
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
#include <QtCore/QString>
#include <QtCore/QVariant>
+ #include <limits>
+
class JSonScanner;
namespace QJson {
%token QUOTMARKCLOSE 15 "close quotation mark"
%token STRING 16 "string"
+%token INFINITY_VAL 17 "Infinity"
+%token NAN_VAL 18 "NaN"
// define the initial token
%start start
qjsonDebug() << "json_parser - parsing finished";
};
-data: object {$$ = $1; }
- | array {$$ = $1; }
+data: value { $$ = $1; }
| error
{
qCritical()<< "json_parser - syntax error found, "
- << "forcing abort";
+ << "forcing abort, Line" << @$.begin.line << "Column" << @$.begin.column;
YYABORT;
}
| END;
};
value: string { $$ = $1; }
- | number { $$ = $1; }
+ | special_or_number { $$ = $1; }
| object { $$ = $1; }
| array { $$ = $1; }
| TRUE_VAL { $$ = QVariant (true); }
$$ = null_variant;
};
+special_or_number: MINUS INFINITY_VAL { $$ = QVariant(QVariant::Double); $$.setValue( -std::numeric_limits<double>::infinity() ); }
+ | INFINITY_VAL { $$ = QVariant(QVariant::Double); $$.setValue( std::numeric_limits<double>::infinity() ); }
+ | NAN_VAL { $$ = QVariant(QVariant::Double); $$.setValue( std::numeric_limits<double>::quiet_NaN() ); }
+ | number;
+
number: int {
if ($1.toByteArray().startsWith('-')) {
$$ = QVariant (QVariant::LongLong);
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
}
JSonScanner::JSonScanner(QIODevice* io)
- : m_io (io)
+ : m_allowSpecialNumbers(false),
+ m_io (io)
{
m_quotmarkClosed = true;
m_quotmarkCount = 0;
}
+void JSonScanner::allowSpecialNumbers(bool allow) {
+ m_allowSpecialNumbers = allow;
+}
+
static QString unescape( const QByteArray& ba, bool* ok ) {
assert( ok );
*ok = false;
int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc)
{
char ch;
-
+
if (!m_io->isOpen()) {
qCritical() << "JSonScanner::yylex - io device is not open";
return -1;
}
qjsonDebug() << "JSonScanner::yylex - got |" << ch << "|";
-
yylloc->columns();
-
+
if (ch == '\n' || ch == '\r')
yylloc->lines();
-
} while (m_quotmarkClosed && (isspace(ch) != 0));
- if (m_quotmarkClosed && ((ch == 't') || (ch == 'T')
- || (ch == 'n') || (ch == 'N'))) {
- // check true & null value
+ if (m_quotmarkClosed && ((ch == 't') || (ch == 'T'))) {
const QByteArray buf = m_io->peek(3).toLower();
+ if (buf == "rue") {
+ m_io->read (3);
+ yylloc->columns(3);
+ qjsonDebug() << "JSonScanner::yylex - TRUE_VAL";
+ return yy::json_parser::token::TRUE_VAL;
+ }
+ }
+ else if (m_quotmarkClosed && ((ch == 'n') || (ch == 'N'))) {
+ const QByteArray buf = m_io->peek(3).toLower();
+ if (buf == "ull") {
+ m_io->read (3);
+ yylloc->columns(3);
+ qjsonDebug() << "JSonScanner::yylex - NULL_VAL";
+ return yy::json_parser::token::NULL_VAL;
+ } else if (buf.startsWith("an") && m_allowSpecialNumbers) {
+ m_io->read(2);
+ yylloc->columns(2);
+ qjsonDebug() << "JSonScanner::yylex - NAN_VAL";
+ return yy::json_parser::token::NAN_VAL;
- if (buf.length() == 3) {
- if (buf == "rue") {
- m_io->read (3);
- yylloc->columns(3);
- qjsonDebug() << "JSonScanner::yylex - TRUE_VAL";
- return yy::json_parser::token::TRUE_VAL;
- }
- else if (buf == "ull") {
- m_io->read (3);
- yylloc->columns(3);
- qjsonDebug() << "JSonScanner::yylex - NULL_VAL";
- return yy::json_parser::token::NULL_VAL;
- }
}
}
else if (m_quotmarkClosed && ((ch == 'f') || (ch == 'F'))) {
const QByteArray buf = m_io->peek(1);
if (!buf.isEmpty()) {
if ((buf[0] == '+' ) || (buf[0] == '-' )) {
- ret += m_io->read (1);
+ ret += m_io->read (1);
yylloc->columns();
}
}
*yylval = QVariant(QString::fromUtf8(ret));
return yy::json_parser::token::E;
}
-
+ else if (m_allowSpecialNumbers && m_quotmarkClosed && ((ch == 'I') || (ch == 'i'))) {
+ QByteArray ret(1, ch);
+ const QByteArray buf = m_io->peek(7);
+ if (buf == "nfinity") {
+ m_io->read(7);
+ yylloc->columns(7);
+ qjsonDebug() << "JSonScanner::yylex - INFINITY_VAL";
+ return yy::json_parser::token::INFINITY_VAL;
+ }
+ }
+
if (ch != '"' && !m_quotmarkClosed) {
// we're inside a " " block
QByteArray raw;
}
}
else if (isdigit(ch) != 0 && m_quotmarkClosed) {
- *yylval = QVariant(QString::fromLatin1(QByteArray(&ch,1)));
+ bool ok;
+ QByteArray numArray = QByteArray::fromRawData( &ch, 1 * sizeof(char) );
+ qulonglong number = numArray.toULongLong(&ok);
+ if (!ok) {
+ //This shouldn't happen
+ qCritical() << "JSonScanner::yylex - error while converting char to ulonglong, returning -1";
+ return -1;
+ }
+ if (number == 0) {
+ // we have to return immediately otherwise numbers like
+ // 2.04 will be converted to 2.4
+ *yylval = QVariant(number);
+ qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::DIGIT";
+ return yy::json_parser::token::DIGIT;
+ }
+
+ char nextCh;
+ qint64 ret = m_io->peek(&nextCh, 1);
+ while (ret == 1 && isdigit(nextCh)) {
+ m_io->read(1); //consume
+ yylloc->columns(1);
+ numArray = QByteArray::fromRawData( &nextCh, 1 * sizeof(char) );
+ number = number * 10 + numArray.toULongLong(&ok);
+ if (!ok) {
+ //This shouldn't happen
+ qCritical() << "JSonScanner::yylex - error while converting char to ulonglong, returning -1";
+ return -1;
+ }
+ ret = m_io->peek(&nextCh, 1);
+ }
+
+ *yylval = QVariant(number);
qjsonDebug() << "JSonScanner::yylex - yy::json_parser::token::DIGIT";
return yy::json_parser::token::DIGIT;
}
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
public:
explicit JSonScanner(QIODevice* io);
int yylex(YYSTYPE* yylval, yy::location *yylloc);
-
+ void allowSpecialNumbers(bool allow);
+
protected:
bool m_quotmarkClosed;
+ bool m_allowSpecialNumbers;
unsigned int m_quotmarkCount;
QIODevice* m_io;
};
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
m_scanner(0)
, m_negate(false)
, m_error(false)
+ , m_errorLine(0)
+ , m_specialNumbersAllowed(false)
{
}
}
d->m_scanner = new JSonScanner (io);
+ d->m_scanner->allowSpecialNumbers(d->m_specialNumbersAllowed);
yy::json_parser parser(d);
parser.parse();
{
return d->m_errorLine;
}
+
+void QJson::Parser::allowSpecialNumbers(bool allowSpecialNumbers) {
+ d->m_specialNumbersAllowed = allowSpecialNumbers;
+}
+
+bool Parser::specialNumbersAllowed() const {
+ return d->m_specialNumbersAllowed;
+}
* Copyright (C) 2008 Flavio Castelli <flavio.castelli@gmail.com>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
int errorLine() const;
+ /**
+ * Sets whether special numbers (Infinity, -Infinity, NaN) are allowed as an extension to
+ * the standard
+ * @param allowSpecialNumbers new value of whether special numbers are allowed
+ * @sa specialNumbersAllowed
+ */
+ void allowSpecialNumbers(bool allowSpecialNumbers);
+
+ /**
+ * @returns whether special numbers (Infinity, -Infinity, NaN) are allowed
+ * @sa allowSpecialNumbers
+ */
+ bool specialNumbersAllowed() const;
+
private:
Q_DISABLE_COPY(Parser)
ParserPrivate* const d;
* Copyright (C) 2009 Michael Leupold <lemma@confuego.org>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
int m_errorLine;
QString m_errorMsg;
QVariant m_result;
+ bool m_specialNumbersAllowed;
};
}
* Copyright (C) 2009 Flavio Castelli <flavio@castelli.name>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
qDebug() << "successfully converted json item to QVariant object";
emit parsingFinished(result, true, QString());
} else {
- const QString errorText = tr("An error occured while parsing json: %1").arg(parser.errorString());
+ const QString errorText = tr("An error occurred while parsing json: %1").arg(parser.errorString());
qCritical() << errorText;
emit parsingFinished(QVariant(), false, errorText);
}
* Copyright (C) 2009 Flavio Castelli <flavio@castelli.name>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
* Copyright (C) 2009 Michael Leupold <lemma@confuego.org>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
Copyright (C) 2009 Pino Toscano <pino@kde.org>
This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ modify it under the terms of the GNU Lesser General Public
+ License version 2.1, as published by the Free Software Foundation.
+
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU Library General Public License
+ You should have received a copy of the GNU Lesser General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
#include <QtCore/qglobal.h>
-#define QJSON_EXPORT
+#ifndef QJSON_EXPORT
+# if defined(QJSON_MAKEDLL)
+ /* We are building this library */
+# define QJSON_EXPORT Q_DECL_EXPORT
+# else
+ /* We are using this library */
+# define QJSON_EXPORT Q_DECL_IMPORT
+# endif
+#endif
#endif
* Copyright (C) 2009 Flavio Castelli <flavio@castelli.name>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
void QObjectHelper::qvariant2qobject(const QVariantMap& variant, QObject* object)
{
- QStringList properies;
const QMetaObject *metaobject = object->metaObject();
- int count = metaobject->propertyCount();
- for (int i=0; i<count; ++i) {
- QMetaProperty metaproperty = metaobject->property(i);
- if (metaproperty.isWritable()) {
- properies << QLatin1String( metaproperty.name());
- }
- }
QVariantMap::const_iterator iter;
- for (iter = variant.constBegin(); iter != variant.end(); iter++) {
- if (properies.contains(iter.key())) {
- object->setProperty(iter.key().toAscii(), iter.value());
+ for (iter = variant.constBegin(); iter != variant.constEnd(); ++iter) {
+ int pIdx = metaobject->indexOfProperty( iter.key().toAscii() );
+
+ if ( pIdx < 0 ) {
+ continue;
+ }
+
+ QMetaProperty metaproperty = metaobject->property( pIdx );
+ QVariant::Type type = metaproperty.type();
+ QVariant v( iter.value() );
+ if ( v.canConvert( type ) ) {
+ v.convert( type );
+ metaproperty.write( object, v );
+ } else if (QString(QLatin1String("QVariant")).compare(QLatin1String(metaproperty.typeName())) == 0) {
+ metaproperty.write( object, v );
}
}
}
* Copyright (C) 2009 Flavio Castelli <flavio@castelli.name>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
* @brief Class used to convert QObject into QVariant and vivce-versa.
* During these operations only the class attributes defined as properties will
* be considered.
+ * Properties marked as 'non-stored' will be ignored.
*
* Suppose the declaration of the Person class looks like this:
* \code
* Copyright (C) 2009 Flavio Castelli <flavio@castelli.name>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
#include <QtCore/QStringList>
#include <QtCore/QVariant>
+#include <cmath>
+
+#ifdef _MSC_VER // using MSVC compiler
+#include <float.h>
+#endif
+
using namespace QJson;
class Serializer::SerializerPrivate {
+ public:
+ SerializerPrivate() :
+ specialNumbersAllowed(false),
+ indentMode(QJson::IndentNone),
+ doublePrecision(6) {
+ }
+ bool specialNumbersAllowed;
+ IndentMode indentMode;
+ int doublePrecision;
+ QByteArray buildIndent(int spaces);
+ QByteArray serialize( const QVariant &v, int reserved = 0);
+ QString sanitizeString( QString str );
+ QByteArray join( const QList<QByteArray>& list, const QByteArray& sep );
};
-Serializer::Serializer() : d( new SerializerPrivate ) {
-}
-
-Serializer::~Serializer() {
- delete d;
-}
-
-void Serializer::serialize( const QVariant& v, QIODevice* io, bool* ok )
-{
- Q_ASSERT( io );
- if (!io->isOpen()) {
- if (!io->open(QIODevice::WriteOnly)) {
- if ( ok != 0 )
- *ok = false;
- qCritical ("Error opening device");
- return;
- }
- }
-
- if (!io->isWritable()) {
- if (ok != 0)
- *ok = false;
- qCritical ("Device is not readable");
- io->close();
- return;
- }
-
- const QByteArray str = serialize( v );
- if ( !str.isNull() ) {
- QDataStream stream( io );
- stream << str;
- } else {
- if ( ok )
- *ok = false;
- }
-}
-
-static QString sanitizeString( QString str )
-{
- str.replace( QLatin1String( "\\" ), QLatin1String( "\\\\" ) );
- str.replace( QLatin1String( "\"" ), QLatin1String( "\\\"" ) );
- str.replace( QLatin1String( "\b" ), QLatin1String( "\\b" ) );
- str.replace( QLatin1String( "\f" ), QLatin1String( "\\f" ) );
- str.replace( QLatin1String( "\n" ), QLatin1String( "\\n" ) );
- str.replace( QLatin1String( "\r" ), QLatin1String( "\\r" ) );
- str.replace( QLatin1String( "\t" ), QLatin1String( "\\t" ) );
- return QString( QLatin1String( "\"%1\"" ) ).arg( str );
-}
-
-static QByteArray join( const QList<QByteArray>& list, const QByteArray& sep ) {
+QByteArray Serializer::SerializerPrivate::join( const QList<QByteArray>& list, const QByteArray& sep ) {
QByteArray res;
Q_FOREACH( const QByteArray& i, list ) {
if ( !res.isEmpty() )
return res;
}
-QByteArray Serializer::serialize( const QVariant &v )
+QByteArray Serializer::SerializerPrivate::serialize( const QVariant &v, int reserved )
{
QByteArray str;
bool error = false;
+ QByteArray indent;
if ( ! v.isValid() ) { // invalid or null?
str = "null";
- } else if ( v.type() == QVariant::List ) { // variant is a list?
+ } else if (( v.type() == QVariant::List ) || ( v.type() == QVariant::StringList )){ // an array or a stringlist?
const QVariantList list = v.toList();
QList<QByteArray> values;
- Q_FOREACH( const QVariant& v, list )
+ Q_FOREACH( const QVariant& var, list )
{
- QByteArray serializedValue = serialize( v );
+ reserved++;
+ QByteArray serializedValue = serialize( var,reserved );
+ reserved--;
if ( serializedValue.isNull() ) {
error = true;
break;
}
values << serializedValue;
}
- str = "[ " + join( values, ", " ) + " ]";
+
+ if (indentMode == QJson::IndentMinimum) {
+ QByteArray indent = buildIndent(reserved - 1);
+ str = "[\n" + join( values, ",\n" ) + "\n" + indent + "]";
+ }
+ else if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
+ QByteArray indent = buildIndent(reserved);
+ str = "[\n" + join( values, ",\n" ) + "\n" + indent + "]";
+ }
+ else if (indentMode == QJson::IndentCompact) {
+ str = "[" + join( values, "," ) + "]";
+ }
+ else {
+ str = "[ " + join( values, ", " ) + " ]";
+ }
+
} else if ( v.type() == QVariant::Map ) { // variant is a map?
const QVariantMap vmap = v.toMap();
QMapIterator<QString, QVariant> it( vmap );
- str = "{ ";
+
+ if (indentMode == QJson::IndentMinimum) {
+ QByteArray indent = buildIndent(reserved);
+ str = indent + "{ ";
+ }
+ else if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
+ QByteArray indent = buildIndent(reserved);
+ QByteArray nextindent = buildIndent(reserved + 1);
+ str = indent + "{\n" + nextindent;
+ }
+ else if (indentMode == QJson::IndentCompact) {
+ str = "{";
+ }
+ else {
+ str = "{ ";
+ }
+
QList<QByteArray> pairs;
while ( it.hasNext() ) {
it.next();
- QByteArray serializedValue = serialize( it.value() );
+ reserved++;
+ QByteArray serializedValue = serialize( it.value() , reserved);
+ reserved--;
if ( serializedValue.isNull() ) {
error = true;
break;
}
- pairs << sanitizeString( it.key() ).toUtf8() + " : " + serializedValue;
+ QByteArray key = sanitizeString( it.key() ).toUtf8();
+ QByteArray value = serializedValue;
+ if (indentMode == QJson::IndentCompact) {
+ pairs << key + ":" + value;
+ } else {
+ pairs << key + " : " + value;
+ }
+ }
+
+ if (indentMode == QJson::IndentFull) {
+ QByteArray indent = buildIndent(reserved + 1);
+ str += join( pairs, ",\n" + indent);
+ }
+ else if (indentMode == QJson::IndentCompact) {
+ str += join( pairs, "," );
}
- str += join( pairs, ", " );
- str += " }";
+ else {
+ str += join( pairs, ", " );
+ }
+
+ if (indentMode == QJson::IndentMedium || indentMode == QJson::IndentFull) {
+ QByteArray indent = buildIndent(reserved);
+ str += "\n" + indent + "}";
+ }
+ else if (indentMode == QJson::IndentCompact) {
+ str += "}";
+ }
+ else {
+ str += " }";
+ }
+
} else if (( v.type() == QVariant::String ) || ( v.type() == QVariant::ByteArray )) { // a string or a byte array?
str = sanitizeString( v.toString() ).toUtf8();
- } else if ( v.type() == QVariant::Double ) { // a double?
- str = QByteArray::number( v.toDouble() );
- if( ! str.contains( "." ) && ! str.contains( "e" ) ) {
- str += ".0";
+ } else if (( v.type() == QVariant::Double) || ((QMetaType::Type)v.type() == QMetaType::Float)) { // a double or a float?
+ const double value = v.toDouble();
+#if defined _WIN32 && !defined(Q_OS_SYMBIAN)
+ const bool special = _isnan(value) || !_finite(value);
+#elif defined(Q_OS_SYMBIAN) || defined(Q_OS_ANDROID)
+ const bool special = isnan(value) || isinf(value);
+#else
+ const bool special = std::isnan(value) || std::isinf(value);
+#endif
+ if (special) {
+ if (specialNumbersAllowed) {
+#if defined _WIN32 && !defined(Q_OS_SYMBIAN)
+ if (_isnan(value)) {
+#elif defined(Q_OS_SYMBIAN) || defined(Q_OS_ANDROID)
+ if (isnan(value)) {
+#else
+ if (std::isnan(value)) {
+#endif
+ str += "NaN";
+ } else {
+ if (value<0) {
+ str += '-';
+ }
+ str += "Infinity";
+ }
+ } else {
+ qCritical("Attempt to write NaN or infinity, which is not supported by json");
+ error = true;
+ }
+ } else {
+ str = QByteArray::number( value , 'g', doublePrecision);
+ if( ! str.contains( "." ) && ! str.contains( "e" ) ) {
+ str += ".0";
+ }
}
} else if ( v.type() == QVariant::Bool ) { // boolean value?
str = ( v.toBool() ? "true" : "false" );
error = true;
}
if ( !error )
+ {
return str;
+ }
else
return QByteArray();
}
+
+QByteArray Serializer::SerializerPrivate::buildIndent(int spaces)
+{
+ QByteArray indent;
+ if (spaces < 0) {
+ spaces = 0;
+ }
+ for (int i = 0; i < spaces; i++ ) {
+ indent += " ";
+ }
+ return indent;
+}
+
+QString Serializer::SerializerPrivate::sanitizeString( QString str )
+{
+ str.replace( QLatin1String( "\\" ), QLatin1String( "\\\\" ) );
+
+ // escape unicode chars
+ QString result;
+ const ushort* unicode = str.utf16();
+ unsigned int i = 0;
+
+ while ( unicode[ i ] ) {
+ if ( unicode[ i ] < 128 ) {
+ result.append( QChar( unicode[ i ] ) );
+ }
+ else {
+ QString hexCode = QString::number( unicode[ i ], 16 ).rightJustified( 4,
+ QLatin1Char('0') );
+
+ result.append( QLatin1String ("\\u") ).append( hexCode );
+ }
+ ++i;
+ }
+ str = result;
+
+ str.replace( QLatin1String( "\"" ), QLatin1String( "\\\"" ) );
+ str.replace( QLatin1String( "\b" ), QLatin1String( "\\b" ) );
+ str.replace( QLatin1String( "\f" ), QLatin1String( "\\f" ) );
+ str.replace( QLatin1String( "\n" ), QLatin1String( "\\n" ) );
+ str.replace( QLatin1String( "\r" ), QLatin1String( "\\r" ) );
+ str.replace( QLatin1String( "\t" ), QLatin1String( "\\t" ) );
+
+ return QString( QLatin1String( "\"%1\"" ) ).arg( str );
+}
+
+Serializer::Serializer()
+ : d( new SerializerPrivate )
+{
+}
+
+Serializer::~Serializer() {
+ delete d;
+}
+
+void Serializer::serialize( const QVariant& v, QIODevice* io, bool* ok)
+{
+ Q_ASSERT( io );
+ if (ok)
+ *ok = false;
+
+ if (!io->isOpen()) {
+ if (!io->open(QIODevice::WriteOnly)) {
+ qCritical ("Error opening device");
+ return;
+ }
+ }
+
+ if (!io->isWritable()) {
+ qCritical ("Device is not readable");
+ io->close();
+ return;
+ }
+
+ const QByteArray str = serialize( v );
+ if (io->write(str) == str.count()) {
+ if (ok)
+ *ok = true;
+ }
+}
+
+QByteArray Serializer::serialize( const QVariant &v)
+{
+ return d->serialize(v);
+}
+
+void QJson::Serializer::allowSpecialNumbers(bool allow) {
+ d->specialNumbersAllowed = allow;
+}
+
+bool QJson::Serializer::specialNumbersAllowed() const {
+ return d->specialNumbersAllowed;
+}
+
+void QJson::Serializer::setIndentMode(IndentMode mode) {
+ d->indentMode = mode;
+}
+
+void QJson::Serializer::setDoublePrecision(int precision) {
+ d->doublePrecision = precision;
+}
+
+IndentMode QJson::Serializer::indentMode() const {
+ return d->indentMode;
+}
* Copyright (C) 2009 Till Adam <adam@kde.org>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
class QVariant;
namespace QJson {
+ /**
+ * @brief How the indentation should work.
+ *
+ * none (default) : { "foo" : 0, "foo1" : 1, "foo2" : [ { "foo3" : 3, "foo4" : 4 } ] }
+ *
+ * compact : {"foo":0,"foo1":1,"foo2":[{"foo3":3,"foo4":4}]}
+ *
+ * minimum : { "foo" : 0, "foo1" : 1, "foo2" : [
+ * { "foo3" : 3, "foo4" : 4 }
+ * ] }
+ *
+ * medium : {
+ * "foo" : 0, "foo1" : 1, "foo2" : [
+ * {
+ * "foo3" : 3, "foo4" : 4
+ * }
+ * ]
+ * }
+ * full : {
+ * "foo" : 0,
+ * "foo1" : 1,
+ * "foo2" : [
+ * {
+ * "foo3" : 3,
+ * "foo4" : 4
+ * }
+ * ]
+ * }
+ */
+ enum IndentMode {
+ IndentNone,
+ IndentCompact,
+ IndentMinimum,
+ IndentMedium,
+ IndentFull
+ };
/**
* @brief Main class used to convert QVariant objects to JSON data.
*
* @param out Input output device
* @param ok if a conversion error occurs, *ok is set to false; otherwise *ok is set to true
*/
- void serialize( const QVariant& variant, QIODevice* out, bool* ok = 0 );
+ void serialize( const QVariant& variant, QIODevice* out, bool* ok = 0);
/**
* This is a method provided for convenience. It turns the passed in in-memory
* parser.
*/
- QByteArray serialize( const QVariant& variant );
+ QByteArray serialize( const QVariant& variant);
+
+ /**
+ * Allow or disallow writing of NaN and/or Infinity (as an extension to QJson)
+ */
+ void allowSpecialNumbers(bool allow);
+
+ /**
+ * Is Nan and/or Infinity allowed?
+ */
+ bool specialNumbersAllowed() const;
+
+ /**
+ * set output indentation mode as defined in QJson::IndentMode
+ */
+ void setIndentMode(IndentMode mode = QJson::IndentNone);
+
+
+ /**
+ * set double precision used while converting Double
+ * \sa QByteArray::number
+ */
+ void setDoublePrecision(int precision);
+
+ /**
+ * Returns one of the indentation modes defined in QJson::IndentMode
+ */
+ IndentMode indentMode() const;
private:
Q_DISABLE_COPY(Serializer)
* 2009 Frank Osterfeld <osterfeld@kde.org>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
* Copyright (C) 2009 Frank Osterfeld <osterfeld@kde.org>
*
* This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
+ * You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
+OpenGL
cgltrace.cpp
d3d10_1trace.cpp
d3d10trace.cpp
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d10trace.cpp
DEPENDS
d3d10trace.py
+ d3dcommontrace.py
dlltrace.py
trace.py
${CMAKE_SOURCE_DIR}/dispatch/dispatch.py
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10_1trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d10_1trace.cpp
DEPENDS
d3d10_1trace.py
+ d3dcommontrace.py
dlltrace.py
trace.py
${CMAKE_SOURCE_DIR}/dispatch/dispatch.py
${CMAKE_SOURCE_DIR}/specs/winapi.py
${CMAKE_SOURCE_DIR}/specs/stdapi.py
)
- add_library (d3d10_1trace MODULE d3d10_1.def d3d10_1trace.cpp)
+ add_library (d3d10_1trace MODULE d3d10_1.def d3d10_1trace.cpp d3d10shader.cpp)
target_link_libraries (d3d10_1trace
common_trace
common
common
${ZLIB_LIBRARIES}
${SNAPPY_LIBRARIES}
- ${X11_X11_LIB}
${CMAKE_THREAD_LIBS_INIT}
dl
)
egltrace.cpp
glcaps.cpp
gltrace_state.cpp
+ ${CMAKE_SOURCE_DIR}/helpers/eglsize.cpp
)
add_dependencies (egltrace glproc)
##########################################################################/
-from dlltrace import DllTracer
+from d3dcommontrace import D3DCommonTracer
from specs.d3d10_1 import d3d10_1
print '#include "os.hpp"'
print
print '#include "d3d10_1imports.hpp"'
+ print '#include "d3d10shader.hpp"'
+ print '#include "d3d10size.hpp"'
print
- tracer = DllTracer('d3d10_1.dll')
+ tracer = D3DCommonTracer('d3d10_1.dll')
tracer.traceApi(d3d10_1)
##########################################################################/
-from dlltrace import DllTracer
-from specs import stdapi
+from d3dcommontrace import D3DCommonTracer
from specs.d3d10misc import d3d10
-class D3D10Tracer(DllTracer):
-
- def serializeArgValue(self, function, arg):
- # Dump shaders as strings
- if isinstance(arg.type, stdapi.Blob) and arg.name.startswith('pShaderBytecode'):
- print ' DumpShader(trace::localWriter, %s, %s);' % (arg.name, arg.type.size)
- return
-
- DllTracer.serializeArgValue(self, function, arg)
-
if __name__ == '__main__':
print '#define INITGUID'
print
print
print '#include "d3d10imports.hpp"'
print '#include "d3d10shader.hpp"'
+ print '#include "d3d10size.hpp"'
print
- tracer = D3D10Tracer('d3d10.dll')
+ tracer = D3DCommonTracer('d3d10.dll')
tracer.traceApi(d3d10)
#include "d3d9shader.hpp"
#include "d3d9imports.hpp"
-#include "d3dsize.hpp"
+#include "d3d9size.hpp"
typedef HRESULT
def enumWrapperInterfaceVariables(self, interface):
variables = DllTracer.enumWrapperInterfaceVariables(self, interface)
+ # Add additional members to track locks
if interface.getMethodByName('Lock') is not None or \
interface.getMethodByName('LockRect') is not None or \
interface.getMethodByName('LockBox') is not None:
print '#include "os.hpp"'
print
print '#include "d3d9imports.hpp"'
- print '#include "d3dsize.hpp"'
+ print '#include "d3d9size.hpp"'
print '#include "d3d9shader.hpp"'
print '#include "dxvaint.h"'
print
--- /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 import stdapi
+
+
+class D3DCommonTracer(DllTracer):
+
+ def serializeArgValue(self, function, arg):
+ # Dump shaders as strings
+ if isinstance(arg.type, stdapi.Blob) and arg.name.startswith('pShaderBytecode'):
+ print ' DumpShader(trace::localWriter, %s, %s);' % (arg.name, arg.type.size)
+ return
+
+ DllTracer.serializeArgValue(self, function, arg)
+
+ def enumWrapperInterfaceVariables(self, interface):
+ variables = DllTracer.enumWrapperInterfaceVariables(self, interface)
+
+ # Add additional members to track maps
+ if interface.getMethodByName('Map') is not None:
+ variables += [
+ ('VOID *', '_pMappedData', '0'),
+ ('size_t', '_MappedSize', '0'),
+ ]
+
+ return variables
+
+ def implementWrapperInterfaceMethodBody(self, interface, base, method):
+ if method.name == 'Unmap':
+ print ' if (_MappedSize && _pMappedData) {'
+ self.emit_memcpy('_pMappedData', '_pMappedData', '_MappedSize')
+ print ' }'
+
+ DllTracer.implementWrapperInterfaceMethodBody(self, interface, base, method)
+
+ if method.name == 'Map':
+ # NOTE: recursive locks are explicitely forbidden
+ print ' if (SUCCEEDED(_result)) {'
+ print ' _getMapInfo(_this, %s, _pMappedData, _MappedSize);' % ', '.join(method.argNames())
+ print ' } else {'
+ print ' _pMappedData = NULL;'
+ print ' _MappedSize = 0;'
+ print ' }'
+
+
print ' gltrace::releaseContext((uintptr_t)ctx);'
print ' }'
+ if function.name == 'glEGLImageTargetTexture2DOES':
+ print ' image_info *info = _EGLImageKHR_get_image_info(target, image);'
+ print ' if (info) {'
+ print ' GLint level = 0;'
+ print ' GLint internalformat = info->internalformat;'
+ print ' GLsizei width = info->width;'
+ print ' GLsizei height = info->height;'
+ print ' GLint border = 0;'
+ print ' GLenum format = info->format;'
+ print ' GLenum type = info->type;'
+ print ' const GLvoid * pixels = info->pixels;'
+ self.emitFakeTexture2D()
+ print ' _EGLImageKHR_free_image_info(info);'
+ print ' }'
+
+ def emitFakeTexture2D(self):
+ function = glapi.getFunctionByName('glTexImage2D')
+ instances = function.argNames()
+ print ' unsigned _fake_call = trace::localWriter.beginEnter(&_%s_sig);' % (function.name,)
+ for arg in function.args:
+ assert not arg.output
+ self.serializeArg(function, arg)
+ print ' trace::localWriter.endEnter();'
+ print ' trace::localWriter.beginLeave(_fake_call);'
+ print ' trace::localWriter.endLeave();'
+
+
+
if __name__ == '__main__':
print '#include <stdlib.h>'
print '#include <string.h>'
print
print '#include "glproc.hpp"'
print '#include "glsize.hpp"'
+ print '#include "eglsize.hpp"'
print
api = API()
#define _GLTRACE_HPP_
+#include <string.h>
+#include <stdlib.h>
+#include <map>
+
#include "glimports.hpp"
PROFILE_ES2,
};
+
+/**
+ * OpenGL ES buffers cannot be read. This class is used to track index buffer
+ * contents.
+ */
+class Buffer {
+public:
+ GLsizeiptr size;
+ GLvoid *data;
+
+ Buffer() :
+ size(0),
+ data(0)
+ {}
+
+ ~Buffer() {
+ free(data);
+ }
+
+ void
+ bufferData(GLsizeiptr new_size, const void *new_data) {
+ if (new_size < 0) {
+ new_size = 0;
+ }
+ size = new_size;
+ data = realloc(data, new_size);
+ if (new_size && new_data) {
+ memcpy(data, new_data, size);
+ }
+ }
+
+ void
+ bufferSubData(GLsizeiptr offset, GLsizeiptr length, const void *new_data) {
+ if (offset >= 0 && offset < size && length > 0 && offset + length <= size && new_data) {
+ memcpy((GLubyte *)data + offset, new_data, length);
+ }
+ }
+
+ void
+ getSubData(GLsizeiptr offset, GLsizeiptr length, void *out_data) {
+ if (offset >= 0 && offset < size && length > 0 && offset + length <= size && out_data) {
+ memcpy(out_data, (GLubyte *)data + offset, length);
+ }
+ }
+};
+
class Context {
public:
enum Profile profile;
bool user_arrays_nv;
unsigned retain_count;
+ // TODO: This will fail for buffers shared by multiple contexts.
+ std::map <GLuint, Buffer> buffers;
+
Context(void) :
profile(PROFILE_COMPAT),
user_arrays(false),
user_arrays_nv(false),
retain_count(0)
{ }
+
+ inline bool
+ needsShadowBuffers(void)
+ {
+ return profile == PROFILE_ES1 || profile == PROFILE_ES2;
+ }
};
void
print '}'
print
+ self.defineShadowBufferHelper()
+
# Whether we need user arrays
print 'static inline bool _need_user_arrays(void)'
print '{'
else:
Tracer.traceApi(self, api)
+ def defineShadowBufferHelper(self):
+ print 'void _shadow_glGetBufferSubData(GLenum target, GLintptr offset,'
+ print ' GLsizeiptr size, GLvoid *data)'
+ print '{'
+ print ' struct gltrace::Context *ctx = gltrace::getContext();'
+ print ' if (!ctx->needsShadowBuffers() || target != GL_ELEMENT_ARRAY_BUFFER) {'
+ print ' _glGetBufferSubData(target, offset, size, data);'
+ print ' return;'
+ print ' }'
+ print
+ print ' GLint buffer_binding = 0;'
+ print ' _glGetIntegerv(target, &buffer_binding);'
+ print ' if (buffer_binding > 0) {'
+ print ' gltrace::Buffer & buf = ctx->buffers[buffer_binding];'
+ print ' buf.getSubData(offset, size, data);'
+ print ' }'
+ print '}'
+
+ def shadowBufferMethod(self, method):
+ # Emit code to fetch the shadow buffer, and invoke a method
+ print ' gltrace::Context *ctx = gltrace::getContext();'
+ print ' if (ctx->needsShadowBuffers() && target == GL_ELEMENT_ARRAY_BUFFER) {'
+ print ' GLint buffer_binding = 0;'
+ print ' _glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buffer_binding);'
+ print ' if (buffer_binding > 0) {'
+ print ' gltrace::Buffer & buf = ctx->buffers[buffer_binding];'
+ print ' buf.' + method + ';'
+ print ' }'
+ print ' }'
+ print
+
+ def shadowBufferProlog(self, function):
+ if function.name == 'glBufferData':
+ self.shadowBufferMethod('bufferData(size, data)')
+
+ if function.name == 'glBufferSubData':
+ self.shadowBufferMethod('bufferSubData(offset, size, data)')
+
+ if function.name == 'glDeleteBuffers':
+ print ' gltrace::Context *ctx = gltrace::getContext();'
+ print ' if (ctx->needsShadowBuffers()) {'
+ print ' for (GLsizei i = 0; i < n; i++) {'
+ print ' ctx->buffers.erase(buffer[i]);'
+ print ' }'
+ print ' }'
+
array_pointer_function_names = set((
"glVertexPointer",
"glNormalPointer",
print ' _glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size);'
print ' if (map && size > 0) {'
self.emit_memcpy('map', 'map', 'size')
+ self.shadowBufferMethod('bufferSubData(0, size, map)')
print ' }'
print ' }'
if function.name == 'glUnmapNamedBufferEXT':
print ' }'
print ' }'
+ self.shadowBufferProlog(function)
+
Tracer.traceFunctionImplBody(self, function)
marker_functions = [
function = api.getFunctionByName('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();'
}
};
-static os::thread_specific_ptr<struct ThreadState> thread_state;
+static thread_specific ThreadState *thread_state;
static ThreadState *get_ts(void)
{
- ThreadState *ts = thread_state.get();
-
+ ThreadState *ts = thread_state;
if (!ts) {
- ts = new ThreadState;
- thread_state.reset(ts);
+ thread_state = ts = new ThreadState;
}
return ts;
void createContext(uintptr_t context_id)
{
+ // wglCreateContextAttribsARB causes internal calls to wglCreateContext to be
+ // traced, causing context to be defined twice.
+ if (context_map.find(context_id) != context_map.end()) {
+ return;
+ }
+
context_ptr_t ctx(new Context);
context_map_mutex.lock();
_retainContext(ctx);
- assert(context_map.find(context_id) == context_map.end());
context_map[context_id] = ctx;
context_map_mutex.unlock();
"glXGetProcAddressARB",
]
+ createContextFunctionNames = [
+ 'glXCreateContext',
+ 'glXCreateContextAttribsARB',
+ 'glXCreateContextWithConfigSGIX',
+ 'glXCreateNewContext',
+ ]
+
+ destroyContextFunctionNames = [
+ 'glXDestroyContext',
+ ]
+
+ makeCurrentFunctionNames = [
+ 'glXMakeCurrent',
+ 'glXMakeContextCurrent',
+ 'glXMakeCurrentReadSGI',
+ ]
+
def traceFunctionImplBody(self, function):
- if function.name == 'glXDestroyContext':
+ if function.name in self.destroyContextFunctionNames:
print ' gltrace::releaseContext((uintptr_t)ctx);'
GlTracer.traceFunctionImplBody(self, function)
- if function.name == 'glXCreateContext':
+ if function.name in self.createContextFunctionNames:
print ' if (_result != NULL)'
print ' gltrace::createContext((uintptr_t)_result);'
- if function.name == 'glXMakeCurrent':
+ if function.name in self.makeCurrentFunctionNames:
print ' if (_result) {'
print ' if (ctx != NULL)'
print ' gltrace::setContext((uintptr_t)ctx);'
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),)
+ print 'static const char * _struct%s_members[%u] = {' % (struct.tag, 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 ' "%s",' % (name,)
+ print '};'
+ print 'static const trace::StructSig _struct%s_sig = {' % (struct.tag,)
+ print ' %u, "%s", %u, _struct%s_members' % (struct.id, struct.name, len(struct.members), struct.tag)
+ print '};'
print
def visitArray(self, array):
ComplexValueSerializer visitor above.
'''
+ def __init__(self):
+ #stdapi.Visitor.__init__(self)
+ self.indices = []
+ self.instances = []
+
+ def expand(self, expr):
+ # Expand a C expression, replacing certain variables
+ variables = {}
+ try:
+ variables['self'] = self.instances[-1]
+ except IndexError:
+ pass
+ try:
+ variables['i'] = self.indices[-1]
+ except IndexError:
+ pass
+ expandedExpr = expr.format(**variables)
+ if expandedExpr != expr:
+ sys.stderr.write(" %r -> %r\n" % (expr, expandedExpr))
+ return expandedExpr
+
def visitLiteral(self, literal, instance):
print ' trace::localWriter.write%s(%s);' % (literal.kind, instance)
def visitString(self, string, instance):
- if string.kind == 'String':
+ if not string.wide:
cast = 'const char *'
- elif string.kind == 'WString':
- cast = 'const wchar_t *'
+ suffix = 'String'
else:
- assert False
+ cast = 'const wchar_t *'
+ suffix = 'WString'
if cast != string.expr:
# reinterpret_cast is necessary for GLubyte * <=> char *
instance = 'reinterpret_cast<%s>(%s)' % (cast, instance)
length = ', %s' % string.length
else:
length = ''
- print ' trace::localWriter.write%s(%s%s);' % (string.kind, instance, length)
+ print ' trace::localWriter.write%s(%s%s);' % (suffix, instance, length)
def visitConst(self, const, instance):
self.visit(const.type, instance)
def visitStruct(self, struct, instance):
- print ' _write__%s(%s);' % (struct.tag, instance)
+ print ' trace::localWriter.beginStruct(&_struct%s_sig);' % (struct.tag,)
+ self.instances.append(instance)
+ try:
+ for type, name in struct.members:
+ self.visit(type, '(%s).%s' % (instance, name,))
+ finally:
+ self.instances.pop()
+ print ' trace::localWriter.endStruct();'
def visitArray(self, array, instance):
length = '_c' + array.type.tag
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))
+ self.indices.append(index)
+ try:
+ self.visit(array.type, '(%s)[%s]' % (instance, index))
+ finally:
+ self.indices.pop()
print ' trace::localWriter.endElement();'
print ' }'
print ' trace::localWriter.endArray();'
print ' }'
def visitBlob(self, blob, instance):
- print ' trace::localWriter.writeBlob(%s, %s);' % (instance, blob.size)
+ print ' trace::localWriter.writeBlob(%s, %s);' % (instance, self.expand(blob.size))
def visitEnum(self, enum, instance):
print ' trace::localWriter.writeEnum(&_enum%s_sig, %s);' % (enum.tag, instance)
print ' trace::localWriter.endEnter();'
print ' trace::localWriter.beginLeave(_call);'
print ' trace::localWriter.endLeave();'
+
+ 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();'
"wglGetProcAddress",
]
+ createContextFunctionNames = [
+ 'wglCreateContext',
+ 'wglCreateContextAttribsARB',
+ 'wglCreateLayerContext',
+ ]
+
+ destroyContextFunctionNames = [
+ 'wglDeleteContext',
+ ]
+
+ makeCurrentFunctionNames = [
+ 'wglMakeCurrent',
+ 'wglMakeContextCurrentARB',
+ 'wglMakeContextCurrentEXT',
+ ]
+
def traceFunctionImplBody(self, function):
- if function.name == 'wglDeleteContext':
+ if function.name in self.destroyContextFunctionNames:
# Unlike other GL APIs like EGL or GLX, WGL will make the context
# inactive if it's currently the active context.
print ' if (_wglGetCurrentContext() == hglrc) {'
GlTracer.traceFunctionImplBody(self, function)
- if function.name == 'wglCreateContext':
+ if function.name in self.createContextFunctionNames:
print ' if (_result)'
print ' gltrace::createContext((uintptr_t)_result);'
- if function.name == 'wglMakeCurrent':
+ if function.name in self.makeCurrentFunctionNames:
print ' if (_result) {'
print ' if (hglrc != NULL)'
print ' gltrace::setContext((uintptr_t)hglrc);'