[PATCH 10/10] wined3d: Implement SetDestWindowOverride() by simply making the context current on a different window.

Henri Verbeet hverbeet at codeweavers.com
Mon Mar 15 15:07:31 CDT 2010


---
 dlls/wined3d/context.c         |   47 ++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/swapchain.c       |   44 ++++++-------------------------------
 dlls/wined3d/wined3d_private.h |    1 +
 3 files changed, 55 insertions(+), 37 deletions(-)

diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 91f647b..4d28cd4 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -688,6 +688,49 @@ static BOOL context_set_pixel_format(const struct wined3d_gl_info *gl_info, HDC
     return TRUE;
 }
 
+static void context_update_window(struct wined3d_context *context)
+{
+    TRACE("Updating context %p window from %p to %p.\n",
+            context, context->win_handle, context->swapchain->win_handle);
+
+    if (context->valid)
+    {
+        if (!ReleaseDC(context->win_handle, context->hdc))
+        {
+            ERR("Failed to release device context %p, last error %#x.\n",
+                    context->hdc, GetLastError());
+        }
+    }
+    else context->valid = 1;
+
+    context->win_handle = context->swapchain->win_handle;
+
+    if (!(context->hdc = GetDC(context->win_handle)))
+    {
+        ERR("Failed to get a device context for window %p.\n", context->win_handle);
+        goto err;
+    }
+
+    if (!context_set_pixel_format(context->gl_info, context->hdc, context->pixel_format))
+    {
+        ERR("Failed to set pixel format %d on device context %p.\n",
+                context->pixel_format, context->hdc);
+        goto err;
+    }
+
+    if (!pwglMakeCurrent(context->hdc, context->glCtx))
+    {
+        ERR("Failed to make GL context %p current on device context %p, last error %#x.\n",
+                context->glCtx, context->hdc, GetLastError());
+        goto err;
+    }
+
+    return;
+
+err:
+    context->valid = 0;
+}
+
 static void context_validate(struct wined3d_context *context)
 {
     HWND wnd = WindowFromDC(context->hdc);
@@ -698,6 +741,9 @@ static void context_validate(struct wined3d_context *context)
                 context->hdc, wnd, context->win_handle);
         context->valid = 0;
     }
+
+    if (context->win_handle != context->swapchain->win_handle)
+        context_update_window(context);
 }
 
 static void context_destroy_gl_resources(struct wined3d_context *context)
@@ -1298,6 +1344,7 @@ struct wined3d_context *context_create(IWineD3DSwapChainImpl *swapchain, IWineD3
     ret->glCtx = ctx;
     ret->win_handle = swapchain->win_handle;
     ret->hdc = hdc;
+    ret->pixel_format = pixel_format;
 
     if (device->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *)device))
     {
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 43a0713..79c2bd8 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -514,46 +514,16 @@ 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 || 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->device->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->device, iface);
-        This->win_handle = window;
-        create_primary_opengl_context((IWineD3DDevice *)This->device, iface);
-    }
-    else
-    {
-        This->win_handle = window;
+static HRESULT WINAPI IWineD3DSwapChainImpl_SetDestWindowOverride(IWineD3DSwapChain *iface, HWND window)
+{
+    IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)iface;
 
-        /* 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]);
+    if (!window) window = swapchain->device_window;
+    if (window == swapchain->win_handle) return WINED3D_OK;
 
-        context_destroy(This->device, This->context[0]);
-        This->context[0] = context_create(This, (IWineD3DSurfaceImpl *)This->frontBuffer);
-        context_release(This->context[0]);
+    TRACE("Setting swapchain %p window from %p to %p\n", swapchain, swapchain->win_handle, window);
+    swapchain->win_handle = window;
 
-        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;
 }
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 66a7afa..3c362bf 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1088,6 +1088,7 @@ struct wined3d_context
     HGLRC                   glCtx;
     HWND                    win_handle;
     HDC                     hdc;
+    int pixel_format;
     GLint                   aux_buffers;
 
     /* FBOs */
-- 
1.6.4.4




More information about the wine-patches mailing list