]> git.cworth.org Git - apitrace/commitdiff
Merge commit '5c298db8fe117e0a445af051335aa0da91c3a31b'
authorJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 12 Jul 2012 12:44:59 +0000 (13:44 +0100)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Thu, 12 Jul 2012 12:44:59 +0000 (13:44 +0100)
13 files changed:
README.markdown
gui/imageviewer.cpp
gui/retracer.cpp
gui/saverthread.cpp
gui/ui/imageviewer.ui
retrace/d3dretrace.py
retrace/glretrace.py
specs/d3d9.py
wrappers/.gitignore
wrappers/CMakeLists.txt
wrappers/trace.cpp [new file with mode: 0644]
wrappers/trace.hpp [new file with mode: 0644]
wrappers/trace.py

index d5c4aedb148623e82c2792e4807c13d0c35213d9..9702ba0739294d14c41c8c7eb1264c3491d1391a 100644 (file)
@@ -141,6 +141,67 @@ To trace the application inside gdb, invoke gdb as:
 
     gdb --ex 'set exec-wrapper env LD_PRELOAD=/path/to/glxtrace.so' --args /path/to/application
 
+### Android ###
+
+The following instructions should work at least for Android Ice Scream
+Sandwitch:
+
+For standalone applications the instructions above for Linux should
+work. To trace applications started from within the Android VM process
+(app_process aka zygote) you'll have to wrap this process and enable
+tracing dynamically for the application to be traced.
+
+- Wrapping the android main VM process:
+
+  In the Android root /init.rc add the LD_PRELOAD setting to zygote's
+  environment in the 'service zygote' section:
+
+  """
+  service zygote ...
+     setenv LD_PRELOAD /data/egltrace.so
+     ...
+  """
+
+  Note that ICS will overwrite the /init.rc during each boot with the
+  version in the recovery image. So you'll have to change the file in
+  your ICS source tree, rebuild and reflash the device.
+  Rebuilding/reflashing only the recovery image should be sufficient.
+
+
+- Copy egltrace.so to /data
+
+  On the host:
+  $ adb push /path/to/apitrace/build/wrappers/egltrace.so /data
+
+
+- Adjust file permissions to store the trace file:
+
+  By default egltrace.so will store the trace in
+  /data/app_process.trace. For this to work for applications running
+  with a uid other than 0, you have to allow writes to the /data
+  directory on the device:
+
+  # chmod 0777 /data
+
+
+- Enable tracing for a specific process name:
+
+  To trace for example the Settings application:
+  # setprop debug.apitrace.procname com.android.settings
+
+  In general this name will match what 'ps' reports.
+
+
+- Start the application:
+
+  If the application was already running, for example due to ICS's way
+  of pre-starting the apps, you might have to kill the application
+  first:
+
+  # kill <pid of app>
+
+  Launch the application for example from the application menu.
+
 ### Mac OS X ###
 
 Run the application you want to trace as
index 7b1e425f3e64ef2438d7d9c8e43ea5fbb6189e75..0e0657a3d60e265cd5d20c85815e69f881933e21 100644 (file)
@@ -19,6 +19,8 @@ ImageViewer::ImageViewer(QWidget *parent)
             SLOT(slotUpdate()));
     connect(opaqueCheckBox, SIGNAL(stateChanged(int)),
             SLOT(slotUpdate()));
+    connect(alphaCheckBox, SIGNAL(stateChanged(int)),
+            SLOT(slotUpdate()));
 
     QPixmap px(32, 32);
     QPainter p(&px);
@@ -62,8 +64,9 @@ void ImageViewer::slotUpdate()
     double upperValue = upperSpinBox->value();
 
     bool opaque = opaqueCheckBox->isChecked();
+    bool alpha  = alphaCheckBox->isChecked();
 
-    if (lowerValue != 0.0 || upperValue != 1.0 || opaque) {
+    if (lowerValue != 0.0 || upperValue != 1.0 || opaque || alpha) {
         /*
          * Rescale the image.
          *
@@ -95,11 +98,16 @@ void ImageViewer::slotUpdate()
                 int g = qGreen(pixel);
                 int b = qBlue(pixel);
                 int a = qAlpha(pixel);
-                r = clamp(((r + offset) * scale) >> 8);
-                g = clamp(((g + offset) * scale) >> 8);
-                b = clamp(((b + offset) * scale) >> 8);
-                a |= aMask;
-                scanline[x] = qRgba(r, g, b, a);
+                if (alpha) {
+                    a = clamp(((a + offset) * scale) >> 8);
+                    scanline[x] = qRgba(a, a, a, 0xff);
+                } else {
+                    r = clamp(((r + offset) * scale) >> 8);
+                    g = clamp(((g + offset) * scale) >> 8);
+                    b = clamp(((b + offset) * scale) >> 8);
+                    a |= aMask;
+                    scanline[x] = qRgba(r, g, b, a);
+                }
             }
         }
     }
index 69dca6c6b26f542845b5857952177692210f19e7..bbe638ca0fc0635f41e10ff9ffdbcf225f0bd0a5 100644 (file)
@@ -406,6 +406,14 @@ void Retracer::run()
             error.type = regexp.cap(2);
             error.message = regexp.cap(3);
             errors.append(error);
+        } else if (!errors.isEmpty()) {
+            // Probably a multiligne message
+            ApiTraceError &previous = errors.last();
+            if (line.endsWith("\n")) {
+                line.chop(1);
+            }
+            previous.message.append('\n');
+            previous.message.append(line);
         }
     }
 
index fc6a023ef908ac6b5375dce2e173d98b86491000..4ad83c5876c5caf1267d80cc8c8029bdc18b7c93 100644 (file)
@@ -247,7 +247,10 @@ public:
     virtual void visit(trace::String *node)
     {
         QString str = m_variant.toString();
-        m_editedValue = new trace::String(str.toLocal8Bit().constData());
+        char *newString = new char[str.length() + 1];
+        QByteArray ba = str.toLocal8Bit();
+        strcpy(newString, ba.constData());
+        m_editedValue = new trace::String(newString);
     }
 
     virtual void visit(trace::Enum *e)
@@ -273,7 +276,6 @@ public:
         trace::Array *newArray = new trace::Array(vals.count());
         for (int i = 0; i < vals.count(); ++i) {
             EditVisitor visitor(vals[i]);
-
             array->values[i]->visit(visitor);
             if (array->values[i] == visitor.value()) {
                 //non-editabled
@@ -282,7 +284,7 @@ public:
                 return;
             }
 
-            newArray->values.push_back(visitor.value());
+            newArray->values[i] = visitor.value();
         }
         m_editedValue = newArray;
     }
index c6ab84600f1a6c72eaf30f83483a210618694877..a595ba790a4b8604f303fda282ca41e22adadbd4 100644 (file)
        </property>
       </widget>
      </item>
+     <item>
+      <widget class="QCheckBox" name="alphaCheckBox">
+       <property name="text">
+        <string>Alpha</string>
+       </property>
+      </widget>
+     </item>
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
index 3270161197f049bb8474cdf07dd914524dd2c2f0..a43289cc64ea6ef9b855ddc4c851d1c4ee4f4009 100644 (file)
@@ -48,14 +48,16 @@ class D3DRetracer(Retracer):
             print r'    d3dretrace::pLastDirect3DDevice9 = _this;'
 
         # create windows as neccessary
-        if method.name in ('CreateDevice', 'CreateDeviceEx'):
+        if method.name in ('CreateDevice', 'CreateDeviceEx', 'CreateAdditionalSwapChain'):
             print r'    HWND hWnd = d3dretrace::createWindow(pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);'
-            print r'    hFocusWindow = hWnd;'
             print r'    pPresentationParameters->hDeviceWindow = hWnd;'
+            if 'hFocusWindow' in method.argNames():
+                print r'    hFocusWindow = hWnd;'
 
         # notify frame has been completed
         if method.name == 'Present':
             print r'    retrace::frameComplete(call);'
+            print r'    hDestWindowOverride = NULL;'
 
         if 'pSharedHandle' in method.argNames():
             print r'    if (pSharedHandle) {'
index 69a6dce6f7e20bc3ed606505d3b6b14892bcce0c..08fc6a054da8bb3bd43ffa7648f30030cb731c8b 100644 (file)
@@ -257,6 +257,11 @@ class GlRetracer(Retracer):
         if function.name == 'memcpy':
             print '    if (!dest || !src || !n) return;'
 
+        # Skip glEnable/Disable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) as we don't
+        # faithfully set the CONTEXT_DEBUG_BIT_ARB flags on context creation.
+        if function.name in ('glEnable', 'glDisable'):
+            print '    if (cap == GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) return;'
+
         # Destroy the buffer mapping
         if function.name in self.unmap_function_names:
             print r'        GLvoid *ptr = NULL;'
index 8091bd91ce4dbda49676bf672369ad7a1d10baa5..fa71e9a87578a68cebd58700654901e10ecc7e51 100644 (file)
@@ -430,3 +430,6 @@ d3d9.addFunctions([
     StdFunction(Void, "D3DPERF_SetOptions", [(DWORD, "dwOptions")], sideeffects=False),
     StdFunction(DWORD, "D3DPERF_GetStatus", [], fail='0', sideeffects=False),
 ])
+d3d9.addInterfaces([
+    IDirect3DSwapChain9Ex,
+])
index 8ba6fb819598527c06c5bdd261c6f5c5a909fac2..2f8172099842b4d27e3ee14feb8ebbd0886b438d 100644 (file)
@@ -9,5 +9,4 @@ dlltrace.cpp
 egltrace.cpp
 gltrace.cpp
 glxtrace.cpp
-trace.cpp
 wgltrace.cpp
index b9e3eefe88314146f5dfc9e6f219c36677d954df..17aff4c6e3a2e3e81b7dda4d4ba5e32761bab73e 100644 (file)
@@ -9,6 +9,14 @@ include_directories (
     ${CMAKE_SOURCE_DIR}/dispatch
 )
 
+add_library (common_trace STATIC
+    trace.cpp
+)
+
+set_target_properties (common_trace PROPERTIES
+    # Ensure it can be statically linked in shared libraries
+    COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}"
+)
 
 if (WIN32)
     if (MINGW)
@@ -36,6 +44,7 @@ if (WIN32)
         )
         add_library (ddrawtrace MODULE ddraw.def ddrawtrace.cpp)
         target_link_libraries (ddrawtrace
+            common_trace
             common
             ${ZLIB_LIBRARIES}
             ${SNAPPY_LIBRARIES}
@@ -66,6 +75,7 @@ if (WIN32)
         )
         add_library (d3d8trace MODULE d3d8.def d3d8trace.cpp d3d9shader.cpp)
         target_link_libraries (d3d8trace
+            common_trace
             common
             ${ZLIB_LIBRARIES}
             ${SNAPPY_LIBRARIES}
@@ -96,6 +106,7 @@ if (WIN32)
         )
         add_library (d3d9trace MODULE d3d9.def d3d9trace.cpp d3d9shader.cpp)
         target_link_libraries (d3d9trace
+            common_trace
             common
             ${ZLIB_LIBRARIES}
             ${SNAPPY_LIBRARIES}
@@ -132,6 +143,7 @@ if (WIN32)
         )
         add_library (d3d10trace MODULE d3d10.def d3d10trace.cpp d3d10shader.cpp)
         target_link_libraries (d3d10trace
+            common_trace
             common
             ${ZLIB_LIBRARIES}
             ${SNAPPY_LIBRARIES}
@@ -166,6 +178,7 @@ if (WIN32)
         )
         add_library (d3d10_1trace MODULE d3d10_1.def d3d10_1trace.cpp)
         target_link_libraries (d3d10_1trace
+            common_trace
             common
             ${ZLIB_LIBRARIES}
             ${SNAPPY_LIBRARIES}
@@ -205,6 +218,7 @@ if (WIN32)
         )
         add_library (d3d11trace MODULE d3d11.def d3d11trace.cpp)
         target_link_libraries (d3d11trace
+            common_trace
             common
             ${ZLIB_LIBRARIES}
             ${SNAPPY_LIBRARIES}
@@ -241,6 +255,7 @@ if (WIN32)
     add_dependencies (wgltrace glproc)
     target_link_libraries (wgltrace
         glproc_gl
+        common_trace
         common
         ${ZLIB_LIBRARIES}
         ${SNAPPY_LIBRARIES}
@@ -284,6 +299,7 @@ elseif (APPLE)
 
     target_link_libraries (cgltrace
         glproc_gl
+        common_trace
         common
         ${ZLIB_LIBRARIES}
         ${SNAPPY_LIBRARIES}
@@ -326,6 +342,7 @@ elseif (X11_FOUND)
 
     target_link_libraries (glxtrace
         glproc_gl
+        common_trace
         common
         ${ZLIB_LIBRARIES}
         ${SNAPPY_LIBRARIES}
@@ -373,6 +390,7 @@ if (ENABLE_EGL AND NOT WIN32 AND NOT APPLE)
 
     target_link_libraries (egltrace
         glproc_egl
+        common_trace
         common
         ${ZLIB_LIBRARIES}
         ${SNAPPY_LIBRARIES}
diff --git a/wrappers/trace.cpp b/wrappers/trace.cpp
new file mode 100644 (file)
index 0000000..eb68934
--- /dev/null
@@ -0,0 +1,115 @@
+/**************************************************************************
+ *
+ * Copyright 2010-2011 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef ANDROID
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/system_properties.h>
+#endif
+
+#include "os.hpp"
+#include "os_string.hpp"
+#include "trace.hpp"
+
+
+namespace trace {
+
+
+#ifdef ANDROID
+
+static bool
+isZygoteProcess(void)
+{
+    os::String proc_name;
+
+    proc_name = os::getProcessName();
+    proc_name.trimDirectory();
+
+    return strcmp(proc_name, "app_process") == 0;
+}
+
+static os::String
+getZygoteProcessName(void)
+{
+    os::String path;
+    size_t size = PATH_MAX;
+    char *buf = path.buf(size);
+    ssize_t len;
+
+    int fd = open("/proc/self/cmdline", O_RDONLY);
+
+    assert(fd >= 0);
+    len = read(fd, buf, size - 1);
+    close(fd);
+    path.truncate(len);
+
+    return path;
+}
+
+bool
+isTracingEnabled(void)
+{
+    static pid_t cached_pid;
+    static bool enabled;
+    pid_t pid;
+
+    pid = getpid();
+    if (cached_pid == pid)
+        return enabled;
+    cached_pid = pid;
+
+    if (!isZygoteProcess()) {
+        os::log("apitrace[%d]: enabled for standalone %s",
+                pid, (const char *)os::getProcessName());
+        enabled = true;
+        return true;
+    }
+
+    char target_proc_name[PROP_VALUE_MAX] = "";
+    os::String proc_name;
+
+    proc_name = getZygoteProcessName();
+    proc_name.trimDirectory();
+
+    __system_property_get("debug.apitrace.procname", target_proc_name);
+    enabled = !strcmp(target_proc_name, proc_name);
+    os::log("apitrace[%d]: %s for %s",
+            pid, enabled ? "enabled" : "disabled", (const char *)proc_name);
+
+    return enabled;
+}
+
+#endif /* ANDROID */
+
+
+} /* namespace trace */
+
diff --git a/wrappers/trace.hpp b/wrappers/trace.hpp
new file mode 100644 (file)
index 0000000..997617e
--- /dev/null
@@ -0,0 +1,56 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Jose Fonseca
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/*
+ * Comon definitions for all tracers.
+ */
+
+
+#ifndef _TRACE_HPP_
+#define _TRACE_HPP_
+
+
+namespace trace {
+
+
+#ifdef ANDROID
+
+bool isTracingEnabled(void);
+
+#else /* !ANDROID */
+
+static inline bool
+isTracingEnabled(void) {
+    return true;
+}
+
+#endif /* !ANDROID */
+
+
+} /* namespace trace */
+
+
+#endif /* _TRACE_HPP_ */
index c838dc78a83df0e8e61190b1f30ef774b20e5ba8..958c07279a1bf55eab84d44d349ef6a3fded764f 100644 (file)
@@ -187,7 +187,7 @@ class ValueSerializer(stdapi.Visitor):
         length = '_c' + array.type.tag
         index = '_i' + array.type.tag
         print '    if (%s) {' % instance
-        print '        size_t %s = %s;' % (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();'
@@ -396,6 +396,9 @@ class Tracer:
         print '#else'
         print '#  include <alloca.h> // alloca'
         print '#endif'
+        print
+        print '#include "trace.hpp"'
+        print
 
     def footer(self, api):
         pass
@@ -422,6 +425,16 @@ class Tracer:
         print function.prototype() + ' {'
         if function.type is not stdapi.Void:
             print '    %s _result;' % function.type
+
+        # No-op if tracing is disabled
+        print '    if (!trace::isTracingEnabled()) {'
+        Tracer.invokeFunction(self, function)
+        if function.type is not stdapi.Void:
+            print '        return _result;'
+        else:
+            print '        return;'
+        print '    }'
+
         self.traceFunctionImplBody(function)
         if function.type is not stdapi.Void:
             print '    return _result;'