From 90fe64cee017dc5e835dc1b1ab22f76b14ccab53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sun, 4 Mar 2007 17:31:06 +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 ead24ee93a8..0849b3db2ce 100644 --- a/dlls/wined3d/context.c +++ b/dlls/wined3d/context.c @@ -616,7 +616,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 @@ -652,7 +652,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; @@ -671,7 +671,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; @@ -694,7 +694,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]; } glDrawBuffer(This->offscreenBuffer); checkGLcall("glDrawBuffer(This->offscreenBuffer)"); diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 7b80b4ae74c..da1b8c92238 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1351,10 +1351,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) { @@ -1363,7 +1368,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); } /********************* @@ -1501,7 +1506,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); @@ -1682,7 +1687,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; @@ -1700,7 +1705,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 8b6187513e7..d46067d41a7 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); } @@ -192,7 +196,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) { @@ -202,7 +206,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 @@ -224,8 +228,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); @@ -234,7 +238,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 3ec80de2419..74a6b42f063 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -506,7 +506,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 */ @@ -1357,7 +1357,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;