[PATCH v2 08/18] mt trace: track GL context create/destroy calls
Imre Deak
imre.deak at intel.com
Tue May 15 07:11:03 PDT 2012
This is needed for muti-threaded tracing to work properly.
Tracing multi-threaded GL apps requires that we track the lifetime of
the GL context objects and store thread specific state like the currently
active GL context on thread-local memory area.
Signed-off-by: Imre Deak <imre.deak at intel.com>
---
wrappers/egltrace.py | 5 +++
wrappers/gltrace.hpp | 17 +++++++++-
wrappers/gltrace_state.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 91 insertions(+), 2 deletions(-)
create mode 100644 wrappers/gltrace_state.cpp
diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py
index 4858e2f..b958a0c 100644
--- a/wrappers/egltrace.py
+++ b/wrappers/egltrace.py
@@ -52,6 +52,9 @@ class EglTracer(GlTracer):
def traceFunctionImplBody(self, function):
GlTracer.traceFunctionImplBody(self, function)
+ if function.name == 'eglCreateContext':
+ print ' gltrace::createContext((unsigned long)_result);'
+
if function.name == 'eglMakeCurrent':
print ' // update the profile'
print ' if (ctx != EGL_NO_CONTEXT) {'
@@ -67,6 +70,8 @@ class EglTracer(GlTracer):
print ' tr->profile = gltrace::PROFILE_ES2;'
print ' }'
+ if function.name == 'eglDestroyContext':
+ print ' gltrace::destroyContext((unsigned long)_result);'
if __name__ == '__main__':
print '#include <stdlib.h>'
diff --git a/wrappers/gltrace.hpp b/wrappers/gltrace.hpp
index cd602cb..627b2f7 100644
--- a/wrappers/gltrace.hpp
+++ b/wrappers/gltrace.hpp
@@ -39,13 +39,26 @@ enum Profile {
PROFILE_ES2,
};
-struct Context {
+class Context {
+public:
enum Profile profile;
bool user_arrays;
bool user_arrays_arb;
bool user_arrays_nv;
+
+ Context(void) : profile(PROFILE_COMPAT), user_arrays(false),
+ user_arrays_arb(false), user_arrays_nv(false) { }
};
-
+
+void
+createContext(unsigned long context_id);
+
+void
+destroyContext(unsigned long context_id);
+
+void
+setContext(unsigned long context_id);
+
Context *
getContext(void);
diff --git a/wrappers/gltrace_state.cpp b/wrappers/gltrace_state.cpp
new file mode 100644
index 0000000..cce4e14
--- /dev/null
+++ b/wrappers/gltrace_state.cpp
@@ -0,0 +1,71 @@
+#include <gltrace.hpp>
+#include <os_thread.hpp>
+#include <assert.h>
+
+namespace gltrace {
+
+static std::map<unsigned long, Context *> context_map;
+
+class ThreadState {
+public:
+ Context *current_context;
+ Context dummy_context;
+
+ ThreadState(void) : current_context(NULL) { }
+};
+
+static os::thread_specific_ptr<struct ThreadState> thread_state;
+
+static ThreadState *get_ts(void)
+{
+ struct ThreadState *ts = thread_state.get();
+
+ if (!ts) {
+ ts = new ThreadState;
+ thread_state.reset(ts);
+ }
+
+ return ts;
+}
+
+void createContext(unsigned long context_id)
+{
+ assert(context_map.find(context_id) == context_map.end());
+ context_map[context_id] = new Context();
+}
+
+void destroyContext(unsigned long context_id)
+{
+ struct ThreadState *ts = get_ts();
+ Context *ctx;
+
+ ctx = context_map[context_id];
+ if (ctx == ts->current_context)
+ ts->current_context = NULL;
+
+ context_map.erase(context_id);
+ delete ctx;
+}
+
+void setContext(unsigned long context_id)
+{
+ struct ThreadState *ts = get_ts();
+
+ ts->current_context = context_map[context_id];
+}
+
+Context *getContext(void)
+{
+ struct ThreadState *ts = get_ts();
+ Context *ctx = ts->current_context;
+
+ /*
+ * We are called from some gl* function at which point the behaviour
+ * is undefined if there is no active context. So in this case return
+ * a dummy context so that at least the apitrace internal book-keeping
+ * - which is context dependent - won't crash.
+ */
+ return ctx ? ctx : &ts->dummy_context;
+}
+
+}
--
1.7.5.4
More information about the apitrace
mailing list