[6/12] WineD3D: Store an array of contexts in the swapchain

Stefan Dösinger stefan at codeweavers.com
Mon Feb 26 07:44:57 CST 2007


Seemed to be stuck too, resending
-------------- next part --------------
From fbc4d8422f8e65f7d7a30ecdd82329f4ea9dbf16 Mon Sep 17 00:00:00 2001
From: Stefan Doesinger <stefan at codeweavers.com>
Date: Fri, 23 Feb 2007 23:12:07 +0100
Subject: [PATCH] WineD3D: Store an array of contexts in the swapchain

This is a preparation for using multiple contexts on one drawable to handle multithreading.
---
 dlls/wined3d/context.c         |    8 ++++----
 dlls/wined3d/device.c          |   17 +++++++++++------
 dlls/wined3d/swapchain.c       |   16 ++++++++++------
 dlls/wined3d/wined3d_private.h |    5 +++--
 4 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index c4715d5..a623917 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -613,7 +613,7 @@ 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;
+            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
@@ -641,7 +641,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
                         /* This may happen if the app jumps streight into offscreen rendering
                          * Start using the context of the primary swapchain
                          */
-                        context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context;
+                        context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0];
                     }
                     set_render_target_fbo((IWineD3DDevice *) This, 0, target);
                     break;
@@ -660,7 +660,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
                          * Create the context on the same server as the primary swapchain. The primary swapchain is exists at this point.
                          */
                         This->pbufferContext = CreateContext(This, targetimpl,
-                                                             ((IWineD3DSwapChainImpl *) This->swapchains[0])->context->display,
+                                                             ((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0]->display,
                                                              0 /* Window */);
                         This->pbufferWidth = targetimpl->currentDesc.Width;
                         This->pbufferHeight = targetimpl->currentDesc.Height;
@@ -683,7 +683,7 @@ void ActivateContext(IWineD3DDeviceImpl *This, IWineD3DSurface *target, ContextU
                         /* This may happen if the app jumps streight into offscreen rendering
                          * Start using the context of the primary swapchain
                          */
-                        context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context;
+                        context = ((IWineD3DSwapChainImpl *) This->swapchains[0])->context[0];
                     }
                     break;
             }
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 02625ef..1cb59ab 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1413,10 +1413,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic
     *     doesn't match actual visual? Cannot choose one here - code removed as it ONLY works if the one
     *     it chooses is identical to the one already being used!
      **********************************/
-
     /** FIXME: Handle stencil appropriately via EnableAutoDepthStencil / AutoDepthStencilFormat **/
+
+    object->context = HeapAlloc(GetProcessHeap(), 0, sizeof(object->context));
+    if(!object->context) {
+    }
+    object->num_contexts = 1;
+
     ENTER_GL();
-    object->context = CreateContext(This, (IWineD3DSurfaceImpl *) object->frontBuffer, display, object->win);
+    object->context[0] = CreateContext(This, (IWineD3DSurfaceImpl *) object->frontBuffer, display, object->win);
     LEAVE_GL();
 
     if (!object->context) {
@@ -1425,7 +1430,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateAdditionalSwapChain(IWineD3DDevic
         goto error;
     } else {
         TRACE("Context created (HWND=%p, glContext=%p, Window=%ld)\n",
-               object->win_handle, object->context->glCtx, object->win);
+               object->win_handle, object->context[0]->glCtx, object->win);
     }
 
    /*********************
@@ -1563,7 +1568,7 @@ error:
         object->backBuffer = NULL;
     }
     if(object->context) {
-        DestroyContext(This, object->context);
+        DestroyContext(This, object->context[0]);
     }
     if(object->frontBuffer) {
         IWineD3DSurface_GetParent(object->frontBuffer, &bufferParent);
@@ -1745,7 +1750,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
         This->lastActiveRenderTarget = swapchain->frontBuffer;
     }
     IWineD3DSurface_AddRef(This->render_targets[0]);
-    This->activeContext = swapchain->context;
+    This->activeContext = swapchain->context[0];
 
     /* Depth Stencil support */
     This->stencilBufferTarget = This->depthStencilBuffer;
@@ -1763,7 +1768,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface, WINED3DPR
     *  with Default values
     */
 
-    ((IWineD3DImpl *) This->wineD3D)->isGLInfoValid = IWineD3DImpl_FillGLCaps( This->wineD3D, swapchain->context->display);
+    ((IWineD3DImpl *) This->wineD3D)->isGLInfoValid = IWineD3DImpl_FillGLCaps(This->wineD3D, swapchain->context[0]->display);
     /* Setup all the devices defaults */
     IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)This->stateBlock);
 #if 0
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 08695a0..2977a05 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -105,6 +105,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_GetParent(IWineD3DSwapChain *iface,
 static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB_DESTROYSURFACEFN D3DCB_DestroyRenderTarget) {
     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
     WINED3DDISPLAYMODE mode;
+    int i;
 
     /* release the ref to the front and back buffer parents */
     if(This->frontBuffer) {
@@ -136,7 +137,10 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface, D3DCB
         mode.Format = This->orig_fmt;
         IWineD3DDevice_SetDisplayMode((IWineD3DDevice *) This->wineD3DDevice, 0, &mode);
     }
-    DestroyContext(This->wineD3DDevice, This->context);
+    for(i = 0; i < This->num_contexts; i++) {
+        DestroyContext(This->wineD3DDevice, This->context[i]);
+    }
+    HeapFree(GetProcessHeap(), 0, This->context);
 
     HeapFree(GetProcessHeap(), 0, This);
 }
@@ -190,7 +194,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
 
     if (pSourceRect || pDestRect) FIXME("Unhandled present options %p/%p\n", pSourceRect, pDestRect);
     /* TODO: If only source rect or dest rect are supplied then clip the window to match */
-    TRACE("preseting display %p, drawable %ld\n", This->context->display, This->context->drawable);
+    TRACE("preseting display %p, drawable %ld\n", This->context[0]->display, This->context[0]->drawable);
 
     /* Don't call checkGLcall, as glGetError is not applicable here */
     if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
@@ -200,7 +204,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
         BYTE *mem;
 
         TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, hDestWindowOverride);
-        if(This->context == This->wineD3DDevice->contexts[0]) {
+        if(This->context[0] == This->wineD3DDevice->contexts[0]) {
             /* The primary context 'owns' all the opengl resources. Destroying and recreating that context would require downloading
              * all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts
              * and reload the resources
@@ -222,8 +226,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
             memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
             IWineD3DSurface_UnlockRect(This->backBuffer[0]);
 
-            DestroyContext(This->wineD3DDevice, This->context);
-            This->context = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer, display, This->win);
+            DestroyContext(This->wineD3DDevice, This->context[0]);
+            This->context[0] = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer, display, This->win);
 
             IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD);
             memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
@@ -232,7 +236,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
         }
     }
 
-    glXSwapBuffers(This->context->display, This->context->drawable); /* TODO: cycle through the swapchain buffers */
+    glXSwapBuffers(This->context[0]->display, This->context[0]->drawable); /* TODO: cycle through the swapchain buffers */
 
     TRACE("glXSwapBuffers called, Starting new frame\n");
     /* FPS support */
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index e314fd1..a441cee 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -473,7 +473,7 @@ struct WineD3DContext {
     DWORD                   isStateDirty[STATE_HIGHEST/32 + 1]; /* Bitmap to find out quickly if a state is dirty */
 
     IWineD3DSurface         *surface;
-    /* TODO: Thread this ctx belongs to                    */
+    DWORD                   tid;    /* Thread ID which owns this context at the moment */
 
     /* Stores some inforation about the context state for optimization */
     BOOL                    last_was_rhw;      /* true iff last draw_primitive was in xyzrhw mode */
@@ -1331,7 +1331,8 @@ typedef struct IWineD3DSwapChainImpl
 
     long prev_time, frames;   /* Performance tracking */
 
-    WineD3DContext         *context; /* Later a array for multithreading */
+    WineD3DContext        **context; /* Later a array for multithreading */
+    unsigned int            num_contexts;
 
     HWND                    win_handle;
     Window                  win;
-- 
1.4.4.3



More information about the wine-patches mailing list