Index: /trunk/include/VBox/VBoxVideo3D.h
===================================================================
--- /trunk/include/VBox/VBoxVideo3D.h	(revision 39602)
+++ /trunk/include/VBox/VBoxVideo3D.h	(revision 39602)
@@ -0,0 +1,106 @@
+/** @file
+ *
+ * VirtualBox 3D common tooling
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+#ifndef ___VBox_VBoxVideo3D_h
+#define ___VBox_VBoxVideo3D_h
+
+#include <iprt/cdefs.h>
+#include <iprt/asm.h>
+#ifndef VBoxTlsRefGetImpl
+# ifdef VBoxTlsRefSetImpl
+#  error "VBoxTlsRefSetImpl is defined, unexpected!"
+# endif
+# include <iprt/thread.h>
+# define VBoxTlsRefGetImpl(_tls) (RTTlsGet((RTTLS)(_tls)))
+# define VBoxTlsRefSetImpl(_tls, _val) (RTTlsSet((RTTLS)(_tls), (_val)))
+#else
+# ifndef VBoxTlsRefSetImpl
+#  error "VBoxTlsRefSetImpl is NOT defined, unexpected!"
+# endif
+#endif
+
+#ifndef VBoxTlsRefAssertImpl
+# define VBoxTlsRefAssertImpl(_a) do {} while (0)
+#endif
+
+typedef DECLCALLBACK(void) FNVBOXTLSREFDTOR(void*);
+typedef FNVBOXTLSREFDTOR *PFNVBOXTLSREFDTOR;
+
+typedef enum {
+    VBOXTLSREFDATA_STATE_UNDEFINED = 0,
+    VBOXTLSREFDATA_STATE_INITIALIZED,
+    VBOXTLSREFDATA_STATE_TOBE_DESTROYED,
+    VBOXTLSREFDATA_STATE_DESTROYING,
+    VBOXTLSREFDATA_STATE_32BIT_HACK = 0x7fffffff
+} VBOXTLSREFDATA_STATE;
+
+#define VBOXTLSREFDATA \
+    volatile int32_t cTlsRefs; \
+    uint32_t enmTlsRefState; \
+    PFNVBOXTLSREFDTOR pfnTlsRefDtor; \
+
+#define VBoxTlsRefInit(_p, _pfnDtor) do { \
+        (_p)->cTlsRefs = 1; \
+        (_p)->enmTlsRefState = VBOXTLSREFDATA_STATE_INITIALIZED; \
+        (_p)->pfnTlsRefDtor = (_pfnDtor); \
+    } while (0)
+
+#define VBoxTlsRefIsFunctional(_p) (!!((_p)->enmTlsRefState == VBOXTLSREFDATA_STATE_INITIALIZED))
+
+#define VBoxTlsRefAddRef(_p) do { \
+        int cRefs = ASMAtomicIncS32(&(_p)->cTlsRefs); \
+        VBoxTlsRefAssertImpl(cRefs > 1 || (_p)->enmTlsRefState == VBOXTLSREFDATA_STATE_DESTROYING); \
+    } while (0)
+
+#define VBoxTlsRefRelease(_p) do { \
+        int cRefs = ASMAtomicDecS32(&(_p)->cTlsRefs); \
+        VBoxTlsRefAssertImpl(cRefs >= 0); \
+        if (!cRefs && (_p)->enmTlsRefState != VBOXTLSREFDATA_STATE_DESTROYING /* <- avoid recursion if VBoxTlsRefAddRef/Release is called from dtor */) { \
+            (_p)->enmTlsRefState = VBOXTLSREFDATA_STATE_DESTROYING; \
+            (_p)->pfnTlsRefDtor((_p)); \
+        } \
+    } while (0)
+
+#define VBoxTlsRefReleaseMarkDestroy(_p) do { \
+        (_p)->enmTlsRefState = VBOXTLSREFDATA_STATE_TOBE_DESTROYED; \
+    } while (0)
+
+#define VBoxTlsRefGetCurrent(_t, _Tsd) ((_t*) VBoxTlsRefGetImpl((_Tsd)))
+
+#define VBoxTlsRefSetCurrent(_t, _Tsd, _p) do { \
+        _t * oldCur = VBoxTlsRefGetCurrent(_t, _Tsd); \
+        if (oldCur != (_p)) { \
+            VBoxTlsRefSetImpl((_Tsd), (_p)); \
+            if (oldCur) { \
+                VBoxTlsRefRelease(oldCur); \
+            } \
+            if ((_p)) { \
+                VBoxTlsRefAddRef((_t*)(_p)); \
+            } \
+        } \
+    } while (0)
+
+#endif /* #ifndef ___VBox_VBoxVideo3D_h */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/Makefile.kmk	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/Makefile.kmk	(revision 39602)
@@ -129,11 +129,10 @@
     LIB_TO_DATADIR=\"\" \
     BIN_TO_DATADIR=\"\"
-wined3d_DEFS.x86     = __i386__
 if "$(KBUILD_TYPE)" != "debug" || defined(VBOX_WINE_NO_DEBUG_MSGS)
  wined3d_DEFS        += WINE_NO_DEBUG_MSGS
 endif
-wined3d_DEFS.amd64   += VBOX_WINE_WITHOUT_LIBWINE
-wined3d_INCS.x86     := $(PATH_SUB_CURRENT)/include
-wined3d_INCS.amd64   := vbox/libWineStub/include
+wined3d_DEFS         += VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
+wined3d_DEFS         += VBOX_WINE_WITHOUT_LIBWINE
+wined3d_INCS         := vbox/libWineStub/include
 wined3d_SOURCES      := \
     wined3d/arb_program_shader.c \
@@ -171,9 +170,8 @@
     wined3d/volumetexture.c \
     wined3d/wined3d_main.c \
+    wined3d/vboxext.c \
+    vbox/libWineStub/debug.c \
     wined3d/wined3d.def
-wined3d_SOURCES.amd64 = vbox/libWineStub/debug.c
-wined3d_LIBS.x86      = \
-    $(PATH_STAGE_LIB)/libWine$(VBOX_SUFF_LIB)
-wined3d_SDKS.amd64    = WINDDKWLH
+wined3d_SDKS          = WINDDKWLH
 ifdef VBOX_WINE_WITH_IPRT
 wined3d_LIBS         += \
@@ -191,21 +189,7 @@
 endif
 wined3dwddm_INCS           = vbox/libWineStub/include
-wined3dwddm_INCS.x86       = $(NO_SUCH_VARIABLE)
-wined3dwddm_LIBS.x86       = $(NO_SUCH_VARIABLE)
-wined3dwddm_DEFS           = $(subst __i386__,,$(wined3d_DEFS)) VBOX_WITH_WDDM VBOX_WINE_WITHOUT_LIBWINE
-wined3dwddm_DEFS.x86       = $(NO_SUCH_VARIABLE)
-wined3dwddm_SOURCES        = $(subst wined3d.def,wined3dwddm.def,$(wined3d_SOURCES)) vbox/libWineStub/debug.c wined3d/vboxext.c vbox/VBoxDbgGl.c
-wined3dwddm_SOURCES.x86    = $(NO_SUCH_VARIABLE)
-wined3dwddm_SOURCES.amd64  = $(NO_SUCH_VARIABLE)
-wined3dwddm_SDKS           = WINDDKWLH
-wined3dwddm_SDKS.amd64     = $(NO_SUCH_VARIABLE)
-#VBOX_WINE_WITH_IPRT is used for debugging currently to enable Assert & stuff
-#ifdef VBOX_WINE_WITH_IPRT
-#wined3dwddm_LIBS          += \
-							$(VBOX_LIB_IPRT_GUEST_R3) \
-							$(VBOX_LIB_VBGL_R3)
-#wined3dwddm_DEFS          += VBOX_WINE_WITH_IPRT
-#endif
-wined3dwddm_DEFS          += VBOX_WINE_WITH_SINGLE_CONTEXT
+wined3dwddm_DEFS           = $(subst VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT,,$(wined3d_DEFS))
+wined3dwddm_DEFS          += VBOX_WITH_WDDM VBOX_WINE_WITH_SINGLE_CONTEXT
+wined3dwddm_SOURCES        = $(subst wined3d.def,wined3dwddm.def,$(wined3d_SOURCES)) vbox/VBoxDbgGl.c
 
 DLLS.amd64 += wined3dwddm-x86
@@ -230,12 +214,10 @@
     LIB_TO_DATADIR=\"\" \
     BIN_TO_DATADIR=\"\"
-VBoxD3D8_DEFS.x86 = __i386__
 if "$(KBUILD_TYPE)" != "debug" || defined(VBOX_WINE_NO_DEBUG_MSGS)
  VBoxD3D8_DEFS       += WINE_NO_DEBUG_MSGS
 endif
-VBoxD3D8_DEFS.amd64   += VBOX_WINE_WITHOUT_LIBWINE
-VBoxD3D8_INCS.x86     := $(PATH_SUB_CURRENT)/include
-VBoxD3D8_INCS.amd64   := vbox/libWineStub/include
-VBoxD3D8_SOURCES      := \
+VBoxD3D8_DEFS        += VBOX_WINE_WITHOUT_LIBWINE
+VBoxD3D8_INCS        := vbox/libWineStub/include
+VBoxD3D8_SOURCES     := \
     d3d8/cubetexture.c \
     d3d8/d3d8_main.c \
@@ -252,11 +234,9 @@
     d3d8/volume.c \
     d3d8/volumetexture.c \
+    vbox/libWineStub/debug.c \
     d3d8/d3d8.def
-VBoxD3D8_LIBS.x86 = \
-    $(PATH_STAGE_LIB)/libWine$(VBOX_SUFF_LIB)
-VBoxD3D8_LIBS     = \
+VBoxD3D8_LIBS         = \
     $(PATH_STAGE_LIB)/wined3d$(VBOX_SUFF_LIB)
-VBoxD3D8_SOURCES.amd64 = vbox/libWineStub/debug.c
-VBoxD3D8_SDKS.amd64    = WINDDKWLH
+VBoxD3D8_SDKS         = WINDDKWLH
 ifdef VBOX_WINE_WITH_IPRT
 VBoxD3D8_LIBS         += \
@@ -277,11 +257,9 @@
     LIB_TO_DATADIR=\"\" \
     BIN_TO_DATADIR=\"\"
-VBoxD3D9_DEFS.x86 = __i386__
 if "$(KBUILD_TYPE)" != "debug" || defined(VBOX_WINE_NO_DEBUG_MSGS)
- VBoxD3D9_DEFS       += WINE_NO_DEBUG_MSGS
-endif
-VBoxD3D9_DEFS.amd64   += VBOX_WINE_WITHOUT_LIBWINE
-VBoxD3D9_INCS.x86     := $(PATH_SUB_CURRENT)/include
-VBoxD3D9_INCS.amd64   := vbox/libWineStub/include
+ VBoxD3D9_DEFS        += WINE_NO_DEBUG_MSGS
+endif
+VBoxD3D9_DEFS         += VBOX_WINE_WITHOUT_LIBWINE
+VBoxD3D9_INCS         := vbox/libWineStub/include
 VBoxD3D9_SOURCES      := \
     d3d9/cubetexture.c \
@@ -300,16 +278,10 @@
     d3d9/vertexshader.c \
     d3d9/volume.c \
-    d3d9/volumetexture.c
-
-VBoxD3D9_SOURCES.x86      = \
-	d3d9/d3d9.def
-VBoxD3D9_SOURCES.amd64    = \
-	vbox/libWineStub/debug.c \
-	d3d9/d3d9xpdm.def
-VBoxD3D9_LIBS.x86         = \
-    $(PATH_STAGE_LIB)/libWine$(VBOX_SUFF_LIB)
+    d3d9/volumetexture.c \
+    vbox/libWineStub/debug.c \
+    d3d9/d3d9xpdm.def
 VBoxD3D9_LIBS             = \
     $(PATH_STAGE_LIB)/wined3d$(VBOX_SUFF_LIB)
-VBoxD3D9_SDKS.amd64    = WINDDKWLH
+VBoxD3D9_SDKS             = WINDDKWLH
 ifdef VBOX_WINE_WITH_IPRT
 VBoxD3D9_LIBS         += \
@@ -327,14 +299,7 @@
 endif
 VBoxD3D9wddm_INCS           = vbox/libWineStub/include
-VBoxD3D9wddm_INCS.x86       = $(NO_SUCH_VARIABLE)
-VBoxD3D9wddm_DEFS.x86       = $(NO_SUCH_VARIABLE)
-VBoxD3D9wddm_DEFS          += $(subst __i386__,,$(VBoxD3D9_DEFS)) VBOX_WITH_WDDM VBOX_WINE_WITHOUT_LIBWINE IN_VBOXWINEEX
-VBoxD3D9wddm_SOURCES        = $(VBoxD3D9_SOURCES) d3d9/d3d9wddm.def vbox/libWineStub/debug.c
-VBoxD3D9wddm_SOURCES.x86    = $(NO_SUCH_VARIABLE)
-VBoxD3D9wddm_SOURCES.amd64  = $(NO_SUCH_VARIABLE)
+VBoxD3D9wddm_DEFS          += $(VBoxD3D9_DEFS) VBOX_WITH_WDDM VBOX_WINE_WITHOUT_LIBWINE IN_VBOXWINEEX
+VBoxD3D9wddm_SOURCES        = $(subst d3d9xpdm.def,d3d9wddm.def,$(VBoxD3D9_SOURCES))
 VBoxD3D9wddm_LIBS           = $(subst $(PATH_STAGE_LIB)/wined3d$(VBOX_SUFF_LIB),$(PATH_STAGE_LIB)/wined3dwddm$(VBOX_SUFF_LIB),$(VBoxD3D9_LIBS)) 
-VBoxD3D9wddm_LIBS.x86       = $(NO_SUCH_VARIABLE)
-VBoxD3D9wddm_SDKS           = WINDDKWLH
-VBoxD3D9wddm_SDKS.amd64     = $(NO_SUCH_VARIABLE)
 #ifdef VBOX_WINE_WITH_IPRT
 #VBoxD3D9wddm_LIBS          += \
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c	(revision 39602)
@@ -478,11 +478,7 @@
     return ret;
 }
-#ifdef VBOX_WITH_WDDM
+
 static HRESULT IDirect3DDevice9Impl_DoCreateAdditionalSwapChain(IDirect3DDevice9Ex *iface,
         D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain9 **swapchain)
-#else
-static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_CreateAdditionalSwapChain(IDirect3DDevice9Ex *iface,
-        D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain9 **swapchain)
-#endif
 {
     IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
@@ -514,5 +510,4 @@
 }
 
-#ifdef VBOX_WITH_WDDM
 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_CreateAdditionalSwapChain(IDirect3DDevice9Ex *iface,
         D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain9 **swapchain)
@@ -541,5 +536,4 @@
     return D3D_OK;
 }
-#endif
 
 static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) {
@@ -3111,11 +3105,6 @@
     local_parameters.PresentationInterval = present_parameters->PresentationInterval;
 
-#ifdef VBOX_WITH_WDDM
     hr = IDirect3DDevice9Impl_DoCreateAdditionalSwapChain((IDirect3DDevice9Ex *)This,
             &local_parameters, (IDirect3DSwapChain9 **)&d3d_swapchain);
-#else
-    hr = IDirect3DDevice9Impl_CreateAdditionalSwapChain((IDirect3DDevice9Ex *)This,
-            &local_parameters, (IDirect3DSwapChain9 **)&d3d_swapchain);
-#endif
     if (FAILED(hr))
     {
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/directx.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/directx.c	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/directx.c	(revision 39602)
@@ -434,4 +434,6 @@
     /* fixup caps  */
 #ifdef VBOX_WITH_WDDM
+    /* needed for Windows Media Player to work properly */
+    pCaps->Caps |= D3DCAPS_READ_SCANLINE;
     pCaps->Caps2 |= 0x00080000 /*D3DCAPS2_CANRENDERWINDOWED*/;
     pCaps->Caps2 |= D3DCAPS2_CANSHARERESOURCE;
@@ -482,7 +484,4 @@
 #endif
 
-    /* needed for Windows Media Player to work properly */
-    pCaps->Caps |= D3DCAPS_READ_SCANLINE;
-
     TRACE("(%p) returning %p\n", This, pCaps);
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/include/wine/wined3d.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/include/wine/wined3d.h	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/include/wine/wined3d.h	(revision 39602)
@@ -7395,13 +7395,13 @@
         ) = 0;
 
+    virtual HRESULT STDMETHODCALLTYPE AddSwapChain(
+        IWineD3DSwapChain *swapchain) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE RemoveSwapChain(
+        IWineD3DSwapChain *swapchain) = 0;
+
 #ifdef VBOX_WITH_WDDM
     virtual HRESULT STDMETHODCALLTYPE Flush(
         ) = 0;
-
-    virtual HRESULT STDMETHODCALLTYPE AddSwapChain(
-        IWineD3DSwapChain *swapchain) = 0;
-
-    virtual HRESULT STDMETHODCALLTYPE RemoveSwapChain(
-        IWineD3DSwapChain *swapchain) = 0;
 #endif
 };
@@ -8170,15 +8170,15 @@
         IWineD3DDevice* This);
 
+    HRESULT (STDMETHODCALLTYPE *AddSwapChain)(
+        IWineD3DDevice* This,
+        IWineD3DSwapChain *swapchain);
+
+    HRESULT (STDMETHODCALLTYPE *RemoveSwapChain)(
+        IWineD3DDevice* This,
+        IWineD3DSwapChain *swapchain);
+
 #ifdef VBOX_WITH_WDDM
     HRESULT (STDMETHODCALLTYPE *Flush)(
         IWineD3DDevice* This);
-
-    HRESULT (STDMETHODCALLTYPE *AddSwapChain)(
-        IWineD3DDevice* This,
-        IWineD3DSwapChain *swapchain);
-
-    HRESULT (STDMETHODCALLTYPE *RemoveSwapChain)(
-        IWineD3DDevice* This,
-        IWineD3DSwapChain *swapchain);
 #endif
 
@@ -8342,8 +8342,8 @@
 #define IWineD3DDevice_AcquireFocusWindow(This,window) (This)->lpVtbl->AcquireFocusWindow(This,window)
 #define IWineD3DDevice_ReleaseFocusWindow(This) (This)->lpVtbl->ReleaseFocusWindow(This)
+#define IWineD3DDevice_AddSwapChain(This,swapchain) (This)->lpVtbl->AddSwapChain(This,swapchain)
+#define IWineD3DDevice_RemoveSwapChain(This,swapchain) (This)->lpVtbl->RemoveSwapChain(This,swapchain)
 #ifdef VBOX_WITH_WDDM
 #define IWineD3DDevice_Flush(This) (This)->lpVtbl->Flush(This)
-#define IWineD3DDevice_AddSwapChain(This,swapchain) (This)->lpVtbl->AddSwapChain(This,swapchain)
-#define IWineD3DDevice_RemoveSwapChain(This,swapchain) (This)->lpVtbl->RemoveSwapChain(This,swapchain)
 #endif
 #endif
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/debug.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/debug.h	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/debug.h	(revision 39602)
@@ -121,5 +121,5 @@
 #ifndef WINE_NO_DEBUG_MSGS
 # define __WINE_GET_DEBUGGING_WARN(dbch)  ((dbch)->flags & (1 << __WINE_DBCL_WARN))
-# if 0// && defined(VBOX_WITH_WDDM) && defined(DEBUG_misha)
+# if 0// && defined(DEBUG_misha)
 #  define __WINE_GET_DEBUGGING_FIXME(dbch) (RT_BREAKPOINT(), ((dbch)->flags & (1 << __WINE_DBCL_FIXME)))
 # else
@@ -128,5 +128,5 @@
 #else
 # define __WINE_GET_DEBUGGING_WARN(dbch)  0
-# if 0 && defined(VBOX_WITH_WDDM) && defined(DEBUG_misha)
+# if 0 && defined(DEBUG_misha)
 #  define __WINE_GET_DEBUGGING_FIXME(dbch) (RT_BREAKPOINT(), 0)
 # else
@@ -136,5 +136,5 @@
 
 /* define error macro regardless of what is configured */
-#if defined(VBOX_WITH_WDDM) && defined(DEBUG_misha)
+#if defined(DEBUG_misha)
 #define __WINE_GET_DEBUGGING_ERR(dbch)  (RT_BREAKPOINT(), ((dbch)->flags & (1 << __WINE_DBCL_ERR)))
 #else
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/vbox/libWineStub/include/wine/wined3d.h	(revision 39602)
@@ -7393,13 +7393,13 @@
         ) = 0;
 
+    virtual HRESULT STDMETHODCALLTYPE AddSwapChain(
+        IWineD3DSwapChain *swapchain) = 0;
+
+    virtual HRESULT STDMETHODCALLTYPE RemoveSwapChain(
+        IWineD3DSwapChain *swapchain) = 0;
+
 #ifdef VBOX_WITH_WDDM
     virtual HRESULT STDMETHODCALLTYPE Flush(
         ) = 0;
-
-    virtual HRESULT STDMETHODCALLTYPE AddSwapChain(
-        IWineD3DSwapChain *swapchain) = 0;
-
-    virtual HRESULT STDMETHODCALLTYPE RemoveSwapChain(
-        IWineD3DSwapChain *swapchain) = 0;
 #endif
 };
@@ -8168,15 +8168,15 @@
         IWineD3DDevice* This);
 
+    HRESULT (STDMETHODCALLTYPE *AddSwapChain)(
+        IWineD3DDevice* This,
+        IWineD3DSwapChain *swapchain);
+
+    HRESULT (STDMETHODCALLTYPE *RemoveSwapChain)(
+        IWineD3DDevice* This,
+        IWineD3DSwapChain *swapchain);
+
 #ifdef VBOX_WITH_WDDM
     HRESULT (STDMETHODCALLTYPE *Flush)(
         IWineD3DDevice* This);
-
-    HRESULT (STDMETHODCALLTYPE *AddSwapChain)(
-        IWineD3DDevice* This,
-        IWineD3DSwapChain *swapchain);
-
-    HRESULT (STDMETHODCALLTYPE *RemoveSwapChain)(
-        IWineD3DDevice* This,
-        IWineD3DSwapChain *swapchain);
 #endif
 
@@ -8340,8 +8340,8 @@
 #define IWineD3DDevice_AcquireFocusWindow(This,window) (This)->lpVtbl->AcquireFocusWindow(This,window)
 #define IWineD3DDevice_ReleaseFocusWindow(This) (This)->lpVtbl->ReleaseFocusWindow(This)
+#define IWineD3DDevice_AddSwapChain(This,swapchain) (This)->lpVtbl->AddSwapChain(This,swapchain)
+#define IWineD3DDevice_RemoveSwapChain(This,swapchain) (This)->lpVtbl->RemoveSwapChain(This,swapchain)
 #ifdef VBOX_WITH_WDDM
 #define IWineD3DDevice_Flush(This) (This)->lpVtbl->Flush(This)
-#define IWineD3DDevice_AddSwapChain(This,swapchain) (This)->lpVtbl->AddSwapChain(This,swapchain)
-#define IWineD3DDevice_RemoveSwapChain(This,swapchain) (This)->lpVtbl->RemoveSwapChain(This,swapchain)
 #endif
 #endif
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/context.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/context.c	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/context.c	(revision 39602)
@@ -42,4 +42,9 @@
 static DWORD wined3d_context_tls_idx;
 
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# define vboxGetCurrentContext() VBoxTlsRefGetCurrent(struct wined3d_context, wined3d_context_tls_idx)
+# define vboxSetCurrentContext(_ctx) VBoxTlsRefSetCurrent(struct wined3d_context, wined3d_context_tls_idx, (_ctx))
+#endif
+
 /* FBO helper functions */
 
@@ -808,5 +813,5 @@
     if (context->valid)
     {
-        if (!ReleaseDC(context->win_handle, context->hdc))
+        if (!VBoxExtReleaseDC(context->win_handle, context->hdc))
         {
             ERR("Failed to release device context %p, last error %#x.\n",
@@ -817,5 +822,5 @@
 
     context->win_handle = context->swapchain->win_handle;
-    if (!(context->hdc = GetDC(context->win_handle)))
+    if (!(context->hdc = VBoxExtGetDC(context->win_handle)))
     {
         ERR("Failed to get a device context for window %p.\n", context->win_handle);
@@ -1051,5 +1056,5 @@
 #ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
 # ifndef VBOX_WITH_WDDM
-    ReleaseDC(context->win_handle, context->hdc);
+    VBoxExtReleaseDC(context->win_handle, context->hdc);
 # else
     VBoxExtReleaseDC(context->win_handle, context->hdc);
@@ -1073,8 +1078,8 @@
 }
 
-#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
 static struct wined3d_context *context_get_current_ex(DWORD adjustTid)
 {
-    struct wined3d_context *ctx = TlsGetValue(wined3d_context_tls_idx);
+    struct wined3d_context *ctx = vboxGetCurrentContext();
     if (!adjustTid)
         return ctx;
@@ -1093,5 +1098,5 @@
 struct wined3d_context *context_get_current(void)
 {
-#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
     return TlsGetValue(wined3d_context_tls_idx);
 #else
@@ -1104,5 +1109,5 @@
 BOOL context_set_current(struct wined3d_context *ctx)
 {
-#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
     struct wined3d_context *old = context_get_current_ex(0);
     DWORD tid = GetCurrentThreadId();
@@ -1112,5 +1117,5 @@
     if (old == ctx)
     {
-#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
         if (ctx && ctx->tid != tid)
         {
@@ -1127,7 +1132,8 @@
     if (old)
     {
-#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
         old->tid = 0;
-#endif
+        old->current = 0;
+#else
         if (old->destroyed)
         {
@@ -1140,4 +1146,5 @@
             old->current = 0;
         }
+#endif
     }
 
@@ -1151,5 +1158,5 @@
             ERR("Failed to make GL context %p current on device context %p, last error %#x.\n",
                     ctx->glCtx, ctx->currentSwapchain->hDC, err);
-            TlsSetValue(wined3d_context_tls_idx, NULL);
+            vboxSetCurrentContext(NULL);
             return FALSE;
         }
@@ -1161,5 +1168,5 @@
             ERR("Failed to make GL context %p current on device context %p, last error %#x.\n",
                     ctx->glCtx, ctx->hdc, err);
-            TlsSetValue(wined3d_context_tls_idx, NULL);
+            vboxSetCurrentContext(NULL);
             return FALSE;
         }
@@ -1174,28 +1181,51 @@
             DWORD err = GetLastError();
             ERR("Failed to clear current GL context, last error %#x.\n", err);
-            TlsSetValue(wined3d_context_tls_idx, NULL);
+            vboxSetCurrentContext(NULL);
             return FALSE;
         }
     }
 
-#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
     return TlsSetValue(wined3d_context_tls_idx, ctx);
 #else
-    if (TlsSetValue(wined3d_context_tls_idx, ctx))
-    {
-        if (ctx)
-        {
-            ctx->tid = tid;
-        }
-        return TRUE;
-    }
-    else
-    {
-        DWORD err = GetLastError();
-        ERR("Failed to set tls value, last error %#x.\n", err);
-    }
-    return FALSE;
-#endif
-}
+    vboxSetCurrentContext(ctx);
+    if (ctx)
+        ctx->tid = tid;
+    return TRUE;
+#endif
+}
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+void context_clear_on_thread_detach()
+{
+    /* In theory, we should do context_set_current(NULL) here,
+     * but since it may result in calling a context dtor, it should be done under wined3d lock.
+     * We can not acquire a wined3d lock here since this routine is called in a DllMain context
+     * and this would result in a lock order violation, which may result in a deadlock.
+     * In other words, wined3d may internally call Win32 API functions which result in
+     * a DLL lock acquisition while holding wined3d lock.
+     * So lock order should always be "wined3d lock" -> "dll lock".
+     *
+     * This is why we do the following:
+     * */
+
+    /* 1. get the current context w/o adjusting its thread id, etc. */
+    struct wined3d_context *old = context_get_current_ex(0);
+    if (!old)
+        return;
+
+    /* there is a currently assigned context,
+     * 2. now increase its ref count to ensure its dtor routine is not called while making set_current(NULL).
+     * This is needed since dtor can only be run with a wined3d lock held */
+    VBoxTlsRefAddRef(old);
+
+    /* 3. now we can call context_set_current(NULL) */
+    context_set_current(NULL);
+
+    /* 4. to avoid possible deadlocks we make an asynchronous call to a worker thread to make
+     * wined3d lock - context release - wined3d unlock from there. */
+    VBoxExtReleaseContextAsync(old);
+}
+#endif
 
 void context_release(struct wined3d_context *context)
@@ -1220,5 +1250,4 @@
                     context->restore_ctx, context->restore_dc, err);
         }
-#ifdef VBOX_WITH_WDDM
         else
         {
@@ -1228,5 +1257,9 @@
             if (current_context && current_context->glCtx != context->restore_ctx)
             {
+#ifdef VBOX_WITH_WDDM
                 IWineD3DDeviceImpl *device = context->device;
+#else
+                IWineD3DDeviceImpl *device = context->swapchain->device;
+#endif
                 UINT i = 0;
                 for (; i < device->numContexts; ++i)
@@ -1246,5 +1279,4 @@
             }
         }
-#endif
 
         context->restore_ctx = NULL;
@@ -1469,4 +1501,12 @@
 }
 
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+static DECLCALLBACK(void) context_tls_dtor(void* pvCtx)
+{
+    struct wined3d_context * context = (struct wined3d_context *)pvCtx;
+    context_destroy_gl_resources(context);
+    HeapFree(GetProcessHeap(), 0, context);
+}
+#endif
 
 /*****************************************************************************
@@ -1507,9 +1547,13 @@
     }
 
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+    VBoxTlsRefInit(ret, context_tls_dtor);
+#endif
+
     if (!(hdc =
 #ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
             swapchain->hDC
 #else
-            GetDC(swapchain->win_handle)
+            VBoxExtGetDC(swapchain->win_handle)
 #endif
             )
@@ -1635,5 +1679,5 @@
 #endif
     ret->current_rt = (IWineD3DSurface *)target;
-#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
     ret->tid = GetCurrentThreadId();
 #endif
@@ -1785,9 +1829,12 @@
     }
 
-#ifdef VBOX_WITH_WDDM
+    /* for WDDM case this is used for shared resource handling
+     *
+     * for XPDM this is needed to at least support texture sharing between device contexts.
+     * this is a kinda hack, but it is needed since our ogl driver currently does not support ShareLists */
     GL_EXTCALL(glChromiumParameteriCR(GL_SHARE_CONTEXT_RESOURCES_CR, GL_TRUE));
+#if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
     GL_EXTCALL(glChromiumParameteriCR(GL_FLUSH_ON_THREAD_SWITCH_CR,  GL_TRUE));
 #endif
-
     LEAVE_GL();
 
@@ -1886,4 +1933,7 @@
     }
 #else
+# ifdef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
+#  error "Port Me!"
+# endif
     context = device->numContexts ? device->contexts[0] : NULL;
 #endif
@@ -1925,8 +1975,11 @@
 void context_destroy(IWineD3DDeviceImpl *This, struct wined3d_context *context)
 {
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
     BOOL destroy;
+#endif
 
     TRACE("Destroying ctx %p\n", context);
 
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
     if (context->tid == GetCurrentThreadId() || !context->current)
     {
@@ -1940,11 +1993,16 @@
         destroy = FALSE;
     }
+#endif
 
     HeapFree(GetProcessHeap(), 0, context->vshader_const_dirty);
     HeapFree(GetProcessHeap(), 0, context->pshader_const_dirty);
     device_context_remove(This, context);
+#ifndef VBOX_WITH_WDDM
+    context->swapchain = NULL;
+#endif
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
     if (destroy) HeapFree(GetProcessHeap(), 0, context);
-#ifndef VBOX_WITH_WDDM
-    else context->swapchain = NULL;
+#else
+    VBoxTlsRefRelease(context);
 #endif
 }
@@ -2186,5 +2244,5 @@
  *****************************************************************************/
 static struct wined3d_context *findThreadContextForSwapChain(IWineD3DSwapChain *swapchain
-#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
         , DWORD tid
 #endif
@@ -2201,4 +2259,7 @@
     for (i = 0; i < device->numContexts; ++i)
     {
+#  ifdef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
+#   error "port me!"
+#  endif
         if (device->contexts[i]->tid == tid)
             return device->contexts[i];
@@ -2206,5 +2267,9 @@
 # else
     for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
+#  ifdef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
+        if(VBoxTlsRefIsFunctional(((IWineD3DSwapChainImpl *) swapchain)->context[i])) {
+#  else
         if(((IWineD3DSwapChainImpl *) swapchain)->context[i]->tid == tid) {
+#  endif
             return ((IWineD3DSwapChainImpl *) swapchain)->context[i];
         }
@@ -2234,10 +2299,16 @@
     IWineD3DSwapChain *swapchain = NULL;
     struct wined3d_context *current_context = context_get_current();
-#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+#ifndef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
     DWORD tid = GetCurrentThreadId();
 #endif
     struct wined3d_context *context;
 
-    if (current_context && current_context->destroyed) current_context = NULL;
+    if (current_context
+#ifndef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
+            && current_context->destroyed
+#else
+            && !VBoxTlsRefIsFunctional(current_context)
+#endif
+            ) current_context = NULL;
 
     if (!target)
@@ -2287,5 +2358,5 @@
 
         context = findThreadContextForSwapChain(swapchain
-#ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+#ifndef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
                 , tid
 #endif
@@ -2315,10 +2386,14 @@
 #ifdef VBOX_WITH_WDDM /* tmp work-around */
             context = findThreadContextForSwapChain(This->swapchains[This->NumberOfSwapChains-1]
-# ifndef VBOX_WINE_WITH_SINGLE_CONTEXT
+# ifndef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
                                                                      , tid
 # endif
                                                                      );
 #else
-            context = findThreadContextForSwapChain(This->swapchains[0], tid);
+            context = findThreadContextForSwapChain(This->swapchains[0]
+# ifndef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
+                                                                     , tid
+# endif
+                    );
 #endif
         }
@@ -2355,5 +2430,5 @@
 
 
-    if (context && context->destroyed)
+    if (context && !VBoxTlsRefIsFunctional(context))
     {
         ERR("context is destroyed");
@@ -2753,5 +2828,9 @@
     context_setup_target(device, context, target);
     context_enter(context);
-    if (!context->valid) return context;
+    if (!context->valid)
+    {
+        ERR("context_acquire failed to get a valid context!");
+        return context;
+    }
 
     if (context != current_context)
@@ -2792,6 +2871,14 @@
     }
 
+#ifdef DEBUG
+    Assert(context->tid == GetCurrentThreadId());
+#endif
+
     context_apply_state(context, device, usage);
 
+#ifdef DEBUG
+    Assert(context->tid == GetCurrentThreadId());
+#endif
+
     return context;
 }
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/device.c	(revision 39602)
@@ -6922,4 +6922,63 @@
 }
 
+static HRESULT WINAPI IWineD3DDeviceImpl_AddSwapChain(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    VOID *pvNewBuf = HeapReAlloc(GetProcessHeap(), 0, This->swapchains, (This->NumberOfSwapChains + 1) * sizeof(IWineD3DSwapChain *));
+    if(!pvNewBuf) {
+        ERR("Out of memory!\n");
+        return E_OUTOFMEMORY;
+    }
+    This->swapchains = (IWineD3DSwapChain **)pvNewBuf;
+    This->swapchains[This->NumberOfSwapChains] = swapchain;
+    ++This->NumberOfSwapChains;
+    return WINED3D_OK;
+}
+
+static HRESULT WINAPI IWineD3DDeviceImpl_RemoveSwapChain(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain)
+{
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    int i;
+    for (i = 0; i < This->NumberOfSwapChains; ++i)
+    {
+        if (This->swapchains[i] == swapchain)
+        {
+            break;
+        }
+    }
+
+    if (i == This->NumberOfSwapChains)
+    {
+        WARN("swapchain 0x%p is not part of device 0x%p\n", swapchain, iface);
+        return E_INVALIDARG;
+    }
+
+    --This->NumberOfSwapChains;
+    if (This->NumberOfSwapChains)
+    {
+        IWineD3DSwapChain **pvNewBuf = (IWineD3DSwapChain **)HeapAlloc(GetProcessHeap(), 0, (This->NumberOfSwapChains) * sizeof(IWineD3DSwapChain *));
+        if(!pvNewBuf) {
+            ERR("Out of memory!\n");
+            return E_OUTOFMEMORY;
+        }
+        if (i) {
+            memcpy (pvNewBuf, This->swapchains, i*sizeof(IWineD3DSwapChain *));
+        }
+        if (i < This->NumberOfSwapChains) {
+            memcpy (pvNewBuf + i, This->swapchains +i+1, (This->NumberOfSwapChains - i)*sizeof(IWineD3DSwapChain *));
+        }
+
+        This->swapchains = pvNewBuf;
+    }
+    else
+    {
+        while (This->numContexts)
+        {
+            context_destroy(This, This->contexts[0]);
+        }
+    }
+    return WINED3D_OK;
+}
+
 #ifdef VBOX_WITH_WDDM
 static HRESULT WINAPI IWineD3DDeviceImpl_Flush(IWineD3DDevice *iface)
@@ -6948,63 +7007,4 @@
         {
             WARN("Invalid context, skipping flush.\n");
-        }
-    }
-    return WINED3D_OK;
-}
-
-static HRESULT WINAPI IWineD3DDeviceImpl_AddSwapChain(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain)
-{
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
-    VOID *pvNewBuf = HeapReAlloc(GetProcessHeap(), 0, This->swapchains, (This->NumberOfSwapChains + 1) * sizeof(IWineD3DSwapChain *));
-    if(!pvNewBuf) {
-        ERR("Out of memory!\n");
-        return E_OUTOFMEMORY;
-    }
-    This->swapchains = (IWineD3DSwapChain **)pvNewBuf;
-    This->swapchains[This->NumberOfSwapChains] = swapchain;
-    ++This->NumberOfSwapChains;
-    return WINED3D_OK;
-}
-
-static HRESULT WINAPI IWineD3DDeviceImpl_RemoveSwapChain(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain)
-{
-    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
-    int i;
-    for (i = 0; i < This->NumberOfSwapChains; ++i)
-    {
-        if (This->swapchains[i] == swapchain)
-        {
-            break;
-        }
-    }
-
-    if (i == This->NumberOfSwapChains)
-    {
-        WARN("swapchain 0x%p is not part of device 0x%p\n", swapchain, iface);
-        return E_INVALIDARG;
-    }
-
-    --This->NumberOfSwapChains;
-    if (This->NumberOfSwapChains)
-    {
-        IWineD3DSwapChain **pvNewBuf = (IWineD3DSwapChain **)HeapAlloc(GetProcessHeap(), 0, (This->NumberOfSwapChains) * sizeof(IWineD3DSwapChain *));
-        if(!pvNewBuf) {
-            ERR("Out of memory!\n");
-            return E_OUTOFMEMORY;
-        }
-        if (i) {
-            memcpy (pvNewBuf, This->swapchains, i*sizeof(IWineD3DSwapChain *));
-        }
-        if (i < This->NumberOfSwapChains) {
-            memcpy (pvNewBuf + i, This->swapchains +i+1, (This->NumberOfSwapChains - i)*sizeof(IWineD3DSwapChain *));
-        }
-
-        This->swapchains = pvNewBuf;
-    }
-    else
-    {
-        while (This->numContexts)
-        {
-            context_destroy(This, This->contexts[0]);
         }
     }
@@ -7165,9 +7165,10 @@
     IWineD3DDeviceImpl_AcquireFocusWindow,
     IWineD3DDeviceImpl_ReleaseFocusWindow,
+    /* VBox extensions */
+    IWineD3DDeviceImpl_AddSwapChain,
+    IWineD3DDeviceImpl_RemoveSwapChain,
 #ifdef VBOX_WITH_WDDM
     /* VBox WDDM extensions */
     IWineD3DDeviceImpl_Flush,
-    IWineD3DDeviceImpl_AddSwapChain,
-    IWineD3DDeviceImpl_RemoveSwapChain,
 #endif
 };
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/directx.c	(revision 39602)
@@ -2208,7 +2208,5 @@
     gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;
 
-#ifdef VBOX_WITH_WDDM
     gl_info->supported[VBOX_SHARED_CONTEXTS] = TRUE;
-#endif
 
     while (*GL_Extensions)
@@ -2912,5 +2910,5 @@
             if (DevModeW.dmFields&DM_DISPLAYFLAGS)
             {
-#if defined(RT_ARCH_AMD64) && !defined(VBOX_WITH_WDDM)
+#if 0 //defined(RT_ARCH_AMD64) && !defined(VBOX_WITH_WDDM)
 # ifndef DM_INTERLACED
 #  define DM_INTERLACED 0x00000002
@@ -2931,5 +2929,5 @@
             if (DevModeW.dmFields&DM_DISPLAYORIENTATION)
             {
-#if defined(RT_ARCH_AMD64) && !defined(VBOX_WITH_WDDM)
+#if 0 //defined(RT_ARCH_AMD64) && !defined(VBOX_WITH_WDDM)
                 switch (DevModeW.dmDisplayOrientation)
 #else
@@ -2950,5 +2948,5 @@
                         break;
                     default:
-#if defined(RT_ARCH_AMD64) && !defined(VBOX_WITH_WDDM)
+#if 0 //defined(RT_ARCH_AMD64) && !defined(VBOX_WITH_WDDM)
                         WARN("Unexpected display orientation %#x", DevModeW.dmDisplayOrientation);
 #else
@@ -5205,5 +5203,5 @@
 #ifdef USE_WIN32_OPENGL
 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
-#ifdef VBOX_WITH_WDDM
+#if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
         BOOL (APIENTRY *pDrvValidateVersion)(DWORD) DECLSPEC_HIDDEN;
 #ifdef VBOX_WDDM_WOW64
@@ -5219,5 +5217,5 @@
             goto nogl_adapter;
         }
-#ifdef VBOX_WITH_WDDM
+#if defined(VBOX_WITH_WDDM) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
         /* init properly */
         pDrvValidateVersion = (void*)GetProcAddress(mod_gl, "DrvValidateVersion");
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface_base.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface_base.c	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/surface_base.c	(revision 39602)
@@ -40,4 +40,6 @@
 #include "wine/port.h"
 #include "wined3d_private.h"
+
+#include <float.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3d_surface);
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/swapchain.c	(revision 39602)
@@ -139,5 +139,5 @@
         This->backBuffer = NULL;
     }
-#ifndef VBOX_WITH_WDDM
+#if 0
     for (i = 0; i < This->num_contexts; ++i)
     {
@@ -146,4 +146,5 @@
 #else
 
+#ifdef VBOX_WITH_WDDM
     if (This->presentRt)
     {
@@ -153,4 +154,6 @@
         This->presentRt = NULL;
     }
+#endif
+
     IWineD3DDevice_RemoveSwapChain((IWineD3DDevice*)This->device, (IWineD3DSwapChain*)This);
     if (!This->device->NumberOfSwapChains)
@@ -479,5 +482,9 @@
     pwglSwapLayerBuffers(context->currentSwapchain->hDC, WGL_SWAP_MAIN_PLANE);
 #else
+# ifdef VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT
+    pwglSwapLayerBuffers(context->hdc, WGL_SWAP_MAIN_PLANE);
+# else
     SwapBuffers(context->hdc); /* TODO: cycle through the swapchain buffers */
+# endif
 #endif
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.c	(revision 39602)
@@ -15,4 +15,5 @@
  */
 #include "config.h"
+#include "wine/port.h"
 #include "wined3d_private.h"
 #include "vboxext.h"
@@ -23,11 +24,17 @@
 typedef FNVBOXEXTWORKERCB *PFNVBOXEXTWORKERCB;
 
-HRESULT VBoxExtDwSubmitProc(PFNVBOXEXTWORKERCB pfnCb, void *pvCb);
+HRESULT VBoxExtDwSubmitProcSync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb);
+HRESULT VBoxExtDwSubmitProcAsync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb);
 
 /*******************************/
-#if defined(VBOX_WDDM_WOW64)
+#ifdef VBOX_WITH_WDDM
+# if defined(VBOX_WDDM_WOW64)
 # define VBOXEXT_WINE_MODULE_NAME "wined3dwddm-x86.dll"
+# else
+# define VBOXEXT_WINE_MODULE_NAME "wined3dwddm.dll"
+# endif
 #else
-# define VBOXEXT_WINE_MODULE_NAME "wined3dwddm.dll"
+/* both 32bit and 64bit versions of xpdm wine libs are named identically */
+# define VBOXEXT_WINE_MODULE_NAME "wined3d.dll"
 #endif
 
@@ -61,5 +68,6 @@
 static VBOXEXT_GLOBAL g_VBoxExtGlobal;
 
-#define WM_VBOXEXT_CALLPROC (WM_APP+1)
+#define WM_VBOXEXT_CALLPROC  (WM_APP+1)
+#define WM_VBOXEXT_INIT_QUIT (WM_APP+2)
 
 typedef struct VBOXEXT_CALLPROC
@@ -103,4 +111,10 @@
                 pData->pfnCb(pData->pvCb);
                 SetEvent(pWorker->hEvent);
+                break;
+            }
+            case WM_VBOXEXT_INIT_QUIT:
+            case WM_CLOSE:
+            {
+                PostQuitMessage(0);
                 break;
             }
@@ -165,5 +179,5 @@
 HRESULT VBoxExtWorkerDestroy(PVBOXEXT_WORKER pWorker)
 {
-    BOOL bResult = PostThreadMessage(pWorker->idThread, WM_QUIT, 0, 0);
+    BOOL bResult = PostThreadMessage(pWorker->idThread, WM_VBOXEXT_INIT_QUIT, 0, 0);
     DWORD dwErr;
     if (!bResult)
@@ -191,5 +205,5 @@
 }
 
-static HRESULT vboxExtWorkerSubmit(VBOXEXT_WORKER *pWorker, UINT Msg, LPARAM lParam)
+static HRESULT vboxExtWorkerSubmit(VBOXEXT_WORKER *pWorker, UINT Msg, LPARAM lParam, BOOL fSync)
 {
     HRESULT hr = E_FAIL;
@@ -201,13 +215,18 @@
     if (bResult)
     {
-        DWORD dwErr = WaitForSingleObject(pWorker->hEvent, INFINITE);
-        if (dwErr == WAIT_OBJECT_0)
-        {
+        if (fSync)
+        {
+            DWORD dwErr = WaitForSingleObject(pWorker->hEvent, INFINITE);
+            if (dwErr == WAIT_OBJECT_0)
+            {
+                hr = S_OK;
+            }
+            else
+            {
+                ERR("WaitForSingleObject returned (%d)", dwErr);
+            }
+        }
+        else
             hr = S_OK;
-        }
-        else
-        {
-            ERR("WaitForSingleObject returned (%d)", dwErr);
-        }
     }
     else
@@ -221,11 +240,42 @@
 }
 
-HRESULT VBoxExtWorkerSubmitProc(PVBOXEXT_WORKER pWorker, PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
+HRESULT VBoxExtWorkerSubmitProcSync(PVBOXEXT_WORKER pWorker, PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
 {
     VBOXEXT_CALLPROC Ctx;
     Ctx.pfnCb = pfnCb;
     Ctx.pvCb = pvCb;
-    return vboxExtWorkerSubmit(pWorker, WM_VBOXEXT_CALLPROC, (LPARAM)&Ctx);
-}
+    return vboxExtWorkerSubmit(pWorker, WM_VBOXEXT_CALLPROC, (LPARAM)&Ctx, TRUE);
+}
+
+static DECLCALLBACK(void) vboxExtWorkerSubmitProcAsyncWorker(void *pvUser)
+{
+    PVBOXEXT_CALLPROC pCallInfo = (PVBOXEXT_CALLPROC)pvUser;
+    pCallInfo[1].pfnCb(pCallInfo[1].pvCb);
+    HeapFree(GetProcessHeap(), 0, pCallInfo);
+}
+
+HRESULT VBoxExtWorkerSubmitProcAsync(PVBOXEXT_WORKER pWorker, PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
+{
+    HRESULT hr;
+    PVBOXEXT_CALLPROC pCallInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof (VBOXEXT_CALLPROC) * 2);
+    if (!pCallInfo)
+    {
+        ERR("HeapAlloc failed\n");
+        return E_OUTOFMEMORY;
+    }
+    pCallInfo[0].pfnCb = vboxExtWorkerSubmitProcAsyncWorker;
+    pCallInfo[0].pvCb = pCallInfo;
+    pCallInfo[1].pfnCb = pfnCb;
+    pCallInfo[1].pvCb = pvCb;
+    hr = vboxExtWorkerSubmit(pWorker, WM_VBOXEXT_CALLPROC, (LPARAM)pCallInfo, FALSE);
+    if (FAILED(hr))
+    {
+        ERR("vboxExtWorkerSubmit failed, hr 0x%x\n", hr);
+        HeapFree(GetProcessHeap(), 0, pCallInfo);
+        return hr;
+    }
+    return S_OK;
+}
+
 
 static HRESULT vboxExtInit()
@@ -295,9 +345,16 @@
 }
 
-HRESULT VBoxExtDwSubmitProc(PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
-{
-    return VBoxExtWorkerSubmitProc(&g_VBoxExtGlobal.Worker, pfnCb, pvCb);
-}
-
+HRESULT VBoxExtDwSubmitProcSync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
+{
+    return VBoxExtWorkerSubmitProcSync(&g_VBoxExtGlobal.Worker, pfnCb, pvCb);
+}
+
+HRESULT VBoxExtDwSubmitProcAsync(PFNVBOXEXTWORKERCB pfnCb, void *pvCb)
+{
+    return VBoxExtWorkerSubmitProcAsync(&g_VBoxExtGlobal.Worker, pfnCb, pvCb);
+}
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# ifndef VBOX_WITH_WDDM
 typedef struct VBOXEXT_GETDC_CB
 {
@@ -324,8 +381,7 @@
     pData->ret = ReleaseDC(pData->hWnd, pData->hDC);
 }
-#if 0
+
 HDC VBoxExtGetDC(HWND hWnd)
 {
-#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
     HRESULT hr;
     VBOXEXT_GETDC_CB Data = {0};
@@ -333,20 +389,16 @@
     Data.hDC = NULL;
 
-    hr = VBoxExtDwSubmitProc(vboxExtGetDCWorker, &Data);
+    hr = VBoxExtDwSubmitProcSync(vboxExtGetDCWorker, &Data);
     if (FAILED(hr))
     {
-        ERR("VBoxExtDwSubmitProc feiled, hr (0x%x)\n", hr);
+        ERR("VBoxExtDwSubmitProcSync feiled, hr (0x%x)\n", hr);
         return NULL;
     }
 
     return Data.hDC;
-#else
-    return GetDC(hWnd);
-#endif
 }
 
 int VBoxExtReleaseDC(HWND hWnd, HDC hDC)
 {
-#ifdef VBOX_WINE_WITH_SINGLE_CONTEXT
     HRESULT hr;
     VBOXEXT_RELEASEDC_CB Data = {0};
@@ -355,17 +407,36 @@
     Data.ret = 0;
 
-    hr = VBoxExtDwSubmitProc(vboxExtReleaseDCWorker, &Data);
+    hr = VBoxExtDwSubmitProcSync(vboxExtReleaseDCWorker, &Data);
     if (FAILED(hr))
     {
-        ERR("VBoxExtDwSubmitProc feiled, hr (0x%x)\n", hr);
+        ERR("VBoxExtDwSubmitProcSync feiled, hr (0x%x)\n", hr);
         return -1;
     }
 
     return Data.ret;
-#else
-    return ReleaseDC(hWnd, hDC);
-#endif
-}
-#endif
+}
+# endif /* #ifndef VBOX_WITH_WDDM */
+
+static DECLCALLBACK(void) vboxExtReleaseContextWorker(void *pvUser)
+{
+    struct wined3d_context *context = (struct wined3d_context *)pvUser;
+    wined3d_mutex_lock();
+    VBoxTlsRefRelease(context);
+    wined3d_mutex_unlock();
+}
+
+void VBoxExtReleaseContextAsync(struct wined3d_context *context)
+{
+    HRESULT hr;
+
+    hr = VBoxExtDwSubmitProcAsync(vboxExtReleaseContextWorker, context);
+    if (FAILED(hr))
+    {
+        ERR("VBoxExtDwSubmitProcAsync feiled, hr (0x%x)\n", hr);
+        return;
+    }
+}
+
+#endif /* #if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT) */
 
 /* window creation API */
@@ -507,5 +578,5 @@
     Info.hWnd = hWnd;
     Info.hDC = hDC;
-    hr = VBoxExtDwSubmitProc(vboxExtWndDestroyWorker, &Info);
+    hr = VBoxExtDwSubmitProcSync(vboxExtWndDestroyWorker, &Info);
     Assert(hr == S_OK);
     if (hr == S_OK)
@@ -524,5 +595,5 @@
     Info.width = width;
     Info.height = height;
-    hr = VBoxExtDwSubmitProc(vboxExtWndCreateWorker, &Info);
+    hr = VBoxExtDwSubmitProcSync(vboxExtWndCreateWorker, &Info);
     Assert(hr == S_OK);
     if (hr == S_OK)
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.h	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/vboxext.h	(revision 39602)
@@ -17,11 +17,13 @@
 #define ___VBOXEXT_H__
 
-#include <windows.h>
+#ifdef VBOX_WINE_WITHOUT_LIBWINE
+# include <windows.h>
+#endif
 #include <iprt/cdefs.h>
-
 
 HRESULT VBoxExtCheckInit();
 HRESULT VBoxExtCheckTerm();
-#if 0
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# ifndef VBOX_WITH_WDDM
 /* Windows destroys HDC created by a given thread when the thread is terminated
  * this leads to a mess-up in Wine & Chromium code in some situations, e.g.
@@ -30,4 +32,12 @@
 HDC VBoxExtGetDC(HWND hWnd);
 int VBoxExtReleaseDC(HWND hWnd, HDC hDC);
+# endif
+/* We need to do a VBoxTlsRefRelease for the current thread context on thread exit to avoid memory leaking
+ * Calling VBoxTlsRefRelease may result in a call to context dtor callback, which is supposed to be run under wined3d lock.
+ * We can not acquire a wined3d lock in DllMain since this would result in a lock order violation, which may result in a deadlock.
+ * In other words, wined3d may internally call Win32 API functions which result in a DLL lock acquisition while holding wined3d lock.
+ * So lock order should always be "wined3d lock" -> "dll lock".
+ * To avoid possible deadlocks we make an asynchronous call to a worker thread to make a context release from there. */
+void VBoxExtReleaseContextAsync(struct wined3d_context *context);
 #endif
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_gl.h	(revision 39602)
@@ -1845,7 +1845,6 @@
     WGL_WINE_PIXEL_FORMAT_PASSTHROUGH,
 
-#ifdef VBOX_WITH_WDDM
     VBOX_SHARED_CONTEXTS,
-#endif
+
     /* Internally used */
     WINE_NORMALIZED_TEXRECT,
@@ -3775,5 +3774,4 @@
         const PIXELFORMATDESCRIPTOR *ppfd);
 
-#ifdef VBOX_WITH_WDDM
 #define GL_SHARE_CONTEXT_RESOURCES_CR 0x8B27
 #define GL_FLUSH_ON_THREAD_SWITCH_CR  0x8B28
@@ -3784,7 +3782,4 @@
                 glChromiumParameteriCR,                VBOX_SHARED_CONTEXTS,            NULL) \
 
-#else
-# define VBOXWDDM_GL_EXT_FUNCS_GEN
-#endif
 
 #define GL_EXT_FUNCS_GEN \
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_main.c	(revision 39602)
@@ -96,5 +96,4 @@
     HRESULT hr;
 
-#ifdef VBOX_WITH_WDDM
     hr = VBoxExtCheckInit();
     if (FAILED(hr))
@@ -103,5 +102,4 @@
         return NULL;
     }
-#endif
 
     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
@@ -109,7 +107,5 @@
     {
         ERR("Failed to allocate wined3d object memory.\n");
-#ifdef VBOX_WITH_WDDM
         VBoxExtCheckTerm();
-#endif
         return NULL;
     }
@@ -151,15 +147,13 @@
 }
 
-#ifdef VBOX_WITH_WDDM
-void WINAPI wined3d_mutex_init(void)
+static void WINAPI wined3d_mutex_init(void)
 {
     InitializeCriticalSection(&wined3d_cs);
 }
 
-void WINAPI wined3d_mutex_term(void)
+static void WINAPI wined3d_mutex_term(void)
 {
     DeleteCriticalSection(&wined3d_cs);
 }
-#endif
 
 static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
@@ -174,7 +168,5 @@
     WNDCLASSA wc;
 
-#ifdef VBOX_WITH_WDDM
     wined3d_mutex_init();
-#endif
 
     wined3d_context_tls_idx = TlsAlloc();
@@ -183,7 +175,6 @@
         DWORD err = GetLastError();
         ERR("Failed to allocate context TLS index, err %#x.\n", err);
-#ifdef VBOX_WITH_WDDM
+
         wined3d_mutex_term();
-#endif
         return FALSE;
     }
@@ -212,7 +203,7 @@
             ERR("Failed to free context TLS index, err %#x.\n", err);
         }
-#ifdef VBOX_WITH_WDDM
+
         wined3d_mutex_term();
-#endif
+
         return FALSE;
     }
@@ -413,7 +404,5 @@
     UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
 
-#ifdef VBOX_WITH_WDDM
     wined3d_mutex_term();
-#endif
 
     return TRUE;
@@ -544,8 +533,12 @@
         case DLL_THREAD_DETACH:
         {
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+            context_clear_on_thread_detach();
+#else
             if (!context_set_current(NULL))
             {
                 ERR("Failed to clear current context.\n");
             }
+#endif
             return TRUE;
         }
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h	(revision 39601)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Wine/wined3d/wined3d_private.h	(revision 39602)
@@ -51,8 +51,4 @@
 #include "wine/debug.h"
 #include "wine/unicode.h"
-#ifdef VBOX_WITH_WDDM
-# include "vboxext.h"
-#endif
-
 
 #ifndef VBOX_WINE_WITHOUT_LIBWINE
@@ -64,6 +60,15 @@
 #include "wine/rbtree.h"
 
+#include "vboxext.h"
+
 #ifdef VBOX_WITH_WDDM
 # include "vboxsharedrc.h"
+#endif
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+# define VBoxTlsRefGetImpl(_tls) (TlsGetValue((DWORD)(_tls)))
+# define VBoxTlsRefSetImpl(_tls, _val) (TlsSetValue((DWORD)(_tls), (_val)))
+# define VBoxTlsRefAssertImpl Assert
+# include <VBox/VBoxVideo3D.h>
 #endif
 
@@ -1121,5 +1126,7 @@
     WORD num_untracked_materials : 2;   /* Max value 2 */
     WORD current : 1;
+#if !defined(VBOX_WINE_WITH_SINGLE_CONTEXT) && !defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
     WORD destroyed : 1;
+#endif
     WORD valid : 1;
     BYTE texShaderBumpMap;              /* MAX_TEXTURES, 8 */
@@ -1142,4 +1149,9 @@
     HDC                     hdc;
 #endif
+
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+    VBOXTLSREFDATA
+#endif
+
     int pixel_format;
     GLint                   aux_buffers;
@@ -1288,5 +1300,7 @@
 void context_set_tls_idx(DWORD idx) DECLSPEC_HIDDEN;
 void context_surface_update(struct wined3d_context *context, IWineD3DSurfaceImpl *surface) DECLSPEC_HIDDEN;
-
+#if defined(VBOX_WINE_WITH_SINGLE_CONTEXT) || defined(VBOX_WINE_WITH_SINGLE_SWAPCHAIN_CONTEXT)
+void context_clear_on_thread_detach();
+#endif
 /* Macros for doing basic GPU detection based on opengl capabilities */
 #define WINE_D3D6_CAPABLE(gl_info) (gl_info->supported[ARB_MULTITEXTURE])
Index: /trunk/src/VBox/Additions/common/crOpenGL/context.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/context.c	(revision 39601)
+++ /trunk/src/VBox/Additions/common/crOpenGL/context.c	(revision 39602)
@@ -397,5 +397,5 @@
 
 #ifdef CHROMIUM_THREADSAFE
-    crTSDRefInit(context, stubContextDtor);
+    VBoxTlsRefInit(context, stubContextDtor);
 #endif
 
@@ -1192,5 +1192,5 @@
     }
 
-    crTSDRefRelease(context);
+    VBoxTlsRefRelease(context);
 #else
     stubDestroyContextLocked(context);
Index: /trunk/src/VBox/Additions/common/crOpenGL/load.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/load.c	(revision 39601)
+++ /trunk/src/VBox/Additions/common/crOpenGL/load.c	(revision 39602)
@@ -27,7 +27,4 @@
 # include <unistd.h>
 #endif
-#ifdef CHROMIUM_THREADSAFE
-#include "cr_threads.h"
-#endif
 
 #ifdef VBOX_WITH_WDDM
@@ -69,4 +66,5 @@
 Stub stub;
 #ifdef CHROMIUM_THREADSAFE
+static bool g_stubIsCurrentContextTSDInited;
 CRtsd g_stubCurrentContextTSD;
 #endif
@@ -510,4 +508,14 @@
     exit(0);  /* this causes stubExitHandler() to be called */
 }
+
+#ifndef RT_OS_WINDOWS
+# ifdef CHROMIUM_THREADSAFE
+static DECLCALLBACK(void) stubThreadTlsDtor(void *pvValue)
+{
+    ContextInfo *pCtx = (ContextInfo*)pvValue;
+    VBoxTlsRefRelease(pCtx);
+}
+# endif
+#endif
 
 
@@ -547,5 +555,9 @@
 #ifndef RT_OS_WINDOWS
 # ifdef CHROMIUM_THREADSAFE
-    crInitTSD(&g_stubCurrentContextTSD);
+    if (!g_stubIsCurrentContextTSDInited)
+    {
+        crInitTSDF(&g_stubCurrentContextTSD, stubThreadTlsDtor);
+        g_stubIsCurrentContextTSDInited = true;
+    }
 # endif
 #endif
@@ -1411,8 +1423,11 @@
         stubSPUSafeTearDown();
 
+#ifdef CHROMIUM_THREADSAFE
+        crFreeTSD(&g_stubCurrentContextTSD);
+#endif
+
 #ifdef VDBG_VEHANDLER
         vboxVDbgVEHandlerUnregister();
 #endif
-
         break;
     }
Index: /trunk/src/VBox/Additions/common/crOpenGL/stub.h
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/stub.h	(revision 39601)
+++ /trunk/src/VBox/Additions/common/crOpenGL/stub.h	(revision 39602)
@@ -56,4 +56,7 @@
 #endif
 
+#ifdef CHROMIUM_THREADSAFE
+# include <cr_threads.h>
+#endif
 /*#define VBOX_TEST_MEGOO*/
 
@@ -113,5 +116,5 @@
 
 #ifdef CHROMIUM_THREADSAFE
-    CRTSDREFDATA
+    VBOXTLSREFDATA
 #endif
 
@@ -265,14 +268,6 @@
 
 #ifdef CHROMIUM_THREADSAFE
-# define stubGetCurrentContext() crTSDRefGetCurrent(ContextInfo, &g_stubCurrentContextTSD)
-# define stubSetCurrentContext(_ctx) crTSDRefSetCurrent(ContextInfo, &g_stubCurrentContextTSD, _ctx)
-#else
-# define stubGetCurrentContext() (stub.currentContext)
-# define stubSetCurrentContext(_ctx) do { stub.currentContext = (_ctx); } while (0)
-#endif
-
-extern Stub stub;
-/* we place the __currentContextTSD outside the Stub data because Stub data is inited by the client's call,
- * while we need __currentContextTSD the __currentContextTSD to be valid at any time to be able to handle
+/* we place the g_stubCurrentContextTLS outside the Stub data because Stub data is inited by the client's call,
+ * while we need g_stubCurrentContextTLS the g_stubCurrentContextTLS to be valid at any time to be able to handle
  * THREAD_DETACH cleanup on windows.
  * Note that we can not do
@@ -284,7 +279,15 @@
  * Note that GetModuleFileName acquires the loader lock.
  * */
-#ifdef CHROMIUM_THREADSAFE
 extern CRtsd g_stubCurrentContextTSD;
-#endif
+
+# define stubGetCurrentContext() VBoxTlsRefGetCurrent(ContextInfo, &g_stubCurrentContextTSD)
+# define stubSetCurrentContext(_ctx) VBoxTlsRefSetCurrent(ContextInfo, &g_stubCurrentContextTSD, _ctx)
+#else
+# define stubGetCurrentContext() (stub.currentContext)
+# define stubSetCurrentContext(_ctx) do { stub.currentContext = (_ctx); } while (0)
+#endif
+
+extern Stub stub;
+
 extern DECLEXPORT(SPUDispatchTable) glim;
 extern SPUDispatchTable stubThreadsafeDispatch;
Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h	(revision 39601)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h	(revision 39602)
@@ -47,5 +47,5 @@
 
 #ifdef CHROMIUM_THREADSAFE
-#include "cr_threads.h"
+# include <cr_threads.h>
 #endif
 
@@ -133,5 +133,5 @@
      * => Thread2 still refers to destroyed ctx1
      * */
-    CRTSDREFDATA
+    VBOXTLSREFDATA
 #endif
 
Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_threads.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_threads.h	(revision 39601)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_threads.h	(revision 39602)
@@ -101,60 +101,9 @@
 extern DECLEXPORT(void) crSignalSemaphore(CRsemaphore *s);
 
-typedef DECLCALLBACK(void) FNCRTSDREFDTOR(void*);
-typedef FNCRTSDREFDTOR *PFNCRTSDREFDTOR;
+#define VBoxTlsRefGetImpl(_tls) (crGetTSD((CRtsd*)(_tls)))
+#define VBoxTlsRefSetImpl(_tls, _val) (crSetTSD((CRtsd*)(_tls), (_val)))
+#define VBoxTlsRefAssertImpl CRASSERT
+#include <VBox/VBoxVideo3D.h>
 
-typedef enum {
-    CRTSDREFDATA_STATE_UNDEFINED = 0,
-    CRTSDREFDATA_STATE_INITIALIZED,
-    CRTSDREFDATA_STATE_TOBE_DESTROYED,
-    CRTSDREFDATA_STATE_DESTROYING,
-    CRTSDREFDATA_STATE_32BIT_HACK = 0x7fffffff
-} CRTSDREFDATA_STATE;
-
-#define CRTSDREFDATA \
-    volatile int32_t cTsdRefs; \
-    uint32_t enmTsdRefState; \
-    PFNCRTSDREFDTOR pfnTsdRefDtor; \
-
-#define crTSDRefInit(_p, _pfnDtor) do { \
-        (_p)->cTsdRefs = 1; \
-        (_p)->enmTsdRefState = CRTSDREFDATA_STATE_INITIALIZED; \
-        (_p)->pfnTsdRefDtor = (_pfnDtor); \
-    } while (0)
-
-#define crTSDRefIsFunctional(_p) (!!((_p)->enmTsdRefState == CRTSDREFDATA_STATE_INITIALIZED))
-
-#define crTSDRefAddRef(_p) do { \
-        int cRefs = ASMAtomicIncS32(&(_p)->cTsdRefs); \
-        CRASSERT(cRefs > 1 || (_p)->enmTsdRefState == CRTSDREFDATA_STATE_DESTROYING); \
-    } while (0)
-
-#define crTSDRefRelease(_p) do { \
-        int cRefs = ASMAtomicDecS32(&(_p)->cTsdRefs); \
-        CRASSERT(cRefs >= 0); \
-        if (!cRefs && (_p)->enmTsdRefState != CRTSDREFDATA_STATE_DESTROYING /* <- avoid recursion if crTSDRefAddRef/Release is called from dtor */) { \
-            (_p)->enmTsdRefState = CRTSDREFDATA_STATE_DESTROYING; \
-            (_p)->pfnTsdRefDtor((_p)); \
-        } \
-    } while (0)
-
-#define crTSDRefReleaseMarkDestroy(_p) do { \
-        (_p)->enmTsdRefState = CRTSDREFDATA_STATE_TOBE_DESTROYED; \
-    } while (0)
-
-#define crTSDRefGetCurrent(_t, _pTsd) ((_t*) crGetTSD((_pTsd)))
-
-#define crTSDRefSetCurrent(_t, _pTsd, _p) do { \
-        _t * oldCur = crTSDRefGetCurrent(_t, _pTsd); \
-        if (oldCur != (_p)) { \
-            crSetTSD((_pTsd), (_p)); \
-            if (oldCur) { \
-                crTSDRefRelease(oldCur); \
-            } \
-            if ((_p)) { \
-                crTSDRefAddRef((_t*)(_p)); \
-            } \
-        } \
-    } while (0)
 #ifdef __cplusplus
 }
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h	(revision 39601)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h	(revision 39602)
@@ -9,7 +9,4 @@
 
 #include "cr_glstate.h"
-#ifdef CHROMIUM_THREADSAFE
-#include "cr_threads.h"
-#endif
 
 typedef struct _crCheckIDHWID {
@@ -23,11 +20,13 @@
 
 #ifdef CHROMIUM_THREADSAFE
+#include <cr_threads.h>
+
 extern CRtsd __contextTSD;
-#define GetCurrentContext() crTSDRefGetCurrent(CRContext, &__contextTSD)
+#define GetCurrentContext() VBoxTlsRefGetCurrent(CRContext, &__contextTSD)
 
 /* NOTE: below SetCurrentContext stuff is supposed to be used only internally!!
  * it is placed here only to simplify things since some code besides state_init.c
  * (i.e. state_glsl.c) is using it */
-#define SetCurrentContext(_ctx) crTSDRefSetCurrent(CRContext, &__contextTSD, _ctx)
+#define SetCurrentContext(_ctx) VBoxTlsRefSetCurrent(CRContext, &__contextTSD, _ctx)
 #else
 extern CRContext *__currentContext;
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c	(revision 39601)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c	(revision 39602)
@@ -175,7 +175,7 @@
 #ifdef CHROMIUM_THREADSAFE
     CRASSERT(g != ctx);
-    crTSDRefAddRef(ctx); /* <- this is a hack to avoid subsequent SetCurrentContext(g) do recursive Destroy for ctx */
+    VBoxTlsRefAddRef(ctx); /* <- this is a hack to avoid subsequent SetCurrentContext(g) do recursive Destroy for ctx */
     if (g)
-        crTSDRefAddRef(g); /* <- ensure the g is not destroyed by the following SetCurrentContext call */
+        VBoxTlsRefAddRef(g); /* <- ensure the g is not destroyed by the following SetCurrentContext call */
     SetCurrentContext(ctx);
 #else
@@ -189,6 +189,6 @@
     SetCurrentContext(g);
     if (g)
-        crTSDRefRelease(g);
-    crTSDRefRelease(ctx); /* <- restore back the cRefs (see above) */
+        VBoxTlsRefRelease(g);
+    VBoxTlsRefRelease(ctx); /* <- restore back the cRefs (see above) */
 #else
     __currentContext = g;
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c	(revision 39601)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c	(revision 39602)
@@ -11,4 +11,5 @@
 
 #ifdef CHROMIUM_THREADSAFE
+static bool __isContextTLSInited = false;
 CRtsd __contextTSD;
 #else
@@ -168,5 +169,5 @@
     ctx->id = i;
 #ifdef CHROMIUM_THREADSAFE
-    crTSDRefInit(ctx, crStateContextDtor);
+    VBoxTlsRefInit(ctx, crStateContextDtor);
 #endif
     ctx->flush_func = NULL;
@@ -291,4 +292,13 @@
 }
 
+#ifdef CHROMIUM_THREADSAFE
+# ifndef RT_OS_WINDOWS
+static DECLCALLBACK(void) crStateThreadTlsDtor(void *pvValue)
+{
+    CRContext *pCtx = (CRContext*)pvValue;
+    VBoxTlsRefRelease(pCtx);
+}
+# endif
+#endif
 
 /*
@@ -316,4 +326,18 @@
         g_availableContexts[i] = 0;
 
+#ifdef CHROMIUM_THREADSAFE
+    if (!__isContextTLSInited)
+    {
+# ifndef RT_OS_WINDOWS
+        /* tls destructor is implemented for all platforms except windows*/
+        crInitTSDF(&__contextTSD, crStateThreadTlsDtor);
+# else
+        /* windows should do cleanup via DllMain THREAD_DETACH notification */
+        crInitTSD(&__contextTSD);
+# endif
+        __isContextTLSInited = 1;
+    }
+#endif
+
     if (defaultContext) {
         /* Free the default/NULL context.
@@ -321,5 +345,5 @@
 #ifdef CHROMIUM_THREADSAFE
         SetCurrentContext(NULL);
-        crTSDRefRelease(defaultContext);
+        VBoxTlsRefRelease(defaultContext);
 #else
         crStateFreeContext(defaultContext);
@@ -355,4 +379,5 @@
 #ifdef CHROMIUM_THREADSAFE
     crFreeTSD(&__contextTSD);
+    __isContextTLSInited = 0;
 #endif
 }
@@ -457,5 +482,5 @@
 
 #ifdef CHROMIUM_THREADSAFE
-    crTSDRefRelease(ctx);
+    VBoxTlsRefRelease(ctx);
 #else
     crStateFreeContext(ctx);
