Module: wine
Branch: master
Commit: dd2c7d0d8c61ab226789b860990095ff91c608fb
URL: http://source.winehq.org/git/wine.git/?a=commit;h=dd2c7d0d8c61ab226789b8609…
Author: Henri Verbeet <hverbeet(a)codeweavers.com>
Date: Thu Apr 7 18:46:01 2011 +0200
wined3d: Don't free D3D swapchains until the wined3d swapchain is destroyed.
This will allow us the get rid of the swapchain refcounting hacks in d3d9 in
particular. This is similar to the way we handle resources that are still in
use by a stateblock, but aren't referenced anywhere by the application.
---
dlls/d3d8/swapchain.c | 31 +++++++++++++++++++++++++++----
dlls/d3d9/swapchain.c | 28 ++++++++++++++++++++++++----
dlls/ddraw/ddraw.c | 2 +-
dlls/dxgi/swapchain.c | 18 +++++++++++++++---
dlls/wined3d/device.c | 4 ++--
dlls/wined3d/swapchain.c | 5 ++++-
dlls/wined3d/wined3d_private.h | 4 +++-
include/wine/wined3d.idl | 1 +
8 files changed, 77 insertions(+), 16 deletions(-)
Diff: http://source.winehq.org/git/wine.git/?a=commitdiff;h=dd2c7d0d8c61ab226789b…
Module: wine
Branch: master
Commit: d19c3588bc3c6fa8a6cf4fa42efeb5a3746b4ee6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d19c3588bc3c6fa8a6cf4fa42…
Author: Henri Verbeet <hverbeet(a)codeweavers.com>
Date: Thu Apr 7 18:46:00 2011 +0200
wined3d: Merge the IWineD3DSwapChain::Destroy() implementations.
They're mostly the same, except for the GL version also destroying its
contexts, and being a bit more careful about the order in which backbuffers
are destroyed.
---
dlls/wined3d/swapchain.c | 175 ++++++++++++++++-----------------------------
1 files changed, 62 insertions(+), 113 deletions(-)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index ddd946d..4ab2209 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -25,6 +25,65 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(fps);
+/* Do not call while under the GL lock. */
+static void WINAPI IWineD3DBaseSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
+{
+ IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)iface;
+ WINED3DDISPLAYMODE mode;
+ UINT i;
+
+ TRACE("Destroying swapchain %p.\n", iface);
+
+ IWineD3DSwapChain_SetGammaRamp(iface, 0, &swapchain->orig_gamma);
+
+ /* Release the swapchain's draw buffers. Make sure swapchain->back_buffers[0]
+ * is the last buffer to be destroyed, FindContext() depends on that. */
+ if (swapchain->front_buffer)
+ {
+ surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_NONE, NULL);
+ if (IWineD3DSurface_Release((IWineD3DSurface *)swapchain->front_buffer))
+ WARN("Something's still holding the front buffer (%p).\n", swapchain->front_buffer);
+ swapchain->front_buffer = NULL;
+ }
+
+ if (swapchain->back_buffers)
+ {
+ i = swapchain->presentParms.BackBufferCount;
+
+ while (i--)
+ {
+ surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_NONE, NULL);
+ if (IWineD3DSurface_Release((IWineD3DSurface *)swapchain->back_buffers[i]))
+ WARN("Something's still holding back buffer %u (%p).\n", i, swapchain->back_buffers[i]);
+ }
+ HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
+ swapchain->back_buffers = NULL;
+ }
+
+ for (i = 0; i < swapchain->num_contexts; ++i)
+ {
+ context_destroy(swapchain->device, swapchain->context[i]);
+ }
+
+ /* Restore the screen resolution if we rendered in fullscreen.
+ * This will restore the screen resolution to what it was before creating
+ * the swapchain. In case of d3d8 and d3d9 this will be the original
+ * desktop resolution. In case of d3d7 this will be a NOP because ddraw
+ * sets the resolution before starting up Direct3D, thus orig_width and
+ * orig_height will be equal to the modes in the presentation params. */
+ if (!swapchain->presentParms.Windowed && swapchain->presentParms.AutoRestoreDisplayMode)
+ {
+ mode.Width = swapchain->orig_width;
+ mode.Height = swapchain->orig_height;
+ mode.RefreshRate = 0;
+ mode.Format = swapchain->orig_fmt;
+ IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)swapchain->device, 0, &mode);
+ }
+
+ HeapFree(GetProcessHeap(), 0, swapchain->context);
+ HeapFree(GetProcessHeap(), 0, swapchain);
+}
+
static HRESULT WINAPI IWineD3DBaseSwapChainImpl_QueryInterface(IWineD3DSwapChain *iface, REFIID riid, void **object)
{
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
@@ -63,7 +122,7 @@ static ULONG WINAPI IWineD3DBaseSwapChainImpl_Release(IWineD3DSwapChain *iface)
TRACE("%p decreasing refcount to %u.\n", swapchain, refcount);
if (!refcount)
- IWineD3DSwapChain_Destroy(iface);
+ IWineD3DBaseSwapChainImpl_Destroy(iface);
return refcount;
}
@@ -213,67 +272,6 @@ static HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetGammaRamp(IWineD3DSwapChain *
return WINED3D_OK;
}
-/* Do not call while under the GL lock. */
-static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
-{
- IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *)iface;
- WINED3DDISPLAYMODE mode;
- unsigned int i;
-
- TRACE("Destroying swapchain %p\n", iface);
-
- IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
-
- /* Release the swapchain's draw buffers. Make sure This->back_buffers[0] is
- * the last buffer to be destroyed, FindContext() depends on that. */
- if (This->front_buffer)
- {
- surface_set_container(This->front_buffer, WINED3D_CONTAINER_NONE, NULL);
- if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer))
- {
- WARN("(%p) Something's still holding the front buffer (%p).\n",
- This, This->front_buffer);
- }
- This->front_buffer = NULL;
- }
-
- if (This->back_buffers)
- {
- UINT i = This->presentParms.BackBufferCount;
-
- while (i--)
- {
- surface_set_container(This->back_buffers[i], WINED3D_CONTAINER_NONE, NULL);
- if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i]))
- WARN("(%p) Something's still holding back buffer %u (%p).\n",
- This, i, This->back_buffers[i]);
- }
- HeapFree(GetProcessHeap(), 0, This->back_buffers);
- This->back_buffers = NULL;
- }
-
- for (i = 0; i < This->num_contexts; ++i)
- {
- context_destroy(This->device, This->context[i]);
- }
- /* Restore the screen resolution if we rendered in fullscreen
- * This will restore the screen resolution to what it was before creating the swapchain. In case of d3d8 and d3d9
- * this will be the original desktop resolution. In case of d3d7 this will be a NOP because ddraw sets the resolution
- * before starting up Direct3D, thus orig_width and orig_height will be equal to the modes in the presentation params
- */
- if (!This->presentParms.Windowed && This->presentParms.AutoRestoreDisplayMode)
- {
- mode.Width = This->orig_width;
- mode.Height = This->orig_height;
- mode.RefreshRate = 0;
- mode.Format = This->orig_fmt;
- IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)This->device, 0, &mode);
- }
-
- HeapFree(GetProcessHeap(), 0, This->context);
- HeapFree(GetProcessHeap(), 0, This);
-}
-
/* A GL context is provided by the caller */
static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context *context,
const RECT *src_rect, const RECT *dst_rect)
@@ -658,7 +656,7 @@ static const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
IWineD3DBaseSwapChainImpl_Release,
/* IWineD3DSwapChain */
IWineD3DBaseSwapChainImpl_GetParent,
- IWineD3DSwapChainImpl_Destroy,
+ IWineD3DBaseSwapChainImpl_Destroy,
IWineD3DBaseSwapChainImpl_GetDevice,
IWineD3DSwapChainImpl_Present,
IWineD3DSwapChainImpl_SetDestWindowOverride,
@@ -671,55 +669,6 @@ static const IWineD3DSwapChainVtbl IWineD3DSwapChain_Vtbl =
IWineD3DBaseSwapChainImpl_GetGammaRamp
};
-static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface)
-{
- IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)iface;
- WINED3DDISPLAYMODE mode;
-
- TRACE("Destroying swapchain %p.\n", iface);
-
- IWineD3DSwapChain_SetGammaRamp(iface, 0, &swapchain->orig_gamma);
-
- /* release the ref to the front and back buffer parents */
- if (swapchain->front_buffer)
- {
- surface_set_container(swapchain->front_buffer, WINED3D_CONTAINER_NONE, NULL);
- if (IWineD3DSurface_Release((IWineD3DSurface *)swapchain->front_buffer))
- WARN("Something's still holding the front buffer.\n");
- }
-
- if (swapchain->back_buffers)
- {
- UINT i;
-
- for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i)
- {
- surface_set_container(swapchain->back_buffers[i], WINED3D_CONTAINER_NONE, NULL);
- if (IWineD3DSurface_Release((IWineD3DSurface *)swapchain->back_buffers[i]))
- WARN("Something's still holding the back buffer.\n");
- }
- HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
- }
-
- /* Restore the screen resolution if we rendered in fullscreen.
- * This will restore the screen resolution to what it was before creating
- * the swapchain. In case of d3d8 and d3d9 this will be the original
- * desktop resolution. In case of d3d7 this will be a NOP because ddraw
- * sets the resolution before starting up Direct3D, thus orig_width and
- * orig_height will be equal to the modes in the presentation params. */
- if (!swapchain->presentParms.Windowed && swapchain->presentParms.AutoRestoreDisplayMode)
- {
- mode.Width = swapchain->orig_width;
- mode.Height = swapchain->orig_height;
- mode.RefreshRate = 0;
- mode.Format = swapchain->orig_fmt;
- IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)swapchain->device, 0, &mode);
- }
-
- HeapFree(GetProcessHeap(), 0, swapchain->context);
- HeapFree(GetProcessHeap(), 0, swapchain);
-}
-
/* Helper function that blits the front buffer contents to the target window. */
void x11_copy_to_screen(IWineD3DSwapChainImpl *swapchain, const RECT *rect)
{
@@ -896,7 +845,7 @@ static const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl =
IWineD3DBaseSwapChainImpl_Release,
/* IWineD3DSwapChain */
IWineD3DBaseSwapChainImpl_GetParent,
- IWineGDISwapChainImpl_Destroy,
+ IWineD3DBaseSwapChainImpl_Destroy,
IWineD3DBaseSwapChainImpl_GetDevice,
IWineGDISwapChainImpl_Present,
IWineGDISwapChainImpl_SetDestWindowOverride,
Module: wine
Branch: master
Commit: 28137ba2e9a829e2f9a44cdf804eb5c315d2a7ec
URL: http://source.winehq.org/git/wine.git/?a=commit;h=28137ba2e9a829e2f9a44cdf8…
Author: Henri Verbeet <hverbeet(a)codeweavers.com>
Date: Fri Apr 8 14:30:59 2011 +0200
wined3d: Only create a swapchain context array for GL swapchains.
Lying about the number of contexts a swapchain has isn't very useful.
---
dlls/wined3d/swapchain.c | 22 +++++++++-------------
1 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 1c875bf..ddd946d 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -1043,15 +1043,6 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
displaymode_set = TRUE;
}
- swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(swapchain->context));
- if (!swapchain->context)
- {
- ERR("Failed to create the context array.\n");
- hr = E_OUTOFMEMORY;
- goto err;
- }
- swapchain->num_contexts = 1;
-
if (surface_type == SURFACE_OPENGL)
{
static const enum wined3d_format_id formats[] =
@@ -1065,6 +1056,15 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+ swapchain->context = HeapAlloc(GetProcessHeap(), 0, sizeof(swapchain->context));
+ if (!swapchain->context)
+ {
+ ERR("Failed to create the context array.\n");
+ hr = E_OUTOFMEMORY;
+ goto err;
+ }
+ swapchain->num_contexts = 1;
+
/* In WGL both color, depth and stencil are features of a pixel format. In case of D3D they are separate.
* You are able to add a depth + stencil surface at a later stage when you need it.
* In order to support this properly in WineD3D we need the ability to recreate the opengl context and
@@ -1099,10 +1099,6 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
}
context_release(swapchain->context[0]);
}
- else
- {
- swapchain->context[0] = NULL;
- }
if (swapchain->presentParms.BackBufferCount > 0)
{