Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'master' into virtual-memory-regions

Conflicts:
	common/os.hpp
	common/os_posix.cpp
	common/trace_writer.hpp
	common/trace_writer_local.cpp
	gltrace.py
  • Loading branch information...
commit 2257503ff3fc87d76309bd58b3206ee4cac33c37 2 parents 6f423e4 + cabebb8
@jrfonseca jrfonseca authored
Showing with 20,023 additions and 8,159 deletions.
  1. +5 −10 .gitignore
  2. +1 −0  .lvimrc
  3. +101 −0 Android.mk
  4. +35 −14 BUGS.markdown
  5. +246 −295 CMakeLists.txt
  6. +100 −9 DEVELOPMENT.markdown
  7. +55 −0 Dalvik.markdown
  8. +125 −0 FORMAT.markdown
  9. +77 −20 INSTALL.markdown
  10. +6 −3 LICENSE
  11. +40 −2 NEWS.markdown
  12. +344 −128 README.markdown
  13. +1 −80 TODO.markdown
  14. +0 −130 cgltrace.py
  15. +51 −0 cli/CMakeLists.txt
  16. +1 −0  cli/README.markdown
  17. +11 −3 cli/cli.hpp
  18. +91 −0 cli/cli_diff.cpp
  19. +87 −0 cli/cli_diff_images.cpp
  20. +104 −0 cli/cli_diff_state.cpp
  21. +114 −36 cli/cli_dump.cpp
  22. +152 −0 cli/cli_dump_images.cpp
  23. +42 −12 cli/cli_main.cpp
  24. +154 −0 cli/cli_pager.cpp
  25. +5 −19 glsnapshot.hpp → cli/cli_pager.hpp
  26. +280 −0 cli/cli_pickle.cpp
  27. +119 −0 cli/cli_repack.cpp
  28. +199 −0 cli/cli_resources.cpp
  29. +46 −0 cli/cli_resources.hpp
  30. +151 −0 cli/cli_retrace.cpp
  31. +46 −0 cli/cli_retrace.hpp
  32. +308 −0 cli/cli_sed.cpp
  33. +376 −0 cli/cli_trace.cpp
  34. +479 −0 cli/cli_trim.cpp
  35. +333 −0 cli/pickle.hpp
  36. +767 −0 cli/trace_analyzer.cpp
  37. +114 −0 cli/trace_analyzer.hpp
  38. +1 −0  cmake/.gitignore
  39. +159 −51 cmake/FindDirectX.cmake
  40. +0 −44 cmake/FindQJSON.cmake
  41. +38 −0 cmake/FindWaffle.cmake
  42. +1,776 −0 cmake/toolchain/android.toolchain.cmake
  43. +0 −81 codegen.py
  44. +0 −174 common/formatter.hpp
  45. +313 −0 common/highlight.cpp
  46. +88 −0 common/highlight.hpp
  47. +0 −112 common/image_pnm.cpp
  48. +0 −342 common/json.hpp
  49. +19 −7 common/os.hpp
  50. +486 −0 common/os_backtrace.cpp
  51. +47 −0 common/os_backtrace.hpp
  52. +61 −0 common/os_binary.hpp
  53. +89 −0 common/os_dl.hpp
  54. +39 −29 compat.h → common/os_memory.hpp
  55. +0 −211 common/os_path.hpp
  56. +152 −60 common/os_posix.cpp
  57. +91 −0 common/os_process.hpp
  58. +435 −0 common/os_string.hpp
  59. +434 −0 common/os_thread.hpp
  60. +106 −0 common/os_time.hpp
  61. +222 −60 common/os_win32.cpp
  62. +57 −0 common/trace_api.hpp
  63. +255 −0 common/trace_callset.cpp
  64. +197 −0 common/trace_callset.hpp
  65. +302 −0 common/trace_dump.cpp
  66. +77 −0 common/trace_dump.hpp
  67. +210 −0 common/trace_fast_callset.cpp
  68. +142 −0 common/trace_fast_callset.hpp
  69. +2 −8 common/trace_file.cpp
  70. +12 −7 common/trace_file.hpp
  71. +69 −0 common/trace_file_read.cpp
  72. +21 −36 common/trace_file_snappy.cpp
  73. +50 −0 common/trace_file_write.cpp
  74. +16 −22 common/trace_file_zlib.cpp
  75. +18 −72 common/trace_format.hpp
  76. +2 −4 common/trace_loader.cpp
  77. +111 −0 common/trace_lookup.hpp
  78. +50 −195 common/trace_model.cpp
  79. +248 −32 common/trace_model.hpp
  80. +53 −0 common/trace_option.cpp
  81. +37 −0 common/trace_option.hpp
  82. +316 −35 common/trace_parser.cpp
  83. +29 −3 common/trace_parser.hpp
  84. +585 −0 common/trace_parser_flags.cpp
  85. +260 −0 common/trace_profiler.cpp
  86. +145 −0 common/trace_profiler.hpp
  87. +52 −7 common/trace_writer.cpp
  88. +12 −49 common/trace_writer.hpp
  89. +88 −27 common/trace_writer_local.cpp
  90. +123 −0 common/trace_writer_local.hpp
  91. +23 −5 common/trace_writer_model.cpp
  92. +0 −96 d3dshader.cpp
  93. +1 −0  dispatch/.gitignore
  94. +55 −0 dispatch/CMakeLists.txt
  95. +9 −0 dispatch/README.markdown
  96. +1 −0  dispatch/__init__.py
  97. +748 −0 dispatch/compat.h
  98. +98 −0 dispatch/d2dimports.hpp
  99. +48 −0 dispatch/d3d10_1imports.hpp
  100. +48 −0 dispatch/d3d10imports.hpp
  101. +45 −0 dispatch/d3d11imports.hpp
  102. +39 −0 dispatch/d3d8imports.hpp
  103. +29 −6 { → dispatch}/d3d9imports.hpp
  104. +63 −0 dispatch/d3derr.hpp
  105. +34 −34 { → dispatch}/dispatch.py
  106. +66 −0 dispatch/dlopen.hpp
  107. +62 −0 dispatch/dxgiint.h
  108. +179 −0 dispatch/dxvaint.h
  109. +91 −0 dispatch/eglimports.hpp
  110. +193 −0 dispatch/glimports.hpp
  111. +91 −34 { → dispatch}/glproc.py
  112. +148 −0 dispatch/glproc_egl.cpp
  113. +228 −0 dispatch/glproc_gl.cpp
  114. +0 −177 glcaps.cpp
  115. +0 −140 glimports.hpp
  116. +0 −125 glretrace_cgl.cpp
  117. +0 −347 glretrace_main.cpp
  118. +0 −309 glretrace_wgl.cpp
  119. +0 −761 glsize.hpp
  120. +0 −224 glsnapshot.cpp
  121. +0 −1,326 glstate.cpp
  122. +0 −471 glstate.py
  123. +0 −798 gltrace.py
  124. +0 −249 glws_wgl.cpp
  125. +0 −231 glxtrace.py
  126. +0 −1  gui/.gitignore
  127. +47 −3 gui/CMakeLists.txt
  128. +1 −0  gui/README.markdown
  129. +43 −16 gui/apicalldelegate.cpp
  130. +158 −12 gui/apisurface.cpp
  131. +20 −5 gui/apisurface.h
  132. +51 −46 gui/apitrace.cpp
  133. +11 −15 gui/apitrace.h
  134. +294 −102 gui/apitracecall.cpp
  135. +47 −14 gui/apitracecall.h
  136. +16 −2 gui/apitracefilter.cpp
  137. +56 −36 gui/apitracemodel.cpp
  138. +2 −0  gui/apitracemodel.h
  139. +45 −74 gui/argumentseditor.cpp
  140. +122 −4 gui/argumentseditor.h
  141. +173 −0 gui/calldurationgraph.h
  142. +99 −0 gui/graphing/frameaxiswidget.cpp
  143. +34 −0 gui/graphing/frameaxiswidget.h
  144. +141 −0 gui/graphing/graphaxiswidget.cpp
  145. +73 −0 gui/graphing/graphaxiswidget.h
  146. +48 −0 gui/graphing/graphing.h
  147. +42 −0 gui/graphing/graphlabelwidget.h
  148. +187 −0 gui/graphing/graphview.cpp
  149. +93 −0 gui/graphing/graphview.h
  150. +583 −0 gui/graphing/graphwidget.cpp
  151. +112 −0 gui/graphing/graphwidget.h
  152. +82 −0 gui/graphing/heatmapverticalaxiswidget.cpp
  153. +24 −0 gui/graphing/heatmapverticalaxiswidget.h
  154. +276 −0 gui/graphing/heatmapview.cpp
  155. +124 −0 gui/graphing/heatmapview.h
  156. +258 −0 gui/graphing/histogramview.cpp
  157. +41 −0 gui/graphing/histogramview.h
  158. +80 −0 gui/graphing/timeaxiswidget.cpp
  159. +16 −0 gui/graphing/timeaxiswidget.h
  160. +136 −8 gui/imageviewer.cpp
  161. +21 −2 gui/imageviewer.h
  162. +68 −3 gui/main.cpp
  163. +282 −50 gui/mainwindow.cpp
  164. +34 −4 gui/mainwindow.h
  165. +408 −0 gui/pixelwidget.cpp
  166. +115 −0 gui/pixelwidget.h
Sorry, we could not display the entire diff because too many files (605) changed.
View
15 .gitignore
@@ -4,16 +4,19 @@
*.a
*.bmp
*.bz2
+*.cbp
*.cmake
*.dll
*.dmg
*.dylib
*.exe
*.exp
+*.framework
*.gz
*.ilk
*.json
*.lib
+*.moc*
*.o
*.obj
*.pdb
@@ -27,21 +30,13 @@
_CPack_Packages
CMakeCache.txt
CMakeFiles
+CMakeLists.txt.user
Makefile
apitrace
build
-cgltrace.cpp
-d3d10trace.cpp
-d3d8trace.cpp
-d3d9trace.cpp
-ddrawtrace.cpp
dxsdk
-glproc.hpp
+eglretrace
glretrace
-glretrace_gl.cpp
-glstate_params.cpp
-glxtrace.cpp
install_manifest.txt
qapitrace
traces
-wgltrace.cpp
View
1  .lvimrc
@@ -0,0 +1 @@
+set sw=4 ts=8 et
View
101 Android.mk
@@ -0,0 +1,101 @@
+#
+# This file helps integrate apitrace into FirefoxOS - when apitrace
+# sources are put in B2GROOT/external/apitrace (including this Android.mk
+# file), then the B2G build system will pick apitrace automatically and
+# compile and install it into the system images seamlessly.
+#
+# This may work in other than FirefoxOS environments, but has not been tested.
+#
+
+NDK := prebuilt/ndk/android-ndk-r7
+
+ifeq ($(shell which cmake),)
+$(shell echo "CMake not found, will not compile apitrace" >&2)
+else # cmake
+ifeq ($(wildcard $(NDK)),)
+$(shell echo "CMake present but NDK not found at $(abspath $(NDK)), will not compile apitrace" >&2)
+else # NDK
+$(shell echo "CMake and NDK ($(abspath $(NDK))) found, will compile apitrace" >&2)
+
+ifeq ($(TARGET_ARCH),arm)
+TOOLCHAIN := arm-linux-androideabi-4.4.x
+endif
+
+ifeq ($(TARGET_ARCH),x86)
+TOOLCHAIN := i686-android-linux-4.4.3
+endif
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := egltrace
+LOCAL_MODULE_TAGS := debug eng
+
+include $(BUILD_SHARED_LIBRARY)
+
+# Below we hook the process of configuring and compiling apitrace,
+# described in INSTALL.markdown (but we use the FirefoxOS's NDK). We override
+# the $(linked_module): targed, which is already defined by
+# $(BUILD_SHARED_LIBRARY) - by default it would want to compile the
+# library out of some source files.
+# We also override the target $(LOCAL_INSTALLED_MODULE): which installs
+# the shared library because we want it installed in
+# /lib/apitrace/wrappers/egltrace.so instead of /lib/egltrace.so because
+# /bin/apitrace searches for the library in that directory.
+# The rules will end up with /lib/apitrace/wrappers/egltrace.so and
+# /bin/apitrace inside system.img.
+MY_APITRACE_ROOT := $(TOPDIR)external/apitrace
+MY_APITRACE_BUILD_ROOT_HOST := out/host/apitrace
+MY_APITRACE_BUILD_ROOT_TARGET := out/target/apitrace
+
+apitrace_private_target:
+ $(hide) # apitrace: run cmake for the host if it has not been run
+ $(hide) if [ ! -e $(MY_APITRACE_BUILD_ROOT_HOST)/Makefile ] ; then \
+ cd $(MY_APITRACE_ROOT) && \
+ cmake -H. -B../../$(MY_APITRACE_BUILD_ROOT_HOST) ; \
+ fi
+ $(hide) # apitrace: compile for the host
+ $(hide) make -C $(MY_APITRACE_BUILD_ROOT_HOST)
+ $(hide) # apitrace: run cmake for android if it has not been run
+ $(hide) if [ ! -e $(MY_APITRACE_BUILD_ROOT_TARGET)/Makefile ] ; then \
+ cd $(MY_APITRACE_ROOT) && \
+ cmake \
+ -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/android.toolchain.cmake \
+ -DANDROID_NDK=../../$(NDK) \
+ -DANDROID_NDK_LAYOUT=LINARO \
+ -DANDROID_TOOLCHAIN_NAME=$(TOOLCHAIN) \
+ -DANDROID_API_LEVEL=9 \
+ -DANDROID_NO_UNDEFINED=OFF \
+ -DLIBRARY_OUTPUT_PATH_ROOT=../../$(MY_APITRACE_BUILD_ROOT_TARGET) \
+ -H. -B../../$(MY_APITRACE_BUILD_ROOT_TARGET) ; \
+ fi
+ $(hide) # apitrace: compile for android
+ $(hide) make -C $(MY_APITRACE_BUILD_ROOT_TARGET)
+
+$(linked_module): apitrace_private_target
+ $(hide) # apitrace: copy egltrace lib to where the build system expects it
+ $(hide) mkdir -p $(dir $@)
+ $(hide) cp $(MY_APITRACE_BUILD_ROOT_TARGET)/libs/*/egltrace$(TARGET_SHLIB_SUFFIX) $@
+
+$(LOCAL_INSTALLED_MODULE): $(LOCAL_BUILT_MODULE) | $(ACP)
+ @echo "Install (overridden): $@"
+ @mkdir -p $(dir $@)/apitrace/wrappers
+ $(hide) $(ACP) -fp $< $(dir $@)/apitrace/wrappers/egltrace$(TARGET_SHLIB_SUFFIX)
+
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := apitrace
+LOCAL_MODULE_TAGS := debug eng
+
+include $(BUILD_EXECUTABLE)
+
+$(linked_module): apitrace_private_target
+ $(hide) # apitrace: copy apitrace executable to where the build system expects it
+ $(hide) mkdir -p $(dir $@)
+ $(hide) cp $(MY_APITRACE_BUILD_ROOT_TARGET)/apitrace$(TARGET_EXECUTABLE_SUFFIX) $@
+
+endif # NDK
+endif # cmake
View
49 BUGS.markdown
@@ -27,12 +27,11 @@ is no immediate plan to address them, because either:
That said, feel free to file an issue and/or send an email to the mailing list
if:
-* send an email to the mailing list if you want discuss the rationale, propose
- your ideas on how to address it, or volunteer to work on it;
+* you want discuss the rationale, propose your ideas on how to address it, or
+ volunteer to work on it;
-* file the issue in the issue tracker (or comment to it if it already exists)
- if it is important for you and you would like to see it addressed sooner
- rather than later.
+* a known issue is important for you and you would like to see it addressed
+ sooner rather than later.
Tracing
@@ -50,12 +49,33 @@ Tracing
There is no way to distinguish the fake calls from those actually
made by the application yet.
+* Huge traces will be generated for applications that make extensive use of
+ immediate mode drawing (ie., glBegin/glEnd), use vertex/element arrays in
+ user memory, or generate a lot of dynamic vertex data per frame. This is
+ because large quantities of (often redundant) data will be recorded over and
+ over; and although the traces are compressed, the compression algorithms used
+ aim a good performance/compression balance, hence fail to identify and remove
+ the redundancy at this scale.
+
+ However, this should not be a problem for modern OpenGL applications that
+ make an efficient use of VBOs and vertex shaders.
+
* On MacOSX, the internal OpenGL calls done by GLU are not traced yet.
Retracing
---------
+* Replaying can take substantially more CPU due to the overhead of reading the
+ trace file from disk.
+
+ However, the overhead should not be significant for modern 3D applications
+ that do efficient use of VBOs and vertex shaders. The communication between
+ CPU to GPU can easily be a bottleneck on the powerful discrete GPUs of
+ nowadays, and trace overhead tend to be propotional so it is not a
+ coincidence that applications that are optimized for modern GPUs will also be
+ traced and replayed efficiently.
+
* glretrace needs to infer window sizes from glViewport calls, because calls
that create/resize windows happen outside of OpenGL and are not traced.
Therefore window will be missing if the application relies on the default
@@ -71,10 +91,8 @@ Retracing
a standard 32bit RGBA, 24bit depth, 8bit alpha, double buffer visual. Unless
overridden on command line.
-* Multi-threaded OpenGL is not yet supported.
-
-* OpenGL context sharing is not fully respected -- all contexts are expected to
- share state, and most likely there
+* OpenGL context sharing is not fully respected -- all contexts are assumed to
+ share state. This is by far the most common case though.
GUI
@@ -119,10 +137,9 @@ github issue tracker doesn't support attachments.
Please attach long logs to https://gist.github.com/ and paste the URL into the
issue description.
-For big attachments, such as traces, please upload it temporarily to a web
-server you control, or use a file upload service such as
-http://www.megaupload.com/ or http://dropbox.com/ and paste the URL into the
-issue description.
+For big attachments, such as traces, please upload them temporarily to a web
+server you control, or use a file upload service such as http://dropbox.com/
+and paste the URL into the issue description.
Trace files are only slightly compressed (for performance reasons). You can
further reduce their size when attaching/uploading by compressing with
@@ -159,7 +176,8 @@ Linux/MacOSX
------------
Please rebuild apitrace with debugging information, by passing
-`-DCMAKE_BUILD_TYPE=Debug` to cmake.
+`-DCMAKE_BUILD_TYPE=Debug` to cmake, or editing its value in `CMakeCache.txt`
+and rebuilding.
To obtain a stack back-trace, run the application with gdb from a terminal:
@@ -168,6 +186,9 @@ To obtain a stack back-trace, run the application with gdb from a terminal:
...
(gdb) bt
+On Linux, to trace an application inside gdb invoke apitrace as:
+
+ apitrace trace --verbose --debug application arg1 ...
See also more detailed and Distro specific instructions:
View
541 CMakeLists.txt 100755 → 100644
@@ -1,5 +1,15 @@
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.
+# But DONT force clang if we are cross-compiling to Android.
+if (APPLE AND NOT ANDROID_NDK)
+ set (CMAKE_C_COMPILER "clang")
+ set (CMAKE_CXX_COMPILER "clang++")
+endif ()
+
+
project (apitrace)
@@ -17,35 +27,80 @@ endif ()
# prescribed in http://www.gentoo.org/proj/en/qa/automagic.xml
set (ENABLE_GUI "AUTO" CACHE STRING "Enable Qt GUI.")
+set (ENABLE_CLI true CACHE BOOL "Enable command Line interface.")
+
+set (ENABLE_EGL true CACHE BOOL "Enable EGL support.")
+
+set (ENABLE_WAFFLE false CACHE BOOL "Enable WAFFLE support.")
+
##############################################################################
# Find dependencies
+# Check for compiler TLS support. We don't use compiler TLS support on Windows
+# because, even if the compiler supports it, Windows XP does not support TLS on
+# DLLs.
+if (NOT WIN32)
+ include (CheckCXXSourceCompiles)
+ check_cxx_source_compiles("__thread int i; int main() { return 0; }" HAVE_COMPILER_TLS)
+ if (HAVE_COMPILER_TLS)
+ add_definitions (-DHAVE_COMPILER_TLS=__thread)
+ else ()
+ message (WARNING "C++ compiler does not support __thread keyword.")
+ endif ()
+endif ()
+
set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
-set (CMAKE_USE_PYTHON_VERSION 2.7 2.6)
+if (ANDROID)
+ set (ENABLE_GUI false)
+else ()
+ macro (find_host_package)
+ find_package (${ARGN})
+ endmacro()
+endif ()
-find_package (PythonInterp REQUIRED)
-find_package (OpenGL REQUIRED)
+find_host_package (PythonInterp 2.6 REQUIRED)
+if (NOT PYTHON_VERSION_MAJOR EQUAL 2)
+ message (FATAL_ERROR "Python 2.x required and requested, but Python ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR} found.")
+endif ()
+
+find_package (Threads)
if (ENABLE_GUI)
if (NOT (ENABLE_GUI STREQUAL "AUTO"))
set (REQUIRE_GUI REQUIRED)
endif ()
find_package (Qt4 4.7 COMPONENTS QtCore QtGui QtWebKit ${REQUIRE_GUI})
- find_package (QJSON ${REQUIRE_GUI})
endif ()
if (WIN32)
find_package (DirectX)
+ foreach (api in D3D D3D8 D3D9 D3D10 D3D10_1 D3D11 D3D11_1 D2D1)
+ if (EXISTS "${DirectX_${api}_INCLUDE_DIR}")
+ find_package_message (${api} "Found ${api}" "${DirectX_${api}_INCLUDE_DIR}")
+ endif ()
+ endforeach ()
+
+ set (ENABLE_EGL false)
elseif (APPLE)
+ set (ENABLE_EGL false)
else ()
- find_package (X11 REQUIRED)
+ find_package (X11)
- set (X11_INCLUDE_DIR ${X11_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR})
- set (X11_GL_LIB ${OPENGL_gl_LIBRARY})
+ 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 ()
- include_directories (${X11_INCLUDE_DIR})
+if (ENABLE_EGL AND (ANDROID OR ENABLE_WAFFLE))
+ # if waffle is found eglretrace will be built for Android.
+ find_package (Waffle)
endif ()
@@ -53,23 +108,28 @@ endif ()
# Set global build options
include (CheckCXXCompilerFlag)
+include (CheckIncludeFileCXX)
if (WIN32)
- # MSVC & MinGW only define & use APIENTRY
- add_definitions (-DGLAPIENTRY=__stdcall)
-
# http://msdn.microsoft.com/en-us/library/aa383745.aspx
- add_definitions (-D_WIN32_WINNT=0x0500 -DWINVER=0x0500)
+ add_definitions (-D_WIN32_WINNT=0x0601 -DWINVER=0x0601)
else (WIN32)
CHECK_CXX_COMPILER_FLAG("-fvisibility=hidden" CXX_COMPILER_FLAG_VISIBILITY)
if (CXX_COMPILER_FLAG_VISIBILITY)
add_definitions ("-fvisibility=hidden")
- endif (CXX_COMPILER_FLAG_VISIBILITY)
-endif (WIN32)
+ endif ()
+endif ()
if (MSVC)
- # C99 includes for msvc
- include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/msvc)
+ # Use bundled stdint.h for older MSVC versions
+ check_include_file_cxx (stdint.h HAVE_STDINT_H)
+ if (NOT HAVE_STDINT_H)
+ include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/msinttypes)
+ endif ()
+
+ # No RTTI required
+ string (REGEX REPLACE "/GR *" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
# Enable math constants defines
add_definitions (-D_USE_MATH_DEFINES)
@@ -80,14 +140,16 @@ if (MSVC)
# Adjust warnings
add_definitions (-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
add_definitions (-D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS)
- add_definitions (-W4)
+ add_definitions (-W3)
+ # XXX: it's safer to use ssize_t everywhere instead of disabling warning
+ add_definitions (-wd4018) # signed/unsigned mismatch
add_definitions (-wd4063) # not a valid value for switch of enum
+ add_definitions (-wd4100) # unreferenced formal parameter
add_definitions (-wd4127) # conditional expression is constant
add_definitions (-wd4244) # conversion from 'type1' to 'type2', possible loss of data
add_definitions (-wd4505) # unreferenced local function has been removed
+ add_definitions (-wd4512) # assignment operator could not be generated
add_definitions (-wd4800) # forcing value to bool 'true' or 'false' (performance warning)
- # XXX: it's safer to use ssize_t everywhere instead of disabling warning
- add_definitions (-wd4018) # signed/unsigned mismatch
# Use static runtime
# http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
@@ -97,13 +159,29 @@ if (MSVC)
)
if (${flag_var} MATCHES "/MD")
string (REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
- endif (${flag_var} MATCHES "/MD")
+ endif ()
endforeach (flag_var)
else ()
# Adjust warnings
add_definitions (-Wall)
# XXX: it's safer to use ssize_t everywhere instead of disabling warning
add_definitions (-Wno-sign-compare) # comparison between signed and unsigned integer expressions
+
+ # No RTTI required
+ #set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
+
+ # Use GDB extensions if available
+ if (CMAKE_COMPILER_IS_GNUC)
+ set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -O0")
+ set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ggdb")
+ endif ()
+ if (CMAKE_COMPILER_IS_GNUCXX)
+ 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)
@@ -122,6 +200,15 @@ if (MINGW)
endif ()
endif ()
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ # For RTLD_DEFAULT and RTLD_NEXT
+ add_definitions (-D_GNU_SOURCE)
+endif ()
+
+check_include_file_cxx (tr1/memory HAVE_TR1_MEMORY)
+if (HAVE_TR1_MEMORY)
+ add_definitions (-DHAVE_TR1_MEMORY)
+endif ()
# Put all executables into the same top level build directory, regardless of
# which subdirectory they are declared
@@ -129,6 +216,43 @@ set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
##############################################################################
+# Installation directories
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ # Debian multiarch support
+ execute_process(COMMAND dpkg-architecture -qDEB_HOST_MULTIARCH
+ OUTPUT_VARIABLE ARCH_SUBDIR
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ CHECK_INCLUDE_FILES(proc/readproc.h READPROC_H_FOUND)
+ if (READPROC_H_FOUND)
+ add_definitions (-DHAVE_READPROC_H)
+ find_library (proc_LIBRARY NAMES proc procps)
+ endif ()
+endif()
+
+if (WIN32 OR APPLE)
+ # On Windows/MacOSX, applications are usually installed on a directory of
+ # their own
+ set (DOC_INSTALL_DIR doc)
+ set (LIB_INSTALL_DIR lib)
+ set (LIB_ARCH_INSTALL_DIR lib)
+else ()
+ set (DOC_INSTALL_DIR share/doc/${CMAKE_PROJECT_NAME})
+ set (LIB_INSTALL_DIR lib${LIB_SUFFIX}/${CMAKE_PROJECT_NAME})
+ if (ARCH_SUBDIR)
+ set (LIB_ARCH_INSTALL_DIR lib/${ARCH_SUBDIR}/${CMAKE_PROJECT_NAME})
+ else ()
+ set (LIB_ARCH_INSTALL_DIR lib${LIB_SUFFIX}/${CMAKE_PROJECT_NAME})
+ endif ()
+endif ()
+
+set (SCRIPTS_INSTALL_DIR ${LIB_INSTALL_DIR}/scripts)
+set (WRAPPER_INSTALL_DIR ${LIB_ARCH_INSTALL_DIR}/wrappers)
+
+
+##############################################################################
# Bundled dependencies
#
# We always use the bundled zlib, libpng, and snappy sources:
@@ -138,120 +262,99 @@ set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (ZLIB_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/zlib)
set (ZLIB_LIBRARIES z_bundled)
-add_subdirectory (thirdparty/zlib EXCLUDE_FROM_ALL)
+add_subdirectory (thirdparty/zlib)
include_directories (${ZLIB_INCLUDE_DIRS})
-link_libraries (${ZLIB_LIBRARIES})
set (SNAPPY_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/snappy)
set (SNAPPY_LIBRARIES snappy_bundled)
-add_subdirectory (thirdparty/snappy EXCLUDE_FROM_ALL)
+add_subdirectory (thirdparty/snappy)
include_directories (${SNAPPY_INCLUDE_DIRS})
-link_libraries (${SNAPPY_LIBRARIES})
set (PNG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/libpng)
set (PNG_DEFINITIONS "")
set (PNG_LIBRARIES png_bundled)
-add_subdirectory (thirdparty/libpng EXCLUDE_FROM_ALL)
-include_directories (${PNG_INCLUDE_DIR})
-add_definitions (${PNG_DEFINITIONS})
-link_libraries (${PNG_LIBRARIES})
+add_subdirectory (thirdparty/libpng)
-# 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"))
- add_subdirectory (thirdparty/qjson EXCLUDE_FROM_ALL)
- set (QJSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/qjson)
- set (QJSON_LIBRARY_DIRS)
- set (QJSON_LIBRARIES qjson_bundled)
- set (QJSON_FOUND TRUE)
+if (MSVC)
+ add_subdirectory (thirdparty/getopt)
+ include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/getopt)
+ set (GETOPT_LIBRARIES getopt_bundled)
endif ()
-# For glext headers
-include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty)
-
-
-##############################################################################
-# Installation directories
+if (WIN32)
+ add_subdirectory (thirdparty/directxtex)
+endif ()
-if (WIN32 OR APPLE)
- # On Windows/MacOSX, applications are usually installed on a directory of
- # their own
- set (DOC_INSTALL_DIR doc)
-else ()
- set (DOC_INSTALL_DIR share/doc/${CMAKE_PROJECT_NAME})
+if (CMAKE_EXECUTABLE_FORMAT STREQUAL "ELF")
+ add_subdirectory (thirdparty/libbacktrace)
+ include_directories (${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/libbacktrace)
+ set (LIBBACKTRACE_LIBRARIES dl backtrace)
+ add_definitions (-DHAVE_BACKTRACE=1)
endif ()
-if (APPLE)
- # MacOSX uses fat binaries, so no need to have per-architecture wrapper
- # directories
- set (WRAPPER_INSTALL_DIR lib/apitrace)
-else ()
- set (WRAPPER_INSTALL_DIR lib/apitrace/${CMAKE_SYSTEM_PROCESSOR})
+add_subdirectory (thirdparty/md5)
+set (MD5_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/md5)
+set (MD5_LIBRARIES md5_bundled)
+
+# 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)
+ set (QJSON_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty)
+ set (QJSON_LIBRARY_DIRS)
+ set (QJSON_LIBRARIES qjson_bundled)
+ set (QJSON_FOUND TRUE)
endif ()
-# Expose the binary/install directories to source
-#
-# TODO: Use the same directory layout, for both build and install directories,
-# so that binaries can find each other using just relative paths.
-#
-add_definitions(
- -DAPITRACE_BINARY_DIR="${CMAKE_BINARY_DIR}"
- -DAPITRACE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}"
- -DAPITRACE_WRAPPER_INSTALL_DIR="${CMAKE_INSTALL_PREFIX}/${WRAPPER_INSTALL_DIR}"
-)
+# We use bundled headers for all Khronos APIs, to guarantee support for both
+# OpenGL and OpenGL ES at build time, because the OpenGL and OpenGL ES 1 APIs
+# are so intertwined that conditional compilation extremely difficult. This
+# also avoids missing/inconsistent declarations in system headers.
+include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/khronos)
##############################################################################
# Common libraries / utilities
include_directories (
+ ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/common
)
-add_custom_command (
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glproc.py > ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
- DEPENDS glproc.py dispatch.py specs/wglapi.py specs/glxapi.py specs/cglapi.py specs/glapi.py specs/gltypes.py specs/stdapi.py
-)
-
if (WIN32)
set (os os_win32.cpp)
- set (glws_os glws_wgl.cpp)
else ()
set (os os_posix.cpp)
- if (APPLE)
- set (glws_os glws_cocoa.mm)
- else ()
- set (glws_os glws_glx.cpp)
- endif ()
endif ()
add_library (common STATIC
+ common/trace_callset.cpp
+ common/trace_dump.cpp
+ common/trace_fast_callset.cpp
common/trace_file.cpp
+ common/trace_file_read.cpp
+ common/trace_file_write.cpp
common/trace_file_zlib.cpp
common/trace_file_snappy.cpp
common/trace_model.cpp
common/trace_parser.cpp
+ common/trace_parser_flags.cpp
common/trace_writer.cpp
common/trace_writer_local.cpp
common/trace_writer_model.cpp
common/trace_loader.cpp
- common/image.cpp
- common/image_bmp.cpp
- common/image_pnm.cpp
- common/image_png.cpp
+ common/trace_profiler.cpp
+ common/trace_option.cpp
common/${os}
+ common/os_backtrace.cpp
+ common/highlight.cpp
)
set_target_properties (common PROPERTIES
@@ -259,227 +362,58 @@ set_target_properties (common PROPERTIES
COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}"
)
-link_libraries (common)
-
-
-##############################################################################
-# API tracers
-
-if (WIN32)
- if (MINGW)
- # Silence warnings about @nn suffix mismatch
- set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--enable-stdcall-fixup")
- endif (MINGW)
-
- # ddraw.dll
- if (DirectX_D3D_INCLUDE_DIR)
- include_directories (SYSTEM ${DirectX_D3D_INCLUDE_DIR})
- add_custom_command (
- OUTPUT ddrawtrace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/ddrawtrace.py > ${CMAKE_CURRENT_BINARY_DIR}/ddrawtrace.cpp
- DEPENDS ddrawtrace.py trace.py specs/d3d.py specs/d3dtypes.py specs/d3dcaps.py specs/ddraw.py specs/winapi.py specs/stdapi.py
- )
- add_library (ddraw MODULE specs/ddraw.def ddrawtrace.cpp)
- set_target_properties (ddraw
- PROPERTIES PREFIX ""
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS ddraw LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
- endif (DirectX_D3D_INCLUDE_DIR)
-
- # d3d8.dll
- if (DirectX_D3D8_INCLUDE_DIR AND DirectX_D3DX9_INCLUDE_DIR)
- include_directories (SYSTEM ${DirectX_D3D8_INCLUDE_DIR} ${DirectX_D3DX9_INCLUDE_DIR})
- add_custom_command (
- OUTPUT d3d8trace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d8trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d8trace.cpp
- DEPENDS d3d8trace.py trace.py specs/d3d8.py specs/d3d8types.py specs/d3d8caps.py specs/winapi.py specs/stdapi.py
- )
- add_library (d3d8 MODULE specs/d3d8.def d3d8trace.cpp d3dshader.cpp)
- set_target_properties (d3d8
- PROPERTIES PREFIX ""
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS d3d8 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
- endif (DirectX_D3D8_INCLUDE_DIR AND DirectX_D3DX9_INCLUDE_DIR)
-
- # d3d9.dll
- if (DirectX_D3DX9_INCLUDE_DIR)
- include_directories (SYSTEM ${DirectX_D3DX9_INCLUDE_DIR})
- add_custom_command (
- OUTPUT d3d9trace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d9trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d9trace.cpp
- DEPENDS d3d9trace.py trace.py specs/d3d9.py specs/d3d9types.py specs/d3d9caps.py specs/winapi.py specs/stdapi.py
- )
- add_library (d3d9 MODULE specs/d3d9.def d3d9trace.cpp d3dshader.cpp)
- set_target_properties (d3d9
- PROPERTIES PREFIX ""
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS d3d9 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
- endif (DirectX_D3DX9_INCLUDE_DIR)
-
- # d3d10.dll
- if (DirectX_D3D10_INCLUDE_DIR)
- include_directories (SYSTEM ${DirectX_D3D10_INCLUDE_DIR})
- add_custom_command (
- OUTPUT d3d10trace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/d3d10trace.py > ${CMAKE_CURRENT_BINARY_DIR}/d3d10trace.cpp
- DEPENDS d3d10trace.py trace.py specs/d3d10misc.py specs/d3d10.py specs/dxgi.py specs/dxgitype.py specs/dxgiformat.py specs/winapi.py specs/stdapi.py
- )
- add_library (d3d10 MODULE specs/d3d10.def d3d10trace.cpp)
- set_target_properties (d3d10
- PROPERTIES PREFIX ""
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS d3d10 LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
- endif (DirectX_D3D10_INCLUDE_DIR)
-
- # opengl32.dll
- add_custom_command (
- OUTPUT wgltrace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/wgltrace.py > ${CMAKE_CURRENT_BINARY_DIR}/wgltrace.cpp
- DEPENDS wgltrace.py gltrace.py trace.py specs/wglapi.py specs/wglenum.py specs/glapi.py specs/glparams.py specs/gltypes.py specs/winapi.py specs/stdapi.py
- )
- add_library (wgltrace MODULE specs/opengl32.def
- wgltrace.cpp
- glcaps.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
- )
- set_target_properties (wgltrace PROPERTIES
- PREFIX ""
- OUTPUT_NAME opengl32
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
- install (TARGETS wgltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
-
-elseif (APPLE)
- # OpenGL framework
- add_custom_command (
- OUTPUT cgltrace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/cgltrace.py > ${CMAKE_CURRENT_BINARY_DIR}/cgltrace.cpp
- DEPENDS cgltrace.py gltrace.py trace.py specs/cglapi.py specs/glapi.py specs/glparams.py specs/gltypes.py specs/stdapi.py
- )
-
- add_library (cgltrace SHARED
- cgltrace.cpp
- glcaps.cpp
- ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
- )
-
- set_target_properties (cgltrace PROPERTIES
- # OpenGL framework name
- PREFIX "" OUTPUT_NAME "OpenGL" SUFFIX ""
- # Specificy the version and reexport GLU symbols
- LINK_FLAGS "-compatibility_version 1 -current_version 1.0.0 -Wl,-reexport_library,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGLU.dylib"
- RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/wrappers
- )
-
- target_link_libraries (cgltrace dl)
-
- install (TARGETS cgltrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
-else ()
- # libGL.so
- add_custom_command (
- OUTPUT glxtrace.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glxtrace.py > ${CMAKE_CURRENT_BINARY_DIR}/glxtrace.cpp
- DEPENDS glxtrace.py gltrace.py trace.py specs/glxapi.py specs/glapi.py specs/glparams.py specs/gltypes.py specs/stdapi.py
- )
-
- add_library (glxtrace SHARED
- ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
- glxtrace.cpp
- glcaps.cpp
- glsnapshot.cpp
- )
-
- set_target_properties (glxtrace PROPERTIES
- # avoid the default "lib" prefix
- PREFIX ""
- )
-
- # Prevent symbol relocations internal to our wrapper library to be
- # overwritten by the application.
- set_target_properties (glxtrace PROPERTIES
- LINK_FLAGS "-Wl,-Bsymbolic -Wl,-Bsymbolic-functions"
+target_link_libraries (common
+ ${LIBBACKTRACE_LIBRARIES}
+)
+if (ANDROID)
+ target_link_libraries (common
+ log
)
-
- target_link_libraries (glxtrace dl ${X11_X11_LIB})
-
- install (TARGETS glxtrace LIBRARY DESTINATION ${WRAPPER_INSTALL_DIR})
endif ()
##############################################################################
-# API retracers
+# Sub-directories
-add_custom_command (
- OUTPUT glretrace_gl.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glretrace.py > ${CMAKE_CURRENT_BINARY_DIR}/glretrace_gl.cpp
- DEPENDS glretrace.py retrace.py specs/glapi.py specs/gltypes.py specs/stdapi.py
-)
+add_subdirectory (dispatch)
+add_subdirectory (helpers)
+add_subdirectory (wrappers)
+add_subdirectory (image)
+add_subdirectory (retrace)
-add_custom_command (
- OUTPUT glstate_params.cpp
- COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/glstate.py > ${CMAKE_CURRENT_BINARY_DIR}/glstate_params.cpp
- DEPENDS glstate.py specs/glparams.py specs/gltypes.py specs/stdapi.py
-)
-include_directories (
- ${CMAKE_CURRENT_BINARY_DIR}
- ${OPENGL_INCLUDE_PATH}
-)
+##############################################################################
+# CLI
-add_executable (glretrace
- glretrace_gl.cpp
- glretrace_cgl.cpp
- glretrace_glx.cpp
- glretrace_wgl.cpp
- glretrace_main.cpp
- glstate.cpp
- glstate_params.cpp
- retrace.cpp
- retrace_stdc.cpp
- glws.cpp
- ${glws_os}
- ${CMAKE_CURRENT_BINARY_DIR}/glproc.hpp
-)
+if (ENABLE_CLI)
+ if (WIN32)
+ add_subdirectory (inject)
+ endif ()
+ add_subdirectory (cli)
+endif ()
-set_property (
- TARGET glretrace
- APPEND
- PROPERTY COMPILE_DEFINITIONS "RETRACE"
-)
+##############################################################################
+# Scripts (to support the CLI)
-target_link_libraries (glretrace
- common
+install (
+ PROGRAMS
+ scripts/highlight.py
+ scripts/jsondiff.py
+ scripts/profileshader.py
+ scripts/retracediff.py
+ scripts/snapdiff.py
+ scripts/tracecheck.py
+ scripts/tracediff.py
+ scripts/unpickle.py
+ DESTINATION ${SCRIPTS_INSTALL_DIR}
)
-
if (WIN32)
- target_link_libraries (glretrace ${OPENGL_gl_LIBRARY})
-elseif (APPLE)
- target_link_libraries (glretrace
- "-framework Cocoa"
- "-framework ApplicationServices" # CGS*
- ${OPENGL_gl_LIBRARY} # CGL*
+ install (
+ PROGRAMS scripts/convert.py
+ DESTINATION ${SCRIPTS_INSTALL_DIR}
)
-else ()
- target_link_libraries (glretrace ${OPENGL_gl_LIBRARY} ${X11_X11_LIB})
endif ()
-install (TARGETS glretrace RUNTIME DESTINATION bin)
-
-##############################################################################
-# CLI
-
-add_subdirectory(cli)
-
##############################################################################
# GUI
@@ -494,14 +428,24 @@ endif ()
install (
FILES
BUGS.markdown
- LICENSE
NEWS.markdown
README.markdown
- TODO.markdown
DESTINATION ${DOC_INSTALL_DIR}
)
+install (
+ FILES LICENSE
+ DESTINATION ${DOC_INSTALL_DIR}
+ RENAME LICENSE.txt
+)
+if (MSVC)
+ install (
+ FILES thirdparty/msinttypes/LICENSE
+ DESTINATION ${DOC_INSTALL_DIR}
+ RENAME LICENSE-msinttypes.txt
+ )
+endif ()
-set (CPACK_PACKAGE_VERSION_MAJOR "2")
+set (CPACK_PACKAGE_VERSION_MAJOR "5")
set (CPACK_PACKAGE_VERSION_MINOR "0")
# Use current date in YYYYMMDD format as patch number
@@ -510,6 +454,13 @@ execute_process (
OUTPUT_VARIABLE CPACK_PACKAGE_VERSION_PATCH
)
+# cpack mistakenly detects Mingw-w64 as win32
+if (MINGW)
+ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set (CPACK_SYSTEM_NAME win64)
+ endif ()
+endif ()
+
# See http://www.vtk.org/Wiki/CMake:CPackPackageGenerators
if (WIN32)
set (CPACK_GENERATOR "ZIP")
View
109 DEVELOPMENT.markdown
@@ -1,8 +1,82 @@
+Overview
+=========
+
+Although focus was and still is on graphical APIs, apitrace has a
+generic infrastructure to trace any kind of API:
+
+ * the APIs types and calls are specified in Python files in specs
+ sub-directory;
+
+ * there is a type hierarchy in specs/stdapi.py, capable of representing
+ most types in C language, and additional semantic metadata
+
+ * Python scripts generate C++ code to trace and serialize calls parameters to
+ a file, and vice-versa.
+
+ * Visitor software design pattern is used to navigate over the types.
+
+ * Template design pattern is use so that any step of code generation can be
+ overriden by derived classes, allowing to easily handle cases that need
+ special treatment without sacrifycing code reuse.
+
+apitrace's architecture is composed of several layers. Too many to show in a
+single graph, so only those relevant for OpenGL API are shown below:
+
+ specs
+ ^
+ |
+ dispatch <-------------- glws
+ ^ ^
+ | /
+ helpers <--- glstate /
+ ^ ^ ^ /
+ / \ | /
+ / \ | /
+ trace retrace | /
+ ^ ^ | /
+ / \ | /
+ gltrace glretrace
+ / | \
+ / | \
+ / | \
+ / | \
+ / | \
+ glxtrace wgltrace cgltrace
+
+Here is a quick synopsis of what the layers do:
+
+ * specs -- specification of the API, expressed in a Python class hierarchy
+
+ * dispatch -- runtime dispatch of calls to DLLs (open the DLL, get the symbol
+ address, and call it passing all arguments as-is)
+
+ * helpers -- helper functions to determine sizes of arrays, blobs, etc. It
+ often needs to dispatch calls to give the answers.
+
+ * trace -- generate C++ code for tracing an API based on its spec
+
+ * gltrace -- specialization of the tracing generation for GL API, with extra
+ code to generate
+
+ * glxtrace, wgltrace, cgltrace -- specialization of the tracing code for the
+ GLX, WGL, and CGL APIs.
+
+ * retrace -- generate C++ code to interpret calls from trace, based on the
+ API's spec
+
+ * glretrace -- specialization of the retrace code for the GL API
+
+ * glstate -- code to dump OpenGL state to a JSON file
+
+ * glws -- abstraction of the window system specific APIs (GXL, WGL, CGL), to
+ enable cross-platform portability of glretrace
+
+
Coding Style
============
-XXX: These are guidelines for new code. Some of existing hasn't been updated
-to these conventions yet.
+These are guidelines for new code. Admittedly some of the existing code hasn't
+been updated to follow these conventions yet.
Whitespace (all languages):
@@ -24,6 +98,9 @@ Naming convention:
* `UPPER_CASE` for #defines
+ * single underscore prefix for variables/functions in automatically generated
+ code
+
C++:
* enclose single statement `if` clauses in { }, specially for automatically
@@ -35,7 +112,7 @@ C++:
CMake:
- * `lower_case`
+ * `lower_case` commands
* space between ( and precedent name
@@ -49,12 +126,24 @@ Commit policy
Feature development:
* Existing features in master branch should not degrade at any time, for any
- platform. (Unless it is not widely used and there is agreement.)
+ platform. (Unless they are seldom used or redundant and there is agreement.)
+
+ * In particular, new features / changes must not introduce any sort of
+ instability when tracing.
-* It's fine to add new features for only some platforms.
+ While application developers and driver developers may be able to
+ workaround quirks in apitrace, we want to be able to obtain traces from
+ non-technical end-users with minimal intervention.
-* Non-trivial changes should be staged in a branch, to enable peer-review and
- regression testing. Branch should be deleted once code has been merged.
+ This implies that tracing should not make any non-standard assumptions, and
+ care must be taken to ensure the tracing code is robust against invalid
+ parameters, multiple threads, etc.
+
+* It's fine to add new features for only some platforms or APIs.
+
+* Non-trivial changes should be staged in a branch, to allow review and
+ regression testing. Feature branches should be deleted once they have been
+ merged.
* Releases are tagged commits from master. There are no stable branches.
@@ -67,7 +156,7 @@ Backwards compatibility:
* No backwards compatibility guarantees for derived data (ASCII dumps, state,
images, etc).
-* There should be no gratuitous change to command line tool interfaces, but no
+* There should be no gratuitous changes to command line tool interfaces, but no
guarantees are given.
@@ -75,4 +164,6 @@ Backwards compatibility:
Regression testing
==================
-Not standardized yet. Work in progress.
+There is a regression test suite under development in
+https://github.com/apitrace/apitrace-tests .
+
View
55 Dalvik.markdown
@@ -0,0 +1,55 @@
+Tracing Dalvik VM (Java) applications on Android
+================================================
+
+Android's Java virtual machine, Dalvik, runs as a system service (started at
+bootup by `init`) and Java applications are run by forks of the initial
+resident process. Thus, injecting apitrace's tracing library is different from
+other operating systems.
+
+The following discussion assumes that tracing library is copied to '/data':
+
+ adb push /path/to/apitrace/build/wrappers/egltrace.so /data
+
+
+Tracing on Android 4.0 and newer
+--------------------------------
+
+Starting from Android 4.0 (Ice Cream Sandwich) release, Dalvik supports
+running designated processes with wrappers, in which case a new Java VM is
+started with 'system()' library call for that process.
+
+Obtain the process name of the application to be traced (the one reported in
+`ps` output, such as `com.android.settings`), and set two system properties:
+
+ PROCNAME=com.android.settings
+ adb root
+ adb shell setprop wrap.$PROCNAME LD_PRELOAD=/data/egltrace.so
+ adb shell setprop debug.apitrace.procname $PROCNAME
+
+(the former is read by Dalvik and specifies wrapping prefix, the latter is
+read by apitrace itself and used in case apitrace is preloaded into Java VM
+globally to specify which process should be traced). Elevating priviliges
+via `adb root` is required to set the first property.
+
+Make sure the process is not loaded before starting to trace it, for example
+use `-S` flag to `am start`:
+
+ adb shell am start -S $PROCNAME
+
+Use `adb logcat \*:S apitrace` to examine apitrace debug output. Trace files
+are saved into '/data/data/$PROCNAME' directory by default:
+
+ adb pull /data/data/$PROCNAME/$PROCNAME.trace
+ adb shell rm /data/data/$PROCNAME/$PROCNAME.trace
+
+
+Tracing on Android pre-4.0
+--------------------------
+
+`LD_PRELOAD` is supported since Android 2.3 "Gingerbread" and newer, but
+injecting tracing library globally is no longer supported, as the
+`debug.apitrace.procname` system propery is no longer honored.
+
+Consider checking out an
+[older commit](https://github.com/apitrace/apitrace/commit/888112983ef9564b3a9d15699faa17c337d3942b)
+if you need to trace on Android pre-4.0.
View
125 FORMAT.markdown
@@ -0,0 +1,125 @@
+# Trace binary format specification #
+
+This document specifies the binary format of trace streams.
+
+Trace streams are not written verbatim to file, but compressed, nowadays with
+snappy (see `common/trace_file_snappy.cpp` for details). Previously they used
+to be compressed with gzip.
+
+
+## Versions ##
+
+We keep backwards compatability reading old traces, i.e., it should always be
+possible to parse and retrace old trace files.
+
+The trace version number refers not only to changes in the binary format
+representation, but also semantic changes in the way certain functions should
+be retraced.
+
+| `version_no` | Changes |
+| ------------ | ------- |
+| 0 | initial implementation |
+| 1 | support for OpenGL user arrays as blobs (whereas before calls that operated with user memory instead of VBOs should be ignored) |
+| 2 | malloc/free memory calls |
+| 3 | enums signatures with the whole set of name/value pairs |
+| 4 | call enter events include thread no |
+| 5 | support for call backtraces |
+
+Writing/editing old traces is not supported however. An older version of
+apitrace should be used in such circunstances.
+
+
+## Basic types ##
+
+| Type | Description |
+| ---- | ----------- |
+| `byte` | Raw byte. |
+| `uint` | Variable-length unsigned integer, where the most significative bit is zero for last byte or non-zero if more bytes follow; the 7 least significant bits of each byte are used for the integer's bits, in little-endian order. |
+| `float` | 32 bits single precision floating point number |
+| `double` | 64 bits single precision floating point number |
+
+Strings are length-prefixed. The trailing zero is implied, not appearing neither in the length prefix nor in the raw bytes.
+
+ string = count byte*
+
+ count = uint
+
+
+## Grammar ##
+
+The trace consists of a small header with version information, followed by an
+arbitrary number of events.
+
+ trace = version_no event*
+
+ version_no = uint
+
+### Calls ###
+
+Calls consist of an enter and leave event pair. Calls are numbered from zero,
+and the call number is implied for the enter event.
+
+ event = 0x00 thread_no call_sig call_detail+ // enter call (version_no >= 4)
+ | 0x00 call_sig call_detail+ // enter call (version_no < 4)
+ | 0x01 call_no call_detail+ // leave call
+
+ call_sig = id function_name count arg_name* // first occurrence
+ | id // follow-on occurrences
+
+ call_detail = 0x00 // terminator
+ | 0x01 arg_no value // argument value
+ | 0x02 value // return value
+ | 0x03 thread_no // thread number (version_no < 4)
+ | 0x04 count frame* // stack backtrace
+
+ arg_name = string
+ function_name = string
+
+ arg_no = uint
+ call_no = uint
+ thread_no = uint
+
+ id = uint
+
+### Values ###
+
+ value = 0x00 // null pointer
+ | 0x01 // false value
+ | 0x02 // true
+ | 0x03 uint // negative integer
+ | 0x04 uint // positive integer value
+ | 0x05 float // single-precision floating point value
+ | 0x06 double // double-precision floating point value
+ | 0x07 string // character string value (zero terminator implied)
+ | 0x08 string // binary blob
+ | 0x09 enum_sig value // enumeration (version_no >= 3)
+ | 0x09 string value // enumeration (version_no < 3)
+ | 0x0a bitmask_sig value // integer bitmask
+ | 0x0b count value* // array
+ | 0x0c struct_sig value* // structure
+ | 0x0d uint // opaque pointer
+ | 0x0e value value // human-machine representation
+
+ enum_sig = id count (name value)+ // first occurrence
+ | id // follow-on occurrences
+
+ bitmask_sig = id count (name value)+ // first occurrence
+ | id // follow-on occurrences
+
+ struct_sig = id count member_name* // first occurrence
+ | id // follow-on occurrences
+
+ name = string
+ member_name = string
+
+### Backtraces ###
+
+ frame = id frame_detail+ // first occurrence
+ | id // follow-on occurrences
+
+ frame_detail = 0x00 // terminator
+ | 0x01 string // module name
+ | 0x02 string // function name
+ | 0x03 string // source file name
+ | 0x04 uint // source line number
+ | 0x05 uint // byte offset from module start
View
97 INSTALL.markdown
@@ -7,19 +7,21 @@ Requirements
Requirements common for all platforms:
-* Python version 2.6 or 2.7
+* Python version 2.7
+
+ * Python Image Library
* CMake version 2.8 or higher (tested with version 2.8)
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.
@@ -33,37 +35,88 @@ tracing.
Linux / Mac OS X
----------------
+Additional optional dependencies for Linux:
+
+* libprocps (procps development libraries)
+
+* libdwarf
+
Build as:
- cmake -H. -Bbuild
+ cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=RelWithDebInfo
make -C build
-You can also build the 32bit GL wrapper on 64bit distro with a multilib gcc by
-doing:
+Other possible values for `CMAKE_BUILD_TYPE` `Debug`, `Release`,
+`RelWithDebInfo`, and `MinSizeRel`.
+
+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 -H. -Bbuild32 -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 -DENABLE_GUI=FALSE
+ 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
+-------
+
+Additional requirements:
+
+* [Android NDK](http://developer.android.com/sdk/ndk/index.html)
+
+Build as:
+
+ export ANDROID_NDK=/path/to/your/ndk
+ cmake -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/android.toolchain.cmake -DANDROID_API_LEVEL=9 -H. -Bbuild
+ make -C build
+
+You can also choose a particular ABI by passing `ANDROID_ABI` variable to
+cmake, e.g., `-DANDROID_ABI=x86`.
+
+FirefoxOS
+---------
+
+Put Apitrace source tree into `B2GROOT/external/apitrace/` and the `Android.mk`
+file (`B2GROOT/external/apitrace/Android.mk`) will do the needful to compile
+and install apitrace appropriately into the system image as part of FirefoxOS
+build process. It expects a linaro-type of Android NDK to be present in
+`../../prebuilt/ndk/android-ndk-r7` (ie `B2GROOT/prebuilt/ndk/android-ndk-r7`).
+
Windows
-------
Additional requirements:
-* Microsoft Visual Studio (tested with 2008 version) or MinGW (tested with gcc version 4.4)
+* For Direct3D 11.1 support:
+
+ * [Microsoft Visual Studio 11 Ultimate Beta](http://www.microsoft.com/download/en/details.aspx?id=27543)
+
+* Other:
-* Microsoft DirectX SDK:
+ * Microsoft Visual Studio (tested with 2010 version) or MinGW (tested with
+ mingw-w64's gcc version 4.6.2)
- * for D3D10 support the [latest](http://msdn.microsoft.com/en-us/directx/default.aspx) is
- recommended.
+ * [Microsoft DirectX SDK](http://msdn.microsoft.com/en-us/directx/aa937781):
- * for DDRAW, D3D7, D3D8 support the [August 2007 release](http://www.microsoft.com/downloads/details.aspx?familyid=529F03BE-1339-48C4-BD5A-8506E5ACF571)
- or earlier is required, as later releases do not include the necessary
- headers.
+ * for D3D 10, 10.1, and 11 support the [June 2010 release](http://www.microsoft.com/en-us/download/details.aspx?id=6812) is
+ recommended.
+
+ * for D3D7, D3D8 support the [August 2007 release](http://www.microsoft.com/downloads/details.aspx?familyid=529F03BE-1339-48C4-BD5A-8506E5ACF571)
+ or earlier is required, as later releases do not include the necessary
+ headers.
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.
@@ -71,15 +124,19 @@ It will try to detect most required/optional dependencies automatically. When
not found automatically, you can manually specify the location of the
dependencies from the CMake GUI.
+Qt on Windows doesn't ship with 64-bit binaries, you may want to add
+`-DENABLE_GUI=FALSE` to the above cmake command line for Windows 64-bits
+builds.
+
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 9
-2008 Win64_ instead of _Visual Studio 9 2008_.
+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).
View
9 LICENSE
@@ -1,5 +1,9 @@
-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
@@ -20,4 +24,3 @@ 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.
-
View
42 NEWS.markdown
@@ -1,7 +1,45 @@
-This file lists the major user visible improvments. For a full list of changes
+This file lists the major user visible improvements. For a full list of changes
and their authors see the git history.
+Version 4.0
+===========
+
+* Support tracing in Android, both native and Dalvik applications.
+
+* Show frame thumbnails in the GUI.
+
+* Basic D3D 10.1, 11, and 11.1 trace support.
+
+* Multi-threaded trace/retrace support.
+
+* Several OpenGL ES state dump fixes.
+
+* GPU profiling.
+
+* Thumbnails in GUI
+
+* Trim improvements.
+
+* Loads of bugfixes
+
+
+Version 3.0
+===========
+
+* Top-level `apitrace` command.
+
+* Trace and replay support for EGL, GLES1, and GLES2 APIs on Linux.
+
+* Ability to trim traces.
+
+* Basic CPU profiling when retracing.
+
+* Basic D3D10 trace support.
+
+* Many bugfixes.
+
+
Version 2.0
===========
@@ -31,4 +69,4 @@ Version 1.0
Pre-history
===========
-* OpenGL retrace support.
+* OpenGL replay support.
View
472 README.markdown
@@ -3,166 +3,384 @@ About **apitrace**
**apitrace** consists of a set of tools to:
-* trace OpenGL, D3D9, D3D8, D3D7, and DDRAW APIs calls to a file;
+* trace OpenGL, OpenGL ES, Direct3D, and DirectDraw APIs calls to a file;
-* retrace OpenGL calls from a file;
+* replay OpenGL and OpenGL ES calls from a file;
* inspect OpenGL state at any call while retracing;
* visualize and edit trace files.
+See the [apitrace homepage](http://apitrace.github.io/) for more details.
-Basic usage
-===========
+Obtaining **apitrace**
+======================
-Linux
------
+To obtain apitrace either [download the latest
+binaries](http://apitrace.github.io/#download) for your platform if
+available, or follow the instructions in INSTALL.markdown to build it yourself.
+On 64bits Linux and Windows platforms you'll need apitrace binaries that match
+the architecture (32bits or 64bits) of the application being traced.
+
+
+Basic usage
+===========
Run the application you want to trace as
- LD_PRELOAD=/path/to/glxtrace.so /path/to/application
+ apitrace trace --api API /path/to/application [args...]
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.
+directory. You can specify the written trace filename by passing the
+`--output` command line option.
+
+Problems while tracing (e.g, if the application uses calls/parameters
+unsupported by apitrace) will be reported via stderr output on Unices. On
+Windows you'll need to run
+[DebugView](http://technet.microsoft.com/en-us/sysinternals/bb896647) to view
+these messages.
+
+Follow the "Tracing manually" instructions below if you cannot obtain a trace.
View the trace with
- /path/to/apitrace dump --color application.trace | less -R
+ apitrace dump application.trace
+
+Replay an OpenGL trace with
-Replay the trace with
+ apitrace replay application.trace
- /path/to/glretrace application.trace
+Pass the `--sb` option to use a single buffered visual. Pass `--help` to
+`apitrace replay` for more options.
-Pass the `-sb` option to use a single buffered visual. Pass `--help` to
-glretrace for more options.
+
+Basic GUI usage
+===============
Start the GUI as
- /path/to/qapitrace application.trace
+ qapitrace application.trace
+
+You can also tell the GUI to go directly to a specific call
+
+ qapitrace application.trace 12345
+
+
+Backtrace Capturing
+===================
+
+apitrace now has the ability to capture the call stack to an OpenGL call.
+This can be helpful in determing which piece of code made that glDrawArrays call.
+
+*NOTE* this feature is currently only available on Android and Linux at the moment.
+
+On linux you need to have libunwind, and libdwarf installed to compile in the feature.
+
+To use the feature you need to set an environment variable with the list of GL
+call prefixes you wish to capture stack traces to.
+
+ export APITRACE_BACKTRACE="glDraw* glUniform*"
+
+The backtrace data will show up in qapitrace in the bottom section as a new tab.
+
+
+Advanced command line usage
+===========================
+
+
+Call sets
+---------
+Several tools take `CALLSET` arguments, e.g:
-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`:
+ apitrace dump --calls=CALLSET foo.trace
+ apitrace dump-images --calls=CALLSET foo.trace
+ apitrace trim --calls=CALLSET1 --calls=CALLSET2 foo.trace
- ln -s glxtrace.so libGL.so
- ln -s glxtrace.so libGL.so.1
- ln -s glxtrace.so libGL.so.1.2
- export LD_LIBRARY_PATH=/path/to/directory/where/glxtrace/is:$LD_LIBRARY_PATH
+The call syntax is very flexible. Here are a few examples:
+
+ * `4` one call
+
+ * `0,2,4,5` set of calls
+
+ * `"0 2 4 5"` set of calls (commas are optional and can be replaced with whitespace)
+
+ * `0-100/2` calls 1, 3, 5, ..., 99
+
+ * `0-1000/draw` all draw calls between 0 and 1000
+
+ * `0-1000/fbo` all fbo changes between calls 0 and 1000
+
+ * `frame` all calls at end of frames
+
+ * `@foo.txt` read call numbers from `foo.txt`, using the same syntax as above
+
+
+
+Tracing manually
+----------------
+
+### Linux ###
+
+On 64 bits systems, you'll need to determine whether the application is 64 bits
+or 32 bits. This can be done by doing
+
+ file /path/to/application
+
+But beware of wrapper shell scripts -- what matters is the architecture of the
+main process.
+
+Run the GLX application you want to trace as
+
+ 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.
+
+For EGL applications you will need to use `egltrace.so` instead of
+`glxtrace.so`.
+
+The `LD_PRELOAD` mechanism should work with the majority of applications. There
+are some applications (e.g., Unigine Heaven, Android GPU emulator, etc.), that
+have global function pointers with the same name as OpenGL entrypoints, living in a
+shared object that wasn't linked with `-Bsymbolic` flag, so relocations to
+those global 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
+ ln -s glxtrace.so wrappers/libGL.so.1.2
+ export LD_LIBRARY_PATH=/path/to/apitrace/wrappers:$LD_LIBRARY_PATH
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.
+### Android ###
+To trace standalone native OpenGL ES applications, use
+`LD_PRELOAD=/path/to/egltrace.so /path/to/application` as described in the
+previous section. To trace Java applications, refer to Dalvik.markdown.
-Mac OS X
---------
+### Mac OS X ###
-Usage on Mac OS X is similar to Linux above, except for the tracing procedure,
-which is instead:
+Run the application you want to trace as
- DYLD_LIBRARY_PATH=/path/to/apitrace/wrappers /path/to/application
+ DYLD_FRAMEWORK_PATH=/path/to/apitrace/wrappers /path/to/application
Note that although Mac OS X has an `LD_PRELOAD` equivalent,
`DYLD_INSERT_LIBRARIES`, it is mostly useless because it only works with
`DYLD_FORCE_FLAT_NAMESPACE=1` which breaks most applications. See the `dyld` man
page for more details about these environment flags.
+### Windows ###
-Windows
--------
+When tracing third-party applications, you can identify the target
+application's main executable, either by:
-* Copy `opengl32.dll`, `d3d8.dll`, or `d3d9.dll` from build/wrappers directory
- to the directory with the application you want to trace.
+* right clicking on the application's icon in the _Start Menu_, choose
+ _Properties_, and see the _Target_ field;
-* Run the application.
+* or by starting the application, run Windows Task Manager (taskmgr.exe), right
+ click on the application name in the _Applications_ tab, choose _Go To Process_,
+ note the highlighted _Image Name_, and search it on `C:\Program Files` or
+ `C:\Program Files (x86)`.
-* View the trace with
+On 64 bits Windows, you'll need to determine ether the application is a 64 bits
+or 32 bits. 32 bits applications will have a `*32` suffix in the _Image Name_
+column of the _Processes_ tab of _Windows Task Manager_ window.
- \path\to\apitrace dump application.trace
+You also need to know which graphics API is being used. If you are unsure, the
+simplest way to determine what API an application uses is to:
-* Replay the trace with
+* download and run [Process Explorer](http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx)
- \path\to\glretrace application.trace
+* search and select the application's process in _Process Explorer_
+* list the DLLs by pressing `Ctrl + D`
-Advanced command line usage
-===========================
+* sort DLLs alphabetically, and look for the DLLs such as `opengl32.dll`,
+ `d3d9.dll`, `d3d10.dll`, etc.
+
+Copy the appropriate `opengl32.dll`, `d3d8.dll`, or `d3d9.dll` from the
+wrappers directory to the directory with the application you want to trace.
+Then run the application as usual.
+You can specify the written trace filename by setting the `TRACE_FILE`
+environment variable before running.
-Emitting annotations to the trace from GL applications
-------------------------------------------------------
+For D3D10 and higher you really must use `apitrace trace -a DXGI ...`. This is
+because D3D10-11 API span many DLLs which depend on each other, and once a DLL
+with a given name is loaded Windows will reuse it for LoadLibrary calls of the
+same name, causing internal calls to be traced erroneously. `apitrace trace`
+solves this issue by injecting a DLL `dxgitrace.dll` and patching all modules
+to hook only the APIs of interest.
-You can emit string and frame annotations through the
-[`GL_GREMEDY_string_marker`](http://www.opengl.org/registry/specs/GREMEDY/string_marker.txt)
-and
-[`GL_GREMEDY_frame_terminator`](http://www.opengl.org/registry/specs/GREMEDY/frame_terminator.txt)
-GL extensions.
-**apitrace** will advertise and intercept these GL extensions independently of
-the GL implementation. So all you have to do is to use these extensions when
-available.
+Emitting annotations to the trace
+---------------------------------
+
+From within OpenGL applications you can embed annotations in the trace file
+through the following extensions:
+
+* [`GL_KHR_debug`](http://www.opengl.org/registry/specs/KHR/debug.txt)
+
+* [`GL_ARB_debug_output`](http://www.opengl.org/registry/specs/ARB/debug_output.txt)
+
+* [`GL_EXT_debug_marker`](http://www.khronos.org/registry/gles/extensions/EXT/EXT_debug_marker.txt)
+
+* [`GL_EXT_debug_label`](http://www.opengl.org/registry/specs/EXT/EXT_debug_label.txt)
+
+* [`GL_AMD_debug_output`](http://www.opengl.org/registry/specs/AMD/debug_output.txt)
+
+* [`GL_GREMEDY_string_marker`](http://www.opengl.org/registry/specs/GREMEDY/string_marker.txt)
+
+* [`GL_GREMEDY_frame_terminator`](http://www.opengl.org/registry/specs/GREMEDY/frame_terminator.txt)
+
+**apitrace** will advertise and intercept these OpenGL extensions regardless
+of whether the OpenGL implementation supports them or not. So all you have
+to do is to use these extensions when available, and you can be sure they
+will be available when tracing inside **apitrace**.
For example, if you use [GLEW](http://glew.sourceforge.net/) to dynamically
-detect and use GL extensions, you could easily accomplish this by doing:
+detect and use OpenGL extensions, you could easily accomplish this by doing:
void foo() {
- if (GLEW_GREMEDY_string_marker) {
- glStringMarkerGREMEDY(0, __FUNCTION__ ": enter");
+ if (GLEW_KHR_debug) {
+ glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, __FUNCTION__);
}
...
- if (GLEW_GREMEDY_string_marker) {
- glStringMarkerGREMEDY(0, __FUNCTION__ ": leave");
+ if (GLEW_KHR_debug) {
+ glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER,
+ 0, GL_DEBUG_SEVERITY_MEDIUM, -1, "bla bla");
}
+ ...
+
+ if (GLEW_KHR_debug) {
+ glPopDebugGroup();
+ }
+
}
-This has the added advantage of working equally well with gDEBugger.
+This has the added advantage of working equally well with other OpenGL debugging tools.
+Also, provided that the OpenGL implementation supports `GL_KHR_debug`, labels
+defined via glObjectLabel() , and the labels of several objects (textures,
+framebuffers, samplers, etc. ) will appear in the GUI state dumps, in the
+parameters tab.
-Dump GL state at a particular call
+
+For OpenGL ES applications you can embed annotations in the trace file through the
+[`GL_KHR_debug`](http://www.khronos.org/registry/gles/extensions/KHR/debug.txt) or
+[`GL_EXT_debug_marker`](http://www.khronos.org/registry/gles/extensions/EXT/EXT_debug_marker.txt)
+extensions.
+
+
+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 OpenGL state at a particular call
----------------------------------
-You can get a dump of the bound GL state at call 12345 by doing:
+You can get a dump of the bound OpenGL state at call 12345 by doing:
- /path/to/glretrace -D 12345 application.trace > 12345.json
+ apitrace replay -D 12345 application.trace > 12345.json
-This is precisely the mechanism the GUI obtains its own state.
+This is precisely the mechanism the GUI uses to obtain its own state.
-You can compare two state dumps with the jsondiff.py script:
+You can compare two state dumps by doing:
- ./scripts/jsondiff.py 12345.json 67890.json
+ apitrace diff-state 12345.json 67890.json
Comparing two traces side by side
---------------------------------
- ./scripts/tracediff.sh trace1.trace trace2.trace
+ apitrace diff trace1.trace trace2.trace
This works only on Unices, and it will truncate the traces due to performance
limitations.
-Recording a video with FFmpeg
------------------------------
+Recording a video with FFmpeg/Libav
+-----------------------------------
-You can make a video of the output by doing
+You can make a video of the output with FFmpeg by doing
- /path/to/glretrace -s - application.trace \
+ apitrace dump-images -o - application.trace \
| ffmpeg -r 30 -f image2pipe -vcodec ppm -i pipe: -vcodec mpeg4 -y output.mp4
+or Libav (which replaces FFmpeg on recent Debian/Ubuntu distros) doing
+
+ apitrace dump-images -o - application.trace \
+ | avconv -r 30 -f image2pipe -vcodec ppm -i - -vcodec mpeg4 -y output.mp4
+
+Recording a video with gstreamer
+--------------------------------------
+
+You can make a video of the output with gstreamer by doing
+
+ glretrace --snapshot-format=RGB -s - smokinguns.trace | gst-launch-0.10 fdsrc blocksize=409600 ! queue \
+ ! videoparse format=rgb width=1920 height=1080 ! queue ! ffmpegcolorspace ! queue \
+ ! vaapiupload direct-rendering=0 ! queue ! vaapiencodeh264 ! filesink location=xxx.264
+
+Trimming a trace
+----------------
+
+You can truncate a trace by doing:
+
+ apitrace trim --exact --calls 0-12345 -o trimed.trace application.trace
+
+If you need precise control over which calls to trim you can specify the
+individual call numbers in a plain text file, as described in the 'Call sets'
+section above.
+
+There is also experimental support for automatically trimming the calls
+necessary for a given frame or call:
+
+ apitrace trim --auto --calls=12345 -o trimed.trace application.trace
+ apitrace trim --auto --frames=12345 -o trimed.trace application.trace
+
+
+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 these can then be read by hand or analyzed 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:
+
+ apitrace replay --pgpu --pcpu --ppd foo.trace | ./scripts/profileshader.py
+
Advanced usage for OpenGL implementors
======================================
@@ -177,23 +395,17 @@ These are the steps to create a regression test-suite around **apitrace**:
* obtain a trace
-* obtain reference snapshots, by doing:
+* obtain reference snapshots, by doing on a reference system:
- mkdir /path/to/snapshots/
- /path/to/glretrace -s /path/to/reference/snapshots/ application.trace
-
- on reference system.
+ mkdir /path/to/reference/snapshots/
+ apitrace dump-images -o /path/to/reference/snapshots/ application.trace
* prune the snapshots which are not interesting
-* to do a regression test, do:
-
- /path/to/glretrace -c /path/to/reference/snapshots/ application.trace
+* to do a regression test, use `apitrace diff-images`:
- Alternatively, for a HTML summary, use the snapdiff script:
-
- /path/to/glretrace -s /path/to/current/snapshots/ application.trace
- ./scripts/snapdiff.py --output summary.html /path/to/reference/snapshots/ /path/to/current/snapshots/
+ apitrace dump-images -o /path/to/test/snapshots/ application.trace
+ apitrace diff-images --output summary.html /path/to/reference/snapshots/ /path/to/test/snapshots/
Automated git-bisection
@@ -203,7 +415,7 @@ With tracecheck.py it is possible to automate git bisect and pinpoint the
commit responsible for a regression.
Below is an example of using tracecheck.py to bisect a regression in the
-Mesa-based Intel 965 driver. But the procedure could be applied to any GL
+Mesa-based Intel 965 driver. But the procedure could be applied to any OpenGL
driver hosted on a git repository.
First, create a build script, named build-script.sh, containing:
@@ -218,7 +430,7 @@ First, create a build script, named build-script.sh, containing:
make "$@"
It is important that builds are both robust, and efficient. Due to broken
-dependency discovery in Mesa's makefile system, it was necessary invoke `make
+dependency discovery in Mesa's makefile system, it was necessary to invoke `make
clean` in every iteration step. `ccache` should be installed to avoid
recompiling unchanged source files.
@@ -243,8 +455,8 @@ The trace-check.py script will skip automatically when there are build
failures.
The `--gl-renderer` option will also cause a commit to be skipped if the
-`GL_RENDERER` is unexpected (e.g., when a software renderer or another GL
-driver is unintentionally loaded due to missing symbol in the DRI driver, or
+`GL_RENDERER` is unexpected (e.g., when a software renderer or another OpenGL
+driver is unintentionally loaded due to a missing symbol in the DRI driver, or
another runtime fault).
@@ -255,72 +467,76 @@ In order to determine which draw call a regression first manifests one could
generate snapshots for every draw call, using the `-S` option. That is, however,
very inefficient for big traces with many draw calls.
-A faster approach is to run both the bad and a good GL driver side-by-side.
-The latter can be either a previously known good build of the GL driver, or a
+A faster approach is to run both the bad and a good OpenGL driver side-by-side.
+The latter can be either a previously known good build of the OpenGL driver, or a
reference software renderer.
This can be achieved with retracediff.py script, which invokes glretrace with
-different environments, allowing to choose the desired GL driver by
-manipulating variables such as `LD_LIBRARY_PATH` or `LIBGL_DRIVERS_DIR`.
+different environments, allowing to choose the desired OpenGL driver by
+manipulating variables such as `LD_LIBRARY_PATH`, `LIBGL_DRIVERS_DIR`, or
+`TRACE_LIBGL`.
-For example:
+For example, on Linux:
./scripts/retracediff.py \
- --ref-env LD_LIBRARY_PATH=/path/to/reference/GL/implementation \
- -r ./glretrace \
+ --ref-env LD_LIBRARY_PATH=/path/to/reference/OpenGL/implementation \
+ --retrace /path/to/glretrace \
--diff-prefix=/path/to/output/diffs \
application.trace
+Or on Windows:
+ 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)
+Advanced GUI usage
+==================
-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:
+qapitrace has rudimentary support for replaying traces on a remote
+target device. This can be useful, for example, when developing for an
+embedded system. The primary GUI will run on the local host, while any
+replays will be performed on the target device.
-* [Microsoft PIX](http://msdn.microsoft.com/en-us/library/ee417062.aspx)
+In order to target a remote device, use the command-line:
- * [D3DSpy](http://doc.51windows.net/Directx9_SDK/?url=/directx9_sdk/graphics/programmingguide/TutorialsAndSamplesAndToolsAndTips/Tools/D3DSpy.htm): the predecessor of PIX
+ qapitrace --remote-target <HOST> <trace-file>
-* [AMD GPU PerfStudio](http://developer.amd.com/gpu/PerfStudio/pages/APITraceWindow.aspx)
+In order for this to work, the following must be available in the
+system configuration:
+1. It must be possible for the current user to initiate an ssh session
+ that has access to the target's window system. The command to be
+ exectuted by qapitrace will be:
-OpenGL
-------
+ ssh <HOST> glretrace
-Open-source:
+ For example, if the target device is using the X window system, one
+ can test whether an ssh session has access to the target X server
+ with:
-* [BuGLe](http://www.opengl.org/sdk/tools/BuGLe/)
+ ssh <HOST> xdpyinfo
-* [GLIntercept](http://code.google.com/p/glintercept/)
+ If this command fails with something like "cannot open display"
+ then the user will have to configure the target to set the DISPLAY
+ environment variable, (for example, setting DISPLAY=:0 in the
+ .bashrc file on the target or similar).
-* [tracy](https://gitorious.org/tracy): OpenGL ES and OpenVG trace, retrace, and state inspection
+ Also, note that if the ssh session requires a custom username, then