[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