wined3d: Store back buffer surfaces as IWineD3DSurfaceImpl pointers in the swapchain.

This commit is contained in:
Henri Verbeet 2010-04-26 21:33:01 +02:00 committed by Alexandre Julliard
parent 62acb2fdbc
commit d977e91b11
7 changed files with 68 additions and 59 deletions

View File

@ -1827,7 +1827,7 @@ static struct wined3d_context *FindContext(IWineD3DDeviceImpl *This, IWineD3DSur
else
{
IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->swapchains[0];
if (swapchain->backBuffer) target = (IWineD3DSurfaceImpl *)swapchain->backBuffer[0];
if (swapchain->back_buffers) target = swapchain->back_buffers[0];
else target = swapchain->front_buffer;
}
}

View File

@ -1622,9 +1622,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Init3D(IWineD3DDevice *iface,
}
This->swapchains[0] = (IWineD3DSwapChain *) swapchain;
if(swapchain->backBuffer && swapchain->backBuffer[0]) {
TRACE("Setting rendertarget to %p\n", swapchain->backBuffer);
This->render_targets[0] = (IWineD3DSurfaceImpl *)swapchain->backBuffer[0];
if (swapchain->back_buffers && swapchain->back_buffers[0])
{
TRACE("Setting rendertarget to %p.\n", swapchain->back_buffers);
This->render_targets[0] = swapchain->back_buffers[0];
}
else
{
@ -5645,10 +5646,10 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
return WINED3DERR_INVALIDCALL;
}
if (!swapchain->backBuffer)
if (!swapchain->back_buffers)
{
swapchain->backBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*swapchain->backBuffer));
if (!swapchain->backBuffer)
swapchain->back_buffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*swapchain->back_buffers));
if (!swapchain->back_buffers)
{
ERR("Failed to allocate back buffer array memory.\n");
IWineD3DSwapChain_Release((IWineD3DSwapChain *)swapchain);
@ -5675,16 +5676,16 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
}
}
if (swapchain->backBuffer[0] != back)
if (swapchain->back_buffers[0] != back_impl)
{
TRACE("Changing the back buffer from %p to %p.\n", swapchain->backBuffer[0], back);
TRACE("Changing the back buffer from %p to %p.\n", swapchain->back_buffers[0], back_impl);
if (swapchain->backBuffer[0])
if (swapchain->back_buffers[0])
{
IWineD3DSurface_SetContainer(swapchain->backBuffer[0], NULL);
((IWineD3DSurfaceImpl *)swapchain->backBuffer[0])->Flags &= ~SFLAG_SWAPCHAIN;
IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->back_buffers[0], NULL);
swapchain->back_buffers[0]->Flags &= ~SFLAG_SWAPCHAIN;
}
swapchain->backBuffer[0] = back;
swapchain->back_buffers[0] = back_impl;
if (back)
{
@ -5699,8 +5700,8 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa
else
{
swapchain->presentParms.BackBufferCount = 0;
HeapFree(GetProcessHeap(), 0, swapchain->backBuffer);
swapchain->backBuffer = NULL;
HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
swapchain->back_buffers = NULL;
}
}
@ -6333,7 +6334,7 @@ static HRESULT create_primary_opengl_context(IWineD3DDevice *iface, IWineD3DSwap
return E_OUTOFMEMORY;
}
target = swapchain->backBuffer ? (IWineD3DSurfaceImpl *)swapchain->backBuffer[0] : swapchain->front_buffer;
target = swapchain->back_buffers ? swapchain->back_buffers[0] : swapchain->front_buffer;
if (!(context = context_create(swapchain, target, swapchain->ds_format)))
{
WARN("Failed to create context.\n");
@ -6518,8 +6519,9 @@ static HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRE
return hr;
}
for(i = 0; i < swapchain->presentParms.BackBufferCount; i++) {
hr = updateSurfaceDesc((IWineD3DSurfaceImpl *)swapchain->backBuffer[i], pPresentationParameters);
for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i)
{
hr = updateSurfaceDesc(swapchain->back_buffers[i], pPresentationParameters);
if(FAILED(hr))
{
IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain);

View File

@ -935,7 +935,7 @@ GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface)
return GL_NONE;
}
if (swapchain->backBuffer && (IWineD3DSurfaceImpl *)swapchain->backBuffer[0] == surface)
if (swapchain->back_buffers && swapchain->back_buffers[0] == surface)
{
if (swapchain->render_to_fbo)
{
@ -3204,7 +3204,7 @@ static void fb_copy_to_texture_hwstretch(IWineD3DSurfaceImpl *dst_surface, IWine
IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DSwapChain, (void **)&src_swapchain);
if (src_swapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)src_swapchain);
if (!src_swapchain || src_surface == (IWineD3DSurfaceImpl *)src_swapchain->backBuffer[0])
if (!src_swapchain || src_surface == src_swapchain->back_buffers[0])
{
src = backup ? backup : src_surface->texture_name;
}
@ -3438,9 +3438,9 @@ static HRESULT IWineD3DSurfaceImpl_BltOverride(IWineD3DSurfaceImpl *dst_surface,
if (src_surface) surface_get_rect(src_surface, SrcRect, &src_rect);
/* 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
if (dstSwapchain && dstSwapchain == srcSwapchain && dstSwapchain->back_buffers
&& dst_surface == dstSwapchain->front_buffer
&& src_surface == (IWineD3DSurfaceImpl *)dstSwapchain->backBuffer[0])
&& src_surface == dstSwapchain->back_buffers[0])
{
/* Half-life does a Blt from the back buffer to the front buffer,
* Full surface size, no flags... Use present instead

View File

@ -46,7 +46,7 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
IWineD3DSwapChain_SetGammaRamp(iface, 0, &This->orig_gamma);
/* Release the swapchain's draw buffers. Make sure This->backBuffer[0] is
/* 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)
{
@ -59,19 +59,19 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
This->front_buffer = NULL;
}
if (This->backBuffer)
if (This->back_buffers)
{
UINT i = This->presentParms.BackBufferCount;
while (i--)
{
IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
if (IWineD3DSurface_Release(This->backBuffer[i]))
IWineD3DSurface_SetContainer((IWineD3DSurface *)This->back_buffers[i], NULL);
if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i]))
WARN("(%p) Something's still holding back buffer %u (%p).\n",
This, i, This->backBuffer[i]);
This, i, This->back_buffers[i]);
}
HeapFree(GetProcessHeap(), 0, This->backBuffer);
This->backBuffer = NULL;
HeapFree(GetProcessHeap(), 0, This->back_buffers);
This->back_buffers = NULL;
}
for (i = 0; i < This->num_contexts; ++i)
@ -100,7 +100,7 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context *
const RECT *src_rect, const RECT *dst_rect)
{
IWineD3DDeviceImpl *device = This->device;
IWineD3DSurfaceImpl *backbuffer = ((IWineD3DSurfaceImpl *) This->backBuffer[0]);
IWineD3DSurfaceImpl *backbuffer = This->back_buffers[0];
UINT src_w = src_rect->right - src_rect->left;
UINT src_h = src_rect->bottom - src_rect->top;
GLenum gl_filter;
@ -142,7 +142,7 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context *
float tex_right = src_rect->right;
float tex_bottom = src_rect->bottom;
context2 = context_acquire(This->device, (IWineD3DSurfaceImpl *)This->backBuffer[0], CTXUSAGE_BLIT);
context2 = context_acquire(This->device, This->back_buffers[0], CTXUSAGE_BLIT);
if(backbuffer->Flags & SFLAG_NORMCOORD)
{
@ -220,7 +220,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride);
context = context_acquire(This->device, (IWineD3DSurfaceImpl *)This->backBuffer[0], CTXUSAGE_RESOURCELOAD);
context = context_acquire(This->device, This->back_buffers[0], CTXUSAGE_RESOURCELOAD);
if (!context->valid)
{
context_release(context);
@ -267,14 +267,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
if (This->presentParms.Windowed) {
MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2);
}
IWineD3DSurface_Blt(This->backBuffer[0], &destRect, (IWineD3DSurface *)&cursor,
IWineD3DSurface_Blt((IWineD3DSurface *)This->back_buffers[0], &destRect, (IWineD3DSurface *)&cursor,
NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_POINT);
}
if (This->device->logo_surface)
{
/* Blit the logo into the upper left corner of the drawable. */
IWineD3DSurface_BltFast(This->backBuffer[0], 0, 0, This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY);
IWineD3DSurface_BltFast((IWineD3DSurface *)This->back_buffers[0], 0, 0,
This->device->logo_surface, NULL, WINEDDBLTFAST_SRCCOLORKEY);
}
TRACE("Presenting HDC %p.\n", context->hdc);
@ -318,8 +319,8 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
*/
if (!This->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{
IWineD3DSurface_LoadLocation(This->backBuffer[0], SFLAG_INTEXTURE, NULL);
IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, FALSE);
IWineD3DSurface_LoadLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INTEXTURE, NULL);
IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INDRAWABLE, FALSE);
This->render_to_fbo = TRUE;
/* Force the context manager to update the render target configuration next draw. */
@ -424,13 +425,13 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
}
if (!This->render_to_fbo && ((This->front_buffer->Flags & SFLAG_INSYSMEM)
|| (((IWineD3DSurfaceImpl *)This->backBuffer[0])->Flags & SFLAG_INSYSMEM)))
|| (This->back_buffers[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 = This->front_buffer;
IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0];
IWineD3DSurfaceImpl *back = This->back_buffers[0];
if(front->resource.size == back->resource.size) {
DWORD fbflags;
@ -456,8 +457,9 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
* If the swapeffect is COPY, the content remains the same. If it is FLIP however,
* the texture / sysmem copy needs to be reloaded from the drawable
*/
if(This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP) {
IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, TRUE);
if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP)
{
IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INDRAWABLE, TRUE);
}
}
@ -832,9 +834,9 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
if (swapchain->presentParms.BackBufferCount > 0)
{
swapchain->backBuffer = HeapAlloc(GetProcessHeap(), 0,
sizeof(*swapchain->backBuffer) * swapchain->presentParms.BackBufferCount);
if (!swapchain->backBuffer)
swapchain->back_buffers = HeapAlloc(GetProcessHeap(), 0,
sizeof(*swapchain->back_buffers) * swapchain->presentParms.BackBufferCount);
if (!swapchain->back_buffers)
{
ERR("Failed to allocate backbuffer array memory.\n");
hr = E_OUTOFMEMORY;
@ -847,15 +849,16 @@ 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->backBuffer[i]);
swapchain->presentParms.MultiSampleQuality, TRUE /* Lockable */,
(IWineD3DSurface **)&swapchain->back_buffers[i]);
if (FAILED(hr))
{
WARN("Failed to create back buffer %u, hr %#x.\n", i, hr);
goto err;
}
IWineD3DSurface_SetContainer(swapchain->backBuffer[i], (IWineD3DBase *)swapchain);
((IWineD3DSurfaceImpl *)swapchain->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN;
IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->back_buffers[i], (IWineD3DBase *)swapchain);
swapchain->back_buffers[i]->Flags |= SFLAG_SWAPCHAIN;
}
}
@ -901,13 +904,13 @@ err:
ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
}
if (swapchain->backBuffer)
if (swapchain->back_buffers)
{
for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i)
{
if (swapchain->backBuffer[i]) IWineD3DSurface_Release(swapchain->backBuffer[i]);
if (swapchain->back_buffers[i]) IWineD3DSurface_Release((IWineD3DSurface *)swapchain->back_buffers[i]);
}
HeapFree(GetProcessHeap(), 0, swapchain->backBuffer);
HeapFree(GetProcessHeap(), 0, swapchain->back_buffers);
}
if (swapchain->context)

View File

@ -106,12 +106,13 @@ HRESULT WINAPI IWineD3DBaseSwapChainImpl_GetBackBuffer(IWineD3DSwapChain *iface,
* used (there This->backBuffer is always NULL). We need this because this function has
* to be called from IWineD3DStateBlockImpl_InitStartupStateBlock to get the default
* scissorrect dimensions. */
if( !This->backBuffer ) {
if (!This->back_buffers)
{
*ppBackBuffer = NULL;
return WINED3DERR_INVALIDCALL;
}
*ppBackBuffer = This->backBuffer[iBackBuffer];
*ppBackBuffer = (IWineD3DSurface *)This->back_buffers[iBackBuffer];
TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
/* Note inc ref on returned surface */

View File

@ -46,16 +46,18 @@ static void WINAPI IWineGDISwapChainImpl_Destroy(IWineD3DSwapChain *iface)
}
}
if(This->backBuffer) {
if (This->back_buffers)
{
UINT i;
for(i = 0; i < This->presentParms.BackBufferCount; i++) {
IWineD3DSurface_SetContainer(This->backBuffer[i], 0);
if (IWineD3DSurface_Release(This->backBuffer[i]) > 0)
for (i = 0; i < This->presentParms.BackBufferCount; ++i)
{
IWineD3DSurface_SetContainer((IWineD3DSurface *)This->back_buffers[i], NULL);
if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i]))
{
WARN("(%p) Something's still holding the back buffer\n",This);
}
}
HeapFree(GetProcessHeap(), 0, This->backBuffer);
HeapFree(GetProcessHeap(), 0, This->back_buffers);
}
/* Restore the screen resolution if we rendered in fullscreen
@ -173,12 +175,13 @@ static HRESULT WINAPI IWineGDISwapChainImpl_Present(IWineD3DSwapChain *iface, CO
IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
IWineD3DSurfaceImpl *front, *back;
if(!This->backBuffer) {
if (!This->back_buffers)
{
WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL;
}
front = This->front_buffer;
back = (IWineD3DSurfaceImpl *) This->backBuffer[0];
back = This->back_buffers[0];
/* Flip the DC */
{

View File

@ -2564,7 +2564,7 @@ struct IWineD3DSwapChainImpl
IWineD3DDeviceImpl *device;
/* IWineD3DSwapChain fields */
IWineD3DSurface **backBuffer;
IWineD3DSurfaceImpl **back_buffers;
IWineD3DSurfaceImpl *front_buffer;
WINED3DPRESENT_PARAMETERS presentParms;
DWORD orig_width, orig_height;