yet another ddraw patch
Ove Kaaven
ovehk at ping.uio.no
Tue Jul 9 16:44:34 CDT 2002
And this... I think this improved diablo 2 performance.
Not sure if it applies unedited.
Log:
Ove Kaaven <ovek at transgaming.com>
Wait for the asynchronous update thread to complete if the app requests
it. Fixed blit offseting issues in windowed mode.
Index: wine/dlls/ddraw/dsurface/user.c
diff -u wine/dlls/ddraw/dsurface/user.c:1.1.1.8 wine/dlls/ddraw/dsurface/user.c:1.57
--- wine/dlls/ddraw/dsurface/user.c:1.1.1.8 Sun Oct 28 06:13:59 2001
+++ wine/dlls/ddraw/dsurface/user.c Fri Feb 8 20:56:43 2002
@@ -72,14 +74,16 @@
DirectDrawSurface_RegisterClass();
#endif
#ifndef SYNC_UPDATE
+ InitializeCriticalSection(&priv->user.crit);
+ priv->user.refresh_event = CreateEventA(NULL, TRUE, FALSE, NULL);
priv->user.update_event = CreateEventA(NULL, FALSE, FALSE, NULL);
priv->user.update_thread = CreateThread(NULL, 0, User_update_thread, This, 0, NULL);
#ifdef OWN_WINDOW
if (This->ddraw_owner->cooperative_level & DDSCL_FULLSCREEN) {
/* wait for window creation (or update thread destruction) */
- while (WaitForMultipleObjects(1, &priv->user.update_thread, FALSE, 10) == WAIT_TIMEOUT)
- if (This->more.lpDDRAWReserved) break;
- if (!This->more.lpDDRAWReserved) {
+ while (WaitForMultipleObjects(1, &priv->user.update_thread, FALSE, 100) == WAIT_TIMEOUT)
+ if (This->more.lpDDRAWReserved) break;
+ if (!This->more.lpDDRAWReserved) {
ERR("window creation failed\n");
}
}
@@ -95,8 +103,8 @@
User_create_own_window(This);
#endif
#endif
- if (!This->more.lpDDRAWReserved)
- This->more.lpDDRAWReserved = (LPVOID)pDD->window;
+ if (!This->more.lpDDRAWReserved)
+ This->more.lpDDRAWReserved = (LPVOID)pDD->window;
}
return DIB_DirectDrawSurface_alloc_dc(This, &priv->user.cached_dc);
@@ -156,13 +164,16 @@
WaitForSingleObject(priv->user.update_thread,INFINITE);
#endif
TRACE("update thread terminated\n");
+ CloseHandle(event);
CloseHandle(priv->user.update_thread);
+ CloseHandle(priv->user.refresh_event);
+ DeleteCriticalSection(&priv->user.crit);
#else
#ifdef OWN_WINDOW
User_destroy_own_window(This);
#endif
#endif
- This->more.lpDDRAWReserved = 0;
+ This->more.lpDDRAWReserved = 0;
#ifdef OWN_WINDOW
DirectDrawSurface_UnregisterClass();
#endif
@@ -171,11 +182,44 @@
DIB_DirectDrawSurface_final_release(This);
}
+static int User_DirectDrawSurface_init_wait(IDirectDrawSurfaceImpl* This)
+{
+ USER_PRIV_VAR(priv, This);
+ int need_wait;
+ EnterCriticalSection(&priv->user.crit);
+ priv->user.wait_count++;
+ need_wait = priv->user.in_refresh;
+ LeaveCriticalSection(&priv->user.crit);
+ return need_wait;
+}
+
+static void User_DirectDrawSurface_end_wait(IDirectDrawSurfaceImpl* This)
+{
+ USER_PRIV_VAR(priv, This);
+ EnterCriticalSection(&priv->user.crit);
+ if (!--priv->user.wait_count)
+ ResetEvent(priv->user.refresh_event);
+ LeaveCriticalSection(&priv->user.crit);
+}
+
+static void User_DirectDrawSurface_wait_update(IDirectDrawSurfaceImpl* This)
+{
+ USER_PRIV_VAR(priv, This);
+ if (priv->user.in_refresh) {
+ if (User_DirectDrawSurface_init_wait(This))
+ WaitForSingleObject(priv->user.refresh_event, 2);
+ User_DirectDrawSurface_end_wait(This);
+ }
+}
+
void User_DirectDrawSurface_lock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect, DWORD dwFlags)
{
+#if 0
if (!(dwFlags & DDLOCK_WRITEONLY))
User_copy_from_screen(This, pRect);
+#endif
+ if (dwFlags & DDLOCK_WAIT) User_DirectDrawSurface_wait_update(This);
if (pRect) {
This->lastlockrect = *pRect;
@@ -187,12 +231,15 @@
void User_DirectDrawSurface_unlock_update(IDirectDrawSurfaceImpl* This,
LPCRECT pRect)
{
+ if (This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)
+ {
#ifdef SYNC_UPDATE
- User_copy_to_screen(This, pRect);
+ User_copy_to_screen(This, pRect);
#else
- USER_PRIV_VAR(priv, This);
- SetEvent(priv->user.update_event);
+ USER_PRIV_VAR(priv, This);
+ SetEvent(priv->user.update_event);
#endif
+ }
}
void User_DirectDrawSurface_set_palette(IDirectDrawSurfaceImpl* This,
@@ -218,7 +265,9 @@
DWORD dwStart, DWORD dwCount,
LPPALETTEENTRY palent)
{
+#ifndef SYNC_UPDATE
USER_PRIV_VAR(priv, This);
+#endif
DIB_DirectDrawSurface_update_palette(This, pal, dwStart, dwCount, palent);
/* FIXME: realize palette on display window */
@@ -261,8 +310,9 @@
User_copy_to_screen(This,NULL);
#else
USER_PRIV_VAR(priv, This);
- This->lastlockrect.left = This->lastlockrect.right = 0;
assert(This->surface_desc.ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE);
+ if (dwFlags & DDFLIP_WAIT) User_DirectDrawSurface_wait_update(This);
+ This->lastlockrect.left = This->lastlockrect.right = 0;
SetEvent(priv->user.update_event);
#endif
}
@@ -393,7 +443,7 @@
This->surface_desc.dwHeight,
GetDesktopWindow(),
0, 0, This);
- This->more.lpDDRAWReserved = (LPVOID)priv->user.window;
+ This->more.lpDDRAWReserved = (LPVOID)priv->user.window;
SetWindowPos(priv->user.window, HWND_TOP, 0, 0, 0, 0,
SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|
SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_SHOWWINDOW);
@@ -410,7 +460,7 @@
SetWindowPos(priv->user.window, 0, 0, 0, 0, 0,
SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOMOVE|SWP_NOZORDER|
SWP_NOREDRAW|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_HIDEWINDOW);
- This->more.lpDDRAWReserved = NULL;
+ This->more.lpDDRAWReserved = NULL;
DestroyWindow(priv->user.window);
priv->user.window = 0;
}
@@ -455,14 +505,21 @@
#endif
if (ret == WAIT_OBJECT_0)
{
- if (*pActive)
+ if (*pActive) {
+ priv->user.in_refresh = TRUE;
User_copy_to_screen(This, NULL);
- else
+ EnterCriticalSection(&priv->user.crit);
+ priv->user.in_refresh = FALSE;
+ if (priv->user.wait_count)
+ SetEvent(priv->user.refresh_event);
+ LeaveCriticalSection(&priv->user.crit);
+ } else
break;
}
else if (ret != WAIT_OBJECT_0+1) break;
} while (TRUE);
+ SetEvent(priv->user.refresh_event);
#ifdef OWN_WINDOW
User_destroy_own_window(This);
#endif
@@ -504,13 +561,9 @@
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);
+ if (hwnd && GetClientRect(hwnd,&xrc)) {
+ OffsetRect(&xrc,offset.x,offset.y);
IntersectRect(&drawrect,&drawrect,&xrc);
- /* translate it back to its original position */
- OffsetRect(&drawrect,-offset.x,-offset.y);
}
}
if (rc)
@@ -522,7 +575,7 @@
IntersectRect(&drawrect,&drawrect,&This->lastlockrect);
}
BitBlt(hDisplayDC,
- drawrect.left+offset.x, drawrect.top+offset.y,
+ drawrect.left-offset.x, drawrect.top-offset.y,
drawrect.right-drawrect.left, drawrect.bottom-drawrect.top,
hSurfaceDC,
drawrect.left, drawrect.top,
Index: wine/dlls/ddraw/dsurface/user.h
diff -u wine/dlls/ddraw/dsurface/user.h:1.1.1.4 wine/dlls/ddraw/dsurface/user.h:1.16
--- wine/dlls/ddraw/dsurface/user.h:1.1.1.4 Thu Oct 4 06:43:01 2001
+++ wine/dlls/ddraw/dsurface/user.h Sat May 5 12:36:54 2001
@@ -12,7 +12,9 @@
{
HWND window;
HDC cached_dc;
- HANDLE update_thread, update_event;
+ HANDLE update_thread, update_event, refresh_event;
+ volatile int wait_count, in_refresh;
+ CRITICAL_SECTION crit;
};
typedef struct
More information about the wine-patches
mailing list