[PATCH v3 17/18] mt retrace: store current context, drawable in thread specific memory
Imre Deak
imre.deak at intel.com
Wed May 23 02:05:31 PDT 2012
Signed-off-by: Imre Deak <imre.deak at intel.com>
---
retrace/CMakeLists.txt | 1 +
retrace/glretrace.hpp | 12 ++++++-
retrace/glretrace.py | 2 +-
retrace/glretrace_cgl.cpp | 3 ++
retrace/glretrace_egl.cpp | 62 +++++++++++++++++++++++++++++++++------
retrace/glretrace_glx.cpp | 2 +-
retrace/glretrace_main.cpp | 8 +++--
retrace/glretrace_state.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++
retrace/glretrace_wgl.cpp | 6 ++--
retrace/glretrace_ws.cpp | 17 ++++++-----
10 files changed, 154 insertions(+), 27 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 fea187c..b4c7b9f 100644
--- a/retrace/glretrace.hpp
+++ b/retrace/glretrace.hpp
@@ -35,9 +35,17 @@ namespace glretrace {
extern bool insideGlBeginEnd;
+glws::Context *
+getCurrentContext(void);
+
+void
+setCurrentContext(glws::Context *context);
-extern glws::Drawable *currentDrawable;
-extern glws::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 69a6dce..a77892d 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' }'
diff --git a/retrace/glretrace_cgl.cpp b/retrace/glretrace_cgl.cpp
index 0c91ba2..9d958df 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();
+ glws::Context *currentContext = getCurrentContext();
+
if (currentDrawable && currentContext) {
if (retrace::doubleBuffer) {
currentDrawable->swapBuffers();
diff --git a/retrace/glretrace_egl.cpp b/retrace/glretrace_egl.cpp
index 70fe354..4603b9f 100644
--- a/retrace/glretrace_egl.cpp
+++ b/retrace/glretrace_egl.cpp
@@ -32,6 +32,7 @@
#include "retrace.hpp"
#include "glretrace.hpp"
#include "os.hpp"
+#include "os_thread.hpp"
#ifndef EGL_OPENGL_ES_API
#define EGL_OPENGL_ES_API 0x30A0
@@ -41,8 +42,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, glws::Context *> ContextMap;
@@ -51,8 +80,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);
@@ -99,7 +139,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);
@@ -126,7 +166,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;
}
@@ -135,17 +175,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();
glws::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;
@@ -191,7 +232,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) {
@@ -215,6 +256,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) {
@@ -224,7 +266,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},
@@ -261,3 +303,5 @@ const retrace::Entry glretrace::egl_callbacks[] = {
{"eglGetProcAddress", &retrace::ignore},
{NULL, NULL},
};
+
+}
diff --git a/retrace/glretrace_glx.cpp b/retrace/glretrace_glx.cpp
index 9d1b5e5..4ff1e13 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 49be505..eb75087 100644
--- a/retrace/glretrace_main.cpp
+++ b/retrace/glretrace_main.cpp
@@ -84,6 +84,8 @@ checkGlError(trace::Call &call) {
void frame_complete(trace::Call &call) {
+ glws::Drawable *currentDrawable = getCurrentDrawable();
+
retrace::frameComplete(call);
if (!currentDrawable) {
@@ -118,7 +120,7 @@ retrace::addCallbacks(retrace::Retracer &retracer)
image::Image *
retrace::getSnapshot(void) {
- if (!glretrace::currentDrawable) {
+ if (!glretrace::getCurrentDrawable()) {
return NULL;
}
@@ -130,8 +132,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..2620703
--- /dev/null
+++ b/retrace/glretrace_state.cpp
@@ -0,0 +1,68 @@
+#include <glretrace.hpp>
+#include <os_thread.hpp>
+
+namespace glretrace {
+
+class ThreadState {
+ glws::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;
+ }
+
+ glws::Context *get_current_context(void)
+ {
+ return current_context;
+ }
+
+ void set_current_context(glws::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;
+}
+
+glws::Context *getCurrentContext(void)
+{
+ return get_thread_state()->get_current_context();
+}
+
+void setCurrentContext(glws::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 c3e1096..e6709f1 100644
--- a/retrace/glretrace_wgl.cpp
+++ b/retrace/glretrace_wgl.cpp
@@ -85,7 +85,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();
}
@@ -100,8 +100,8 @@ static void retrace_wglShareLists(trace::Call &call) {
glws::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 ceb5d7f..43fa94d 100644
--- a/retrace/glretrace_ws.cpp
+++ b/retrace/glretrace_ws.cpp
@@ -40,10 +40,6 @@
namespace glretrace {
-glws::Drawable *currentDrawable = NULL;
-glws::Context *currentContext = NULL;
-
-
static glws::Visual *
visuals[glws::PROFILE_MAX];
@@ -110,6 +106,9 @@ createContext(glws::Context *shareContext) {
bool
makeCurrent(trace::Call &call, glws::Drawable *drawable, glws::Context *context)
{
+ glws::Drawable *currentDrawable = getCurrentDrawable();
+ glws::Context *currentContext = getCurrentContext();
+
if (drawable == currentDrawable && context == currentContext) {
return true;
}
@@ -130,11 +129,11 @@ makeCurrent(trace::Call &call, glws::Drawable *drawable, glws::Context *context)
}
if (drawable && context) {
- currentDrawable = drawable;
- currentContext = context;
+ setCurrentDrawable(drawable);
+ setCurrentContext(context);
} else {
- currentDrawable = NULL;
- currentContext = NULL;
+ setCurrentDrawable(NULL);
+ setCurrentContext(NULL);
}
return true;
@@ -151,6 +150,8 @@ makeCurrent(trace::Call &call, glws::Drawable *drawable, glws::Context *context)
*/
void
updateDrawable(int width, int height) {
+ glws::Drawable *currentDrawable = getCurrentDrawable();
+
if (!currentDrawable) {
return;
}
--
1.7.5.4
More information about the apitrace
mailing list