PATCH: some ddraw speedups
Marcus Meissner
marcus at jet.franken.de
Sat Sep 8 12:29:53 CDT 2001
Hi,
This patch contains ddraw related stuff:
* Added dwFlags to lock_update()
The USER mode does not to blt the old surface for DDLOCK_WRITEONLY.
* Restrict blting to the locked rectangle.
The ddraw side now remembers the 'last locked' rectangle (if unlock gets
passed a NULL rectangle) and only Blts this rectangle from and back to
the screen.
It also uses the clipping window to limit extents.
* The HAL driver now looks for Lock and Unlock and tries to use it, if
it is there. This required structure definitions for DDHAL_LOCKDATA and
DDHAL_UNLOCKDATA.
There is no HAL driver there yet to use this, but this part interlocked
with parts above. (I am working towards implementing such a HAL driver.)
Ciao, Marcus
Changelog:
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.
Index: include/ddrawi.h
===================================================================
RCS file: /home/wine/wine/include/ddrawi.h,v
retrieving revision 1.3
diff -u -r1.3 ddrawi.h
--- include/ddrawi.h 2001/04/16 19:04:58 1.3
+++ include/ddrawi.h 2001/09/08 14:48:16
@@ -538,6 +538,24 @@
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;
Index: dlls/ddraw/ddraw_private.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/ddraw_private.h,v
retrieving revision 1.20
diff -u -r1.20 ddraw_private.h
--- dlls/ddraw/ddraw_private.h 2001/07/28 00:09:07 1.20
+++ dlls/ddraw/ddraw_private.h 2001/09/08 14:48:26
@@ -222,6 +222,7 @@
DDSURFACEDESC2 surface_desc;
HDC hDC;
+ RECT lastlockrect;
BOOL dc_in_use;
HRESULT (*duplicate_surface)(IDirectDrawSurfaceImpl* src,
@@ -230,7 +231,7 @@
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,
Index: dlls/ddraw/dsurface/dib.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/dib.c,v
retrieving revision 1.4
diff -u -r1.4 dib.c
--- dlls/ddraw/dsurface/dib.c 2001/04/17 17:36:28 1.4
+++ dlls/ddraw/dsurface/dib.c 2001/09/08 14:48:28
@@ -322,9 +322,9 @@
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);
Index: dlls/ddraw/dsurface/hal.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/hal.c,v
retrieving revision 1.2
diff -u -r1.2 hal.c
--- dlls/ddraw/dsurface/hal.c 2001/04/18 17:40:43 1.2
+++ dlls/ddraw/dsurface/hal.c 2001/09/08 14:48:28
@@ -239,18 +254,50 @@
}
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 {
Index: dlls/ddraw/dsurface/hal.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/hal.h,v
retrieving revision 1.1
diff -u -r1.1 hal.h
--- dlls/ddraw/dsurface/hal.h 2001/04/17 17:48:19 1.1
+++ dlls/ddraw/dsurface/hal.h 2001/09/08 14:48:28
@@ -45,7 +45,7 @@
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,
Index: dlls/ddraw/dsurface/main.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/main.c,v
retrieving revision 1.22
diff -u -r1.22 main.c
--- dlls/ddraw/dsurface/main.c 2001/08/09 21:21:13 1.22
+++ dlls/ddraw/dsurface/main.c 2001/09/08 14:48:30
@@ -163,7 +163,8 @@
}
void
-Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect)
+Main_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect,
+ DWORD dwFlags)
{
}
@@ -680,7 +681,7 @@
* 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 @@
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;
Index: dlls/ddraw/dsurface/main.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/main.h,v
retrieving revision 1.3
diff -u -r1.3 main.h
--- dlls/ddraw/dsurface/main.h 2001/04/16 19:35:18 1.3
+++ dlls/ddraw/dsurface/main.h 2001/09/08 14:48:30
@@ -44,7 +44,7 @@
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);
Index: dlls/ddraw/dsurface/user.h
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/user.h,v
retrieving revision 1.3
diff -u -r1.3 user.h
--- dlls/ddraw/dsurface/user.h 2001/04/17 17:34:11 1.3
+++ dlls/ddraw/dsurface/user.h 2001/09/08 14:48:30
@@ -35,7 +35,7 @@
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,
Index: dlls/ddraw/dsurface/thunks.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/thunks.c,v
retrieving revision 1.3
diff -u -r1.3 thunks.c
--- dlls/ddraw/dsurface/thunks.c 2001/04/16 19:06:13 1.3
+++ dlls/ddraw/dsurface/thunks.c 2001/09/08 15:11:25
@@ -300,8 +300,8 @@
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
Index: dlls/ddraw/dsurface/user.c
===================================================================
RCS file: /home/wine/wine/dlls/ddraw/dsurface/user.c,v
retrieving revision 1.6
diff -u -r1.6 user.c
--- dlls/ddraw/dsurface/user.c 2001/07/31 00:14:06 1.6
+++ dlls/ddraw/dsurface/user.c 2001/09/08 16:10:36
@@ -172,9 +172,16 @@
}
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 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 @@
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);
}
}
More information about the wine-patches
mailing list