Henri Verbeet : ddraw: Use real flips.

Alexandre Julliard julliard at winehq.org
Fri Sep 16 13:28:30 CDT 2011


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

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Thu Sep 15 20:01:51 2011 +0200

ddraw: Use real flips.

---

 dlls/ddraw/ddraw.c         |   30 +++++++++++++++++++-----------
 dlls/ddraw/ddraw_private.h |    4 +---
 dlls/ddraw/surface.c       |   25 +++++++++++++++++++++++++
 dlls/wined3d/surface.c     |   21 +++++++--------------
 4 files changed, 52 insertions(+), 28 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index a8b8985..1a63938 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -5642,35 +5642,43 @@ static HRESULT CDECL device_parent_create_surface(struct wined3d_device_parent *
     return D3D_OK;
 }
 
+static void STDMETHODCALLTYPE ddraw_frontbuffer_destroyed(void *parent)
+{
+    struct IDirectDrawImpl *ddraw = parent;
+    ddraw->wined3d_frontbuffer = NULL;
+}
+
+static const struct wined3d_parent_ops ddraw_frontbuffer_parent_ops =
+{
+    ddraw_frontbuffer_destroyed,
+};
+
 static HRESULT CDECL device_parent_create_rendertarget(struct wined3d_device_parent *device_parent,
         void *container_parent, UINT width, UINT height, enum wined3d_format_id format,
         WINED3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, BOOL lockable,
         struct wined3d_surface **surface)
 {
     struct IDirectDrawImpl *ddraw = ddraw_from_device_parent(device_parent);
-    IDirectDrawSurfaceImpl *d3d_surface = ddraw->d3d_target;
+    HRESULT hr;
 
     TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, multisample_type %#x,\n"
             "\tmultisample_quality %u, lockable %u, surface %p.\n",
             device_parent, container_parent, width, height, format, multisample_type,
             multisample_quality, lockable, surface);
 
-    /* TODO: Return failure if the dimensions do not match, but this shouldn't
-     * happen. */
-
-    if (d3d_surface->isRenderTarget)
+    if (ddraw->wined3d_frontbuffer)
     {
         ERR("Frontbuffer already created.\n");
         return E_FAIL;
     }
-    d3d_surface->isRenderTarget = TRUE;
-
-    *surface = d3d_surface->wined3d_surface;
-    wined3d_surface_incref(*surface);
 
-    TRACE("Returning wineD3DSurface %p, it belongs to surface %p\n", *surface, d3d_surface);
+    hr = wined3d_surface_create(ddraw->wined3d_device, width, height, format, lockable, FALSE, 0,
+            WINED3DUSAGE_RENDERTARGET, WINED3DPOOL_DEFAULT, multisample_type, multisample_quality,
+            DefaultSurfaceType, ddraw, &ddraw_frontbuffer_parent_ops, surface);
+    if (SUCCEEDED(hr))
+        ddraw->wined3d_frontbuffer = *surface;
 
-    return D3D_OK;
+    return hr;
 }
 
 static HRESULT CDECL device_parent_create_depth_stencil(struct wined3d_device_parent *device_parent,
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index b5d85d1..c1c52ca 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -89,6 +89,7 @@ struct IDirectDrawImpl
     BOOL                    d3d_initialized;
 
     IDirectDrawSurfaceImpl *primary;
+    struct wined3d_surface *wined3d_frontbuffer;
 
     /* DirectDraw things, which are not handled by WineD3D */
     DWORD                   cooperative_level;
@@ -184,9 +185,6 @@ struct IDirectDrawSurfaceImpl
     DWORD                   uniqueness_value;
     UINT                    mipmap_level;
 
-    /* For D3DDevice creation */
-    BOOL                    isRenderTarget;
-
     /* Clipper objects */
     IDirectDrawClipperImpl  *clipper;
 
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index 7357742..96caa3f 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -39,6 +39,12 @@ static inline IDirectDrawSurfaceImpl *impl_from_IDirectDrawGammaControl(IDirectD
     return CONTAINING_RECORD(iface, IDirectDrawSurfaceImpl, IDirectDrawGammaControl_iface);
 }
 
+static HRESULT ddraw_surface_update_frontbuffer(IDirectDrawSurfaceImpl *surface)
+{
+    return wined3d_surface_blt(surface->ddraw->wined3d_frontbuffer, NULL,
+            surface->wined3d_surface, NULL, 0, NULL, WINED3DTEXF_POINT);
+}
+
 /*****************************************************************************
  * IUnknown parts follow
  *****************************************************************************/
@@ -1072,6 +1078,8 @@ static HRESULT WINAPI ddraw_surface7_Unlock(IDirectDrawSurface7 *iface, RECT *pR
     hr = wined3d_surface_unmap(This->wined3d_surface);
     if (SUCCEEDED(hr))
     {
+        if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
+            hr = ddraw_surface_update_frontbuffer(This);
         This->surface_desc.lpSurface = NULL;
     }
     LeaveCriticalSection(&ddraw_cs);
@@ -1170,6 +1178,9 @@ static HRESULT WINAPI ddraw_surface7_Flip(IDirectDrawSurface7 *iface, IDirectDra
     }
 
     hr = wined3d_surface_flip(This->wined3d_surface, Override->wined3d_surface, Flags);
+    if (SUCCEEDED(hr) && This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER)
+        hr = ddraw_surface_update_frontbuffer(This);
+
     LeaveCriticalSection(&ddraw_cs);
     return hr;
 }
@@ -1268,6 +1279,8 @@ static HRESULT WINAPI ddraw_surface7_Blt(IDirectDrawSurface7 *iface, RECT *DestR
      * struct are supported anyway. */
     hr = wined3d_surface_blt(This->wined3d_surface, DestRect, Src ? Src->wined3d_surface : NULL,
             SrcRect, Flags, (WINEDDBLTFX *)DDBltFx, WINED3DTEXF_LINEAR);
+    if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER))
+        hr = ddraw_surface_update_frontbuffer(This);
 
     LeaveCriticalSection(&ddraw_cs);
     switch(hr)
@@ -1828,6 +1841,8 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC h
 
     EnterCriticalSection(&ddraw_cs);
     hr = wined3d_surface_releasedc(This->wined3d_surface, hdc);
+    if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER))
+        hr = ddraw_surface_update_frontbuffer(This);
     LeaveCriticalSection(&ddraw_cs);
     return hr;
 }
@@ -3673,6 +3688,8 @@ static HRESULT WINAPI ddraw_surface7_BltFast(IDirectDrawSurface7 *iface, DWORD d
     EnterCriticalSection(&ddraw_cs);
     hr = wined3d_surface_bltfast(This->wined3d_surface, dstx, dsty,
             src->wined3d_surface, rsrc, trans);
+    if (SUCCEEDED(hr) && (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER))
+        hr = ddraw_surface_update_frontbuffer(This);
     LeaveCriticalSection(&ddraw_cs);
     switch(hr)
     {
@@ -4298,6 +4315,14 @@ static HRESULT WINAPI ddraw_surface7_SetPalette(IDirectDrawSurface7 *iface, IDir
     /* Release the old palette */
     if(oldPal) IDirectDrawPalette_Release(oldPal);
 
+    /* Update the wined3d frontbuffer if this is the frontbuffer. */
+    if ((This->surface_desc.ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER) && This->ddraw->wined3d_frontbuffer)
+    {
+        hr = wined3d_surface_set_palette(This->ddraw->wined3d_frontbuffer, PalImpl ? PalImpl->wineD3DPalette : NULL);
+        if (FAILED(hr))
+            ERR("Failed to set frontbuffer palette, hr %#x.\n", hr);
+    }
+
     /* If this is a front buffer, also update the back buffers
      * TODO: How do things work for palettized cube textures?
      */
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 22f194a..f64e0ca 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -3793,11 +3793,9 @@ HRESULT CDECL wined3d_surface_flip(struct wined3d_surface *surface, struct wined
             WARN("Ignoring flags %#x.\n", flags);
     }
 
-    /* FIXME: This will also prevent overlay flips, since overlays aren't on
-     * a swapchain either. */
-    if (surface->container.type != WINED3D_CONTAINER_SWAPCHAIN)
+    if (surface->container.type == WINED3D_CONTAINER_SWAPCHAIN)
     {
-        ERR("Flipped surface is not on a swapchain.\n");
+        ERR("Not supported on swapchain surfaces.\n");
         return WINEDDERR_NOTFLIPPABLE;
     }
 
@@ -3808,18 +3806,13 @@ HRESULT CDECL wined3d_surface_flip(struct wined3d_surface *surface, struct wined
         return WINEDDERR_NOTFLIPPABLE;
     }
 
-    if (surface->resource.usage & WINED3DUSAGE_OVERLAY)
-    {
-        flip_surface(surface, override);
+    flip_surface(surface, override);
 
-        /* Update the overlay if it is visible */
-        if (surface->overlay_dest)
-            return surface->surface_ops->surface_draw_overlay(surface);
-        else
-            return WINED3D_OK;
-    }
+    /* Update overlays if they're visible. */
+    if ((surface->resource.usage & WINED3DUSAGE_OVERLAY) && surface->overlay_dest)
+        return surface->surface_ops->surface_draw_overlay(surface);
 
-    return wined3d_surface_blt(surface, NULL, override, NULL, 0, NULL, WINED3DTEXF_POINT);
+    return WINED3D_OK;
 }
 
 /* Do not call while under the GL lock. */




More information about the wine-cvs mailing list