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