]> git.cworth.org Git - apitrace/commitdiff
Merge branch 'master' into d2d
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Wed, 7 Nov 2012 07:20:06 +0000 (07:20 +0000)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Wed, 7 Nov 2012 07:20:06 +0000 (07:20 +0000)
87 files changed:
.lvimrc [new file with mode: 0644]
CMakeLists.txt
INSTALL.markdown
README.markdown
cmake/FindQJSON.cmake [deleted file]
cmake/toolchain/android.toolchain.cmake
common/os_posix.cpp
common/os_thread.hpp
common/os_time.hpp
common/pickle.hpp
common/trace_parser_flags.cpp
common/trace_writer_local.cpp
dispatch/dxvaint.h [new file with mode: 0644]
gui/CMakeLists.txt
gui/graphing/graphview.cpp
gui/retracer.cpp
helpers/d3d10size.hpp [new file with mode: 0644]
helpers/d3d9size.hpp [new file with mode: 0644]
helpers/d3dsize.hpp [deleted file]
helpers/glsize.hpp
retrace/d3dretrace.py
retrace/d3dretrace_main.cpp
retrace/glretrace.hpp
retrace/glretrace.py
retrace/glretrace_cgl.cpp
retrace/glretrace_egl.cpp
retrace/glretrace_glx.cpp
retrace/glretrace_main.cpp
retrace/glretrace_wgl.cpp
retrace/glretrace_ws.cpp
retrace/glstate_images.cpp
retrace/glws.cpp
retrace/glws.hpp
retrace/glws_cocoa.mm
retrace/glws_egl_xlib.cpp
retrace/glws_glx.cpp
retrace/glws_wgl.cpp
retrace/json.hpp
retrace/retrace.cpp
retrace/retrace_main.cpp
retrace/retrace_swizzle.cpp
scripts/retracediff.py
scripts/tracediff.py
scripts/tracediff2.py
scripts/unpickle.py
specs/d3d10.py
specs/d3d9dxva2.py [new file with mode: 0644]
specs/dxgi.py
specs/glapi.py
specs/glparams.py
specs/gltypes.py
specs/glxapi.py
specs/stdapi.py
thirdparty/qjson/.gitignore [new file with mode: 0644]
thirdparty/qjson/CMakeLists.txt
thirdparty/qjson/COPYING [deleted file]
thirdparty/qjson/COPYING.lib [new file with mode: 0644]
thirdparty/qjson/README
thirdparty/qjson/json_parser.cc
thirdparty/qjson/json_parser.hh
thirdparty/qjson/json_parser.yy
thirdparty/qjson/json_scanner.cpp
thirdparty/qjson/json_scanner.h
thirdparty/qjson/parser.cpp
thirdparty/qjson/parser.h
thirdparty/qjson/parser_p.h
thirdparty/qjson/parserrunnable.cpp
thirdparty/qjson/parserrunnable.h
thirdparty/qjson/qjson_debug.h
thirdparty/qjson/qjson_export.h
thirdparty/qjson/qobjecthelper.cpp
thirdparty/qjson/qobjecthelper.h
thirdparty/qjson/serializer.cpp
thirdparty/qjson/serializer.h
thirdparty/qjson/serializerrunnable.cpp
thirdparty/qjson/serializerrunnable.h
wrappers/.gitignore
wrappers/CMakeLists.txt
wrappers/d3d10_1trace.py
wrappers/d3d10trace.py
wrappers/d3d9shader.cpp
wrappers/d3d9trace.py
wrappers/d3dcommontrace.py [new file with mode: 0644]
wrappers/gltrace.hpp
wrappers/gltrace.py
wrappers/gltrace_state.cpp
wrappers/trace.py

diff --git a/.lvimrc b/.lvimrc
new file mode 100644 (file)
index 0000000..815bdd0
--- /dev/null
+++ b/.lvimrc
@@ -0,0 +1 @@
+set sw=4 ts=4 et
index 9fe20026c6e438be1778bd8fff0bf6e64d591f57..83490d56b3d7e17c2230a6ccd0c7d9c725e25acc 100644 (file)
@@ -1,5 +1,14 @@
 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)
 
 
@@ -25,6 +34,21 @@ set (ENABLE_EGL true CACHE BOOL "Enable EGL support.")
 ##############################################################################
 # 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)
@@ -45,7 +69,6 @@ if (ENABLE_GUI)
         set (REQUIRE_GUI REQUIRED)
     endif ()
     find_package (Qt4 4.7 COMPONENTS QtCore QtGui QtWebKit ${REQUIRE_GUI})
-    find_package (QJSON ${REQUIRE_GUI})
 endif ()
 
 if (WIN32)
@@ -59,6 +82,10 @@ else ()
     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 ()
 
@@ -127,6 +154,9 @@ else ()
         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)
@@ -189,16 +219,12 @@ if (WIN32)
     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)
index 94e2d631cc0a8450e37cd1a04fd65209afe2e427..2228bdff860368cdf72203e97f0b62a54683b736 100644 (file)
@@ -16,7 +16,7 @@ Requirements common for all platforms:
 
 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)
 
@@ -40,8 +40,9 @@ Build as:
     cmake -H. -Bbuild
     make -C build
 
-You can also build the 32bit GL wrapper on 64bit distro with a multilib gcc by
-doing:
+
+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 \
@@ -52,6 +53,10 @@ doing:
         -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
 -------
 
index b59ee3bef506501b69d0ce4dc6e976345f3c8a43..ab1453059d6f97b325197a14ce07b1e961889a39 100644 (file)
@@ -11,6 +11,8 @@ About **apitrace**
 
 * visualize and edit trace files.
 
+See the [apitrace homepage](http://apitrace.github.com/) for more details.
+
 
 Obtaining **apitrace**
 ======================
@@ -50,7 +52,9 @@ Replay an OpenGL trace with
     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
@@ -110,22 +114,25 @@ or 32 bits.  This can be done by doing
 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
@@ -134,6 +141,9 @@ to trace by using `glxtrace.so` as an ordinary `libGL.so` and injecting into
     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.
 
@@ -272,8 +282,14 @@ From OpenGL ES applications you can embed annotations in the trace file through
 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
@@ -452,60 +468,4 @@ 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)
-
-
-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)
diff --git a/cmake/FindQJSON.cmake b/cmake/FindQJSON.cmake
deleted file mode 100644 (file)
index cd007e1..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-# 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)
index 37c9ad15ffe5b2ff0f2ffa3c1e012214e110d4bb..56c7fd2fc4574c041ed3ec16bbe056a79f22e9cb 100644 (file)
@@ -714,18 +714,19 @@ endif()
 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" )
-
-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()
+# 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" )
index 7d39d8ada5e0ffafc0f730bcdd3e913744f734d2..0d93b31bcafa6e56604fa639a7656d20128835ca 100644 (file)
@@ -134,7 +134,11 @@ int execute(char * const * args)
     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
index fe7faaa004ae98fc318a07da9ea3aa174ee9fbec..5e9577b56a29924b816abfc10fb16baf70a9bb14 100644 (file)
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * 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
@@ -24,9 +24,9 @@
  **************************************************************************/
 
 /*
- * 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
@@ -51,7 +75,7 @@ namespace os {
         typedef pthread_mutex_t native_handle_type;
 #endif
 
-        recursive_mutex(void) {
+        _base_mutex(void) {
 #ifdef _WIN32
             InitializeCriticalSection(&_native_handle);
 #else
@@ -63,7 +87,7 @@ namespace os {
 #endif
         }
 
-        ~recursive_mutex() {
+        ~_base_mutex() {
 #ifdef _WIN32
             DeleteCriticalSection(&_native_handle);
 #else
@@ -89,73 +113,235 @@ namespace os {
 #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 */
index 75175d85f6ecb15d8fc69622e10526b23ab5bb3d..13cc733ae05488312b4fb5554d08fcb8fd49bc2d 100644 (file)
 
 
 #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
 
 
@@ -88,6 +91,15 @@ namespace os {
 #endif
     }
 
+    // Suspend execution
+    inline void
+    sleep(unsigned long usecs) {
+#if defined(_WIN32)
+        Sleep((usecs + 999) / 1000);
+#else
+        usleep(usecs);
+#endif
+    }
 
 } /* namespace os */
 
index 60694fa83d92d8da1e9891e6865574d13d7e0ea2..41667e653783be3bf934ceba9a11afaaba373615 100644 (file)
@@ -300,12 +300,15 @@ protected:
             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;
index fe245149e1b7ad96c5b121be69d616d87a76e118..78a095523c5095d6a42a5f4450a3f574e244766f 100644 (file)
@@ -56,6 +56,7 @@ defaultCallFlags = 0;
 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 },
@@ -172,6 +173,8 @@ callFlagTable[] = {
     { "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 },
index 5aeedac520febb823ad08e86aa10bd30a05a24ca..feb5c912dfd06b2a61f2a003f9f9759bc23255e0 100644 (file)
@@ -128,8 +128,8 @@ LocalWriter::open(void) {
 #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();
@@ -139,17 +139,13 @@ unsigned LocalWriter::beginEnter(const FunctionSig *sig) {
         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);
 }
 
diff --git a/dispatch/dxvaint.h b/dispatch/dxvaint.h
new file mode 100644 (file)
index 0000000..f275d55
--- /dev/null
@@ -0,0 +1,154 @@
+/**************************************************************************
+ *
+ * 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 <dxva2api.h>
+
+
+typedef struct _DXVA2_PVP_SETKEY DXVA2_PVP_SETKEY; /* XXX */
+
+typedef struct _DXVA2_DECODEBUFFERDESC {
+    IDirect3DSurface9 *pRenderTarget;
+    DWORD CompressedBufferType;
+    DWORD BufferIndex;
+    DWORD DataOffset;
+    DWORD DataSize;
+    DWORD FirstMBaddress;
+    DWORD NumMBsInBuffer;
+    DWORD Width;
+    DWORD Height;
+    DWORD Stride;
+    DWORD ReservedBits;
+    PVOID pCipherCounter;
+} DXVA2_DECODEBUFFERDESC;
+
+typedef struct _DXVA2_DECODEEXECUTE {
+    UINT NumCompBuffers;
+    DXVA2_DECODEBUFFERDESC *pCompressedBuffers;
+} DXVA2_DECODEEXECUTE;
+
+typedef struct _DXVA2_VIDEOSAMPLE {
+  REFERENCE_TIME           Start;
+  REFERENCE_TIME           End;
+  DXVA2_ExtendedFormat   SampleFormat;
+  DWORD SampleFlags;
+  IDirect3DSurface9*   SrcSurface;
+  RECT                     SrcRect;
+  RECT                     DstRect;
+  DXVA2_AYUVSample8      Pal[16];
+  DXVA2_Fixed32          PlanarAlpha;
+} DXVA2_VIDEOSAMPLE;
+
+/**
+ * See also:
+ * - D3DDDIARG_VIDEOPROCESSBLT
+ * - DXVA2_VideoProcessBltParams
+ */
+typedef struct _DXVA2_VIDEOPROCESSBLT {
+    REFERENCE_TIME               TargetFrame;
+    RECT                         TargetRect;
+    SIZE                         ConstrictionSize;
+    DWORD                        StreamingFlags;
+    DXVA2_AYUVSample16         BackgroundColor;
+    DXVA2_ExtendedFormat       DestFormat;
+    DWORD DestFlags;
+    DXVA2_ProcAmpValues        ProcAmpValues;
+    DXVA2_Fixed32              Alpha;
+    DXVA2_FilterValues         NoiseFilterLuma;
+    DXVA2_FilterValues         NoiseFilterChroma;
+    DXVA2_FilterValues         DetailFilterLuma;
+    DXVA2_FilterValues         DetailFilterChroma;
+    DXVA2_VIDEOSAMPLE          *pSrcSurfaces;
+    UINT                         NumSrcSurfaces;
+}  DXVA2_VIDEOPROCESSBLT;
+
+typedef struct _DXVA2_DECODEBUFFERINFO DXVA2_DECODEBUFFERINFO; /* XXX */
+
+typedef struct _DXVA2_EXTENSIONEXECUTE DXVA2_EXTENSIONEXECUTE; /* XXX */
+
+
+static const GUID IID_IDirect3DDecodeDevice9 = {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}; /* XXX */
+static const GUID IID_IDirect3DVideoProcessDevice9 = {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}} /* XXX */;
+static const GUID IID_IDirect3DDXVAExtensionDevice9 = {0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}; /* XXX */
+static const GUID IID_IDirect3DDxva2Container9 = {0x126D0349,0x4787,0x4AA6,{0x8E,0x1B,0x40,0xC1,0x77,0xC6,0x0A,0x01}};
+
+
+class IDirect3DDecodeDevice9 : public IUnknown
+{
+public:
+    virtual HRESULT STDMETHODCALLTYPE DecodeBeginFrame(DXVA2_PVP_SETKEY *pPVPSetKey) = 0;
+    virtual HRESULT STDMETHODCALLTYPE DecodeEndFrame(HANDLE *pHandleComplete) = 0;
+    virtual HRESULT STDMETHODCALLTYPE DecodeSetRenderTarget(IDirect3DSurface9 *pRenderTarget) = 0;
+    virtual HRESULT STDMETHODCALLTYPE DecodeExecute(DXVA2_DECODEEXECUTE /* const */ *pExecuteParams) = 0;
+};
+
+
+class IDirect3DVideoProcessDevice9 : public IUnknown
+{
+public:
+    virtual HRESULT STDMETHODCALLTYPE VideoProcessBeginFrame(void) = 0;
+    virtual HRESULT STDMETHODCALLTYPE VideoProcessEndFrame(HANDLE *pHandleComplete) = 0;
+    virtual HRESULT STDMETHODCALLTYPE VideoProcessSetRenderTarget(IDirect3DSurface9 *pRenderTarget) = 0;
+    virtual HRESULT STDMETHODCALLTYPE VideoProcessBlt(DXVA2_VIDEOPROCESSBLT /* const */ *pData) = 0;
+};
+
+
+class IDirect3DDXVAExtensionDevice9 : public IUnknown
+{
+public:
+    virtual HRESULT STDMETHODCALLTYPE ExtensionExecute(DXVA2_EXTENSIONEXECUTE *pData) = 0;
+};
+
+
+class IDirect3DDxva2Container9 : public IUnknown
+{
+public:
+    virtual HRESULT STDMETHODCALLTYPE CreateSurface(UINT Width, UINT Height, UINT BackBuffers, D3DFORMAT Format, D3DPOOL Pool, DWORD Usage, DWORD DxvaType, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle) = 0;
+    virtual HRESULT STDMETHODCALLTYPE VidToSysBlt(IDirect3DSurface9 *pSourceSurface, RECT *pSourceRect, IDirect3DSurface9 *pDestSurface, RECT *pDestRect) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetDecodeGuidCount(UINT *pCount) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetDecodeGuids(UINT Count, GUID *pGuids) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetDecodeRenderTargetFormatCount(REFGUID Guid, UINT *pCount) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetDecodeRenderTargets(REFGUID Guid, UINT Count, D3DFORMAT *pFormats) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetDecodeCompressedBufferCount(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, UINT *pCount) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetDecodeCompressedBuffers(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, UINT Count, DXVA2_DECODEBUFFERINFO *pBufferInfo) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetDecodeConfigurationCount(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, UINT *pCount) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetDecodeConfigurations(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, UINT Count, DXVA2_ConfigPictureDecode *pConfigs) = 0;
+    virtual HRESULT STDMETHODCALLTYPE CreateDecodeDevice(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, DXVA2_ConfigPictureDecode const *pConfig, IDirect3DSurface9 * *ppDecoderRenderTargets, UINT NumSurfaces, IDirect3DDecodeDevice9 ** ppDecode) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorDeviceGuidCount(const DXVA2_VideoDesc *pVideoDesc, UINT *pCount) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorDeviceGuids(const DXVA2_VideoDesc *pVideoDesc, UINT Count, GUID *pGuids) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorCaps(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT Format, DXVA2_VideoProcessorCaps *pCaps) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetProcAmpRange(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT Format, UINT ProcAmpCap, DXVA2_ValueRange *pRange) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetFilterPropertyRange(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT Format, UINT FilterSetting, DXVA2_ValueRange *pRange) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorRenderTargetCount(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, UINT *pCount) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorRenderTargets(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, UINT Count, D3DFORMAT *pFormats) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorSubStreamFormatCount(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT Format, UINT *pCount) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorSubStreamFormats(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT Format, UINT Count, D3DFORMAT *pFormats) = 0;
+    virtual HRESULT STDMETHODCALLTYPE CreateVideoProcessDevice(REFGUID Guid, const DXVA2_VideoDesc *pVideoDesc, D3DFORMAT Format, UINT, IDirect3DVideoProcessDevice9 * * ppVideoProcessDevice) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetExtensionGuidCount(DWORD Extension, UINT *pCount) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetExtensionGuids(DWORD Extension, UINT Count, GUID *pGuids) = 0;
+    virtual HRESULT STDMETHODCALLTYPE GetExtensionCaps(REFGUID Guid, UINT, void *, UINT, void *, UINT) = 0;
+    virtual HRESULT STDMETHODCALLTYPE CreateExtensionDevice(REFGUID Guid, void *, UINT, IDirect3DDXVAExtensionDevice9 ** ppExtension) = 0;
+};
+
index ece66434a1ad922e502bb58583e0294144450118..8968cb4852f2c52eff7e328f7f822b59941864fa 100644 (file)
@@ -71,6 +71,11 @@ target_link_libraries (qapitrace
     ${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)
index 6ecac573212e5b55dfaf6b0c166f13f87e5ec298..9b42c4baebfbf44899096307288689a0b7c210a8 100644 (file)
@@ -5,7 +5,6 @@
 
 GraphView::GraphView(QWidget* parent) :
     QWidget(parent),
-    m_selectionState(NULL),
     m_viewLeft(0),
     m_viewRight(0),
     m_viewBottom(0),
@@ -19,7 +18,8 @@ GraphView::GraphView(QWidget* parent) :
     m_viewWidthMax(0),
     m_viewHeight(0),
     m_viewHeightMin(0),
-    m_viewHeightMax(0)
+    m_viewHeightMax(0),
+    m_selectionState(NULL)
 {
     memset(&m_previous, -1, sizeof(m_previous));
 }
index 592c1a4215d66bf947294236c953bf71beb00d1a..6d743f70e72d04aab4cb7e181603e5597ea52f96 100644 (file)
@@ -353,6 +353,9 @@ void Retracer::run()
 
             bool ok = false;
             QJson::Parser jsonParser;
+
+            // Allow Nan/Infinity
+            jsonParser.allowSpecialNumbers(true);
 #if 0
             parsedJson = jsonParser.parse(&io, &ok).toMap();
 #else
diff --git a/helpers/d3d10size.hpp b/helpers/d3d10size.hpp
new file mode 100644 (file)
index 0000000..dbcab6a
--- /dev/null
@@ -0,0 +1,447 @@
+/**************************************************************************
+ *
+ * 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_ */
diff --git a/helpers/d3d9size.hpp b/helpers/d3d9size.hpp
new file mode 100644 (file)
index 0000000..0041e25
--- /dev/null
@@ -0,0 +1,379 @@
+/**************************************************************************
+ *
+ * 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_ */
diff --git a/helpers/d3dsize.hpp b/helpers/d3dsize.hpp
deleted file mode 100644 (file)
index 156fdd2..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-/**************************************************************************
- *
- * 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_ */
index 6ffba688df60ec227354e559088719a0278a9b82..9d39a3b717f6f812aee787d58a3be5a73623ad6d 100644 (file)
@@ -301,6 +301,14 @@ _glArrayPointer_size(GLint size, GLenum type, GLsizei stride, GLsizei count)
         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;
@@ -332,6 +340,11 @@ _glDrawArrays_count(GLint first, GLsizei count)
 
 #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)
 {
@@ -352,7 +365,7 @@ _glDrawElementsBaseVertex_count(GLsizei count, GLenum type, const GLvoid *indice
             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) {
index ddd37b95a8b7c3d4b3ca34e1b287846fed5d6f8a..14b92ab4fe7503f50945412b4f34453273388865 100644 (file)
@@ -35,7 +35,8 @@ from specs.d3d9 import *
 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()
@@ -86,12 +87,11 @@ class D3DRetracer(Retracer):
             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 '    }'
@@ -104,7 +104,7 @@ if __name__ == '__main__':
 #include <iostream>
 
 #include "d3d9imports.hpp"
-#include "d3dsize.hpp"
+#include "d3d9size.hpp"
 #include "d3dretrace.hpp"
 
 '''
index 40d53eafb1b946201a076cb996b8dddb5d12202e..9878fe3c87b059690527f6c6e44f523d72f4880d 100644 (file)
@@ -87,6 +87,7 @@ retrace::flushRendering(void) {
 
 void
 retrace::waitForInput(void) {
+    /* TODO */
 }
 
 void
index 11f4d27574dd1a05bd7ec88a001a9b64db94d44a..95a6d7596df230e8dd059194c493bbf58055cad3 100644 (file)
@@ -35,27 +35,40 @@ namespace glretrace {
 struct Context {
     Context(glws::Context* context)
         : wsContext(context),
+          drawable(0),
           activeProgram(0),
           used(false)
     {
     }
 
-    ~Context()
-    {
-        delete wsContext;
-    }
+    ~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 Context *currentContext;
+Context *
+getCurrentContext(void);
+
+
+int
+parseAttrib(const trace::Value *attribs, int param, int default_);
+
 
 glws::Drawable *
 createDrawable(glws::Profile profile);
@@ -63,6 +76,9 @@ createDrawable(glws::Profile profile);
 glws::Drawable *
 createDrawable(void);
 
+glws::Drawable *
+createPbuffer(int width, int height);
+
 Context *
 createContext(Context *shareContext, glws::Profile profile);
 
index 6c73e697d9128f3947b50d5be712f30916dbd7bb..e2ea3201bf183bd63597a964b11f95bcc101424f 100644 (file)
@@ -250,7 +250,7 @@ class GlRetracer(Retracer):
             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'    }'
 
@@ -299,8 +299,9 @@ class GlRetracer(Retracer):
         )
 
         if function.name in ('glUseProgram', 'glUseProgramObjectARB'):
-            print r'    if (glretrace::currentContext) {'
-            print r'        glretrace::currentContext->activeProgram = call.arg(0).toUInt();'
+            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
@@ -362,7 +363,7 @@ class GlRetracer(Retracer):
         # 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;'
@@ -477,14 +478,20 @@ class GlRetracer(Retracer):
            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
 
index 76b62fb4f9f856191ee9cefebbd12eacff2015ac..a0755953b3a52059e35f9d4e0ff9447cba878305 100644 (file)
 #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;
 
 
@@ -81,6 +124,106 @@ getContext(unsigned long long ctx) {
 }
 
 
+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();
 
@@ -92,19 +235,85 @@ static void retrace_CGLSetCurrentContext(trace::Call &call) {
 
 
 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},
@@ -112,6 +321,8 @@ const retrace::Entry glretrace::cgl_callbacks[] = {
     {"CGLSetParameter", &retrace::ignore},
     {"CGLGetParameter", &retrace::ignore},
     {"CGLFlushDrawable", &retrace_CGLFlushDrawable},
+    {"CGLUpdateContext", &retrace::ignore},
+    {"CGLTexImageIOSurface2D", &retrace_CGLTexImageIOSurface2D},
     {NULL, NULL},
 };
 
index 3f83f55b41c734a44cd34f747209f85696584fa0..45855643f5b55272e494be1bcef8a799e26c928f 100644 (file)
@@ -127,7 +127,8 @@ static void retrace_eglDestroySurface(trace::Call &call) {
     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;
         }
@@ -202,7 +203,11 @@ static void retrace_eglDestroyContext(trace::Call &call) {
     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);
     }
 }
@@ -216,10 +221,14 @@ static void retrace_eglMakeCurrent(trace::Call &call) {
 
 
 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();
     }
index bc63063d5a0c6394e885f6491300c86e3e7d2b80..4ab3d676c189f4984fbc0bb1b6c329c4037e5d86 100644 (file)
 #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;
 
 
@@ -103,9 +112,13 @@ static void retrace_glXDestroyContext(trace::Call &call) {
 }
 
 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();
     }
@@ -119,6 +132,28 @@ static void retrace_glXCreateNewContext(trace::Call &call) {
     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());
     Context *new_context = getContext(call.arg(3).toUIntPtr());
@@ -146,14 +181,14 @@ const retrace::Entry glretrace::glx_callbacks[] = {
     //{"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},
@@ -176,6 +211,7 @@ const retrace::Entry glretrace::glx_callbacks[] = {
     {"glXGetProcAddress", &retrace::ignore},
     {"glXGetSelectedEvent", &retrace::ignore},
     {"glXGetSelectedEventSGIX", &retrace::ignore},
+    {"glXGetSwapIntervalMESA", &retrace::ignore},
     {"glXGetSyncValuesOML", &retrace::ignore},
     {"glXGetVideoSyncSGI", &retrace::ignore},
     {"glXGetVisualFromFBConfig", &retrace::ignore},
index d857d03604b649ea145076da4367270dccc09f82..5ccb2e2d2a2955f6b83a03da4508cfbd8ad5d57c 100755 (executable)
@@ -67,46 +67,46 @@ debugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsi
 void
 checkGlError(trace::Call &call) {
     GLenum error = glGetError();
-    if (error == GL_NO_ERROR) {
-        return;
-    }
-
-    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;
+    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();
     }
-    os << "\n";
 }
 
 static void
@@ -174,12 +174,14 @@ flushQueries() {
 
 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 = glretrace::currentContext ? glretrace::currentContext->activeProgram : 0;
+    query.program = currentContext ? currentContext->activeProgram : 0;
 
     /* GPU profiling only for draw calls */
     if (isDraw) {
@@ -230,13 +232,14 @@ endProfile(trace::Call &call, bool isDraw) {
 
 void
 initContext() {
-    const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
+    glretrace::Context *currentContext = glretrace::getCurrentContext();
 
     /* Ensure we have adequate extension support */
-    supportsTimestamp   = glws::checkExtension("GL_ARB_timer_query", extensions);
-    supportsElapsed     = glws::checkExtension("GL_EXT_timer_query", extensions) || supportsTimestamp;
-    supportsOcclusion   = glws::checkExtension("GL_ARB_occlusion_query", extensions);
-    supportsDebugOutput = glws::checkExtension("GL_ARB_debug_output", extensions);
+    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) {
@@ -262,6 +265,7 @@ initContext() {
 
     /* Setup debug message call back */
     if (retrace::debug && supportsDebugOutput) {
+        glretrace::Context *currentContext = glretrace::getCurrentContext();
         glDebugMessageCallbackARB(&debugOutputCallback, currentContext);
 
         if (DEBUG_OUTPUT_SYNCHRONOUS) {
@@ -310,11 +314,13 @@ 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";
     }
 }
@@ -404,7 +410,7 @@ retrace::addCallbacks(retrace::Retracer &retracer)
 
 image::Image *
 retrace::getSnapshot(void) {
-    if (!glretrace::currentDrawable) {
+    if (!glretrace::getCurrentContext()) {
         return NULL;
     }
 
@@ -415,9 +421,10 @@ retrace::getSnapshot(void) {
 bool
 retrace::dumpState(std::ostream &os)
 {
+    glretrace::Context *currentContext = glretrace::getCurrentContext();
+
     if (glretrace::insideGlBeginEnd ||
-        !glretrace::currentDrawable ||
-        !glretrace::currentContext) {
+        !currentContext) {
         return false;
     }
 
@@ -428,13 +435,17 @@ retrace::dumpState(std::ostream &os)
 
 void
 retrace::flushRendering(void) {
-    glretrace::flushQueries();
-    glFlush();
+    glretrace::Context *currentContext = glretrace::getCurrentContext();
+    if (currentContext) {
+        glretrace::flushQueries();
+        glFlush();
+    }
 }
 
 void
 retrace::waitForInput(void) {
     while (glws::processEvents()) {
+        os::sleep(100*1000);
     }
 }
 
index bf2f38a19024b1a2c19cd69c5eda6697204d5215..abcf068a057056f88bdefbe1d8c002bd2e9e0459 100644 (file)
@@ -94,9 +94,18 @@ static void retrace_wglSetPixelFormat(trace::Call &call) {
 }
 
 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();
     }
@@ -111,8 +120,9 @@ static void retrace_wglShareLists(trace::Call &call) {
 
     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;
@@ -176,10 +186,7 @@ static void retrace_wglCreatePbufferARB(trace::Call &call) {
     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;
 }
index bead54ee10ea0566a471604e2a37c423f1eeb181..ac03fcc97de6d56390f807a3b1661e6571d489c1 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <string.h>
 
+#include "os_thread.hpp"
 #include "retrace.hpp"
 #include "glproc.hpp"
 #include "glstate.hpp"
 namespace glretrace {
 
 
-glws::Drawable *currentDrawable = NULL;
-Context *currentContext = NULL;
-
-
 static glws::Visual *
 visuals[glws::PROFILE_MAX];
 
@@ -53,6 +50,10 @@ getVisual(glws::Profile profile) {
     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;
 }
@@ -69,29 +70,42 @@ getDefaultProfile(void)
 }
 
 
-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);
 }
 
 
 Context *
 createContext(Context *shareContext, glws::Profile profile) {
+    glws::Visual *visual = getVisual(profile);
     glws::Context *shareWsContext = shareContext ? shareContext->wsContext : NULL;
-    glws::Context *ctx = glws::createContext(getVisual(profile), shareWsContext, profile, retrace::debug);
+    glws::Context *ctx = glws::createContext(visual, shareWsContext, profile, retrace::debug);
     if (!ctx) {
         std::cerr << "error: failed to create OpenGL context\n";
         exit(1);
@@ -108,14 +122,30 @@ createContext(Context *shareContext) {
 }
 
 
+Context::~Context()
+{
+    //assert(this != getCurrentContext());
+    if (this != getCurrentContext()) {
+        delete wsContext;
+    }
+}
+
+
+static thread_specific Context *
+currentContextPtr;
+
+
 bool
 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);
@@ -132,25 +162,25 @@ makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context)
         return false;
     }
 
-    if (context) {
+    currentContextPtr = context;
+
+    if (drawable && context) {
+        context->drawable = drawable;
+        
         if (!context->used) {
             initContext();
             context->used = true;
         }
     }
 
-    if (drawable && context) {
-        currentDrawable = drawable;
-        currentContext = context;
-    } else {
-        currentDrawable = NULL;
-        currentContext = NULL;
-    }
-
     return true;
 }
 
 
+Context *
+getCurrentContext(void) {
+    return currentContextPtr;
+}
 
 
 /**
@@ -161,7 +191,15 @@ makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context)
  */
 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;
     }
 
@@ -190,4 +228,26 @@ updateDrawable(int width, int height) {
 }
 
 
+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 */
index 6390980966a91c8e17048718b20f01630e6aa338..e534a654320ef55bafbe1adda4d847df0af3e6da 100644 (file)
@@ -88,6 +88,31 @@ struct ImageDesc
 };
 
 
+/**
+ * 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()
@@ -232,6 +257,8 @@ getActiveTextureLevelDescOES(Context &context, GLenum target, GLint level, Image
 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);
     }
@@ -386,7 +413,7 @@ dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint
     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
@@ -409,7 +436,7 @@ dumpActiveTextureLevel(JSONWriter &json, Context &context, GLenum target, GLint
     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__
@@ -431,15 +458,18 @@ dumpTexture(JSONWriter &json, Context &context, GLenum target, GLenum binding)
     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);
         }
 
@@ -833,7 +863,7 @@ dumpReadBufferImage(JSONWriter &json, GLint width, GLint height, GLenum format,
     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
index 4e07ede9d227a856e0bffe091300906638771604..f89f980c5f8094928f0a5d8db391d78db792508b 100644 (file)
@@ -24,6 +24,9 @@
  **************************************************************************/
 
 
+#include <assert.h>
+
+#include "glproc.hpp"
 #include "glws.hpp"
 
 
@@ -33,26 +36,68 @@ namespace glws {
 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();
 }
 
 
index 05903a7b55281b96b6d00058c844fe551a2b9f7e..c76e19321706a5c8a02fca80dfcce7774ad2ce6f 100644 (file)
 #define _GLWS_HPP_
 
 
+#include <assert.h>
+
 #include <vector>
+#include <set>
+#include <string>
 
 
 namespace glws {
@@ -98,12 +102,14 @@ public:
     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)
     {}
 
@@ -117,6 +123,7 @@ public:
 
     virtual void
     show(void) {
+        assert(!pbuffer);
         visible = true;
     }
 
@@ -130,12 +137,18 @@ public:
     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);
 };
 
 
@@ -149,7 +162,7 @@ Visual *
 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);
index 2ac30913d515e3f5405c4f8f019a62eea1fce7c9..e410862f1996aa278d64db22c2ec3ba4eac81694 100644 (file)
  * - 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
@@ -69,10 +97,11 @@ class CocoaDrawable : public Drawable
 {
 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;
@@ -88,9 +117,9 @@ public:
                                        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];
@@ -113,7 +142,7 @@ public:
         if (currentContext != nil) {
             [currentContext update];
             [window makeKeyAndOrderFront:nil];
-            [currentContext setView:[window contentView]];
+            [currentContext setView:view];
             [currentContext makeCurrentContext];
         }
 
@@ -154,11 +183,29 @@ public:
 };
 
 
+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];
 }
@@ -172,6 +219,9 @@ cleanup(void) {
 
 Visual *
 createVisual(bool doubleBuffer, Profile profile) {
+
+    initThread();
+
     if (profile != PROFILE_COMPAT &&
         profile != PROFILE_CORE) {
         return nil;
@@ -193,6 +243,12 @@ createVisual(bool doubleBuffer, Profile profile) {
        return NULL;
 #endif
     }
+    
+    // Use Apple software rendering for debugging purposes.
+    if (0) {
+        attribs.add(NSOpenGLPFARendererID, 0x00020200); // kCGLRendererGenericID
+    }
+
     attribs.end();
 
     NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc]
@@ -202,14 +258,18 @@ createVisual(bool doubleBuffer, Profile profile) {
 }
 
 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;
@@ -234,6 +294,8 @@ createContext(const Visual *visual, Context *shareContext, Profile profile, bool
 bool
 makeCurrent(Drawable *drawable, Context *context)
 {
+    initThread();
+
     if (!drawable || !context) {
         [NSOpenGLContext clearCurrentContext];
     } else {
@@ -252,8 +314,9 @@ makeCurrent(Drawable *drawable, Context *context)
 
 bool
 processEvents(void) {
-   NSEvent* event;
+    initThread();
 
+    NSEvent* event;
     do {
         event = [NSApp nextEventMatchingMask:NSAnyEventMask
                                    untilDate:[NSDate distantPast]
index 58824c29b2b897765e0af4c8fe36753e907ef79e..5aacdfed2b5bea5c0b738b907711d936610a93f8 100644 (file)
@@ -92,8 +92,9 @@ public:
     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;
 
@@ -393,9 +394,9 @@ createVisual(bool doubleBuffer, Profile profile) {
 }
 
 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 *
index 1573bb9d69ec80c41fdb3db4d59db8d5bda2e2c4..1494d060d7245cae687637db7c5452cc6a6c2f2b 100644 (file)
@@ -60,7 +60,8 @@ public:
 };
 
 
-static void describeEvent(const XEvent &event) {
+static void
+processEvent(XEvent &event) {
     if (0) {
         switch (event.type) {
         case ConfigureNotify:
@@ -83,6 +84,19 @@ static void describeEvent(const XEvent &event) {
         }
         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
@@ -90,8 +104,8 @@ 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;
 
@@ -102,7 +116,7 @@ public:
         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;
@@ -135,11 +149,18 @@ public:
         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);
     }
 
@@ -194,6 +215,8 @@ public:
 
     void swapBuffers(void) {
         glXSwapBuffers(display, window);
+
+        processKeys();
     }
 };
 
@@ -215,6 +238,8 @@ public:
 
 void
 init(void) {
+    XInitThreads();
+
     display = XOpenDisplay(NULL);
     if (!display) {
         std::cerr << "error: unable to open display " << XDisplayName(NULL) << "\n";
@@ -290,9 +315,9 @@ createVisual(bool doubleBuffer, Profile profile) {
 }
 
 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 *
@@ -368,7 +393,7 @@ processEvents(void) {
     while (XPending(display) > 0) {
         XEvent event;
         XNextEvent(display, &event);
-        describeEvent(event);
+        processEvent(event);
     }
     return true;
 }
index c6e4a3fb39b1935e3c29a2a806fdcf007250f211..de6c7d6b546161fe4c1968cb1f3305632cb1dee9 100644 (file)
@@ -100,8 +100,8 @@ public:
     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;
@@ -243,6 +243,34 @@ public:
             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;
+    }
+
 };
 
 
@@ -275,7 +303,8 @@ cleanup(void) {
 
 Visual *
 createVisual(bool doubleBuffer, Profile profile) {
-    if (profile != PROFILE_COMPAT) {
+    if (profile != PROFILE_COMPAT &&
+        profile != PROFILE_CORE) {
         return NULL;
     }
 
@@ -287,18 +316,23 @@ createVisual(bool doubleBuffer, Profile profile) {
 }
 
 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));
 }
 
@@ -311,22 +345,7 @@ makeCurrent(Drawable *drawable, Context *context)
         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);
     }
index 2f50a8c55aedc28fccad91c1493031289113cc2b..4ad2ab35d2fd9f270fd4c53845b4ef0293b0b422 100644 (file)
@@ -37,8 +37,9 @@
 #ifdef _MSC_VER
 #  include <float.h>
 #  define isfinite _finite
+#  define isnan _isnan
 #else
-#  include <math.h> // isfinite
+#  include <math.h> // isfinite, isnan
 #endif
 
 #include <iomanip>
@@ -335,15 +336,21 @@ public:
 
     template<class T>
     inline void writeNumber(T n) {
-        if (!isfinite(n)) {
-            // NaN/Inf
-            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) {
index 182d1182eece7f2768ebaf15df8de70f249e14d6..ee876ca3eae2c5ebe092c374df1340b1c4a42020 100644 (file)
@@ -40,6 +40,7 @@ static bool call_dumped = false;
 
 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;
@@ -82,13 +83,6 @@ void Retracer::addCallbacks(const Entry *entries) {
 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;
@@ -112,6 +106,14 @@ void Retracer::retrace(trace::Call &call) {
     assert(callback);
     assert(callbacks[id] == callback);
 
+    if (verbosity >= 1) {
+        if (verbosity >= 2 ||
+            (!(call.flags & trace::CALL_FLAG_VERBOSE) &&
+             callback != &ignore)) {
+            dumpCall(call);
+        }
+    }
+
     callback(call);
 }
 
index 9386a6182a989621a62a60c5e5b689fbd2fcaac6..7e171e67bf97f504744ab2268f94d84362a6f7a7 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "os_binary.hpp"
 #include "os_time.hpp"
+#include "os_thread.hpp"
 #include "image.hpp"
 #include "trace_callset.hpp"
 #include "trace_dump.hpp"
@@ -44,6 +45,8 @@ static trace::CallSet compareFrequency;
 
 static unsigned dumpStateCallNo = ~0;
 
+retrace::Retracer retracer;
+
 
 namespace retrace {
 
@@ -74,6 +77,9 @@ frameComplete(trace::Call &call) {
 }
 
 
+/**
+ * Take/compare snapshots.
+ */
 static void
 takeSnapshot(unsigned call_no) {
     assert(snapshotPrefix || comparePrefix);
@@ -120,56 +126,342 @@ takeSnapshot(unsigned call_no) {
 }
 
 
+/**
+ * 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);
         }
 
-        callNo = call->no;
-        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;
+            }
         }
+    }
+
+    /**
+     * Called by other threads when relinquishing the baton.
+     */
+    void
+    receiveBaton(trace::Call *call) {
+        assert (call->thread_id == leg);
+
+        mutex.lock();
+        baton = call;
+        mutex.unlock();
 
-        delete call;
+        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);
index 52d1d74dfd251eeb20cc9ce8c462a4f81a970313..a7e777d45cba26e8da0abe4a6bf92900a1db5162 100644 (file)
@@ -75,6 +75,12 @@ lowerBound(unsigned long long address) {
         }
     }
 
+#ifndef NDEBUG
+    if (it != regionMap.end()) {
+        assert(contains(it, address) || it->first > address);
+    }
+#endif
+
     return it;
 }
 
@@ -83,6 +89,12 @@ static RegionMap::iterator
 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;
 }
 
@@ -108,7 +120,7 @@ addRegion(unsigned long long address, void *buffer, unsigned long long size)
 
 #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);
index 8a0837a82bf6a17d9e973c62db70cdbaf6b9860c..d665c7601b7acf7a91ef3708fd521c4165e0891f 100755 (executable)
@@ -98,7 +98,15 @@ def read_pnm(stream):
     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('#'):
@@ -107,8 +115,8 @@ def read_pnm(stream):
     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
 
 
index 86d1e0020f1e55a72c196b93c8ba9a20c727e7a9..26395879a10b8c54f3308f6a3a8eeab2e5506414 100755 (executable)
@@ -70,6 +70,8 @@ else:
 
 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)
 
@@ -78,6 +80,9 @@ def diff(ref_trace, src_trace):
         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',
             ]
@@ -92,6 +97,9 @@ def diff(ref_trace, src_trace):
                 'wdiff',
                 #'--terminal',
                 '--avoid-wraps',
+            ]
+        if isatty:
+            diff_args += [
                 '--start-delete=' + start_delete,
                 '--end-delete=' + end_delete,
                 '--start-insert=' + start_insert,
@@ -105,7 +113,7 @@ def diff(ref_trace, src_trace):
     src_dumper.dump.wait()
 
     less = None
-    if sys.stdout.isatty():
+    if isatty:
         less = subprocess.Popen(
             args = ['less', '-FRXn'],
             stdin = subprocess.PIPE
index 0f59d87983df51be1a23bb8400c3c601d172402b..255191e8c5bf93bd9a744ef558b4c28e7f386e2d 100755 (executable)
@@ -58,7 +58,7 @@ class Blob:
         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
index d2db44df2b9cf577fd68c0145e3bc3436b52152a..50d8480aac948143f78c091bb5198d2a04ec4773 100755 (executable)
@@ -245,7 +245,7 @@ class Counter(Unpickler):
 
 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,
index b7c3e653af5a2b7f1447545216da7436daf70461..7b0f1824158405aa7b7bc535764baebd9d3681a7 100644 (file)
@@ -544,7 +544,7 @@ D3D10_BOX = Struct("D3D10_BOX", [
 ])
 
 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"),
 ])
@@ -824,7 +824,7 @@ ID3D10Device.methods += [
     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")]),
@@ -861,10 +861,10 @@ ID3D10Device.methods += [
     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")]),
diff --git a/specs/d3d9dxva2.py b/specs/d3d9dxva2.py
new file mode 100644 (file)
index 0000000..f72d093
--- /dev/null
@@ -0,0 +1,374 @@
+##########################################################################
+#
+# 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.
+#
+##########################################################################/
+
+
+from d3d9 import *
+
+REFERENCE_TIME = Alias("REFERENCE_TIME", LONGLONG)
+
+DXVA2_ProcAmp = Flags(UINT, [
+    "DXVA2_ProcAmp_None",
+    "DXVA2_ProcAmp_Brightness",
+    "DXVA2_ProcAmp_Contrast",
+    "DXVA2_ProcAmp_Hue",
+    "DXVA2_ProcAmp_Saturation",
+])
+
+HRESULT = FakeEnum(HRESULT, [
+    "DXVA2_E_NOT_INITIALIZED",
+    "DXVA2_E_NEW_VIDEO_DEVICE",
+    "DXVA2_E_VIDEO_DEVICE_LOCKED",
+    "DXVA2_E_NOT_AVAILABLE",
+])
+
+DXVA2_SampleFormat = Enum("DXVA2_SampleFormat", [
+    "DXVA2_SampleFormatMask",
+    "DXVA2_SampleUnknown",
+    "DXVA2_SampleProgressiveFrame",
+    "DXVA2_SampleFieldInterleavedEvenFirst",
+    "DXVA2_SampleFieldInterleavedOddFirst",
+    "DXVA2_SampleFieldSingleEven",
+    "DXVA2_SampleFieldSingleOdd",
+    "DXVA2_SampleSubStream",
+])
+
+DXVA2_VideoChromaSubSampling = Enum("DXVA2_VideoChromaSubSampling", [
+    "DXVA2_VideoChromaSubsamplingMask",
+    "DXVA2_VideoChromaSubsampling_Unknown",
+    "DXVA2_VideoChromaSubsampling_ProgressiveChroma",
+    "DXVA2_VideoChromaSubsampling_Horizontally_Cosited",
+    "DXVA2_VideoChromaSubsampling_Vertically_Cosited",
+    "DXVA2_VideoChromaSubsampling_Vertically_AlignedChromaPlanes",
+    "DXVA2_VideoChromaSubsampling_MPEG2",
+    "DXVA2_VideoChromaSubsampling_MPEG1",
+    "DXVA2_VideoChromaSubsampling_DV_PAL",
+    "DXVA2_VideoChromaSubsampling_Cosited",
+])
+
+DXVA2_NominalRange = Enum("DXVA2_NominalRange", [
+    "DXVA2_NominalRangeMask",
+    "DXVA2_NominalRange_Unknown",
+    "DXVA2_NominalRange_Normal",
+    "DXVA2_NominalRange_Wide",
+    "DXVA2_NominalRange_0_255",
+    "DXVA2_NominalRange_16_235",
+    "DXVA2_NominalRange_48_208",
+])
+
+DXVA2_VideoLighting = Enum("DXVA2_VideoLighting", [
+    "DXVA2_VideoLightingMask",
+    "DXVA2_VideoLighting_Unknown",
+    "DXVA2_VideoLighting_bright",
+    "DXVA2_VideoLighting_office",
+    "DXVA2_VideoLighting_dim",
+    "DXVA2_VideoLighting_dark",
+])
+
+DXVA2_VideoPrimaries = Enum("DXVA2_VideoPrimaries", [
+    "DXVA2_VideoPrimariesMask",
+    "DXVA2_VideoPrimaries_Unknown",
+    "DXVA2_VideoPrimaries_reserved",
+    "DXVA2_VideoPrimaries_BT709",
+    "DXVA2_VideoPrimaries_BT470_2_SysM",
+    "DXVA2_VideoPrimaries_BT470_2_SysBG",
+    "DXVA2_VideoPrimaries_SMPTE170M",
+    "DXVA2_VideoPrimaries_SMPTE240M",
+    "DXVA2_VideoPrimaries_EBU3213",
+    "DXVA2_VideoPrimaries_SMPTE_C",
+])
+
+DXVA2_VideoTransferFunction = Enum("DXVA2_VideoTransferFunction", [
+    "DXVA2_VideoTransFuncMask",
+    "DXVA2_VideoTransFunc_Unknown",
+    "DXVA2_VideoTransFunc_10",
+    "DXVA2_VideoTransFunc_18",
+    "DXVA2_VideoTransFunc_20",
+    "DXVA2_VideoTransFunc_22",
+    "DXVA2_VideoTransFunc_709",
+    "DXVA2_VideoTransFunc_240M",
+    "DXVA2_VideoTransFunc_sRGB",
+    "DXVA2_VideoTransFunc_28",
+])
+
+DXVA2_SurfaceType = FakeEnum(DWORD, [
+    "DXVA2_SurfaceType_DecoderRenderTarget",
+    "DXVA2_SurfaceType_ProcessorRenderTarget",
+    "DXVA2_SurfaceType_D3DRenderTargetTexture",
+])
+
+DXVA2_VideoTransferMatrix = Enum("DXVA2_VideoTransferMatrix", [
+    "DXVA2_VideoTransferMatrixMask",
+    "DXVA2_VideoTransferMatrix_Unknown",
+    "DXVA2_VideoTransferMatrix_BT709",
+    "DXVA2_VideoTransferMatrix_BT601",
+    "DXVA2_VideoTransferMatrix_SMPTE240M",
+])
+
+DXVA2_AYUVSample16 = Struct("DXVA2_AYUVSample16", [
+    (USHORT, "Cr"),
+    (USHORT, "Cb"),
+    (USHORT, "Y"),
+    (USHORT, "Alpha"),
+])
+
+DXVA2_AYUVSample8 = Struct("DXVA2_AYUVSample8", [
+    (UCHAR, "Cr"),
+    (UCHAR, "Cb"),
+    (UCHAR, "Y"),
+    (UCHAR, "Alpha"),
+])
+
+DXVA2_ConfigPictureDecode = Struct("DXVA2_ConfigPictureDecode", [
+    (GUID, "guidConfigBitstreamEncryption"),
+    (GUID, "guidConfigMBcontrolEncryption"),
+    (GUID, "guidConfigResidDiffEncryption"),
+    (UINT, "ConfigBitstreamRaw"),
+    (UINT, "ConfigMBcontrolRasterOrder"),
+    (UINT, "ConfigResidDiffHost"),
+    (UINT, "ConfigSpatialResid8"),
+    (UINT, "ConfigResid8Subtraction"),
+    (UINT, "ConfigSpatialHost8or9Clipping"),
+    (UINT, "ConfigSpatialResidInterleaved"),
+    (UINT, "ConfigIntraResidUnsigned"),
+    (UINT, "ConfigResidDiffAccelerator"),
+    (UINT, "ConfigHostInverseScan"),
+    (UINT, "ConfigSpecificIDCT"),
+    (UINT, "Config4GroupedCoefs"),
+    (USHORT, "ConfigMinRenderTargetBuffCount"),
+    (USHORT, "ConfigDecoderSpecific"),
+])
+
+DXVA2_DecodeBufferDesc = Struct("DXVA2_DecodeBufferDesc", [
+    (DWORD, "CompressedBufferType"),
+    (UINT, "BufferIndex"),
+    (UINT, "DataOffset"),
+    (UINT, "DataSize"),
+    (UINT, "FirstMBaddress"),
+    (UINT, "NumMBsInBuffer"),
+    (UINT, "Width"),
+    (UINT, "Height"),
+    (UINT, "Stride"),
+    (UINT, "ReservedBits"),
+    (PVOID, "pvPVPState"),
+])
+
+DXVA2_DecodeExtensionData = Struct("DXVA2_DecodeExtensionData", [
+    (UINT, "Function"),
+    (PVOID, "pPrivateInputData"),
+    (UINT, "PrivateInputDataSize"),
+    (PVOID, "pPrivateOutputData"),
+    (UINT, "PrivateOutputDataSize"),
+])
+
+DXVA2_DecodeExecuteParams = Struct("DXVA2_DecodeExecuteParams", [
+    (UINT, "NumCompBuffers"),
+    (Pointer(DXVA2_DecodeBufferDesc), "pCompressedBuffers"),
+    (Pointer(DXVA2_DecodeExtensionData), "pExtensionData"),
+])
+
+DXVA2_ExtendedFormat = Struct("DXVA2_ExtendedFormat", [
+    (UINT, "value"),
+])
+
+DXVA2_Fixed32 = Struct("DXVA2_Fixed32", [
+    (USHORT, "Fraction"),
+    (SHORT, "Value"),
+])
+
+DXVA2_FilterValues = Struct("DXVA2_FilterValues", [
+    (DXVA2_Fixed32, "Level"),
+    (DXVA2_Fixed32, "Threshold"),
+    (DXVA2_Fixed32, "Radius"),
+])
+
+DXVA2_Frequency = Struct("DXVA2_Frequency", [
+    (UINT, "Numerator"),
+    (UINT, "Denominator"),
+])
+
+DXVA2_ProcAmpValues = Struct("DXVA2_ProcAmpValues", [
+    (DXVA2_Fixed32, "Brightness"),
+    (DXVA2_Fixed32, "Contrast"),
+    (DXVA2_Fixed32, "Hue"),
+    (DXVA2_Fixed32, "Saturation"),
+])
+
+DXVA2_ValueRange = Struct("DXVA2_ValueRange", [
+    (DXVA2_Fixed32, "MinValue"),
+    (DXVA2_Fixed32, "MaxValue"),
+    (DXVA2_Fixed32, "DefaultValue"),
+    (DXVA2_Fixed32, "StepSize"),
+])
+
+DXVA2_VideoDesc = Struct("DXVA2_VideoDesc", [
+    (UINT, "SampleWidth"),
+    (UINT, "SampleHeight"),
+    (DXVA2_ExtendedFormat, "SampleFormat"),
+    (D3DFORMAT, "Format"),
+    (DXVA2_Frequency, "InputSampleFreq"),
+    (DXVA2_Frequency, "OutputFrameFreq"),
+    (UINT, "UABProtectionLevel"),
+    (UINT, "Reserved"),
+])
+
+DXVA2_VideoProcessBltParams = Struct("DXVA2_VideoProcessBltParams", [
+    (REFERENCE_TIME, "TargetFrame"),
+    (RECT, "TargetRect"),
+    (SIZE, "ConstrictionSize"),
+    (UINT, "StreamingFlags"),
+    (DXVA2_AYUVSample16, "BackgroundColor"),
+    (DXVA2_ExtendedFormat, "DestFormat"),
+    (DXVA2_ProcAmpValues, "ProcAmpValues"),
+    (DXVA2_Fixed32, "Alpha"),
+    (DXVA2_FilterValues, "NoiseFilterLuma"),
+    (DXVA2_FilterValues, "NoiseFilterChroma"),
+    (DXVA2_FilterValues, "DetailFilterLuma"),
+    (DXVA2_FilterValues, "DetailFilterChroma"),
+    (DWORD, "DestData"),
+])
+
+DXVA2_VideoProcessorCaps = Struct("DXVA2_VideoProcessorCaps", [
+    (UINT, "DeviceCaps"),
+    (D3DPOOL, "InputPool"),
+    (UINT, "NumForwardRefSamples"),
+    (UINT, "NumBackwardRefSamples"),
+    (UINT, "Reserved"),
+    (UINT, "DeinterlaceTechnology"),
+    (UINT, "ProcAmpControlCaps"),
+    (UINT, "VideoProcessorOperations"),
+    (UINT, "NoiseFilterTechnology"),
+    (UINT, "DetailFilterTechnology"),
+])
+
+
+DXVA2_PVP_SETKEY = Opaque('DXVA2_PVP_SETKEY')
+
+DXVA2_DECODEBUFFERDESC = Struct("DXVA2_DECODEBUFFERDESC", [
+    (ObjPointer(IDirect3DSurface9), "pRenderTarget"),
+    (DWORD, "CompressedBufferType"),
+    (DWORD, "BufferIndex"),
+    (DWORD, "DataOffset"),
+    (DWORD, "DataSize"),
+    (DWORD, "FirstMBaddress"),
+    (DWORD, "NumMBsInBuffer"),
+    (DWORD, "Width"),
+    (DWORD, "Height"),
+    (DWORD, "Stride"),
+    (DWORD, "ReservedBits"),
+    (PVOID, "pCipherCounter"),
+])
+
+DXVA2_DECODEEXECUTE = Struct("DXVA2_DECODEEXECUTE", [
+    (UINT, "NumCompBuffers"),
+    (Array(DXVA2_DECODEBUFFERDESC, "{self}.NumCompBuffers"), "pCompressedBuffers"),
+])
+
+DXVA2_VIDEOSAMPLE = Struct("DXVA2_VIDEOSAMPLE", [
+    (REFERENCE_TIME, "Start"),
+    (REFERENCE_TIME, "End"),
+    (DXVA2_ExtendedFormat, "SampleFormat"),
+    (DWORD, "SampleFlags"),
+    (ObjPointer(IDirect3DSurface9), "SrcSurface"),
+    (RECT, "SrcRect"),
+    (RECT, "DstRect"),
+    #(Array(DXVA2_AYUVSample8, 16), "Pal"),
+    (DXVA2_Fixed32, "PlanarAlpha"),
+])
+
+DXVA2_VIDEOPROCESSBLT = Struct("DXVA2_VIDEOPROCESSBLT", [
+    (REFERENCE_TIME, "TargetFrame"),
+    (RECT, "TargetRect"),
+    (SIZE, "ConstrictionSize"),
+    (DWORD, "StreamingFlags"),
+    (DXVA2_AYUVSample16, "BackgroundColor"),
+    (DXVA2_ExtendedFormat, "DestFormat"),
+    (DWORD, "DestFlags"),
+    (DXVA2_ProcAmpValues, "ProcAmpValues"),
+    (DXVA2_Fixed32, "Alpha"),
+    (DXVA2_FilterValues, "NoiseFilterLuma"),
+    (DXVA2_FilterValues, "NoiseFilterChroma"),
+    (DXVA2_FilterValues, "DetailFilterLuma"),
+    (DXVA2_FilterValues, "DetailFilterChroma"),
+    (Array(DXVA2_VIDEOSAMPLE, "{self}.NumSrcSurfaces"), "pSrcSurfaces"),
+    (UINT, "NumSrcSurfaces"),
+])
+
+DXVA2_EXTENSIONEXECUTE = Opaque('DXVA2_EXTENSIONEXECUTE')
+DXVA2_DECODEBUFFERINFO = Opaque('DXVA2_DECODEBUFFERINFO')
+
+
+IDirect3DDecodeDevice9 = Interface("IDirect3DDecodeDevice9", IUnknown)
+IDirect3DDecodeDevice9.methods += [
+    Method(HRESULT, "DecodeBeginFrame", [(OpaquePointer(DXVA2_PVP_SETKEY), "pPVPSetKey")]),
+    Method(HRESULT, "DecodeEndFrame", [(Pointer(HANDLE), "pHandleComplete")]),
+    Method(HRESULT, "DecodeSetRenderTarget", [(ObjPointer(IDirect3DSurface9), "pRenderTarget")]),
+    Method(HRESULT, "DecodeExecute", [(Pointer(DXVA2_DECODEEXECUTE), "pExecuteParams")]),
+]
+
+IDirect3DVideoProcessDevice9 = Interface("IDirect3DVideoProcessDevice9", IUnknown)
+IDirect3DVideoProcessDevice9.methods += [
+    Method(HRESULT, "VideoProcessBeginFrame", []),
+    Method(HRESULT, "VideoProcessEndFrame", [(Pointer(HANDLE), "pHandleComplete")]),
+    Method(HRESULT, "VideoProcessSetRenderTarget", [(ObjPointer(IDirect3DSurface9), "pRenderTarget")]),
+    Method(HRESULT, "VideoProcessBlt", [(Pointer(DXVA2_VIDEOPROCESSBLT), "pData")]),
+]
+
+IDirect3DDXVAExtensionDevice9 = Interface("IDirect3DDXVAExtensionDevice9", IUnknown)
+IDirect3DDXVAExtensionDevice9.methods += [
+    Method(HRESULT, "ExtensionExecute", [(OpaquePointer(DXVA2_EXTENSIONEXECUTE), "pData")]),
+]
+
+IDirect3DDxva2Container9 = Interface("IDirect3DDxva2Container9", IUnknown)
+IDirect3DDxva2Container9.methods += [
+    Method(HRESULT, "CreateSurface", [(UINT, "Width"), (UINT, "Height"), (UINT, "BackBuffers"), (D3DFORMAT, "Format"), (D3DPOOL, "Pool"), (DWORD, "Usage"), (DXVA2_SurfaceType, "DxvaType"), Out(Array(ObjPointer(IDirect3DSurface9), "1 + BackBuffers"), "ppSurface"), (Pointer(HANDLE), "pSharedHandle")]),
+    Method(HRESULT, "VidToSysBlt", [(ObjPointer(IDirect3DSurface9), "pSourceSurface"), (Pointer(RECT), "pSourceRect"), (ObjPointer(IDirect3DSurface9), "pDestSurface"), (Pointer(RECT), "pDestRect")]),
+    Method(HRESULT, "GetDecodeGuidCount", [Out(Pointer(UINT), "pCount")], sideeffects=False),
+    Method(HRESULT, "GetDecodeGuids", [(UINT, "Count"), Out(Array(GUID, "Count"), "pGuids")], sideeffects=False),
+    Method(HRESULT, "GetDecodeRenderTargetFormatCount", [(REFGUID, "Guid"), Out(Pointer(UINT), "pCount")], sideeffects=False),
+    Method(HRESULT, "GetDecodeRenderTargets", [(REFGUID, "Guid"), (UINT, "Count"), Out(Array(D3DFORMAT, "Count"), "pFormats")], sideeffects=False),
+    Method(HRESULT, "GetDecodeCompressedBufferCount", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), Out(Pointer(UINT), "pCount")], sideeffects=False),
+    Method(HRESULT, "GetDecodeCompressedBuffers", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (UINT, "Count"), Out(OpaquePointer(DXVA2_DECODEBUFFERINFO), "pBufferInfo")], sideeffects=False),
+    Method(HRESULT, "GetDecodeConfigurationCount", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), Out(Pointer(UINT), "pCount")], sideeffects=False),
+    Method(HRESULT, "GetDecodeConfigurations", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (UINT, "Count"), Out(Array(DXVA2_ConfigPictureDecode, "Count"), "pConfigs")], sideeffects=False),
+    Method(HRESULT, "CreateDecodeDevice", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (Pointer(Const(DXVA2_ConfigPictureDecode)), "pConfig"), (Array(ObjPointer(IDirect3DSurface9), "NumSurfaces"), "ppDecoderRenderTargets"), (UINT, "NumSurfaces"), Out(Pointer(ObjPointer(IDirect3DDecodeDevice9)), "ppDecode")]),
+    Method(HRESULT, "GetVideoProcessorDeviceGuidCount", [(Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), Out(Pointer(UINT), "pCount")], sideeffects=False),
+    Method(HRESULT, "GetVideoProcessorDeviceGuids", [(Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (UINT, "Count"), Out(Pointer(GUID), "pGuids")], sideeffects=False),
+    Method(HRESULT, "GetVideoProcessorCaps", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (D3DFORMAT, "Format"), Out(Pointer(DXVA2_VideoProcessorCaps), "pCaps")], sideeffects=False),
+    Method(HRESULT, "GetProcAmpRange", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (D3DFORMAT, "Format"), (UINT, "ProcAmpCap"), Out(Pointer(DXVA2_ValueRange), "pRange")]),
+    Method(HRESULT, "GetFilterPropertyRange", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (D3DFORMAT, "Format"), (UINT, "FilterSetting"), Out(Pointer(DXVA2_ValueRange), "pRange")], sideeffects=False),
+    Method(HRESULT, "GetVideoProcessorRenderTargetCount", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), Out(Pointer(UINT), "pCount")], sideeffects=False),
+    Method(HRESULT, "GetVideoProcessorRenderTargets", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (UINT, "Count"), Out(Array(D3DFORMAT, "Count"), "pFormats")], sideeffects=False),
+    Method(HRESULT, "GetVideoProcessorSubStreamFormatCount", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (D3DFORMAT, "Format"), Out(Pointer(UINT), "pCount")], sideeffects=False),
+    Method(HRESULT, "GetVideoProcessorSubStreamFormats", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (D3DFORMAT, "Format"), (UINT, "Count"), Out(Array(D3DFORMAT, "Count"), "pFormats")], sideeffects=False),
+    Method(HRESULT, "CreateVideoProcessDevice", [(REFGUID, "Guid"), (Pointer(Const(DXVA2_VideoDesc)), "pVideoDesc"), (D3DFORMAT, "Format"), (UINT, "MaxSubStreams"), Out(Pointer(ObjPointer(IDirect3DVideoProcessDevice9)), "ppVideoProcessDevice")]),
+    Method(HRESULT, "GetExtensionGuidCount", [(DWORD, "Extension"), Out(Pointer(UINT), "pCount")], sideeffects=False),
+    Method(HRESULT, "GetExtensionGuids", [(DWORD, "Extension"), (UINT, "Count"), Out(Array(GUID, "Count"), "pGuids")], sideeffects=False),
+    Method(HRESULT, "GetExtensionCaps", [(REFGUID, "Guid"), (UINT, "arg2"), (OpaquePointer(Void), "arg3"), (UINT, "arg4"), (OpaquePointer(Void), "arg5"), (UINT, "arg6")], sideeffects=False),
+    Method(HRESULT, "CreateExtensionDevice", [(REFGUID, "Guid"), (OpaquePointer(Void), "arg2"), (UINT, "arg3"), Out(Pointer(ObjPointer(IDirect3DDXVAExtensionDevice9)), "ppExtension")]),
+]
+
+d3d9.addInterfaces([
+    IDirect3DDxva2Container9,
+])
index 5c7925e4427d62eec7a6a54f35e4453bfe9cbaff..45af484d138637763ed89d967991666cad32adf3 100644 (file)
@@ -284,6 +284,6 @@ IDXGIDevice1.methods += [
 
 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")]),
 ])
index fa7e91e9900bb50bfcc134217da1ab5602e3098d..3db0739dc3767b5608e350ac00007affcbea6dc9 100644 (file)
@@ -376,7 +376,7 @@ glapi.addFunctions([
 
     # 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")]),
@@ -515,7 +515,7 @@ glapi.addFunctions([
     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")]),
@@ -647,7 +647,7 @@ glapi.addFunctions([
     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")]),
@@ -870,7 +870,7 @@ glapi.addFunctions([
     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")]),
@@ -1526,7 +1526,7 @@ glapi.addFunctions([
 
     # 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),
@@ -1664,7 +1664,7 @@ glapi.addFunctions([
     # 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
@@ -1690,7 +1690,7 @@ glapi.addFunctions([
     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")]),
@@ -1858,8 +1858,8 @@ glapi.addFunctions([
     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")]),
@@ -1881,13 +1881,13 @@ glapi.addFunctions([
     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")]),
@@ -1929,7 +1929,7 @@ glapi.addFunctions([
     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")]),
@@ -2133,20 +2133,20 @@ glapi.addFunctions([
     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")]),
index 98d4ee6f392a4f04d7615f7e95eb6faedeb7aba6..3be99a89bebc9cf45513bf8817d8ede604ced25b 100644 (file)
@@ -2115,7 +2115,7 @@ parameters = [
     ("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
index 45231b244cf29304bbf4592413af93b3f6e91be0..23af3279e54f2e51a33e8ebba9ad6166131a7d36 100644 (file)
@@ -100,15 +100,19 @@ GLshader = Handle("shader", GLuint)
 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.
 #
@@ -229,3 +233,7 @@ GLbitfield_barrier = Flags(GLbitfield, [
     "GL_ATOMIC_COUNTER_BARRIER_BIT",            # 0x00001000
 ])
 
+# GL_ARB_vertex_array_bgra
+size_bgra = FakeEnum(GLint, [
+    "GL_BGRA",
+])
index 85699ead83c0b1a74904c2f8b240800f40149d38..157752719c87c5692e2f98c5dcd44e268dd67278 100644 (file)
@@ -270,9 +270,9 @@ glxapi.addFunctions([
     Function(Void, "glXUseXFont", [(Font, "font"), (Int, "first"), (Int, "count"), (Int, "list")]),
 
     # GLX 1.1 and later
-    Function((ConstCString), "glXQueryExtensionsString", [(Display, "dpy"), (Int, "screen")]),
-    Function((ConstCString), "glXQueryServerString",  [(Display, "dpy"), (Int, "screen"), (GLXname, "name")]),
-    Function((ConstCString), "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),
@@ -385,7 +385,7 @@ glxapi.addFunctions([
 
     # 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")]),
index cde94cb6fa522a583f0deb31edce660901d6c9cb..8a5a5a7fa5b647f3e45a29fbe3c06db114d87b6c 100644 (file)
@@ -129,6 +129,8 @@ 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):
 
diff --git a/thirdparty/qjson/.gitignore b/thirdparty/qjson/.gitignore
new file mode 100644 (file)
index 0000000..b2b8eb2
--- /dev/null
@@ -0,0 +1 @@
+moc_*.cxx
index 14bda2c2dcf2b5cd197c1bd328dd5890c5614e8a..512efc83ef33629a5a7cc9bdf4fb96f68fa260fc 100644 (file)
@@ -1,4 +1,8 @@
-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)
 
@@ -8,11 +12,19 @@ include_directories (${CMAKE_CURRENT_BINARY_DIR})
 
 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})
diff --git a/thirdparty/qjson/COPYING b/thirdparty/qjson/COPYING
deleted file mode 100644 (file)
index 5ab7695..0000000
+++ /dev/null
@@ -1,504 +0,0 @@
-                 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!
-
-
diff --git a/thirdparty/qjson/COPYING.lib b/thirdparty/qjson/COPYING.lib
new file mode 100644 (file)
index 0000000..08f25cd
--- /dev/null
@@ -0,0 +1,504 @@
+                 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!
+
+
index 9e7b037c9d1bdea24e74afa27ea7a6ec9ccda5b3..fe4853de1f7ef3e6c80d24e020c47bc9989afde0 100644 (file)
@@ -1,6 +1,5 @@
-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
 
@@ -13,8 +12,8 @@ Install
 
 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
 -----------
index a99be6c6f2d07ccfd8180a64194b4540beea48cb..620e135a85bb50ed23d56fdf31249ec387f2293e 100644 (file)
@@ -42,7 +42,7 @@
 #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)
@@ -384,7 +384,7 @@ namespace yy
     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";
@@ -392,36 +392,31 @@ namespace yy
     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
@@ -429,13 +424,13 @@ namespace yy
           ;}
     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
@@ -443,8 +438,8 @@ namespace yy
           ;}
     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)])));
@@ -452,18 +447,18 @@ namespace yy
           ;}
     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
@@ -472,13 +467,13 @@ namespace yy
         ;}
     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
@@ -487,46 +482,61 @@ namespace yy
           ;}
     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);
@@ -539,8 +549,8 @@ namespace yy
           ;}
     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);
@@ -548,65 +558,65 @@ namespace yy
           ;}
     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)]);
               ;}
@@ -614,7 +624,7 @@ namespace yy
 
 
     /* Line 675 of lalr1.cc.  */
-#line 618 "json_parser.cc"
+#line 628 "json_parser.cc"
        default: break;
       }
     YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc);
@@ -821,16 +831,16 @@ namespace yy
 
   /* 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
@@ -839,28 +849,28 @@ namespace yy
   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
@@ -870,20 +880,24 @@ namespace yy
   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
@@ -891,12 +905,12 @@ namespace yy
   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
@@ -906,7 +920,8 @@ namespace yy
   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
 
@@ -914,20 +929,22 @@ namespace yy
   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
@@ -940,9 +957,10 @@ namespace yy
   "\"]\"", "\":\"", "\",\"", "\"-\"", "\".\"", "\"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
 
@@ -951,16 +969,16 @@ namespace yy
   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
@@ -968,20 +986,22 @@ namespace yy
   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.
@@ -1022,7 +1042,7 @@ namespace yy
     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,
@@ -1055,20 +1075,20 @@ namespace yy
   }
 
   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)
index 673923d9e385be51813417b509705889d63ee992..e61ca7c644c6434670257ca6f013bdec1162cab3 100644 (file)
@@ -59,6 +59,8 @@ namespace yy
   #include <QtCore/QString>
   #include <QtCore/QVariant>
 
+  #include <limits>
+
   class JSonScanner;
 
   namespace QJson {
@@ -68,8 +70,8 @@ namespace yy
   #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"
 
@@ -146,7 +148,9 @@ namespace yy
      NULL_VAL = 13,
      QUOTMARKOPEN = 14,
      QUOTMARKCLOSE = 15,
-     STRING = 16
+     STRING = 16,
+     INFINITY_VAL = 17,
+     NAN_VAL = 18
    };
 
     };
@@ -241,7 +245,7 @@ namespace yy
     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_[];
index ad8e105b73c4488ebd99209ae638ddeb1f56b7ca..2540889bae2647c133bc5daac766262ac83eba3c 100644 (file)
@@ -3,16 +3,16 @@
   * 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.
@@ -32,6 +32,8 @@
   #include <QtCore/QString>
   #include <QtCore/QVariant>
 
+  #include <limits>
+
   class JSonScanner;
 
   namespace QJson {
@@ -69,6 +71,8 @@
 %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
@@ -82,12 +86,11 @@ start: data {
               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;
@@ -133,7 +136,7 @@ r_values: /* empty */ { $$ = QVariant (QVariantList()); }
           };
 
 value: string { $$ = $1; }
-        | number { $$ = $1; }
+        | special_or_number { $$ = $1; }
         | object { $$ = $1; }
         | array { $$ = $1; }
         | TRUE_VAL { $$ = QVariant (true); }
@@ -143,6 +146,11 @@ value: string { $$ = $1; }
           $$ = 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);
index 7f7b88fa0a74fe75c41a3af29d5cfb221e2517f1..de0ddc23c53c94cfd1122c8f7248b5a30b0dedb3 100644 (file)
@@ -3,16 +3,16 @@
  * 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.
@@ -38,12 +38,17 @@ bool ishexnstring(const QString& string) {
 }
 
 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;
@@ -125,7 +130,7 @@ static QString unescape( const QByteArray& ba, bool* ok ) {
 int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc)
 {
   char ch;
-  
+
   if (!m_io->isOpen()) {
     qCritical() << "JSonScanner::yylex - io device is not open";
     return -1;
@@ -148,32 +153,34 @@ int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc)
     }
 
     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'))) {
@@ -193,14 +200,24 @@ int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc)
     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;
@@ -259,7 +276,38 @@ int JSonScanner::yylex(YYSTYPE* yylval, yy::location *yylloc)
     }
   }
   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;
   }
index 593426b9636a32db62216c7c140283e4dde383d9..f13e565f5845b1eaa21e8af2d77d306269c11780 100644 (file)
@@ -3,16 +3,16 @@
  * 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.
@@ -41,9 +41,11 @@ class JSonScanner
     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;
 };
index 3096d177a378b16e55bf78deb6e3c2bdc941a025..e203b876f76bef989f8b551ac5f11ed6be5fb161 100644 (file)
@@ -3,16 +3,16 @@
  * 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.
@@ -34,6 +34,8 @@ ParserPrivate::ParserPrivate() :
     m_scanner(0)
   , m_negate(false)
   , m_error(false)
+  , m_errorLine(0)
+  , m_specialNumbersAllowed(false)
 {
 }
 
@@ -82,6 +84,7 @@ QVariant Parser::parse (QIODevice* io, bool* ok)
   }
 
   d->m_scanner = new JSonScanner (io);
+  d->m_scanner->allowSpecialNumbers(d->m_specialNumbersAllowed);
   yy::json_parser parser(d);
   parser.parse();
 
@@ -112,3 +115,11 @@ int Parser::errorLine() const
 {
   return d->m_errorLine;
 }
+
+void QJson::Parser::allowSpecialNumbers(bool allowSpecialNumbers) {
+  d->m_specialNumbersAllowed = allowSpecialNumbers;
+}
+
+bool Parser::specialNumbersAllowed() const {
+  return d->m_specialNumbersAllowed;
+}
index 8d323cd4d5ece52e06f06fc0cbae8348c5c5e57b..6fb58d89f24cce4907349bbb73a068887beffae0 100644 (file)
@@ -3,16 +3,16 @@
  * 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.
@@ -71,6 +71,20 @@ namespace QJson {
       */
       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;
index e12b565721c7ae1c32e195b3937e59c3b231e6a4..aae86a124c9c92e35c1b2e0fcfcc21874fcb470a 100644 (file)
@@ -4,16 +4,16 @@
  * 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.
@@ -49,6 +49,7 @@ namespace QJson {
       int m_errorLine;
       QString m_errorMsg;
       QVariant m_result;
+      bool m_specialNumbersAllowed;
   };
 }
 
index d09423e4cbb6c1ab5a7ea697062dedc4ffabc10e..88baf4cf68e24ac3f7ab3385a6e199fdcc660f85 100644 (file)
@@ -3,16 +3,16 @@
   * 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.
@@ -61,7 +61,7 @@ void ParserRunnable::run()
     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);
   }
index 822e1fdba8f047a1ac78c05eeea7bcea57d92f1e..2badeb64b74635c5b4cf4a21d80e63c360a85ca7 100644 (file)
@@ -3,16 +3,16 @@
   * 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.
index 5ae1da3a771f82f1ba8317a8425d7544fc7fdfa5..0a511aeef08f29e03598d5f30f8e72375a09dc84 100644 (file)
@@ -3,16 +3,16 @@
   * 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.
index 67355f5fae125bbbdef19935f93e35e07d67e50b..9a807b91b282ded6dfd62930e976b3ec918d1007 100644 (file)
@@ -2,16 +2,16 @@
     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
index 8bba181b706774dc2b23d0bf56c0db3df3ddfdbe..b756488f07773dbe0fe2b7859a68c07ab1d4cdcc 100644 (file)
@@ -4,16 +4,16 @@
   * 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.
@@ -62,20 +62,24 @@ QVariantMap QObjectHelper::qobject2qvariant( const QObject* object,
 
 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 );
     }
   }
 }
index 7bf6b03570e581db4f05eb778c06d9c55d080c58..514ca1fa1b4b7f09b9688a173e09bbd2fb2b13e1 100644 (file)
@@ -3,16 +3,16 @@
   * 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.
@@ -34,6 +34,7 @@ namespace QJson {
   * @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
index f012246d43f1cded564751922bdb29253928ff13..41407c2745940b7580b31b221a34f2d505fc9b47 100644 (file)
@@ -4,16 +4,16 @@
   * 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() )
@@ -89,48 +59,141 @@ static QByteArray join( const QList<QByteArray>& list, const QByteArray& sep ) {
   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" );
@@ -146,7 +209,114 @@ QByteArray Serializer::serialize( const QVariant &v )
     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;
+}
index fd301b21c052a4df8c8eaa4b7d97a8d3b3097aad..66b349cf7e5ac226f7a33d369c43328c1439aee5 100644 (file)
@@ -3,16 +3,16 @@
   * 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.
@@ -28,6 +28,42 @@ class QString;
 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.
   *
@@ -47,7 +83,7 @@ namespace QJson {
       * @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
@@ -59,7 +95,34 @@ namespace QJson {
       * 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)
index 2e57c4517e05ea3934c54dda8f78f2548df5907f..9ebf68b7225f952ad9fbe531530ea708c1988973 100644 (file)
@@ -6,16 +6,16 @@
  *               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.
index c6b5fe1175d4ffb23a6c25edb05fd385239b9ca6..d665fc5138f15a60770e2ab743aafeef9da906ba 100644 (file)
@@ -3,16 +3,16 @@
  * 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.
index 38fd57f7c4b28767e7889bd76e8d8ee1ddec0cff..cc5f074b65f5017f7ec6a52e5d9304c5d3c128a6 100644 (file)
@@ -1,3 +1,4 @@
+OpenGL
 cgltrace.cpp
 d2d1trace.cpp
 d3d10_1trace.cpp
index cc817d51399f0262896b0ceac2ba2b5ef0721c9c..01cbdea4ac42af18c4d86d8cf011414b019bcb55 100644 (file)
@@ -101,6 +101,7 @@ if (WIN32)
                 ${CMAKE_SOURCE_DIR}/specs/d3d9.py
                 ${CMAKE_SOURCE_DIR}/specs/d3d9types.py
                 ${CMAKE_SOURCE_DIR}/specs/d3d9caps.py
+                ${CMAKE_SOURCE_DIR}/specs/d3d9dxva2.py
                 ${CMAKE_SOURCE_DIR}/specs/winapi.py
                 ${CMAKE_SOURCE_DIR}/specs/stdapi.py
         )
@@ -126,6 +127,7 @@ if (WIN32)
             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
@@ -163,6 +165,7 @@ if (WIN32)
             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
@@ -176,7 +179,7 @@ if (WIN32)
                 ${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
@@ -413,7 +416,6 @@ elseif (X11_FOUND)
         common
         ${ZLIB_LIBRARIES}
         ${SNAPPY_LIBRARIES}
-        ${X11_X11_LIB}
         ${CMAKE_THREAD_LIBS_INIT}
         dl
     )
index 485ec32b672d536b94253313ff5f74c24d73f3c0..d2f72a773c046b71ddd86e06262c7c461105b60c 100644 (file)
@@ -24,7 +24,7 @@
 ##########################################################################/
 
 
-from dlltrace import DllTracer
+from d3dcommontrace import D3DCommonTracer
 from specs.d3d10_1 import d3d10_1
 
 
@@ -35,6 +35,8 @@ if __name__ == '__main__':
     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)
index d43f042b08f2a8e6efa1328f045b524f24cc88ac..adb5dae207c94a0d6eef6554b67585ae0f6eee29 100644 (file)
 ##########################################################################/
 
 
-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
@@ -47,6 +36,7 @@ if __name__ == '__main__':
     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)
index f44cad385203612d0b229bb6dfce1033b52daccf..b2a39f6604969d3dff5d9f347ef52e8632a5fd64 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "d3d9shader.hpp"
 #include "d3d9imports.hpp"
-#include "d3dsize.hpp"
+#include "d3d9size.hpp"
 
 
 typedef HRESULT
index 6ee059fa3d9f039f28decaec1ec5e15da8554fde..fc6e65ef2ae86982df2f74f340aea5dfda51e799 100644 (file)
@@ -27,6 +27,8 @@
 from dlltrace import DllTracer
 from specs.d3d9 import d3d9, D3DSHADER9
 
+import specs.d3d9dxva2
+
 
 class D3D9Tracer(DllTracer):
 
@@ -41,6 +43,7 @@ class D3D9Tracer(DllTracer):
     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:
@@ -76,8 +79,9 @@ if __name__ == '__main__':
     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
     print '''
 static inline size_t
diff --git a/wrappers/d3dcommontrace.py b/wrappers/d3dcommontrace.py
new file mode 100644 (file)
index 0000000..e0927cc
--- /dev/null
@@ -0,0 +1,70 @@
+##########################################################################
+#
+# 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 '    }'
+
+
index db824bb315ffd5f1044b3752104b83e7de466fac..04c64b6afc0623ad690cbeb80ced17d3687de53f 100644 (file)
 #define _GLTRACE_HPP_
 
 
+#include <string.h>
+#include <stdlib.h>
+#include <map>
+
 #include "glimports.hpp"
 
 
@@ -39,6 +43,52 @@ enum Profile {
     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;
@@ -47,6 +97,9 @@ public:
     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),
@@ -54,6 +107,12 @@ public:
         user_arrays_nv(false),
         retain_count(0)
     { }
+
+    inline bool
+    needsShadowBuffers(void)
+    {
+        return profile == PROFILE_ES1 || profile == PROFILE_ES2;
+    }
 };
 
 void
index 411a19b16a630c71deec2cc6581e94f9c6eebe4d..96da4e85c576e25af119696f9c849ae2ecbb3724 100644 (file)
@@ -141,6 +141,8 @@ class GlTracer(Tracer):
         print '}'
         print
 
+        self.defineShadowBufferHelper()
+
         # Whether we need user arrays
         print 'static inline bool _need_user_arrays(void)'
         print '{'
@@ -349,6 +351,52 @@ class GlTracer(Tracer):
         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",
@@ -557,6 +605,7 @@ class GlTracer(Tracer):
             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':
@@ -632,6 +681,8 @@ class GlTracer(Tracer):
             print '        }'
             print '    }'
 
+        self.shadowBufferProlog(function)
+
         Tracer.traceFunctionImplBody(self, function)
 
     marker_functions = [
index cb8e08b1accce6b7818a55528f74809f7da1cd53..68bda100354db46025c678618d3d66f2a9d6749e 100644 (file)
@@ -57,15 +57,13 @@ public:
     }
 };
 
-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;
@@ -115,12 +113,17 @@ bool releaseContext(uintptr_t context_id)
 
 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();
index 4e52cf652a661fab24931ec65508280e3d84f91e..4563f454f710822887ad9bd5eaa4de5606db7d4f 100644 (file)
@@ -39,6 +39,45 @@ def getWrapperInterfaceName(interface):
     return "Wrap" + interface.expr
 
 
+
+class ExpanderMixin:
+    '''Mixin class that provides a bunch of methods to expand C expressions
+    from the specifications.'''
+
+    __structs = None
+    __indices = None
+
+    def expand(self, expr):
+        # Expand a C expression, replacing certain variables
+        if not isinstance(expr, basestring):
+            return expr
+        variables = {}
+
+        if self.__structs is not None:
+            variables['self'] = '(%s)' % self.__structs[0]
+        if self.__indices is not None:
+            variables['i'] = self.__indices[0]
+
+        expandedExpr = expr.format(**variables)
+        if expandedExpr != expr and 0:
+            sys.stderr.write("  %r -> %r\n" % (expr, expandedExpr))
+        return expandedExpr
+
+    def visitMember(self, structInstance, member_type, *args, **kwargs):
+        self.__structs = (structInstance, self.__structs)
+        try:
+            return self.visit(member_type, *args, **kwargs)
+        finally:
+            _, self.__structs = self.__structs
+
+    def visitElement(self, element_index, element_type, *args, **kwargs):
+        self.__indices = (element_index, self.__indices)
+        try:
+            return self.visit(element_type, *args, **kwargs)
+        finally:
+            _, self.__indices = self.__indices
+
+
 class ComplexValueSerializer(stdapi.OnceVisitor):
     '''Type visitors which generates serialization functions for
     complex types.
@@ -63,21 +102,13 @@ class ComplexValueSerializer(stdapi.OnceVisitor):
         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):
@@ -150,7 +181,7 @@ class ComplexValueSerializer(stdapi.OnceVisitor):
         print
 
 
-class ValueSerializer(stdapi.Visitor):
+class ValueSerializer(stdapi.Visitor, ExpanderMixin):
     '''Visitor which generates code to serialize any type.
     
     Simple types are serialized inline here, whereas the serialization of
@@ -158,6 +189,11 @@ class ValueSerializer(stdapi.Visitor):
     ComplexValueSerializer visitor above.
     '''
 
+    def __init__(self):
+        #stdapi.Visitor.__init__(self)
+        self.indices = []
+        self.instances = []
+
     def visitLiteral(self, literal, instance):
         print '    trace::localWriter.write%s(%s);' % (literal.kind, instance)
 
@@ -181,17 +217,21 @@ class ValueSerializer(stdapi.Visitor):
         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,)
+        for type, name in struct.members:
+            self.visitMember(instance, type, '(%s).%s' % (instance, name,))
+        print '    trace::localWriter.endStruct();'
 
     def visitArray(self, array, instance):
         length = '_c' + array.type.tag
         index = '_i' + array.type.tag
+        array_length = self.expand(array.length)
         print '    if (%s) {' % instance
-        print '        size_t %s = %s > 0 ? %s : 0;' % (length, array.length, array.length)
+        print '        size_t %s = %s > 0 ? %s : 0;' % (length, array_length, array_length)
         print '        trace::localWriter.beginArray(%s);' % length
         print '        for (size_t %s = 0; %s < %s; ++%s) {' % (index, index, length, index)
         print '            trace::localWriter.beginElement();'
-        self.visit(array.type, '(%s)[%s]' % (instance, index))
+        self.visitElement(index, array.type, '(%s)[%s]' % (instance, index))
         print '            trace::localWriter.endElement();'
         print '        }'
         print '        trace::localWriter.endArray();'
@@ -200,7 +240,7 @@ class ValueSerializer(stdapi.Visitor):
         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)
@@ -272,7 +312,7 @@ class WrapDecider(stdapi.Traverser):
         self.needsWrapping = True
 
 
-class ValueWrapper(stdapi.Traverser):
+class ValueWrapper(stdapi.Traverser, ExpanderMixin):
     '''Type visitor which will generate the code to wrap an instance.
     
     Wrapping is necessary mostly for interfaces, however interface pointers can
@@ -281,12 +321,13 @@ class ValueWrapper(stdapi.Traverser):
 
     def visitStruct(self, struct, instance):
         for type, name in struct.members:
-            self.visit(type, "(%s).%s" % (instance, name))
+            self.visitMember(instance, type, "(%s).%s" % (instance, name))
 
     def visitArray(self, array, instance):
+        array_length = self.expand(array.length)
         print "    if (%s) {" % instance
-        print "        for (size_t _i = 0, _s = %s; _i < _s; ++_i) {" % array.length
-        self.visit(array.type, instance + "[_i]")
+        print "        for (size_t _i = 0, _s = %s; _i < _s; ++_i) {" % array_length
+        self.visitElement('_i', array.type, instance + "[_i]")
         print "        }"
         print "    }"
 
@@ -342,10 +383,11 @@ class ValueUnwrapper(ValueWrapper):
     def visitArray(self, array, instance):
         if self.allocated or isinstance(instance, stdapi.Interface):
             return ValueWrapper.visitArray(self, array, instance)
+        array_length = self.expand(array.length)
         elem_type = array.type.mutable()
-        print "    if (%s && %s) {" % (instance, array.length)
-        print "        %s * _t = static_cast<%s *>(alloca(%s * sizeof *_t));" % (elem_type, elem_type, array.length)
-        print "        for (size_t _i = 0, _s = %s; _i < _s; ++_i) {" % array.length
+        print "    if (%s && %s) {" % (instance, array_length)
+        print "        %s * _t = static_cast<%s *>(alloca(%s * sizeof *_t));" % (elem_type, elem_type, array_length)
+        print "        for (size_t _i = 0, _s = %s; _i < _s; ++_i) {" % array_length
         print "            _t[_i] = %s[_i];" % instance 
         self.allocated = True
         self.visit(array.type, "_t[_i]")