From 851dd7339e52407a7f44b55798379ac518d8c336 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Thu, 24 Jul 2008 11:38:51 -0500 Subject: [PATCH] wined3d: Implement overlay flipping. --- dlls/ddraw/surface.c | 2 +- dlls/wined3d/surface.c | 89 +++++++++++++++++++++++++++++++++++++++++- dlls/wined3d/swapchain.c | 72 +--------------------------------- dlls/wined3d/wined3d_private.h | 2 + 4 files changed, 91 insertions(+), 74 deletions(-) diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index bc252181f7c..1cf4d5724af 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -710,7 +710,7 @@ IDirectDrawSurfaceImpl_Flip(IDirectDrawSurface7 *iface, /* Flip has to be called from a front buffer * What about overlay surfaces, AFAIK they can flip too? */ - if( !(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) ) + if( !(This->surface_desc.ddsCaps.dwCaps & (DDSCAPS_FRONTBUFFER | DDSCAPS_OVERLAY)) ) return DDERR_INVALIDOBJECT; /* Unchecked */ EnterCriticalSection(&ddraw_cs); diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 42ce5d14ec8..1ea221ce268 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -2622,14 +2622,99 @@ HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *Mem) { return WINED3D_OK; } +void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back) { + + /* Flip the surface contents */ + /* Flip the DC */ + { + HDC tmp; + tmp = front->hDC; + front->hDC = back->hDC; + back->hDC = tmp; + } + + /* Flip the DIBsection */ + { + HBITMAP tmp; + BOOL hasDib = front->Flags & SFLAG_DIBSECTION; + tmp = front->dib.DIBsection; + front->dib.DIBsection = back->dib.DIBsection; + back->dib.DIBsection = tmp; + + if(back->Flags & SFLAG_DIBSECTION) front->Flags |= SFLAG_DIBSECTION; + else front->Flags &= ~SFLAG_DIBSECTION; + if(hasDib) back->Flags |= SFLAG_DIBSECTION; + else back->Flags &= ~SFLAG_DIBSECTION; + } + + /* Flip the surface data */ + { + void* tmp; + + tmp = front->dib.bitmap_data; + front->dib.bitmap_data = back->dib.bitmap_data; + back->dib.bitmap_data = tmp; + + tmp = front->resource.allocatedMemory; + front->resource.allocatedMemory = back->resource.allocatedMemory; + back->resource.allocatedMemory = tmp; + + tmp = front->resource.heapMemory; + front->resource.heapMemory = back->resource.heapMemory; + back->resource.heapMemory = tmp; + } + + /* Flip the PBO */ + { + GLuint tmp_pbo = front->pbo; + front->pbo = back->pbo; + back->pbo = tmp_pbo; + } + + /* client_memory should not be different, but just in case */ + { + BOOL tmp; + tmp = front->dib.client_memory; + front->dib.client_memory = back->dib.client_memory; + back->dib.client_memory = tmp; + } + + /* Flip the opengl texture */ + { + glDescriptor tmp_desc = back->glDescription; + back->glDescription = front->glDescription; + front->glDescription = tmp_desc; + } + + { + DWORD tmp_flags = back->Flags; + back->Flags = front->Flags; + front->Flags = tmp_flags; + } +} + static HRESULT WINAPI IWineD3DSurfaceImpl_Flip(IWineD3DSurface *iface, IWineD3DSurface *override, DWORD Flags) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; IWineD3DSwapChainImpl *swapchain = NULL; HRESULT hr; TRACE("(%p)->(%p,%x)\n", This, override, Flags); - /* Flipping is only supported on RenderTargets */ - if( !(This->resource.usage & WINED3DUSAGE_RENDERTARGET) ) return WINEDDERR_NOTFLIPPABLE; + /* Flipping is only supported on RenderTargets and overlays*/ + if( !(This->resource.usage & (WINED3DUSAGE_RENDERTARGET | WINED3DUSAGE_OVERLAY)) ) { + WARN("Tried to flip a non-render target, non-overlay surface\n"); + return WINEDDERR_NOTFLIPPABLE; + } + + if(This->resource.usage & WINED3DUSAGE_OVERLAY) { + flip_surface(This, (IWineD3DSurfaceImpl *) override); + + /* Update the overlay if it is visible */ + if(This->overlay_dest) { + return IWineD3DSurface_DrawOverlay((IWineD3DSurface *) This); + } else { + return WINED3D_OK; + } + } if(override) { /* DDraw sets this for the X11 surfaces, so don't confuse the user diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index e564a81dd39..77655d03db5 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -307,79 +307,9 @@ static HRESULT WINAPI IWineD3DSwapChainImpl_Present(IWineD3DSwapChain *iface, CO /* Both memory copies of the surfaces are ok, flip them around too instead of dirtifying */ IWineD3DSurfaceImpl *front = (IWineD3DSurfaceImpl *) This->frontBuffer; IWineD3DSurfaceImpl *back = (IWineD3DSurfaceImpl *) This->backBuffer[0]; - BOOL frontuptodate = front->Flags & SFLAG_INSYSMEM; - BOOL backuptodate = back->Flags & SFLAG_INSYSMEM; if(front->resource.size == back->resource.size) { - /* Flip the DC */ - { - HDC tmp; - tmp = front->hDC; - front->hDC = back->hDC; - back->hDC = tmp; - } - - /* Flip the DIBsection */ - { - HBITMAP tmp; - BOOL hasDib = front->Flags & SFLAG_DIBSECTION; - tmp = front->dib.DIBsection; - front->dib.DIBsection = back->dib.DIBsection; - back->dib.DIBsection = tmp; - - if(back->Flags & SFLAG_DIBSECTION) front->Flags |= SFLAG_DIBSECTION; - else front->Flags &= ~SFLAG_DIBSECTION; - if(hasDib) back->Flags |= SFLAG_DIBSECTION; - else back->Flags &= ~SFLAG_DIBSECTION; - } - - /* Flip the surface data */ - { - void* tmp; - - tmp = front->dib.bitmap_data; - front->dib.bitmap_data = back->dib.bitmap_data; - back->dib.bitmap_data = tmp; - - tmp = front->resource.allocatedMemory; - front->resource.allocatedMemory = back->resource.allocatedMemory; - back->resource.allocatedMemory = tmp; - - tmp = front->resource.heapMemory; - front->resource.heapMemory = back->resource.heapMemory; - back->resource.heapMemory = tmp; - } - - /* Flip the PBO */ - { - DWORD tmp_flags = front->Flags; - - GLuint tmp_pbo = front->pbo; - front->pbo = back->pbo; - back->pbo = tmp_pbo; - - if(back->Flags & SFLAG_PBO) - front->Flags |= SFLAG_PBO; - else - front->Flags &= ~SFLAG_PBO; - - if(tmp_flags & SFLAG_PBO) - back->Flags |= SFLAG_PBO; - else - back->Flags &= ~SFLAG_PBO; - } - - /* client_memory should not be different, but just in case */ - { - BOOL tmp; - tmp = front->dib.client_memory; - front->dib.client_memory = back->dib.client_memory; - back->dib.client_memory = tmp; - } - if(frontuptodate) back->Flags |= SFLAG_INSYSMEM; - else back->Flags &= ~SFLAG_INSYSMEM; - if(backuptodate) front->Flags |= SFLAG_INSYSMEM; - else front->Flags &= ~SFLAG_INSYSMEM; + flip_surface(front, back); } else { IWineD3DSurface_ModifyLocation((IWineD3DSurface *) front, SFLAG_INDRAWABLE, TRUE); IWineD3DSurface_ModifyLocation((IWineD3DSurface *) back, SFLAG_INDRAWABLE, TRUE); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4d31b8c1ee6..669e8654b0d 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1379,6 +1379,8 @@ void get_drawable_size_backbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT * void get_drawable_size_pbuffer(IWineD3DSurfaceImpl *This, UINT *width, UINT *height); void get_drawable_size_fbo(IWineD3DSurfaceImpl *This, UINT *width, UINT *height); +void flip_surface(IWineD3DSurfaceImpl *front, IWineD3DSurfaceImpl *back); + /* Surface flags: */ #define SFLAG_OVERSIZE 0x00000001 /* Surface is bigger than gl size, blts only */ #define SFLAG_CONVERTED 0x00000002 /* Converted for color keying or Palettized */ -- 2.11.4.GIT