Commit 4d2f173c authored by Marcus Meissner's avatar Marcus Meissner Committed by Alexandre Julliard

Added dwFlags to lock_update private functions so we can pass

WRITEONLY/READONLY. Added those flags to the internal Lock() calls. Only copy the surface from screen to surface if not writeonly. Restrict blitting between display window and surface to the locked/unlocked rectangle and the clipwindow section. Added defines for DDHAL_UNLOCKDATA/DDHAL_LOCKDATA, added calls to HAL implementation.
parent 3c9ab8f6
......@@ -222,6 +222,7 @@ struct IDirectDrawSurfaceImpl
DDSURFACEDESC2 surface_desc;
HDC hDC;
RECT lastlockrect;
BOOL dc_in_use;
HRESULT (*duplicate_surface)(IDirectDrawSurfaceImpl* src,
......@@ -230,7 +231,7 @@ struct IDirectDrawSurfaceImpl
HRESULT (*late_allocate)(IDirectDrawSurfaceImpl *This);
BOOL (*attach)(IDirectDrawSurfaceImpl *This, IDirectDrawSurfaceImpl *to);
BOOL (*detach)(IDirectDrawSurfaceImpl *This);
void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);
void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
void (*lose_surface)(IDirectDrawSurfaceImpl* This);
BOOL (*flip_data)(IDirectDrawSurfaceImpl* front,
......
......@@ -322,9 +322,9 @@ DIB_DirectDrawSurface_Blt(LPDIRECTDRAWSURFACE7 iface, LPRECT rdst,
DD_STRUCT_INIT(&sdesc);
sdesc.dwSize = sizeof(sdesc);
if (src) IDirectDrawSurface7_Lock(src, NULL, &sdesc, 0, 0);
if (src) IDirectDrawSurface7_Lock(src, NULL, &sdesc, DDLOCK_READONLY, 0);
ddesc.dwSize = sizeof(ddesc);
IDirectDrawSurface7_Lock(iface,NULL,&ddesc,0,0);
IDirectDrawSurface7_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
if (TRACE_ON(ddraw)) {
if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
......
......@@ -239,18 +239,50 @@ HRESULT HAL_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
}
void HAL_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect)
LPCRECT pRect, DWORD dwFlags)
{
LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
DDHAL_LOCKDATA data;
data.lpDD = dd_gbl;
data.lpDDSurface = &This->local;
data.ddRVal = 0;
data.lpSurfData = This->surface_desc.lpSurface; /* FIXME: correct? */
if (pRect) {
data.rArea.top = pRect->top;
data.rArea.bottom = pRect->bottom;
data.rArea.left = pRect->left;
data.rArea.right = pRect->right;
data.bHasRect = TRUE;
} else {
data.bHasRect = FALSE;
}
data.dwFlags = dwFlags;
data.Lock = dd_gbl->lpDDCBtmp->HALDDSurface.Lock;
if (data.Lock && (data.Lock(&data) == DDHAL_DRIVER_HANDLED))
return;
if (HAL_IsUser(This)) {
User_DirectDrawSurface_lock_update(This, pRect);
User_DirectDrawSurface_lock_update(This, pRect, dwFlags);
} else {
Main_DirectDrawSurface_lock_update(This, pRect);
Main_DirectDrawSurface_lock_update(This, pRect, dwFlags);
}
}
void HAL_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect)
{
LPDDRAWI_DIRECTDRAW_GBL dd_gbl = This->more.lpDD_lcl->lpGbl;
DDHAL_UNLOCKDATA data;
data.lpDD = dd_gbl;
data.lpDDSurface = &This->local;
data.ddRVal = 0;
data.Unlock = dd_gbl->lpDDCBtmp->HALDDSurface.Unlock;
if (data.Unlock && (data.Unlock(&data) == DDHAL_DRIVER_HANDLED))
return;
if (HAL_IsUser(This)) {
User_DirectDrawSurface_unlock_update(This, pRect);
} else {
......
......@@ -45,7 +45,7 @@ void HAL_DirectDrawSurface_update_palette(IDirectDrawSurfaceImpl* This,
HRESULT HAL_DirectDrawSurface_duplicate_surface(IDirectDrawSurfaceImpl* This,
LPDIRECTDRAWSURFACE7* ppDup);
void HAL_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect);
LPCRECT pRect, DWORD dwFlags);
void HAL_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect);
BOOL HAL_DirectDrawSurface_flip_data(IDirectDrawSurfaceImpl* front,
......
......@@ -163,7 +163,8 @@ BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This)
}
void
Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect,
DWORD dwFlags)
{
}
......@@ -680,7 +681,7 @@ Main_DirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE7 iface, HDC *phDC)
* Strange: Lock lists DDERR_SURFACEBUSY as an error, meaning that another
* thread has it locked, but GetDC does not. */
ddsd.dwSize = sizeof(ddsd);
hr = IDirectDrawSurface7_Lock(iface, NULL, &ddsd, 0, 0);
hr = IDirectDrawSurface7_Lock(iface, NULL, &ddsd, DDLOCK_READONLY, 0);
if (FAILED(hr))
{
UNLOCK_OBJECT(This);
......@@ -904,11 +905,13 @@ Main_DirectDrawSurface_Lock(LPDIRECTDRAWSURFACE7 iface, LPRECT prect,
return DDERR_INVALIDPARAMS;
}
This->lock_update(This, prect);
This->lock_update(This, prect, flags);
pDDSD->lpSurface = (char *)This->surface_desc.lpSurface
+ prect->top * This->surface_desc.u1.lPitch
+ prect->left * GET_BPP(This->surface_desc);
} else {
This->lock_update(This, NULL, flags);
}
return DD_OK;
......
......@@ -44,7 +44,7 @@ Main_DirectDrawSurface_attach(IDirectDrawSurfaceImpl *This,
BOOL Main_DirectDrawSurface_detach(IDirectDrawSurfaceImpl *This);
void
Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect);
LPCRECT pRect, DWORD dwFlags);
void
Main_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect);
......
......@@ -300,8 +300,8 @@ IDirectDrawSurface3Impl_SetPalette(LPDIRECTDRAWSURFACE3 This,
static HRESULT WINAPI
IDirectDrawSurface3Impl_Unlock(LPDIRECTDRAWSURFACE3 This, LPVOID data)
{
/* XXX This might be wrong as LPVOID changed to LPRECT along the way. */
return IDirectDrawSurface7_Unlock(CONVERT(This), data);
/* data might not be the LPRECT of later versions, so drop it. */
return IDirectDrawSurface7_Unlock(CONVERT(This), NULL);
}
static HRESULT WINAPI
......
......@@ -172,9 +172,16 @@ void User_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This)
}
void User_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect)
LPCRECT pRect, DWORD dwFlags)
{
User_copy_from_screen(This, pRect);
if (!(dwFlags & DDLOCK_WRITEONLY))
User_copy_from_screen(This, pRect);
if (pRect) {
This->lastlockrect = *pRect;
} else {
This->lastlockrect.left = This->lastlockrect.right = 0;
}
}
void User_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
......@@ -464,14 +471,13 @@ static DWORD CALLBACK User_update_thread(LPVOID arg)
static void User_copy_to_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc)
{
/* rc is unused. We copy the whole thing. */
if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
POINT offset;
HWND hDisplayWnd;
HDC hDisplayDC;
HDC hSurfaceDC;
RECT drawrect;
if (FAILED(This->get_dc(This, &hSurfaceDC)))
return;
......@@ -488,28 +494,65 @@ static void User_copy_to_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc)
RealizePalette(hDisplayDC); /* sends messages => deadlocks */
}
#endif
BitBlt(hDisplayDC, 0, 0, This->surface_desc.dwWidth,
This->surface_desc.dwHeight, hSurfaceDC, offset.x, offset.y,
SRCCOPY);
drawrect.left = 0;
drawrect.right = This->surface_desc.dwWidth;
drawrect.top = 0;
drawrect.bottom = This->surface_desc.dwHeight;
if (This->clipper) {
RECT xrc;
HWND hwnd = This->clipper->hWnd;
if (hwnd && GetWindowRect(hwnd,&xrc)) {
/* Do not forget to honor the offset within the clip window. */
/* translate the surface to 0.0 of the clip window */
OffsetRect(&drawrect,offset.x,offset.y);
IntersectRect(&drawrect,&drawrect,&xrc);
/* translate it back to its original position */
OffsetRect(&drawrect,-offset.x,-offset.y);
}
}
if (rc)
IntersectRect(&drawrect,&drawrect,rc);
else {
/* Only use this if the caller did not pass a rectangle, since
* due to double locking this could be the wrong one ... */
if (This->lastlockrect.left != This->lastlockrect.right)
IntersectRect(&drawrect,&drawrect,&This->lastlockrect);
}
BitBlt(hDisplayDC,
drawrect.left+offset.x, drawrect.top+offset.y,
drawrect.right-drawrect.left, drawrect.bottom-drawrect.top,
hSurfaceDC,
drawrect.left, drawrect.top,
SRCCOPY
);
ReleaseDC(hDisplayWnd, hDisplayDC);
}
}
static void User_copy_from_screen(IDirectDrawSurfaceImpl* This, LPCRECT rc)
{
/* rc is unused. We copy the whole thing. */
if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
{
POINT offset;
HWND hDisplayWnd = get_display_window(This, &offset);
HDC hDisplayDC = GetDC(hDisplayWnd);
BitBlt(This->hDC, offset.x, offset.y, This->surface_desc.dwWidth,
This->surface_desc.dwHeight, hDisplayDC, 0, 0, SRCCOPY);
RECT drawrect;
drawrect.left = 0;
drawrect.right = This->surface_desc.dwWidth;
drawrect.top = 0;
drawrect.bottom = This->surface_desc.dwHeight;
if (rc)
IntersectRect(&drawrect,&drawrect,rc);
BitBlt(This->hDC,
drawrect.left, drawrect.top,
drawrect.right-drawrect.left, drawrect.bottom-drawrect.top,
hDisplayDC,
drawrect.left+offset.x, drawrect.top+offset.y,
SRCCOPY
);
ReleaseDC(hDisplayWnd, hDisplayDC);
}
}
......
......@@ -35,7 +35,7 @@ User_DirectDrawSurface_Create(IDirectDrawImpl *pDD,
void User_DirectDrawSurface_final_release(IDirectDrawSurfaceImpl* This);
void User_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect);
LPCRECT pRect, DWORD dwFlags);
void User_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect);
void User_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
......
......@@ -538,6 +538,24 @@ typedef struct _DDHAL_FLIPDATA {
LPDDRAWI_DDRAWSURFACE_LCL lpSurfTargLeft;
} DDHAL_FLIPDATA;
typedef struct _DDHAL_LOCKDATA {
LPDDRAWI_DIRECTDRAW_GBL lpDD;
LPDDRAWI_DDRAWSURFACE_LCL lpDDSurface;
DWORD bHasRect;
RECTL rArea;
LPVOID lpSurfData;
HRESULT ddRVal;
LPDDHALSURFCB_LOCK Lock;
DWORD dwFlags;
} DDHAL_LOCKDATA;
typedef struct _DDHAL_UNLOCKDATA {
LPDDRAWI_DIRECTDRAW_GBL lpDD;
LPDDRAWI_DDRAWSURFACE_LCL lpDDSurface;
HRESULT ddRVal;
LPDDHALSURFCB_UNLOCK Unlock;
} DDHAL_UNLOCKDATA;
typedef struct _DDHAL_BLTDATA {
LPDDRAWI_DIRECTDRAW_GBL lpDD;
LPDDRAWI_DDRAWSURFACE_LCL lpDDDestSurface;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment