[PATCH v6 6/6] mt retrace: store current context, drawable in thread specific memory

Imre Deak imre.deak at intel.com
Thu Sep 20 02:33:17 PDT 2012


Signed-off-by: Imre Deak <imre.deak at intel.com>
---
 retrace/CMakeLists.txt      |    1 +
 retrace/glretrace.hpp       |   14 +++++++--
 retrace/glretrace.py        |    7 +++--
 retrace/glretrace_cgl.cpp   |    3 ++
 retrace/glretrace_egl.cpp   |   62 +++++++++++++++++++++++++++++++++------
 retrace/glretrace_glx.cpp   |    2 +-
 retrace/glretrace_main.cpp  |   15 ++++++----
 retrace/glretrace_state.cpp |   68 +++++++++++++++++++++++++++++++++++++++++++
 retrace/glretrace_wgl.cpp   |    6 ++--
 retrace/glretrace_ws.cpp    |   17 ++++++-----
 10 files changed, 163 insertions(+), 32 deletions(-)
 create mode 100644 retrace/glretrace_state.cpp

diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt
index 63fbed6..7d27db0 100644
--- a/retrace/CMakeLists.txt
+++ b/retrace/CMakeLists.txt
@@ -53,6 +53,7 @@ add_library (glretrace_common
     glretrace_egl.cpp
     glretrace_main.cpp
     glretrace_ws.cpp
+    glretrace_state.cpp
     glstate.cpp
     glstate_images.cpp
     glstate_params.cpp
diff --git a/retrace/glretrace.hpp b/retrace/glretrace.hpp
index 11f4d27..942512f 100644
--- a/retrace/glretrace.hpp
+++ b/retrace/glretrace.hpp
@@ -26,6 +26,8 @@
 #ifndef _GLRETRACE_HPP_
 #define _GLRETRACE_HPP_
 
+#include <GL/gl.h>
+
 #include "glws.hpp"
 #include "retrace.hpp"
 
@@ -53,9 +55,17 @@ struct Context {
 extern bool insideList;
 extern bool insideGlBeginEnd;
 
+Context *
+getCurrentContext(void);
+
+void
+setCurrentContext(Context *context);
 
-extern glws::Drawable *currentDrawable;
-extern Context *currentContext;
+glws::Drawable *
+getCurrentDrawable(void);
+
+void
+setCurrentDrawable(glws::Drawable *drawable);
 
 glws::Drawable *
 createDrawable(glws::Profile profile);
diff --git a/retrace/glretrace.py b/retrace/glretrace.py
index 43acfcd..62f71de 100644
--- a/retrace/glretrace.py
+++ b/retrace/glretrace.py
@@ -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'    if (glretrace::getCurrentContext()) {'
+            print r'        glretrace::getCurrentContext()->activeProgram ='
+            print r'            call.arg(0).toUInt();'
             print r'    }'
 
         # Only profile if not inside a list as the queries get inserted into list
diff --git a/retrace/glretrace_cgl.cpp b/retrace/glretrace_cgl.cpp
index 76b62fb..021471c 100644
--- a/retrace/glretrace_cgl.cpp
+++ b/retrace/glretrace_cgl.cpp
@@ -92,6 +92,9 @@ static void retrace_CGLSetCurrentContext(trace::Call &call) {
 
 
 static void retrace_CGLFlushDrawable(trace::Call &call) {
+    glws::Drawable *currentDrawable = getCurrentDrawable();
+    Context *currentContext = getCurrentContext();
+
     if (currentDrawable && currentContext) {
         if (retrace::doubleBuffer) {
             currentDrawable->swapBuffers();
diff --git a/retrace/glretrace_egl.cpp b/retrace/glretrace_egl.cpp
index 3f83f55..220c617 100644
--- a/retrace/glretrace_egl.cpp
+++ b/retrace/glretrace_egl.cpp
@@ -33,6 +33,7 @@
 #include "glretrace.hpp"
 #include "os.hpp"
 #include "eglsize.hpp"
+#include "os_thread.hpp"
 
 #ifndef EGL_OPENGL_ES_API
 #define EGL_OPENGL_ES_API		0x30A0
@@ -42,8 +43,36 @@
 #endif
 
 
-using namespace glretrace;
+namespace glretrace
+{
 
+class EglThreadState {
+	unsigned int current_api;
+	glws::Profile last_profile;
+public:
+	unsigned int get_current_api(void)
+	{
+		return current_api;
+	}
+
+	void set_current_api(unsigned int api)
+	{
+		current_api = api;
+	}
+
+	glws::Profile get_last_profile(void)
+	{
+		return last_profile;
+	}
+
+	void set_last_profile(glws::Profile profile)
+	{
+		last_profile = profile;
+	}
+
+	EglThreadState(void) : current_api(EGL_OPENGL_ES_API),
+			    last_profile(glws::PROFILE_COMPAT) { }
+};
 
 typedef std::map<unsigned long long, glws::Drawable *> DrawableMap;
 typedef std::map<unsigned long long, Context *> ContextMap;
@@ -52,8 +81,19 @@ static DrawableMap drawable_map;
 static ContextMap context_map;
 static ProfileMap profile_map;
 
-static unsigned int current_api = EGL_OPENGL_ES_API;
-static glws::Profile last_profile = glws::PROFILE_COMPAT;
+static os::thread_specific_ptr<class EglThreadState> egl_thread_state;
+
+static EglThreadState *get_egl_thread_state(void)
+{
+	EglThreadState *ts = egl_thread_state.get();
+
+	if (!ts) {
+		ts = new EglThreadState;
+		egl_thread_state.reset(ts);
+	}
+
+	return ts;
+}
 
 static void
 createDrawable(unsigned long long orig_config, unsigned long long orig_surface);
@@ -100,7 +140,7 @@ static void createDrawable(unsigned long long orig_config, unsigned long long or
     if (it != profile_map.end()) {
         profile = it->second;
     } else {
-        profile = last_profile;
+        profile = get_egl_thread_state()->get_last_profile();
     }
 
     glws::Drawable *drawable = glretrace::createDrawable(profile);
@@ -127,7 +167,7 @@ static void retrace_eglDestroySurface(trace::Call &call) {
     it = drawable_map.find(orig_surface);
 
     if (it != drawable_map.end()) {
-        if (it->second != currentDrawable) {
+        if (it->second != getCurrentDrawable()) {
             // TODO: reference count
             delete it->second;
         }
@@ -136,17 +176,18 @@ static void retrace_eglDestroySurface(trace::Call &call) {
 }
 
 static void retrace_eglBindAPI(trace::Call &call) {
-    current_api = call.arg(0).toUInt();
+    get_egl_thread_state()->set_current_api(call.arg(0).toUInt());
 }
 
 static void retrace_eglCreateContext(trace::Call &call) {
+    EglThreadState *ts = get_egl_thread_state();
     unsigned long long orig_context = call.ret->toUIntPtr();
     unsigned long long orig_config = call.arg(1).toUIntPtr();
     Context *share_context = getContext(call.arg(2).toUIntPtr());
     trace::Array *attrib_array = dynamic_cast<trace::Array *>(&call.arg(3));
     glws::Profile profile;
 
-    switch (current_api) {
+    switch (ts->get_current_api()) {
     case EGL_OPENGL_API:
         profile = glws::PROFILE_COMPAT;
         break;
@@ -192,7 +233,7 @@ static void retrace_eglCreateContext(trace::Call &call) {
 
     context_map[orig_context] = context;
     profile_map[orig_config] = profile;
-    last_profile = profile;
+    ts->set_last_profile(profile);
 }
 
 static void retrace_eglDestroyContext(trace::Call &call) {
@@ -216,6 +257,7 @@ static void retrace_eglMakeCurrent(trace::Call &call) {
 
 
 static void retrace_eglSwapBuffers(trace::Call &call) {
+    glws::Drawable *currentDrawable = getCurrentDrawable();
     frame_complete(call);
 
     if (retrace::doubleBuffer && currentDrawable) {
@@ -225,7 +267,7 @@ static void retrace_eglSwapBuffers(trace::Call &call) {
     }
 }
 
-const retrace::Entry glretrace::egl_callbacks[] = {
+const retrace::Entry egl_callbacks[] = {
     {"eglGetError", &retrace::ignore},
     {"eglGetDisplay", &retrace::ignore},
     {"eglInitialize", &retrace::ignore},
@@ -265,3 +307,5 @@ const retrace::Entry glretrace::egl_callbacks[] = {
     {"glEGLImageTargetTexture2DOES", &retrace::ignore},
     {NULL, NULL},
 };
+
+}
diff --git a/retrace/glretrace_glx.cpp b/retrace/glretrace_glx.cpp
index bc63063..3930dac 100644
--- a/retrace/glretrace_glx.cpp
+++ b/retrace/glretrace_glx.cpp
@@ -105,7 +105,7 @@ static void retrace_glXDestroyContext(trace::Call &call) {
 static void retrace_glXSwapBuffers(trace::Call &call) {
     frame_complete(call);
     if (retrace::doubleBuffer) {
-        currentDrawable->swapBuffers();
+        getCurrentDrawable()->swapBuffers();
     } else {
         glFlush();
     }
diff --git a/retrace/glretrace_main.cpp b/retrace/glretrace_main.cpp
index d857d03..9835bab 100755
--- a/retrace/glretrace_main.cpp
+++ b/retrace/glretrace_main.cpp
@@ -179,7 +179,8 @@ beginProfile(trace::Call &call, bool isDraw) {
     query.isDraw = isDraw;
     query.call = call.no;
     query.sig = call.sig;
-    query.program = glretrace::currentContext ? glretrace::currentContext->activeProgram : 0;
+    query.program = glretrace::getCurrentContext() ?
+            glretrace::getCurrentContext()->activeProgram : 0;
 
     /* GPU profiling only for draw calls */
     if (isDraw) {
@@ -262,7 +263,7 @@ initContext() {
 
     /* Setup debug message call back */
     if (retrace::debug && supportsDebugOutput) {
-        glDebugMessageCallbackARB(&debugOutputCallback, currentContext);
+        glDebugMessageCallbackARB(&debugOutputCallback, getCurrentContext());
 
         if (DEBUG_OUTPUT_SYNCHRONOUS) {
             glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
@@ -283,6 +284,8 @@ initContext() {
 
 void
 frame_complete(trace::Call &call) {
+    glws::Drawable *currentDrawable = getCurrentDrawable();
+
     if (retrace::profiling) {
         /* Complete any remaining queries */
         flushQueries();
@@ -310,7 +313,7 @@ frame_complete(trace::Call &call) {
 
     retrace::frameComplete(call);
 
-    if (!currentDrawable) {
+    if (currentDrawable) {
         return;
     }
 
@@ -404,7 +407,7 @@ retrace::addCallbacks(retrace::Retracer &retracer)
 
 image::Image *
 retrace::getSnapshot(void) {
-    if (!glretrace::currentDrawable) {
+    if (!glretrace::getCurrentDrawable()) {
         return NULL;
     }
 
@@ -416,8 +419,8 @@ bool
 retrace::dumpState(std::ostream &os)
 {
     if (glretrace::insideGlBeginEnd ||
-        !glretrace::currentDrawable ||
-        !glretrace::currentContext) {
+        !glretrace::getCurrentDrawable() ||
+        !glretrace::getCurrentContext()) {
         return false;
     }
 
diff --git a/retrace/glretrace_state.cpp b/retrace/glretrace_state.cpp
new file mode 100644
index 0000000..17fe842
--- /dev/null
+++ b/retrace/glretrace_state.cpp
@@ -0,0 +1,68 @@
+#include <glretrace.hpp>
+#include <os_thread.hpp>
+
+namespace glretrace {
+
+class ThreadState {
+	Context *current_context;
+	glws::Drawable *current_drawable;
+
+public:
+	glws::Drawable *get_current_drawable(void)
+	{
+		return current_drawable;
+	}
+
+	void set_current_drawable(glws::Drawable *drawable)
+	{
+		current_drawable = drawable;
+	}
+
+	Context *get_current_context(void)
+	{
+		return current_context;
+	}
+
+	void set_current_context(Context *context)
+	{
+		current_context = context;
+	}
+
+	ThreadState(void) : current_context(NULL), current_drawable(NULL) { }
+};
+
+static os::thread_specific_ptr<class ThreadState> thread_state;
+
+static ThreadState *get_thread_state(void)
+{
+	ThreadState *ts = thread_state.get();
+
+	if (!ts) {
+		ts = new ThreadState;
+		thread_state.reset(ts);
+	}
+
+	return ts;
+}
+
+Context *getCurrentContext(void)
+{
+	return get_thread_state()->get_current_context();
+}
+
+void setCurrentContext(Context *context)
+{
+	get_thread_state()->set_current_context(context);
+}
+
+glws::Drawable *getCurrentDrawable(void)
+{
+	return get_thread_state()->get_current_drawable();
+}
+
+void setCurrentDrawable(glws::Drawable *drawable)
+{
+	get_thread_state()->set_current_drawable(drawable);
+}
+
+}
diff --git a/retrace/glretrace_wgl.cpp b/retrace/glretrace_wgl.cpp
index bf2f38a..230fd3b 100644
--- a/retrace/glretrace_wgl.cpp
+++ b/retrace/glretrace_wgl.cpp
@@ -96,7 +96,7 @@ static void retrace_wglSetPixelFormat(trace::Call &call) {
 static void retrace_wglSwapBuffers(trace::Call &call) {
     frame_complete(call);
     if (retrace::doubleBuffer) {
-        currentDrawable->swapBuffers();
+        getCurrentDrawable()->swapBuffers();
     } else {
         glFlush();
     }
@@ -111,8 +111,8 @@ static void retrace_wglShareLists(trace::Call &call) {
 
     Context *new_context = glretrace::createContext(share_context);
     if (new_context) {
-        if (currentContext == old_context) {
-            glretrace::makeCurrent(call, currentDrawable, new_context);
+        if (getCurrentContext() == old_context) {
+            glretrace::makeCurrent(call, getCurrentDrawable(), new_context);
         }
 
         context_map[hglrc2] = new_context;
diff --git a/retrace/glretrace_ws.cpp b/retrace/glretrace_ws.cpp
index bead54e..5207589 100644
--- a/retrace/glretrace_ws.cpp
+++ b/retrace/glretrace_ws.cpp
@@ -40,10 +40,6 @@
 namespace glretrace {
 
 
-glws::Drawable *currentDrawable = NULL;
-Context *currentContext = NULL;
-
-
 static glws::Visual *
 visuals[glws::PROFILE_MAX];
 
@@ -111,6 +107,9 @@ createContext(Context *shareContext) {
 bool
 makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context)
 {
+    glws::Drawable *currentDrawable = getCurrentDrawable();
+    Context *currentContext = getCurrentContext();
+
     if (drawable == currentDrawable && context == currentContext) {
         return true;
     }
@@ -140,11 +139,11 @@ makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context)
     }
 
     if (drawable && context) {
-        currentDrawable = drawable;
-        currentContext = context;
+        setCurrentDrawable(drawable);
+        setCurrentContext(context);
     } else {
-        currentDrawable = NULL;
-        currentContext = NULL;
+        setCurrentDrawable(NULL);
+        setCurrentContext(NULL);
     }
 
     return true;
@@ -161,6 +160,8 @@ makeCurrent(trace::Call &call, glws::Drawable *drawable, Context *context)
  */
 void
 updateDrawable(int width, int height) {
+    glws::Drawable *currentDrawable = getCurrentDrawable();
+
     if (!currentDrawable) {
         return;
     }
-- 
1.7.9.5



More information about the apitrace mailing list