Stefan Dösinger : wined3d: Select onscreen contexts based on the thread id.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Jul 3 08:01:24 CDT 2007


Module: wine
Branch: master
Commit: 13f24c380814614714d7a4f172be2c998f4efcfe
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=13f24c380814614714d7a4f172be2c998f4efcfe

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sat Jun  2 20:20:17 2007 +0000

wined3d: Select onscreen contexts based on the thread id.

---

 dlls/wined3d/context.c         |   24 +++++++++++++++++++++---
 dlls/wined3d/device.c          |    1 +
 dlls/wined3d/wined3d_private.h |    5 +++--
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 5b2ab01..0f2529a 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -312,6 +312,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
     }
     ret->surface = (IWineD3DSurface *) target;
     ret->isPBuffer = win == 0;
+    ret->tid = GetCurrentThreadId();
 
     TRACE("Successfully created new context %p\n", ret);
 
@@ -641,7 +642,7 @@ static inline void SetupForBlit(IWineD3DDeviceImpl *This, WineD3DContext *contex
  *
  *****************************************************************************/
 void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextUsage usage) {
-    DWORD tid = This->createParms.BehaviorFlags & WINED3DCREATE_MULTITHREADED ? GetCurrentThreadId() : 0;
+    DWORD                         tid = GetCurrentThreadId();
     int                           i;
     DWORD                         dirtyState, idx;
     BYTE                          shift;
@@ -650,7 +651,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
 
     TRACE("(%p): Selecting context for render target %p, thread %d\n", This, target, tid);
 
-    if(This->lastActiveRenderTarget != target) {
+    if(This->lastActiveRenderTarget != target || tid != This->lastThread) {
         IWineD3DSwapChain *swapchain = NULL;
         HRESULT hr;
         BOOL readTexture = wined3d_settings.offscreen_rendering_mode != ORM_FBO && This->render_offscreen;
@@ -658,7 +659,18 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
         hr = IWineD3DSurface_GetContainer(target, &IID_IWineD3DSwapChain, (void **) &swapchain);
         if(hr == WINED3D_OK && swapchain) {
             TRACE("Rendering onscreen\n");
-            context = ((IWineD3DSwapChainImpl *) swapchain)->context[0];
+
+            context = NULL;
+            for(i = 0; i < ((IWineD3DSwapChainImpl *) swapchain)->num_contexts; i++) {
+                if(((IWineD3DSwapChainImpl *) swapchain)->context[i]->tid == tid) {
+                    context = ((IWineD3DSwapChainImpl *) swapchain)->context[i];
+                }
+            }
+
+            if(!context) {
+                /* TODO: Create a new context for the thread */
+                FIXME("Context creation for a new thread not implemented yet\n");
+            }
             This->render_offscreen = FALSE;
             /* The context != This->activeContext will catch a NOP context change. This can occur
              * if we are switching back to swapchain rendering in case of FBO or Back Buffer offscreen
@@ -682,10 +694,16 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
                 Context_MarkStateDirty(context, STATE_VDECL);
                 Context_MarkStateDirty(context, STATE_VIEWPORT);
             }
+
         } else {
             TRACE("Rendering offscreen\n");
             This->render_offscreen = TRUE;
 
+            if(tid != This->lastThread) {
+                FIXME("Offscreen rendering is only supported from the creation thread yet\n");
+                FIXME("Expect a crash now ...\n");
+            }
+
             switch(wined3d_settings.offscreen_rendering_mode) {
                 case ORM_FBO:
                     /* FBOs do not need a different context. Stay with whatever context is active at the moment */
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 4a15b33..4749113 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1851,6 +1851,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
     }
     IWineD3DSurface_AddRef(This->render_targets[0]);
     This->activeContext = swapchain->context[0];
+    This->lastThread = GetCurrentThreadId();
 
     /* Depth Stencil support */
     This->stencilBufferTarget = This->depthStencilBuffer;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index dbfe40c..89f207e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -736,8 +736,9 @@ struct IWineD3DDeviceImpl
 
     /* Context management */
     WineD3DContext          **contexts;                  /* Dynamic array containing pointers to context structures */
-    WineD3DContext          *activeContext;              /* Only 0 for now      */
-    UINT                    numContexts;                 /* Always 1 for now    */
+    WineD3DContext          *activeContext;
+    DWORD                   lastThread;
+    UINT                    numContexts;
     WineD3DContext          *pbufferContext;             /* The context that has a pbuffer as drawable */
     DWORD                   pbufferWidth, pbufferHeight; /* Size of the buffer drawable */
 };




More information about the wine-cvs mailing list