From: Riccardo Bortolato Subject: [PATCH 11/12] ddraw: cache active DCs Message-Id: <1442996856-32611-11-git-send-email-rikyz619@gmail.com> Date: Wed, 23 Sep 2015 10:27:35 +0200 --- 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