Stefan Dösinger : wined3d: Implement overlay flipping.

Alexandre Julliard julliard at winehq.org
Tue Aug 5 07:26:41 CDT 2008


Module: wine
Branch: master
Commit: 851dd7339e52407a7f44b55798379ac518d8c336
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=851dd7339e52407a7f44b55798379ac518d8c336

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Thu Jul 24 11:38:51 2008 -0500

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 bc25218..1cf4d57 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 42ce5d1..1ea221c 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 e564a81..77655d0 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 4d31b8c..669e865 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 */




More information about the wine-cvs mailing list