From 4e7d1a679f21b78ce099ad2ad1cfff37a53f62e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Mon, 14 Dec 2009 23:25:29 +0100 Subject: [PATCH 02/18] WineD3D: Properly release client storage memory --- dlls/wined3d/surface.c | 49 +++++++++++++++++++++++++++++++++++------------ 1 files changed, 36 insertions(+), 13 deletions(-) diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c index 59dda6e..68d8837 100644 --- a/dlls/wined3d/surface.c +++ b/dlls/wined3d/surface.c @@ -1624,6 +1624,36 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_UnlockRect(IWineD3DSurface *iface) { return WINED3D_OK; } +static void surface_release_client_storage(IWineD3DSurfaceImpl *This) +{ + struct wined3d_context *context; + + context = context_acquire(This->resource.device, NULL, CTXUSAGE_RESOURCELOAD); + + ENTER_GL(); + glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_FALSE); + if(This->texture_name) + { + surface_bind_and_dirtify(This, FALSE); + glTexImage2D(This->texture_target, This->texture_level, + GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + } + if(This->texture_name_srgb) + { + surface_bind_and_dirtify(This, TRUE); + glTexImage2D(This->texture_target, This->texture_level, + GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + } + glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); + + LEAVE_GL(); + context_release(context); + + IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INSRGBTEX, FALSE); + IWineD3DSurface_ModifyLocation((IWineD3DSurface *) This, SFLAG_INTEXTURE, FALSE); + This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); +} + static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHDC) { IWineD3DSurfaceImpl *This = (IWineD3DSurfaceImpl *)iface; @@ -1650,11 +1680,12 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_GetDC(IWineD3DSurface *iface, HDC *pHD /* Create a DIB section if there isn't a hdc yet */ if(!This->hDC) { - hr = IWineD3DBaseSurfaceImpl_CreateDIBSection(iface); - if(FAILED(hr)) return WINED3DERR_INVALIDCALL; if(This->Flags & SFLAG_CLIENT) { - surface_internal_preload(iface, SRGB_RGB); + IWineD3DSurface_LoadLocation(iface, SFLAG_INSYSMEM, NULL); + surface_release_client_storage(This); } + hr = IWineD3DBaseSurfaceImpl_CreateDIBSection(iface); + if(FAILED(hr)) return WINED3DERR_INVALIDCALL; /* Use the dib section from now on if we are not using a PBO */ if(!(This->Flags & SFLAG_PBO)) @@ -2911,11 +2942,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M /* For client textures opengl has to be notified */ if(This->Flags & SFLAG_CLIENT) { - DWORD oldFlags = This->Flags; - This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); - if(oldFlags & SFLAG_ALLOCATED) surface_internal_preload(iface, SRGB_RGB); - if(oldFlags & SFLAG_SRGBALLOCATED) surface_internal_preload(iface, SRGB_SRGB); - /* And hope that the app behaves correctly and did not free the old surface memory before setting a new pointer */ + surface_release_client_storage(This); } /* Now free the old memory if any */ @@ -2928,11 +2955,7 @@ static HRESULT WINAPI IWineD3DSurfaceImpl_SetMem(IWineD3DSurface *iface, void *M This->Flags &= ~SFLAG_USERPTR; if(This->Flags & SFLAG_CLIENT) { - DWORD oldFlags = This->Flags; - This->Flags &= ~(SFLAG_ALLOCATED | SFLAG_SRGBALLOCATED); - /* This respecifies an empty texture and opengl knows that the old memory is gone */ - if(oldFlags & SFLAG_ALLOCATED) surface_internal_preload(iface, SRGB_RGB); - if(oldFlags & SFLAG_SRGBALLOCATED) surface_internal_preload(iface, SRGB_SRGB); + surface_release_client_storage(This); } } return WINED3D_OK; -- 1.6.4.4