Commit 62acb2fd authored by Henri Verbeet's avatar Henri Verbeet Committed by Alexandre Julliard

wined3d: Store the front buffer surface as an IWineD3DSurfaceImpl pointer in the swapchain.

parent ab788c7c
......@@ -6917,7 +6917,7 @@ HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_
* Also beware that the front buffer's surface size is screen width x screen height,
* whereas the real gl drawable size is the size of the window. */
dst_swapchain = (dst_surface->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)dst_surface->container : NULL;
if (dst_swapchain && (IWineD3DSurface *)dst_surface == dst_swapchain->frontBuffer)
if (dst_swapchain && dst_surface == dst_swapchain->front_buffer)
{
RECT windowsize;
POINT offset = {0,0};
......@@ -6943,7 +6943,7 @@ HRESULT arbfp_blit_surface(IWineD3DDeviceImpl *device, IWineD3DSurfaceImpl *src_
arbfp_blit_unset((IWineD3DDevice *)device);
if (wined3d_settings.strict_draw_ordering || (dst_swapchain
&& ((IWineD3DSurface *)dst_surface == dst_swapchain->frontBuffer
&& (dst_surface == dst_swapchain->front_buffer
|| dst_swapchain->num_contexts > 1)))
wglFlush(); /* Flush to ensure ordering across contexts. */
......
......@@ -1828,7 +1828,7 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur
{
IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->swapchains[0];
if (swapchain->backBuffer) target = (IWineD3DSurfaceImpl *)swapchain->backBuffer[0];
else target = (IWineD3DSurfaceImpl *)swapchain->frontBuffer;
else target = swapchain->front_buffer;
}
}
......
......@@ -1626,9 +1626,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
TRACE("Setting rendertarget to %p\n", swapchain->backBuffer);
This->render_targets[0] = (IWineD3DSurfaceImpl *)swapchain->backBuffer[0];
}
else {
TRACE("Setting rendertarget to %p\n", swapchain->frontBuffer);
This->render_targets[0] = (IWineD3DSurfaceImpl *)swapchain->frontBuffer;
else
{
TRACE("Setting rendertarget to %p.\n", swapchain->front_buffer);
This->render_targets[0] = swapchain->front_buffer;
}
IWineD3DSurface_AddRef((IWineD3DSurface *)This->render_targets[0]);
......@@ -1658,7 +1659,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
/* Setup all the devices defaults */
IWineD3DStateBlock_InitStartupStateBlock((IWineD3DStateBlock *)This->stateBlock);
context = context_acquire(This, (IWineD3DSurfaceImpl *)swapchain->frontBuffer, CTXUSAGE_RESOURCELOAD);
context = context_acquire(This, swapchain->front_buffer, CTXUSAGE_RESOURCELOAD);
create_dummy_textures(This);
......@@ -4535,7 +4536,7 @@ HRESULT IWineD3DDeviceImpl_ClearSurface(IWineD3DDeviceImpl *This, IWineD3DSurfac
LEAVE_GL();
if (wined3d_settings.strict_draw_ordering || ((target->Flags & SFLAG_SWAPCHAIN)
&& ((IWineD3DSwapChainImpl *)target->container)->frontBuffer == (IWineD3DSurface *)target))
&& ((IWineD3DSwapChainImpl *)target->container)->front_buffer == target))
wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
......@@ -5656,16 +5657,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
}
}
if (swapchain->frontBuffer != front)
if (swapchain->front_buffer != front_impl)
{
TRACE("Changing the front buffer from %p to %p.\n", swapchain->frontBuffer, front);
TRACE("Changing the front buffer from %p to %p.\n", swapchain->front_buffer, front_impl);
if (swapchain->frontBuffer)
if (swapchain->front_buffer)
{
IWineD3DSurface_SetContainer(swapchain->frontBuffer, NULL);
((IWineD3DSurfaceImpl *)swapchain->frontBuffer)->Flags &= ~SFLAG_SWAPCHAIN;
IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->front_buffer, NULL);
swapchain->front_buffer->Flags &= ~SFLAG_SWAPCHAIN;
}
swapchain->frontBuffer = front;
swapchain->front_buffer = front_impl;
if (front)
{
......@@ -6332,7 +6333,7 @@ static HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwap
return E_OUTOFMEMORY;
}
target = (IWineD3DSurfaceImpl *)(swapchain->backBuffer ? swapchain->backBuffer[0] : swapchain->frontBuffer);
target = swapchain->backBuffer ? (IWineD3DSurfaceImpl *)swapchain->backBuffer[0] : swapchain->front_buffer;
if (!(context = context_create(swapchain, target, swapchain->ds_format)))
{
WARN("Failed to create context.\n");
......@@ -6510,7 +6511,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
swapchain->presentParms.BackBufferWidth = pPresentationParameters->BackBufferWidth;
swapchain->presentParms.BackBufferHeight = pPresentationParameters->BackBufferHeight;
hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->frontBuffer, pPresentationParameters);
hr = updateSurfaceDesc(swapchain->front_buffer, pPresentationParameters);
if(FAILED(hr))
{
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);
......
......@@ -945,7 +945,7 @@ GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface)
TRACE("Returning GL_BACK\n");
return GL_BACK;
}
else if ((IWineD3DSurfaceImpl *)swapchain->frontBuffer == surface)
else if (surface == swapchain->front_buffer)
{
TRACE("Returning GL_FRONT\n");
return GL_FRONT;
......@@ -2095,7 +2095,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD
IWineD3DSurfaceImpl *dds_primary;
IWineD3DSwapChainImpl *swapchain;
swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0];
dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer;
dds_primary = swapchain->front_buffer;
if (dds_primary && dds_primary->palette)
pal = dds_primary->palette->palents;
}
......@@ -3439,7 +3439,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface,
/* The only case where both surfaces on a swapchain are supported is a back buffer -> front buffer blit on the same swapchain */
if (dstSwapchain && dstSwapchain == srcSwapchain && dstSwapchain->backBuffer
&& dst_surface == (IWineD3DSurfaceImpl *)dstSwapchain->frontBuffer
&& dst_surface == dstSwapchain->front_buffer
&& src_surface == (IWineD3DSurfaceImpl *)dstSwapchain->backBuffer[0])
{
/* Half-life does a Blt from the back buffer to the front buffer,
......@@ -3685,7 +3685,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface,
* Also beware that the front buffer's surface size is screen width x screen height,
* whereas the real gl drawable size is the size of the window.
*/
if (dstSwapchain && dst_surface == (IWineD3DSurfaceImpl *)dstSwapchain->frontBuffer)
if (dstSwapchain && dst_surface == dstSwapchain->front_buffer)
{
RECT windowsize;
POINT offset = {0,0};
......@@ -3748,7 +3748,7 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface,
device->blitter->unset_shader((IWineD3DDevice *)device);
if (wined3d_settings.strict_draw_ordering || (dstSwapchain
&& (dst_surface == (IWineD3DSurfaceImpl *)dstSwapchain->frontBuffer
&& (dst_surface == dstSwapchain->front_buffer
|| dstSwapchain->num_contexts > 1)))
wglFlush(); /* Flush to ensure ordering across contexts. */
......@@ -4347,8 +4347,7 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT
swapchain = (This->Flags & SFLAG_SWAPCHAIN) ? (IWineD3DSwapChainImpl *)This->container : NULL;
if (wined3d_settings.strict_draw_ordering || (swapchain
&& ((IWineD3DSurface *)This == swapchain->frontBuffer
|| swapchain->num_contexts > 1)))
&& (This == swapchain->front_buffer || swapchain->num_contexts > 1)))
wglFlush(); /* Flush to ensure ordering across contexts. */
context_release(context);
......@@ -4678,7 +4677,7 @@ BOOL surface_is_offscreen(IWineD3DSurfaceImpl *surface)
if (!(surface->Flags & SFLAG_SWAPCHAIN)) return TRUE;
/* The front buffer is always onscreen */
if (surface == (IWineD3DSurfaceImpl *)swapchain->frontBuffer) return FALSE;
if (surface == swapchain->front_buffer) return FALSE;
/* If the swapchain is rendered to an FBO, the backbuffer is
* offscreen, otherwise onscreen */
......
......@@ -200,7 +200,7 @@ IWineGDISurfaceImpl_UnlockRect(IWineD3DSurface *iface)
/* Tell the swapchain to update the screen */
if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
{
if(iface == swapchain->frontBuffer)
if (This == swapchain->front_buffer)
{
x11_copy_to_screen(swapchain, &This->lockedRect);
}
......@@ -431,7 +431,7 @@ static HRESULT WINAPI IWineGDISurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD
IWineD3DSurfaceImpl *dds_primary;
IWineD3DSwapChainImpl *swapchain;
swapchain = (IWineD3DSwapChainImpl *)This->resource.device->swapchains[0];
dds_primary = (IWineD3DSurfaceImpl *)swapchain->frontBuffer;
dds_primary = swapchain->front_buffer;
if (dds_primary && dds_primary->palette)
pal = dds_primary->palette->palents;
}
......@@ -501,7 +501,7 @@ static HRESULT WINAPI IWineGDISurfaceImpl_RealizePalette(IWineD3DSurface *iface)
/* Tell the swapchain to update the screen */
if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain)))
{
if(iface == swapchain->frontBuffer)
if (This == swapchain->front_buffer)
{
x11_copy_to_screen(swapchain, NULL);
}
......
......@@ -48,15 +48,15 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
/* Release the swapchain's draw buffers. Make sure This->backBuffer[0] is
* the last buffer to be destroyed, FindContext() depends on that. */
if (This->frontBuffer)
if (This->front_buffer)
{
IWineD3DSurface_SetContainer(This->frontBuffer, 0);
if (IWineD3DSurface_Release(This->frontBuffer))
IWineD3DSurface_SetContainer((IWineD3DSurface *)This->front_buffer, NULL);
if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer))
{
WARN("(%p) Something's still holding the front buffer (%p).\n",
This, This->frontBuffer);
This, This->front_buffer);
}
This->frontBuffer = NULL;
This->front_buffer = NULL;
}
if (This->backBuffer)
......@@ -423,13 +423,13 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
WINED3DCLEAR_TARGET, 0xff00ffff, 1.0f, 0);
}
if(!This->render_to_fbo &&
( ((IWineD3DSurfaceImpl *) This->frontBuffer)->Flags & SFLAG_INSYSMEM ||
((IWineD3DSurfaceImpl *) This->backBuffer[0])->Flags & SFLAG_INSYSMEM ) ) {
if (!This->render_to_fbo && ((This->front_buffer->Flags & SFLAG_INSYSMEM)
|| (((IWineD3DSurfaceImpl *)This->backBuffer[0])->Flags & SFLAG_INSYSMEM)))
{
/* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying
* Doesn't work with render_to_fbo because we're not flipping
*/
IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer;
IWineD3DSurfaceImpl *front = This->front_buffer;
IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0];
if(front->resource.size == back->resource.size) {
......@@ -441,14 +441,16 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
* This serves to update the emulated overlay, if any
*/
fbflags = front->Flags;
IWineD3DSurface_ModifyLocation(This->frontBuffer, SFLAG_INDRAWABLE, TRUE);
IWineD3DSurface_ModifyLocation((IWineD3DSurface *)front, SFLAG_INDRAWABLE, TRUE);
front->Flags = fbflags;
} else {
IWineD3DSurface_ModifyLocation((IWineD3DSurface *) front, SFLAG_INDRAWABLE, TRUE);
IWineD3DSurface_ModifyLocation((IWineD3DSurface *) back, SFLAG_INDRAWABLE, TRUE);
}
} else {
IWineD3DSurface_ModifyLocation(This->frontBuffer, SFLAG_INDRAWABLE, TRUE);
}
else
{
IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->front_buffer, SFLAG_INDRAWABLE, TRUE);
/* If the swapeffect is DISCARD, the back buffer is undefined. That means the SYSMEM
* and INTEXTURE copies can keep their old content if they have any defined content.
* If the swapeffect is COPY, the content remains the same. If it is FLIP however,
......@@ -746,18 +748,19 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent,
swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType,
swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */, &swapchain->frontBuffer);
swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */,
(IWineD3DSurface **)&swapchain->front_buffer);
if (FAILED(hr))
{
WARN("Failed to create front buffer, hr %#x.\n", hr);
goto err;
}
IWineD3DSurface_SetContainer(swapchain->frontBuffer, (IWineD3DBase *)swapchain);
((IWineD3DSurfaceImpl *)swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN;
IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->front_buffer, (IWineD3DBase *)swapchain);
swapchain->front_buffer->Flags |= SFLAG_SWAPCHAIN;
if (surface_type == SURFACE_OPENGL)
{
IWineD3DSurface_ModifyLocation(swapchain->frontBuffer, SFLAG_INDRAWABLE, TRUE);
IWineD3DSurface_ModifyLocation((IWineD3DSurface *)swapchain->front_buffer, SFLAG_INDRAWABLE, TRUE);
}
/* MSDN says we're only allowed a single fullscreen swapchain per device,
......@@ -813,8 +816,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
FIXME("Add OpenGL context recreation support to context_validate_onscreen_formats\n");
}
swapchain->ds_format = getFormatDescEntry(WINED3DFMT_D24_UNORM_S8_UINT, gl_info);
swapchain->context[0] = context_create(swapchain, (IWineD3DSurfaceImpl *)swapchain->frontBuffer,
swapchain->ds_format);
swapchain->context[0] = context_create(swapchain, swapchain->front_buffer, swapchain->ds_format);
if (!swapchain->context[0])
{
WARN("Failed to create context.\n");
......@@ -919,7 +921,7 @@ err:
HeapFree(GetProcessHeap(), 0, swapchain->context);
}
if (swapchain->frontBuffer) IWineD3DSurface_Release(swapchain->frontBuffer);
if (swapchain->front_buffer) IWineD3DSurface_Release((IWineD3DSurface *)swapchain->front_buffer);
return hr;
}
......@@ -932,7 +934,7 @@ struct wined3d_context *swapchain_create_context_for_thread(IWineD3DSwapChain *i
TRACE("Creating a new context for swapchain %p, thread %d\n", This, GetCurrentThreadId());
if (!(ctx = context_create(This, (IWineD3DSurfaceImpl *)This->frontBuffer, This->ds_format)))
if (!(ctx = context_create(This, This->front_buffer, This->ds_format)))
{
ERR("Failed to create a new context for the swapchain\n");
return NULL;
......
......@@ -85,7 +85,7 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetFrontBufferData(IWineD3DSwapChain *i
MapWindowPoints(This->win_handle, NULL, &start, 1);
}
IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, This->frontBuffer, NULL, 0);
IWineD3DSurface_BltFast(pDestSurface, start.x, start.y, (IWineD3DSurface *)This->front_buffer, NULL, 0);
return WINED3D_OK;
}
......
......@@ -37,9 +37,10 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface)
IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
/* release the ref to the front and back buffer parents */
if(This->frontBuffer) {
IWineD3DSurface_SetContainer(This->frontBuffer, 0);
if (IWineD3DSurface_Release(This->frontBuffer) > 0)
if (This->front_buffer)
{
IWineD3DSurface_SetContainer((IWineD3DSurface *)This->front_buffer, NULL);
if (IWineD3DSurface_Release((IWineD3DSurface *)This->front_buffer) > 0)
{
WARN("(%p) Something's still holding the front buffer\n",This);
}
......@@ -86,7 +87,7 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface)
*****************************************************************************/
void x11_copy_to_screen(IWineD3DSwapChainImpl *This, const RECT *rc)
{
IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer;
IWineD3DSurfaceImpl *front = This->front_buffer;
if(front->resource.usage & WINED3DUSAGE_RENDERTARGET) {
POINT offset = {0,0};
......@@ -176,7 +177,7 @@ static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface, CO
WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL;
}
front = (IWineD3DSurfaceImpl *) This->frontBuffer;
front = This->front_buffer;
back = (IWineD3DSurfaceImpl *) This->backBuffer[0];
/* Flip the DC */
......
......@@ -2565,7 +2565,7 @@ struct IWineD3DSwapChainImpl
/* IWineD3DSwapChain fields */
IWineD3DSurface **backBuffer;
IWineD3DSurface *frontBuffer;
IWineD3DSurfaceImpl *front_buffer;
WINED3DPRESENT_PARAMETERS presentParms;
DWORD orig_width, orig_height;
WINED3DFORMAT orig_fmt;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment