[7/12] WineD3D: Select an onscreen context based on the thread

Stefan Dösinger stefan at codeweavers.com
Mon Feb 26 06:49:20 CST 2007


-------------- next part --------------
From 0be729985a9a6e0b61f3005cbed69e94c628a777 Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Sat, 24 Feb 2007 23:22:36 +0100
Subject: [PATCH] WineD3D: Select an onscreen context based on the thread

This patch enables ActivateContext to search for an onscreen context when the rendering thread is changed.
No offscreen rendering is supported yet, and onscreen context are not created yet for multithreading.

This code is thread safe because ActivateContext is protected by ENTER_GL() / LEAVE_GL().
---
 dlls/wined3d/context.c         |   30 +++++++++++++++++++++++++++---
 dlls/wined3d/device.c          |    1 +
 dlls/wined3d/wined3d_private.h |    5 +++--
 3 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index a623917..3a815b3 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -311,6 +311,7 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
     }
     ret->surface = (IWineD3DSurface *) target;
     ret->isPBuffer = win == 0;
+    ret->tid = This->createParms.BehaviorFlags & WINED3DCREATE_MULTITHREADED ? GetCurrentThreadId() : 0;
 
     TRACE("Successfully created new context %p\n", ret);
 
@@ -596,7 +597,8 @@ 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;
+    BOOL multithreaded = This->createParms.BehaviorFlags & WINED3DCREATE_MULTITHREADED;
+    DWORD tid = multithreaded ? GetCurrentThreadId() : 0;
     int                           i;
     DWORD                         dirtyState, idx;
     BYTE                          shift;
@@ -605,7 +607,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;
@@ -613,7 +615,23 @@ 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];
+
+            if(multithreaded) {
+                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");
+                }
+            } else {
+                context = ((IWineD3DSwapChainImpl *) swapchain)->context[0];
+            }
             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
@@ -628,10 +646,16 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
             if(oldRenderOffscreen) {
                 Context_MarkStateDirty(context, WINED3DRS_CULLMODE);
             }
+
         } 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 1cb59ab..7f08fcc 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1751,6 +1751,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
     }
     IWineD3DSurface_AddRef(This->render_targets[0]);
     This->activeContext = swapchain->context[0];
+    This->lastThread = This->createParms.BehaviorFlags & WINED3DCREATE_MULTITHREADED ? GetCurrentThreadId() : 0;
 
     /* Depth Stencil support */
     This->stencilBufferTarget = This->depthStencilBuffer;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a441cee..45e69bf 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -690,8 +690,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 */
 };
-- 
1.4.4.3



More information about the wine-patches mailing list