Stefan Dösinger : wined3d: Support redirecting the primary context.

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


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Jul 29 12:09:34 2008 -0500

wined3d: Support redirecting the primary context.

---

 dlls/wined3d/device.c          |  153 ++++++++++++++++++++++------------------
 dlls/wined3d/swapchain.c       |    6 +-
 dlls/wined3d/wined3d_private.h |    3 +
 3 files changed, 92 insertions(+), 70 deletions(-)

diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 836b318..abcd90f 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -7239,15 +7239,92 @@ static BOOL is_display_mode_supported(IWineD3DDeviceImpl *This, WINED3DPRESENT_P
     return FALSE;
 }
 
+void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface;
+    UINT i;
+    IWineD3DBaseShaderImpl *shader;
+
+    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
+        reset_fbo_state((IWineD3DDevice *) This);
+    }
+
+    IWineD3DDevice_EnumResources(iface, reset_unload_resources, NULL);
+    LIST_FOR_EACH_ENTRY(shader, &This->shaders, IWineD3DBaseShaderImpl, baseShader.shader_list_entry) {
+        This->shader_backend->shader_destroy((IWineD3DBaseShader *) shader);
+    }
+
+    ENTER_GL();
+    if(This->depth_blt_texture) {
+        glDeleteTextures(1, &This->depth_blt_texture);
+        This->depth_blt_texture = 0;
+    }
+    if (This->depth_blt_rb) {
+        GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb));
+        This->depth_blt_rb = 0;
+        This->depth_blt_rb_w = 0;
+        This->depth_blt_rb_h = 0;
+    }
+    This->frag_pipe->free_private(iface);
+    This->shader_backend->shader_free_private(iface);
+
+    for (i = 0; i < GL_LIMITS(textures); i++) {
+        /* Textures are recreated below */
+        glDeleteTextures(1, &This->dummyTextureName[i]);
+        checkGLcall("glDeleteTextures(1, &This->dummyTextureName[i])");
+        This->dummyTextureName[i] = 0;
+    }
+    LEAVE_GL();
+
+    while(This->numContexts) {
+        DestroyContext(This, This->contexts[0]);
+    }
+    This->activeContext = NULL;
+    HeapFree(GetProcessHeap(), 0, swapchain->context);
+    swapchain->context = NULL;
+    swapchain->num_contexts = 0;
+}
+
+HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain_iface) {
+    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
+    IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) swapchain_iface;
+    HRESULT hr;
+    IWineD3DSurfaceImpl *target;
+
+    /* Recreate the primary swapchain's context */
+    swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context));
+    if(swapchain->backBuffer) {
+        target = (IWineD3DSurfaceImpl *) swapchain->backBuffer[0];
+    } else {
+        target = (IWineD3DSurfaceImpl *) swapchain->frontBuffer;
+    }
+    swapchain->context[0] = CreateContext(This, target, swapchain->win_handle, FALSE,
+                                          &swapchain->presentParms);
+    swapchain->num_contexts = 1;
+    This->activeContext = swapchain->context[0];
+
+    create_dummy_textures(This);
+
+    hr = This->shader_backend->shader_alloc_private(iface);
+    if(FAILED(hr)) {
+        ERR("Failed to recreate shader private data\n");
+        return hr;
+    }
+    hr = This->frag_pipe->alloc_private(iface);
+    if(FAILED(hr)) {
+        TRACE("Fragment pipeline private data couldn't be allocated\n");
+        return hr;
+    }
+
+    return WINED3D_OK;
+}
+
 static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRESENT_PARAMETERS* pPresentationParameters) {
     IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
     IWineD3DSwapChainImpl *swapchain;
     HRESULT hr;
     BOOL DisplayModeChanged = FALSE;
     WINED3DDISPLAYMODE mode;
-    IWineD3DBaseShaderImpl *shader;
-    IWineD3DSurfaceImpl *target;
-    UINT i;
     TRACE("(%p)\n", This);
 
     hr = IWineD3DDevice_GetSwapChain(iface, 0, (IWineD3DSwapChain **) &swapchain);
@@ -7308,46 +7385,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
         ERR("What do do about a changed auto depth stencil parameter?\n");
     }
 
-    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) {
-        reset_fbo_state((IWineD3DDevice *) This);
-    }
-
-    IWineD3DDevice_EnumResources(iface, reset_unload_resources, NULL);
-    LIST_FOR_EACH_ENTRY(shader, &This->shaders, IWineD3DBaseShaderImpl, baseShader.shader_list_entry) {
-        This->shader_backend->shader_destroy((IWineD3DBaseShader *) shader);
-    }
-
-    ENTER_GL();
-    if(This->depth_blt_texture) {
-        glDeleteTextures(1, &This->depth_blt_texture);
-        This->depth_blt_texture = 0;
-    }
-    if (This->depth_blt_rb) {
-        GL_EXTCALL(glDeleteRenderbuffersEXT(1, &This->depth_blt_rb));
-        This->depth_blt_rb = 0;
-        This->depth_blt_rb_w = 0;
-        This->depth_blt_rb_h = 0;
-    }
-    This->frag_pipe->free_private(iface);
-    This->shader_backend->shader_free_private(iface);
-
-    for (i = 0; i < GL_LIMITS(textures); i++) {
-        /* Textures are recreated below */
-        glDeleteTextures(1, &This->dummyTextureName[i]);
-        checkGLcall("glDeleteTextures(1, &This->dummyTextureName[i])");
-        This->dummyTextureName[i] = 0;
-    }
-    LEAVE_GL();
-
-    while(This->numContexts) {
-        DestroyContext(This, This->contexts[0]);
-    }
-    This->activeContext = NULL;
-    HeapFree(GetProcessHeap(), 0, swapchain->context);
-    swapchain->context = NULL;
-    swapchain->num_contexts = 0;
+    delete_opengl_contexts(iface, (IWineD3DSwapChain *) swapchain);
 
-     if(pPresentationParameters->Windowed) {
+    if(pPresentationParameters->Windowed) {
         mode.Width = swapchain->orig_width;
         mode.Height = swapchain->orig_height;
         mode.RefreshRate = 0;
@@ -7413,41 +7453,18 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
         This->exStyle = exStyle;
     }
 
-    /* Recreate the primary swapchain's context */
-    swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(*swapchain->context));
-    if(swapchain->backBuffer) {
-        target = (IWineD3DSurfaceImpl *) swapchain->backBuffer[0];
-    } else {
-        target = (IWineD3DSurfaceImpl *) swapchain->frontBuffer;
-    }
-    swapchain->context[0] = CreateContext(This, target, swapchain->win_handle, FALSE,
-                                          &swapchain->presentParms);
-    swapchain->num_contexts = 1;
-    This->activeContext = swapchain->context[0];
-    IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
-
     hr = IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *) This->stateBlock);
     if(FAILED(hr)) {
         ERR("Resetting the stateblock failed with error 0x%08x\n", hr);
     }
-    create_dummy_textures(This);
-
 
-    hr = This->shader_backend->shader_alloc_private(iface);
-    if(FAILED(hr)) {
-        ERR("Failed to recreate shader private data\n");
-        return hr;
-    }
-    hr = This->frag_pipe->alloc_private(iface);
-    if(FAILED(hr)) {
-        TRACE("Fragment pipeline private data couldn't be allocated\n");
-        return hr;
-    }
+    hr = create_primary_opengl_context(iface, (IWineD3DSwapChain *) swapchain);
+    IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
 
     /* All done. There is no need to reload resources or shaders, this will happen automatically on the
      * first use
      */
-    return WINED3D_OK;
+    return hr;
 }
 
 static HRESULT WINAPI IWineD3DDeviceImpl_SetDialogBoxMode(IWineD3DDevice *iface, BOOL bEnableDialogs) {
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 72b1c7c..9ec296c 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -149,11 +149,13 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
 
         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 would require downloading
+            /* 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
              */
-            ERR("Cannot change the destination window of the owner of the primary context\n");
+            delete_opengl_contexts((IWineD3DDevice *) This->wineD3DDevice, iface);
+            This->win_handle             = hDestWindowOverride;
+            create_primary_opengl_context((IWineD3DDevice *) This->wineD3DDevice, iface);
         } else {
             This->win_handle             = hDestWindowOverride;
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0c163f4..3cdfd1a 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -629,6 +629,9 @@ WineD3DContext *CreateContext(IWineD3DDeviceImpl *This, IWineD3DSurfaceImpl *tar
 void DestroyContext(IWineD3DDeviceImpl *This, WineD3DContext *context);
 void apply_fbo_state(IWineD3DDevice *iface);
 
+void delete_opengl_contexts(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain);
+HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwapChain *swapchain);
+
 /* Macros for doing basic GPU detection based on opengl capabilities */
 #define WINE_D3D6_CAPABLE(gl_info) (gl_info->supported[ARB_MULTITEXTURE])
 #define WINE_D3D7_CAPABLE(gl_info) (gl_info->supported[ARB_TEXTURE_COMPRESSION] && gl_info->supported[ARB_TEXTURE_CUBE_MAP] && gl_info->supported[ARB_TEXTURE_ENV_DOT3])




More information about the wine-cvs mailing list