Index: trunk/src/VBox/Additions/common/crOpenGL/Makefile.kmk
===================================================================
--- trunk/src/VBox/Additions/common/crOpenGL/Makefile.kmk	(revision 18975)
+++ trunk/src/VBox/Additions/common/crOpenGL/Makefile.kmk	(revision 19099)
@@ -398,4 +398,5 @@
 	feedback/feedbackspu_config.c \
 	feedback/feedbackspu_init.c \
+	feedback/feedback_context.c \
 	$(VBOX_PATH_CROGL_GENFILES)/feedbackspu.c \
 	$(VBOX_PATH_CROGL_GENFILES)/feedbackspu_state.c
Index: trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c
===================================================================
--- trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c	(revision 19099)
+++ trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c	(revision 19099)
@@ -0,0 +1,111 @@
+/* $Id$ */
+
+/** @file
+ * VBox feedback spu, context tracking.
+ */
+
+/*
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * Sun Microsystems, Inc. confidential
+ * All rights reserved
+ */
+
+#include "cr_spu.h"
+#include "cr_error.h"
+#include "feedbackspu.h"
+
+/*@todo Multithreading case. (See feedback_spu.self.RenderMode)*/
+
+GLint FEEDBACKSPU_APIENTRY
+feedbackspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
+{
+    GLint ctx, slot;
+
+#ifdef CHROMIUM_THREADSAFE
+    crLockMutex(&feedback_spu.mutex);
+#endif
+
+    ctx = feedback_spu.child.CreateContext(dpyName, visual, shareCtx);
+
+    /* find an empty context slot */
+    for (slot = 0; slot < feedback_spu.numContexts; slot++) {
+        if (!feedback_spu.context[slot].clientState) {
+            /* found empty slot */
+            break;
+        }
+    }
+    if (slot == feedback_spu.numContexts) {
+        feedback_spu.numContexts++;
+    }
+
+    feedback_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
+    feedback_spu.context[slot].clientCtx = ctx;
+
+#ifdef CHROMIUM_THREADSAFE
+    crUnlockMutex(&feedback_spu.mutex);
+#endif
+
+    return ctx;
+}
+
+void FEEDBACKSPU_APIENTRY
+feedbackspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
+{
+#ifdef CHROMIUM_THREADSAFE
+    crLockMutex(&feedback_spu.mutex);
+#endif
+    feedback_spu.child.MakeCurrent(window, nativeWindow, ctx);
+
+    if (ctx) {
+        int slot;
+        GLint oldmode;
+
+        for (slot=0; slot<feedback_spu.numContexts; ++slot)
+            if (feedback_spu.context[slot].clientCtx == ctx) break;
+        CRASSERT(slot < feedback_spu.numContexts);
+
+        crStateMakeCurrent(feedback_spu.context[slot].clientState);
+
+        crStateGetIntegerv(GL_RENDER_MODE, &oldmode);
+
+        if (oldmode!=feedback_spu.render_mode)
+        {
+            feedback_spu.self.RenderMode(oldmode);
+        }
+    }
+    else 
+    {
+        crStateMakeCurrent(NULL);
+    }
+
+#ifdef CHROMIUM_THREADSAFE
+    crUnlockMutex(&feedback_spu.mutex);
+#endif
+}
+
+void FEEDBACKSPU_APIENTRY
+feedbackspu_DestroyContext( GLint ctx )
+{
+#ifdef CHROMIUM_THREADSAFE
+    crLockMutex(&feedback_spu.mutex);
+#endif
+    feedback_spu.child.DestroyContext(ctx);
+
+    if (ctx) {
+        int slot;
+
+        for (slot=0; slot<feedback_spu.numContexts; ++slot)
+            if (feedback_spu.context[slot].clientCtx == ctx) break;
+        CRASSERT(slot < feedback_spu.numContexts);
+
+        crStateDestroyContext(feedback_spu.context[slot].clientState);
+
+        feedback_spu.context[slot].clientState = NULL;
+        feedback_spu.context[slot].clientCtx = 0;
+    }
+
+#ifdef CHROMIUM_THREADSAFE
+    crUnlockMutex(&feedback_spu.mutex);
+#endif
+}
Index: trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py
===================================================================
--- trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py	(revision 18975)
+++ trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py	(revision 19099)
@@ -16,15 +16,18 @@
 #include "feedbackspu_proto.h"
 """
+custom = ["CreateContext", "MakeCurrent", "DestroyContext"]
 
 keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
 
 for func_name in keys:
-	if apiutil.FindSpecial( "feedback_state", func_name ):
-		return_type = apiutil.ReturnType(func_name)
-		params = apiutil.Parameters(func_name)
-		print '%s FEEDBACKSPU_APIENTRY feedbackspu_%s( %s )' % (return_type, func_name, apiutil.MakeDeclarationString(params))
-		print '{'
-		print '\tcrState%s( %s );' % (func_name, apiutil.MakeCallString(params))
-		print ''
-		print '\tfeedback_spu.super.%s( %s );' % (func_name, apiutil.MakeCallString(params))
-		print '}'
+    if apiutil.FindSpecial( "feedback_state", func_name ):
+        if func_name in custom:
+            continue
+        return_type = apiutil.ReturnType(func_name)
+        params = apiutil.Parameters(func_name)
+        print '%s FEEDBACKSPU_APIENTRY feedbackspu_%s( %s )' % (return_type, func_name, apiutil.MakeDeclarationString(params))
+        print '{'
+        print '\tcrState%s( %s );' % (func_name, apiutil.MakeCallString(params))
+        print ''
+        print '\tfeedback_spu.super.%s( %s );' % (func_name, apiutil.MakeCallString(params))
+        print '}'
Index: trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state_special
===================================================================
--- trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state_special	(revision 18975)
+++ trunk/src/VBox/Additions/common/crOpenGL/feedback/feedback_state_special	(revision 19099)
@@ -59,2 +59,5 @@
 RasterPos4s
 RasterPos4sv
+CreateContext
+MakeCurrent
+DestroyContext
Index: trunk/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.h
===================================================================
--- trunk/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.h	(revision 18975)
+++ trunk/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.h	(revision 19099)
@@ -18,4 +18,11 @@
 #include "cr_glstate.h"
 
+typedef struct context_info_t ContextInfo;
+
+struct context_info_t {
+    CRContext *clientState;  /* used to store client-side GL state */
+    GLint clientCtx;         /* client context ID */
+};
+
 typedef struct {
 	int id;
@@ -28,4 +35,12 @@
 
 	CRCurrentStatePointers current;
+
+    CRContext *defaultctx;
+    int numContexts;
+    ContextInfo context[CR_MAX_CONTEXTS];
+
+#ifdef CHROMIUM_THREADSAFE
+    CRmutex mutex;
+#endif
 } feedbackSPU;
 
Index: trunk/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_init.c
===================================================================
--- trunk/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_init.c	(revision 18975)
+++ trunk/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_init.c	(revision 19099)
@@ -33,4 +33,8 @@
 	(void) num_contexts;
 
+#ifdef CHROMIUM_THREADSAFE
+    crInitMutex(&feedback_spu.mutex);
+#endif
+
 	feedback_spu.id = id;
 	feedback_spu.has_child = 0;
@@ -47,7 +51,10 @@
 	/* create/init default state tracker */
 	crStateInit();
-	ctx = crStateGetCurrent();
-	CRASSERT(ctx);
-	crStateSetCurrentPointers(ctx, &feedback_spu.current);
+
+    feedback_spu.defaultctx = crStateCreateContext(NULL, 0, NULL);
+    crStateSetCurrent(feedback_spu.defaultctx);
+
+    feedback_spu.numContexts = 0;
+    crMemZero(feedback_spu.context, CR_MAX_CONTEXTS * sizeof(ContextInfo));
 
 	return &feedback_functions;
