Implement context sharing.
authorZack Rusin <zack@kde.org>
Sun, 8 May 2011 04:52:13 +0000 (00:52 -0400)
committerJosé Fonseca <jose.r.fonseca@gmail.com>
Sun, 8 May 2011 10:27:35 +0000 (11:27 +0100)
early support for sharing contexts.

glretrace_glx.cpp
glretrace_wgl.cpp
glws.hpp
glws_glx.cpp
glws_wgl.cpp

index 1784cf0..463de0a 100644 (file)
@@ -58,7 +58,13 @@ static void retrace_glXChooseVisual(Trace::Call &call) {
 
 static void retrace_glXCreateContext(Trace::Call &call) {
     void * orig_context = call.ret->toPointer();
-    glws::Context *context = ws->createContext(glretrace::visual);
+    glws::Context *share_context = NULL;
+
+    if (call.arg(2).toPointer()) {
+        share_context = context_map[call.arg(2).toPointer()];
+    }
+
+    glws::Context *context = ws->createContext(glretrace::visual, share_context);
     context_map[orig_context] = context;
 }
 
@@ -169,7 +175,15 @@ static void retrace_glXQueryDrawable(Trace::Call &call) {
 }
 
 static void retrace_glXCreateNewContext(Trace::Call &call) {
-    retrace_glXCreateContext(call);
+    void * orig_context = call.ret->toPointer();
+    glws::Context *share_context = NULL;
+
+    if (call.arg(3).toPointer()) {
+        share_context = context_map[call.arg(3).toPointer()];
+    }
+
+    glws::Context *context = ws->createContext(glretrace::visual, share_context);
+    context_map[orig_context] = context;
 }
 
 static void retrace_glXMakeContextCurrent(Trace::Call &call) {
index d899772..a7185f7 100644 (file)
@@ -107,6 +107,18 @@ static void retrace_wglSwapBuffers(Trace::Call &call) {
 }
 
 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) {
@@ -198,8 +210,15 @@ static void retrace_wglSetPbufferAttribARB(Trace::Call &call) {
 }
 
 static void retrace_wglCreateContextAttribsARB(Trace::Call &call) {
-    retrace_wglCreateContext(call);
-    /* TODO: handle context sharing */
+    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) {
index 23de839..bfd3448 100644 (file)
--- a/glws.hpp
+++ b/glws.hpp
@@ -97,7 +97,7 @@ public:
     createDrawable(const Visual *visual, int width = 256, int height = 256) = 0;
 
     virtual Context *
-    createContext(const Visual *visual) = 0;
+    createContext(const Visual *visual, Context *shareContext = NULL) = 0;
     
     virtual bool
     makeCurrent(Drawable *drawable, Context *context) = 0;
index 39e0c46..732f33d 100644 (file)
@@ -190,10 +190,18 @@ public:
     }
 
     Context *
-    createContext(const Visual *visual)
+    createContext(const Visual *visual, Context *shareContext)
     {
         XVisualInfo *visinfo = dynamic_cast<const GlxVisual *>(visual)->visinfo;
-        GLXContext context = glXCreateContext(display, visinfo, NULL, True);
+        GLXContext share_context = NULL;
+        GLXContext context;
+
+        if (shareContext) {
+            share_context = dynamic_cast<GlxContext*>(shareContext)->context;
+        }
+
+        context = glXCreateContext(display, visinfo,
+                                   share_context, True);
         return new GlxContext(visual, context);
     }
 
index b1e274b..b203743 100644 (file)
@@ -154,10 +154,12 @@ class WglContext : public Context
 {
 public:
     HGLRC hglrc;
-    
-    WglContext(const Visual *vis) :
+    WglContext *shareContext;
+
+    WglContext(const Visual *vis, WglContext *share) :
         Context(vis),
-        hglrc(0)
+        hglrc(0),
+        shareContext(share)
     {}
 
     ~WglContext() {
@@ -187,9 +189,9 @@ public:
     }
 
     Context *
-    createContext(const Visual *visual)
+    createContext(const Visual *visual, Context *shareContext)
     {
-        return new WglContext(visual);
+        return new WglContext(visual, dynamic_cast<WglContext *>(shareContext));
     }
 
     bool
@@ -206,6 +208,10 @@ public:
                 if (!wglContext->hglrc) {
                     return false;
                 }
+                if (wglContext->shareContext) {
+                    wglShareLists(wglContext->shareContext->hglrc,
+                                  wglContext->hglrc);
+                }
             }
 
             return wglMakeCurrent(wglDrawable->hDC, wglContext->hglrc);