using namespace glretrace;
+typedef std::map<unsigned long long, glws::Drawable *> DrawableMap;
+typedef std::map<unsigned long long, glws::Context *> ContextMap;
+static DrawableMap drawable_map;
+static DrawableMap pbuffer_map;
+static ContextMap context_map;
+
+
+static glws::Drawable *
+getDrawable(unsigned long long hdc) {
+ if (hdc == 0) {
+ return NULL;
+ }
+
+ DrawableMap::const_iterator it;
+ it = drawable_map.find(hdc);
+ if (it == drawable_map.end()) {
+ return (drawable_map[hdc] = ws->createDrawable(visual));
+ }
+
+ return it->second;
+}
+
static void retrace_wglCreateContext(Trace::Call &call) {
+ unsigned long long orig_context = call.ret->toUIntPtr();
+ glws::Context *context = ws->createContext(glretrace::visual);
+ context_map[orig_context] = context;
}
static void retrace_wglDeleteContext(Trace::Call &call) {
}
static void retrace_wglMakeCurrent(Trace::Call &call) {
- glFlush();
- if (!double_buffer) {
- frame_complete(call.no);
+ if (drawable && context) {
+ glFlush();
+ if (!double_buffer) {
+ frame_complete(call.no);
+ }
+ }
+
+ glws::Drawable *new_drawable = getDrawable(call.arg(0).toUIntPtr());
+ glws::Context *new_context = context_map[call.arg(1).toUIntPtr()];
+
+ bool result = ws->makeCurrent(new_drawable, new_context);
+
+ if (new_drawable && new_context && result) {
+ drawable = new_drawable;
+ context = new_context;
+ } else {
+ drawable = NULL;
+ context = NULL;
}
}
}
static void retrace_wglShareLists(Trace::Call &call) {
+ unsigned long long hglrc1 = call.arg(0).toUIntPtr();
+ unsigned long long hglrc2 = call.arg(1).toUIntPtr();
+
+ glws::Context *share_context = context_map[hglrc1];
+ glws::Context *old_context = context_map[hglrc2];
+
+ glws::Context *new_context =
+ ws->createContext(old_context->visual, share_context);
+ if (new_context) {
+ delete old_context;
+ context_map[hglrc2] = new_context;
+ }
}
static void retrace_wglCreateLayerContext(Trace::Call &call) {
+ retrace_wglCreateContext(call);
}
static void retrace_wglDescribeLayerPlane(Trace::Call &call) {
}
static void retrace_wglSwapLayerBuffers(Trace::Call &call) {
+ retrace_wglSwapBuffers(call);
}
static void retrace_wglUseFontBitmapsA(Trace::Call &call) {
}
static void retrace_wglCreatePbufferARB(Trace::Call &call) {
+ int iWidth = call.arg(2).toUInt();
+ int iHeight = call.arg(3).toUInt();
+
+ unsigned long long orig_pbuffer = call.ret->toUIntPtr();
+ glws::Drawable *drawable = ws->createDrawable(glretrace::visual);
+
+ drawable->resize(iWidth, iHeight);
+
+ pbuffer_map[orig_pbuffer] = drawable;
+}
+
+static void retrace_wglGetPbufferDCARB(Trace::Call &call) {
+ glws::Drawable *pbuffer = pbuffer_map[call.arg(0).toUIntPtr()];
+
+ unsigned long long orig_hdc = call.ret->toUIntPtr();
+
+ drawable_map[orig_hdc] = pbuffer;
}
static void retrace_wglReleasePbufferDCARB(Trace::Call &call) {
}
static void retrace_wglCreateContextAttribsARB(Trace::Call &call) {
+ unsigned long long orig_context = call.ret->toUIntPtr();
+ glws::Context *share_context = NULL;
+
+ if (call.arg(1).toPointer()) {
+ share_context = context_map[call.arg(1).toUIntPtr()];
+ }
+
+ glws::Context *context = ws->createContext(glretrace::visual, share_context);
+ context_map[orig_context] = context;
}
static void retrace_wglMakeContextCurrentEXT(Trace::Call &call) {
}
void glretrace::retrace_call_wgl(Trace::Call &call) {
- const char *name = call.name().c_str();
+ const char *name = call.name();
switch (name[0]) {
case 'g':
case 'b':
if (name[8] == 'u' && name[9] == 'f' && name[10] == 'f' && name[11] == 'e' && name[12] == 'r' && name[13] == 'D' && name[14] == 'C' && name[15] == 'A' && name[16] == 'R' && name[17] == 'B' && name[18] == '\0') {
// wglGetPbufferDCARB
+ retrace_wglGetPbufferDCARB(call);
return;
}
break;