[PATCH 11/12] ddraw: cache active DCs

Riccardo Bortolato rikyz619 at gmail.com
Wed Sep 23 03:27:35 CDT 2015


---
 dlls/ddraw/ddraw.c         | 42 ++++++++++++++++++++++++++++++++----------
 dlls/ddraw/ddraw_private.h |  2 ++
 dlls/ddraw/surface.c       |  6 +++++-
 3 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 465b1ef..5d32243 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -2605,39 +2605,60 @@ static HRESULT WINAPI ddraw4_GetDeviceIdentifier(IDirectDraw4 *iface,
  * IDirectDraw7::GetSurfaceFromDC
  *
  * Returns the Surface for a GDI device context handle.
- * Is this related to IDirectDrawSurface::GetDC ???
  *
  * Params:
  *  hdc: hdc to return the surface for
  *  Surface: Address to write the surface pointer to
  *
  * Returns:
- *  Always returns DD_OK because it's a stub
+ *  DD_OK on success, otherwise DDERR_NOTFOUND.
+ *  E_INVALIDARG when no valid surface is given.
  *
  *****************************************************************************/
 static HRESULT WINAPI ddraw7_GetSurfaceFromDC(IDirectDraw7 *iface, HDC hdc,
         IDirectDrawSurface7 **Surface)
 {
     struct ddraw *ddraw = impl_from_IDirectDraw7(iface);
-    struct wined3d_surface *wined3d_surface;
     struct ddraw_surface *surface_impl;
+    struct wined3d_resource *sub_resource;
+    struct wined3d_surface *wined3d_surface;
+    HDC surface_dc;
+    HRESULT hr;
 
     TRACE("iface %p, dc %p, surface %p.\n", iface, hdc, Surface);
 
     if (!Surface) return E_INVALIDARG;
 
-    if (!(wined3d_surface = wined3d_device_get_surface_from_dc(ddraw->wined3d_device, hdc)))
+    if (!hdc)
     {
-        TRACE("No surface found for dc %p.\n", hdc);
         *Surface = NULL;
         return DDERR_NOTFOUND;
     }
 
-    surface_impl = wined3d_surface_get_parent(wined3d_surface);
-    *Surface = &surface_impl->IDirectDrawSurface7_iface;
-    IDirectDrawSurface7_AddRef(*Surface);
-    TRACE("Returning surface %p.\n", Surface);
-    return DD_OK;
+    wined3d_mutex_lock();
+    LIST_FOR_EACH_ENTRY(surface_impl, &ddraw->active_dcs, struct ddraw_surface, active_dcs_entry)
+    {
+        sub_resource = wined3d_texture_get_sub_resource(surface_impl->wined3d_texture, surface_impl->sub_resource_idx);
+        wined3d_surface = wined3d_surface_from_resource(sub_resource);
+        if (FAILED(hr = wined3d_surface_getdc(wined3d_surface, &surface_dc)))
+        {
+            ERR("Failed to get surface DC, hr %#x.\n", hr);
+            continue;
+        }
+
+        if (surface_dc == hdc)
+        {
+            wined3d_mutex_unlock();
+            *Surface = &surface_impl->IDirectDrawSurface7_iface;
+            IDirectDrawSurface7_AddRef(*Surface);
+            TRACE("Returning surface %p.\n", Surface);
+            return DD_OK;
+        }
+    }
+    wined3d_mutex_unlock();
+
+    *Surface = NULL;
+    return DDERR_NOTFOUND;
 }
 
 static HRESULT WINAPI ddraw4_GetSurfaceFromDC(IDirectDraw4 *iface, HDC dc,
@@ -4879,6 +4900,7 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
     }
 
     list_init(&ddraw->surface_list);
+    list_init(&ddraw->active_dcs);
 
     return DD_OK;
 }
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index f710a25..8023d60 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -97,6 +97,7 @@ struct ddraw
 
     /* DirectDraw things, which are not handled by WineD3D */
     DWORD                   cooperative_level;
+    struct list active_dcs;
 
     /* D3D things */
     HWND                    d3d_window;
@@ -194,6 +195,7 @@ struct ddraw_surface
 
     /* For the ddraw surface list */
     struct list             surface_list_entry;
+    struct list             active_dcs_entry;
 
     DWORD                   Handle;
 };
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index dcf7c61..e2ab79b 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -2176,7 +2176,9 @@ static HRESULT WINAPI ddraw_surface7_GetDC(IDirectDrawSurface7 *iface, HDC *hdc)
             if(hdc) *hdc = NULL;
             return DDERR_INVALIDPARAMS;
 
-        default: return hr;
+        default:
+            list_add_head(&surface->ddraw->active_dcs, &surface->active_dcs_entry);
+            return hr;
     }
 }
 
@@ -2246,6 +2248,8 @@ static HRESULT WINAPI ddraw_surface7_ReleaseDC(IDirectDrawSurface7 *iface, HDC h
         hr = ddraw_surface_update_frontbuffer(surface, NULL, FALSE);
     wined3d_mutex_unlock();
 
+    list_remove(&surface->active_dcs_entry);
+
     return hr;
 }
 
-- 
1.9.1




More information about the wine-patches mailing list