Skip to content

Commit

Permalink
mt retrace: store current context,drawable in thread specific memory
Browse files Browse the repository at this point in the history
Signed-off-by: Imre Deak <imre.deak@intel.com>
  • Loading branch information
ideak committed Oct 10, 2012
1 parent 97efc7f commit 9a6f29e
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 33 deletions.
1 change: 1 addition & 0 deletions retrace/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 12 additions & 2 deletions retrace/glretrace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#ifndef _GLRETRACE_HPP_
#define _GLRETRACE_HPP_

#include <GL/gl.h>

#include "glws.hpp"
#include "retrace.hpp"

Expand Down Expand Up @@ -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);
Expand Down
9 changes: 5 additions & 4 deletions retrace/glretrace.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def invokeFunction(self, function):
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' }'

Expand Down Expand Up @@ -299,8 +299,9 @@ def invokeFunction(self, function):
)

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
Expand Down Expand Up @@ -479,7 +480,7 @@ def extractArg(self, function, arg, arg_type, lvalue, rvalue):
print ' GLint program = -1;'
print ' if (glretrace::insideList) {'
print ' // glUseProgram & glUseProgramObjectARB are display-list-able'
print ' program = _program_map[glretrace::currentContext->activeProgram];'
print ' program = _program_map[glretrace::getCurrentContext()->activeProgram];'
print ' } else {'
print ' GLint pipeline = 0;'
print ' if (_pipelineHasBeenBound) {'
Expand Down
3 changes: 3 additions & 0 deletions retrace/glretrace_cgl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
62 changes: 53 additions & 9 deletions retrace/glretrace_egl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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},
Expand Down Expand Up @@ -265,3 +307,5 @@ const retrace::Entry glretrace::egl_callbacks[] = {
{"glEGLImageTargetTexture2DOES", &retrace::ignore},
{NULL, NULL},
};

}
2 changes: 1 addition & 1 deletion retrace/glretrace_glx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,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();
}
Expand Down
15 changes: 9 additions & 6 deletions retrace/glretrace_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -283,6 +284,8 @@ initContext() {

void
frame_complete(trace::Call &call) {
glws::Drawable *currentDrawable = getCurrentDrawable();

if (retrace::profiling) {
/* Complete any remaining queries */
flushQueries();
Expand Down Expand Up @@ -310,7 +313,7 @@ frame_complete(trace::Call &call) {

retrace::frameComplete(call);

if (!currentDrawable) {
if (currentDrawable) {
return;
}

Expand Down Expand Up @@ -404,7 +407,7 @@ retrace::addCallbacks(retrace::Retracer &retracer)

image::Image *
retrace::getSnapshot(void) {
if (!glretrace::currentDrawable) {
if (!glretrace::getCurrentDrawable()) {
return NULL;
}

Expand All @@ -416,8 +419,8 @@ bool
retrace::dumpState(std::ostream &os)
{
if (glretrace::insideGlBeginEnd ||
!glretrace::currentDrawable ||
!glretrace::currentContext) {
!glretrace::getCurrentDrawable() ||
!glretrace::getCurrentContext()) {
return false;
}

Expand Down
68 changes: 68 additions & 0 deletions retrace/glretrace_state.cpp
Original file line number Diff line number Diff line change
@@ -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);
}

}
6 changes: 3 additions & 3 deletions retrace/glretrace_wgl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 9a6f29e

Please sign in to comment.