diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 7bf6b576777..9c7e6ca8744 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -1730,6 +1730,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice *iface, object->presentParms.MultiSampleQuality, TRUE /* Lockable */, &object->frontBuffer); if (SUCCEEDED(hr)) { IWineD3DSurface_SetContainer(object->frontBuffer, (IWineD3DBase *)object); + ((IWineD3DSurfaceImpl *)object->frontBuffer)->Flags |= SFLAG_SWAPCHAIN; if(surface_type == SURFACE_OPENGL) { IWineD3DSurface_ModifyLocation(object->frontBuffer, SFLAG_INDRAWABLE, TRUE); } @@ -1812,6 +1813,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice *iface, object->presentParms.MultiSampleQuality, TRUE /* Lockable */, &object->backBuffer[i]); if(SUCCEEDED(hr)) { IWineD3DSurface_SetContainer(object->backBuffer[i], (IWineD3DBase *)object); + ((IWineD3DSurfaceImpl *)object->backBuffer[i])->Flags |= SFLAG_SWAPCHAIN; } else { ERR("Cannot create new back buffer\n"); goto error; @@ -6618,11 +6620,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa TRACE("Changing the front buffer from %p to %p\n", Swapchain->frontBuffer, Front); if(Swapchain->frontBuffer) + { IWineD3DSurface_SetContainer(Swapchain->frontBuffer, NULL); + ((IWineD3DSurfaceImpl *)Swapchain->frontBuffer)->Flags &= ~SFLAG_SWAPCHAIN; + } Swapchain->frontBuffer = Front; if(Swapchain->frontBuffer) { IWineD3DSurface_SetContainer(Swapchain->frontBuffer, (IWineD3DBase *) Swapchain); + ((IWineD3DSurfaceImpl *)Swapchain->frontBuffer)->Flags |= SFLAG_SWAPCHAIN; } } @@ -6660,11 +6666,15 @@ static HRESULT WINAPI IWineD3DDeviceImpl_SetFrontBackBuffers(IWineD3DDevice *ifa LEAVE_GL(); if(Swapchain->backBuffer[0]) + { IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], NULL); + ((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags &= ~SFLAG_SWAPCHAIN; + } Swapchain->backBuffer[0] = Back; if(Swapchain->backBuffer[0]) { IWineD3DSurface_SetContainer(Swapchain->backBuffer[0], (IWineD3DBase *) Swapchain); + ((IWineD3DSurfaceImpl *)Swapchain->backBuffer[0])->Flags |= SFLAG_SWAPCHAIN; } else { HeapFree(GetProcessHeap(), 0, Swapchain->backBuffer); Swapchain->backBuffer = NULL; diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index ecca666273a..b0c6511b6f0 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1120,7 +1120,6 @@ static void surface_prepare_system_memory(IWineD3DSurfaceImpl *This) { static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED3DLOCKED_RECT* pLockedRect, CONST RECT* pRect, DWORD Flags) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; - IWineD3DSwapChain *swapchain = NULL; TRACE("(%p) : rect@%p flags(%08x), output lockedRect@%p, memory@%p\n", This, pRect, Flags, pLockedRect, This->resource.allocatedMemory); @@ -1157,8 +1156,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED * Use the render target readback if the surface is on a swapchain(=onscreen render target) or the current primary target * Offscreen targets which are not active at the moment or are higher targets(FBOs) can be locked with the texture path */ - IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain); - if(swapchain || iface == myDevice->render_targets[0]) { + if ((This->Flags & SFLAG_SWAPCHAIN) || iface == myDevice->render_targets[0]) + { const RECT *pass_rect = pRect; /* IWineD3DSurface_LoadLocation does not check if the rectangle specifies the full surfaces @@ -1194,8 +1193,6 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LockRect(IWineD3DSurface *iface, WINED case RTL_DISABLE: break; } - if(swapchain) IWineD3DSwapChain_Release(swapchain); - } else if(iface == myDevice->stencilBufferTarget) { /** the depth stencil in openGL has a format of GL_FLOAT * which should be good for WINED3DFMT_D16_LOCKABLE @@ -1376,7 +1373,6 @@ static void flush_to_framebuffer_drawpixels(IWineD3DSurfaceImpl *This, GLenum fm static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DDeviceImpl *myDevice = This->resource.wineD3DDevice; - IWineD3DSwapChainImpl *swapchain = NULL; BOOL fullsurface; if (!(This->Flags & SFLAG_LOCKED)) { @@ -1403,10 +1399,8 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { goto unlock_end; } - IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain); - if(swapchain || (myDevice->render_targets && iface == myDevice->render_targets[0])) { - if(swapchain) IWineD3DSwapChain_Release((IWineD3DSwapChain *) swapchain); - + if ((This->Flags & SFLAG_SWAPCHAIN) || (myDevice->render_targets && iface == myDevice->render_targets[0])) + { if(wined3d_settings.rendertargetlock_mode == RTL_DISABLE) { static BOOL warned = FALSE; if(!warned) { @@ -4220,12 +4214,9 @@ static void WINAPI IWineD3DSurfaceImpl_ModifyLocation(IWineD3DSurface *iface, DW persistent ? "TRUE" : "FALSE"); if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - IWineD3DSwapChain *swapchain = NULL; - - if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain))) { + if (This->Flags & SFLAG_SWAPCHAIN) + { TRACE("Surface %p is an onscreen surface\n", iface); - - IWineD3DSwapChain_Release(swapchain); } else { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */ if (flag & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE)) flag |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE); @@ -4478,7 +4469,6 @@ static inline void surface_blt_to_drawable(IWineD3DSurfaceImpl *This, const RECT static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, DWORD flag, const RECT *rect) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *) iface; IWineD3DDeviceImpl *device = This->resource.wineD3DDevice; - IWineD3DSwapChain *swapchain = NULL; GLenum format, internal, type; CONVERT_TYPES convert; int bpp; @@ -4487,10 +4477,9 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D BOOL drawable_read_ok = TRUE; if (wined3d_settings.offscreen_rendering_mode == ORM_FBO) { - if (SUCCEEDED(IWineD3DSurface_GetContainer(iface, &IID_IWineD3DSwapChain, (void **)&swapchain))) { + if (This->Flags & SFLAG_SWAPCHAIN) + { TRACE("Surface %p is an onscreen surface\n", iface); - - IWineD3DSwapChain_Release(swapchain); } else { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. * Prefer SFLAG_INTEXTURE. */ @@ -4691,7 +4680,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_LoadLocation(IWineD3DSurface *iface, D This->Flags |= flag; } - if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !swapchain + if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !(This->Flags & SFLAG_SWAPCHAIN) && (This->Flags & (SFLAG_INTEXTURE | SFLAG_INDRAWABLE))) { /* With ORM_FBO, SFLAG_INTEXTURE and SFLAG_INDRAWABLE are the same for offscreen targets. */ This->Flags |= (SFLAG_INTEXTURE | SFLAG_INDRAWABLE); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 87947ee35c4..d53f2d5f1bb 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1643,6 +1643,7 @@ void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back); #define SFLAG_DS_ONSCREEN 0x00200000 /* Is a depth stencil, last modified onscreen */ #define SFLAG_DS_OFFSCREEN 0x00400000 /* Is a depth stencil, last modified offscreen */ #define SFLAG_INOVERLAYDRAW 0x00800000 /* Overlay drawing is in progress. Recursion prevention */ +#define SFLAG_SWAPCHAIN 0x01000000 /* The surface is part of a swapchain */ /* In some conditions the surface memory must not be freed: * SFLAG_OVERSIZE: Not all data can be kept in GL