Module: wine Branch: master Commit: 7f2b8f9bba906b8620eb6c643a86c65b69d022fb URL: http://source.winehq.org/git/wine.git/?a=commit;h=7f2b8f9bba906b8620eb6c643a...
Author: Stefan Dösinger stefan@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])