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