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 else
{ {
IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *)This->swapchains[0]; 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; else target = swapchain->front_buffer;
} }
} }

View File

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

View File

@ -935,7 +935,7 @@ GLenum surface_get_gl_buffer(IWineD3DSurfaceImpl *surface)
return GL_NONE; 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) 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); IWineD3DSurface_GetContainer((IWineD3DSurface *)src_surface, &IID_IWineD3DSwapChain, (void **)&src_swapchain);
if (src_swapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *)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; 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); 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 */ /* 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 && 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, /* Half-life does a Blt from the back buffer to the front buffer,
* Full surface size, no flags... Use present instead * 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); 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. */ * the last buffer to be destroyed, FindContext() depends on that. */
if (This->front_buffer) if (This->front_buffer)
{ {
@ -59,19 +59,19 @@ static void WINAPI IWineD3DSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
This->front_buffer = NULL; This->front_buffer = NULL;
} }
if (This->backBuffer) if (This->back_buffers)
{ {
UINT i = This->presentParms.BackBufferCount; UINT i = This->presentParms.BackBufferCount;
while (i--) while (i--)
{ {
IWineD3DSurface_SetContainer(This->backBuffer[i], 0); IWineD3DSurface_SetContainer((IWineD3DSurface *)This->back_buffers[i], NULL);
if (IWineD3DSurface_Release(This->backBuffer[i])) if (IWineD3DSurface_Release((IWineD3DSurface *)This->back_buffers[i]))
WARN("(%p) Something's still holding back buffer %u (%p).\n", 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); HeapFree(GetProcessHeap(), 0, This->back_buffers);
This->backBuffer = NULL; This->back_buffers = NULL;
} }
for (i = 0; i < This->num_contexts; ++i) 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) const RECT *src_rect, const RECT *dst_rect)
{ {
IWineD3DDeviceImpl *device = This->device; 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_w = src_rect->right - src_rect->left;
UINT src_h = src_rect->bottom - src_rect->top; UINT src_h = src_rect->bottom - src_rect->top;
GLenum gl_filter; GLenum gl_filter;
@ -142,7 +142,7 @@ static void swapchain_blit(IWineD3DSwapChainImpl *This, struct wined3d_context *
float tex_right = src_rect->right; float tex_right = src_rect->right;
float tex_bottom = src_rect->bottom; 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) if(backbuffer->Flags & SFLAG_NORMCOORD)
{ {
@ -220,7 +220,7 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
IWineD3DSwapChain_SetDestWindowOverride(iface, hDestWindowOverride); 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) if (!context->valid)
{ {
context_release(context); context_release(context);
@ -267,14 +267,15 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO
if (This->presentParms.Windowed) { if (This->presentParms.Windowed) {
MapWindowPoints(NULL, This->win_handle, (LPPOINT)&destRect, 2); 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); NULL, WINEDDBLT_KEYSRC, NULL, WINED3DTEXF_POINT);
} }
if (This->device->logo_surface) if (This->device->logo_surface)
{ {
/* Blit the logo into the upper left corner of the drawable. */ /* 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); 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) if (!This->render_to_fbo && render_to_fbo && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
{ {
IWineD3DSurface_LoadLocation(This->backBuffer[0], SFLAG_INTEXTURE, NULL); IWineD3DSurface_LoadLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INTEXTURE, NULL);
IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, FALSE); IWineD3DSurface_ModifyLocation((IWineD3DSurface *)This->back_buffers[0], SFLAG_INDRAWABLE, FALSE);
This->render_to_fbo = TRUE; This->render_to_fbo = TRUE;
/* Force the context manager to update the render target configuration next draw. */ /* 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) 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 /* 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 * Doesn't work with render_to_fbo because we're not flipping
*/ */
IWineD3DSurfaceImpl *front = This->front_buffer; IWineD3DSurfaceImpl *front = This->front_buffer;
IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0]; IWineD3DSurfaceImpl *back = This->back_buffers[0];
if(front->resource.size == back->resource.size) { if(front->resource.size == back->resource.size) {
DWORD fbflags; 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, * 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 * the texture / sysmem copy needs to be reloaded from the drawable
*/ */
if(This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP) { if (This->presentParms.SwapEffect == WINED3DSWAPEFFECT_FLIP)
IWineD3DSurface_ModifyLocation(This->backBuffer[0], SFLAG_INDRAWABLE, TRUE); {
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) if (swapchain->presentParms.BackBufferCount > 0)
{ {
swapchain->backBuffer = HeapAlloc(GetProcessHeap(), 0, swapchain->back_buffers = HeapAlloc(GetProcessHeap(), 0,
sizeof(*swapchain->backBuffer) * swapchain->presentParms.BackBufferCount); sizeof(*swapchain->back_buffers) * swapchain->presentParms.BackBufferCount);
if (!swapchain->backBuffer) if (!swapchain->back_buffers)
{ {
ERR("Failed to allocate backbuffer array memory.\n"); ERR("Failed to allocate backbuffer array memory.\n");
hr = E_OUTOFMEMORY; hr = E_OUTOFMEMORY;
@ -847,15 +849,16 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent, hr = IWineD3DDeviceParent_CreateRenderTarget(device->device_parent, parent,
swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight, swapchain->presentParms.BackBufferWidth, swapchain->presentParms.BackBufferHeight,
swapchain->presentParms.BackBufferFormat, swapchain->presentParms.MultiSampleType, 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)) if (FAILED(hr))
{ {
WARN("Failed to create back buffer %u, hr %#x.\n", i, hr); WARN("Failed to create back buffer %u, hr %#x.\n", i, hr);
goto err; goto err;
} }
IWineD3DSurface_SetContainer(swapchain->backBuffer[i], (IWineD3DBase *)swapchain); IWineD3DSurface_SetContainer((IWineD3DSurface *)swapchain->back_buffers[i], (IWineD3DBase *)swapchain);
((IWineD3DSurfaceImpl *)swapchain->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN; swapchain->back_buffers[i]->Flags |= SFLAG_SWAPCHAIN;
} }
} }
@ -901,13 +904,13 @@ err:
ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL); ChangeDisplaySettingsExW(adapter->DeviceName, &devmode, NULL, CDS_FULLSCREEN, NULL);
} }
if (swapchain->backBuffer) if (swapchain->back_buffers)
{ {
for (i = 0; i < swapchain->presentParms.BackBufferCount; ++i) 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) 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 * used (there This->backBuffer is always NULL). We need this because this function has
* to be called from IWineD3DStateBlockImpl_InitStartupStateBlock to get the default * to be called from IWineD3DStateBlockImpl_InitStartupStateBlock to get the default
* scissorrect dimensions. */ * scissorrect dimensions. */
if( !This->backBuffer ) { if (!This->back_buffers)
{
*ppBackBuffer = NULL; *ppBackBuffer = NULL;
return WINED3DERR_INVALIDCALL; 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); TRACE("(%p) : BackBuf %d Type %d returning %p\n", This, iBackBuffer, Type, *ppBackBuffer);
/* Note inc ref on returned surface */ /* 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; UINT i;
for(i = 0; i < This->presentParms.BackBufferCount; i++) { for (i = 0; i < This->presentParms.BackBufferCount; ++i)
IWineD3DSurface_SetContainer(This->backBuffer[i], 0); {
if (IWineD3DSurface_Release(This->backBuffer[i]) > 0) 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); 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 /* 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; IWineD3DSwapChainImpl *This = (IWineD3DSwapChainImpl *) iface;
IWineD3DSurfaceImpl *front, *back; IWineD3DSurfaceImpl *front, *back;
if(!This->backBuffer) { if (!This->back_buffers)
{
WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n"); WARN("Swapchain doesn't have a backbuffer, returning WINED3DERR_INVALIDCALL\n");
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
front = This->front_buffer; front = This->front_buffer;
back = (IWineD3DSurfaceImpl *) This->backBuffer[0]; back = This->back_buffers[0];
/* Flip the DC */ /* Flip the DC */
{ {

View File

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