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.
This commit is contained in:
parent
3c9ab8f62d
commit
4d2f173ce3
|
@ -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)
|
||||
{
|
||||
if (HAL_IsUser(This)) {
|
||||
User_DirectDrawSurface_lock_update(This, pRect);
|
||||
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 {
|
||||
Main_DirectDrawSurface_lock_update(This, pRect);
|
||||
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, dwFlags);
|
||||
} else {
|
||||
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
|
||||
drawrect.left = 0;
|
||||
drawrect.right = This->surface_desc.dwWidth;
|
||||
drawrect.top = 0;
|
||||
drawrect.bottom = This->surface_desc.dwHeight;
|
||||
|
||||
BitBlt(hDisplayDC, 0, 0, This->surface_desc.dwWidth,
|
||||
This->surface_desc.dwHeight, hSurfaceDC, offset.x, offset.y,
|
||||
SRCCOPY);
|
||||
|
||||
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);
|
||||
RECT drawrect;
|
||||
|
||||
BitBlt(This->hDC, offset.x, offset.y, This->surface_desc.dwWidth,
|
||||
This->surface_desc.dwHeight, hDisplayDC, 0, 0, SRCCOPY);
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue