Stefan Dösinger : wined3d: Add a swapchain method to set the dest override.

Alexandre Julliard julliard at winehq.org
Tue Aug 19 08:46:29 CDT 2008


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Mon Jul 28 22:34:32 2008 -0500

wined3d: Add a swapchain method to set the dest override.

DDraw can draw to the front buffer only, thus there's never a Present
call which could pass this window. Due to that a drawing-independent
method is needed.

---

 dlls/wined3d/swapchain.c         |   73 +++++++++++++++++++++----------------
 dlls/wined3d/swapchain_gdi.c     |    8 ++++
 include/wine/wined3d_interface.h |    2 +
 3 files changed, 51 insertions(+), 32 deletions(-)

diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 9ec296c..1a82ab8 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -144,38 +144,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
 
     /* Don't call checkGLcall, as glGetError is not applicable here */
     if (hDestWindowOverride && This->win_handle != hDestWindowOverride) {
-        WINED3DLOCKED_RECT r;
-        BYTE *mem;
-
-        TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, hDestWindowOverride);
-        if(This->context[0] == This->wineD3DDevice->contexts[0]) {
-            /* The primary context 'owns' all the opengl resources. Destroying and recreating that context requires downloading
-             * all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts
-             * and reload the resources
-             */
-            delete_opengl_contexts((IWineD3DDevice *) This->wineD3DDevice, iface);
-            This->win_handle             = hDestWindowOverride;
-            create_primary_opengl_context((IWineD3DDevice *) This->wineD3DDevice, iface);
-        } else {
-            This->win_handle             = hDestWindowOverride;
-
-            /* The old back buffer has to be copied over to the new back buffer. A lockrect - switchcontext - unlockrect
-             * would suffice in theory, but it is rather nasty and may cause troubles with future changes of the locking code
-             * So lock read only, copy the surface out, then lock with the discard flag and write back
-             */
-            IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_READONLY);
-            mem = HeapAlloc(GetProcessHeap(), 0, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
-            memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
-            IWineD3DSurface_UnlockRect(This->backBuffer[0]);
-
-            DestroyContext(This->wineD3DDevice, This->context[0]);
-            This->context[0] = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer, This->win_handle, FALSE /* pbuffer */, &This->presentParms);
-
-            IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD);
-            memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
-            HeapFree(GetProcessHeap(), 0, mem);
-            IWineD3DSurface_UnlockRect(This->backBuffer[0]);
-        }
+        IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride);
     }
 
     SwapBuffers(This->context[0]->hdc); /* TODO: cycle through the swapchain buffers */
@@ -335,6 +304,45 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
     return WINED3D_OK;
 }
 
+static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window) {
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+    WINED3DLOCKED_RECT r;
+    BYTE *mem;
+
+    if(window == This->win_handle) return WINED3D_OK;
+
+    TRACE("Performing dest override of swapchain %p from window %p to %p\n", This, This->win_handle, window);
+    if(This->context[0] == This->wineD3DDevice->contexts[0]) {
+        /* The primary context 'owns' all the opengl resources. Destroying and recreating that context requires downloading
+         * all opengl resources, deleting the gl resources, destroying all other contexts, then recreating all other contexts
+         * and reload the resources
+         */
+        delete_opengl_contexts((IWineD3DDevice *) This->wineD3DDevice, iface);
+        This->win_handle             = window;
+        create_primary_opengl_context((IWineD3DDevice *) This->wineD3DDevice, iface);
+    } else {
+        This->win_handle             = window;
+
+        /* The old back buffer has to be copied over to the new back buffer. A lockrect - switchcontext - unlockrect
+         * would suffice in theory, but it is rather nasty and may cause troubles with future changes of the locking code
+         * So lock read only, copy the surface out, then lock with the discard flag and write back
+         */
+        IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_READONLY);
+        mem = HeapAlloc(GetProcessHeap(), 0, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
+        memcpy(mem, r.pBits, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
+        IWineD3DSurface_UnlockRect(This->backBuffer[0]);
+
+        DestroyContext(This->wineD3DDevice, This->context[0]);
+        This->context[0] = CreateContext(This->wineD3DDevice, (IWineD3DSurfaceImpl *) This->frontBuffer, This->win_handle, FALSE /* pbuffer */, &This->presentParms);
+
+        IWineD3DSurface_LockRect(This->backBuffer[0], &r, NULL, WINED3DLOCK_DISCARD);
+        memcpy(r.pBits, mem, r.Pitch * ((IWineD3DSurfaceImpl *) This->backBuffer[0])->currentDesc.Height);
+        HeapFree(GetProcessHeap(), 0, mem);
+        IWineD3DSurface_UnlockRect(This->backBuffer[0]);
+    }
+    return WINED3D_OK;
+}
+
 const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
 {
     /* IUnknown */
@@ -346,6 +354,7 @@ const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
     IWineD3DSwapChainImpl_Destroy,
     IWineD3DBaseSwapChainImpl_GetDevice,
     IWineD3DSwapChainImpl_Present,
+    IWineD3DSwapChainImpl_SetDestWindowOverride,
     IWineD3DBaseSwapChainImpl_GetFrontBufferData,
     IWineD3DBaseSwapChainImpl_GetBackBuffer,
     IWineD3DBaseSwapChainImpl_GetRasterStatus,
diff --git a/dlls/wined3d/swapchain_gdi.c b/dlls/wined3d/swapchain_gdi.c
index 7aa81c2..d76b9b5 100644
--- a/dlls/wined3d/swapchain_gdi.c
+++ b/dlls/wined3d/swapchain_gdi.c
@@ -156,6 +156,13 @@ void x11_copy_to_screen(IWineD3DSwapChainImpl *This, LPRECT rc) {
     }
 }
 
+static HRESULT WINAPI IWineGDISwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window) {
+    IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
+
+    This->win_handle = window;
+    return WINED3D_OK;
+}
+
 static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
     IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
     IWineD3DSurfaceImpl *front, *back;
@@ -254,6 +261,7 @@ const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl =
     IWineGDISwapChainImpl_Destroy,
     IWineD3DBaseSwapChainImpl_GetDevice,
     IWineGDISwapChainImpl_Present,
+    IWineGDISwapChainImpl_SetDestWindowOverride,
     IWineD3DBaseSwapChainImpl_GetFrontBufferData,
     IWineD3DBaseSwapChainImpl_GetBackBuffer,
     IWineD3DBaseSwapChainImpl_GetRasterStatus,
diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h
index 0768b0a..d2c8a2c 100644
--- a/include/wine/wined3d_interface.h
+++ b/include/wine/wined3d_interface.h
@@ -1421,6 +1421,7 @@ DECLARE_INTERFACE_(IWineD3DSwapChain,IWineD3DBase)
     STDMETHOD_(void, Destroy)(THIS_ D3DCB_DESTROYSURFACEFN pFn) PURE;
     STDMETHOD(GetDevice)(THIS_ IWineD3DDevice **ppDevice) PURE;
     STDMETHOD(Present)(THIS_ CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) PURE;
+    STDMETHOD(SetDestWindowOverride)(THIS_ HWND window);
     STDMETHOD(GetFrontBufferData)(THIS_ IWineD3DSurface *pDestSurface) PURE;
     STDMETHOD(GetBackBuffer)(THIS_ UINT iBackBuffer, WINED3DBACKBUFFER_TYPE Type, IWineD3DSurface **ppBackBuffer) PURE;
     STDMETHOD(GetRasterStatus)(THIS_ WINED3DRASTER_STATUS *pRasterStatus) PURE;
@@ -1442,6 +1443,7 @@ DECLARE_INTERFACE_(IWineD3DSwapChain,IWineD3DBase)
 #define IWineD3DSwapChain_Destroy(p,a)                 (p)->lpVtbl->Destroy(p,a)
 #define IWineD3DSwapChain_GetDevice(p,a)               (p)->lpVtbl->GetDevice(p,a)
 #define IWineD3DSwapChain_Present(p,a,b,c,d,e)         (p)->lpVtbl->Present(p,a,b,c,d,e)
+#define IWineD3DSwapChain_SetDestWindowOverride(p,a)   (p)->lpVtbl->SetDestWindowOverride(p,a)
 #define IWineD3DSwapChain_GetFrontBufferData(p,a)      (p)->lpVtbl->GetFrontBufferData(p,a)
 #define IWineD3DSwapChain_GetBackBuffer(p,a,b,c)       (p)->lpVtbl->GetBackBuffer(p,a,b,c)
 #define IWineD3DSwapChain_GetRasterStatus(p,a)         (p)->lpVtbl->GetRasterStatus(p,a)




More information about the wine-cvs mailing list