Every 33ms on toplevel windows with a non-dummy, non-offscreen window surface.
Making sure the window surfaces are flushed from their owner thread instead of any other thread that might draw to it and trigger an occasional flush. This removes the need for tracking window surfaces to additionally flush them in win32u.
It will make it easier to implement GL-based window surfaces for compositing, and simplify context management. Instead of one context per window, made current on the flushing thread we can have a single context on each thread owning a window that is used to flush them.
-- v2: win32u: Remove now unnecessary window surfaces list. win32u: Flush window surfaces in process_wine_present. server: Post a WINE_WM_PRESENT for window surface present. win32u: Remove unnecessary window_surface exports.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 22 +++++++++++----------- dlls/win32u/win32u_private.h | 7 ++++++- include/wine/gdi_driver.h | 6 ------ 3 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index d1cf5c78bab..be31b909b3f 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -524,8 +524,8 @@ static BOOL update_surface_shape( struct window_surface *surface, const RECT *re return clear_surface_shape( surface ); }
-W32KAPI struct window_surface *window_surface_create( UINT size, const struct window_surface_funcs *funcs, HWND hwnd, - const RECT *rect, BITMAPINFO *info, HBITMAP bitmap ) +struct window_surface *window_surface_create( UINT size, const struct window_surface_funcs *funcs, HWND hwnd, + const RECT *rect, BITMAPINFO *info, HBITMAP bitmap ) { struct window_surface *surface;
@@ -552,12 +552,12 @@ W32KAPI struct window_surface *window_surface_create( UINT size, const struct wi return surface; }
-W32KAPI void window_surface_add_ref( struct window_surface *surface ) +void window_surface_add_ref( struct window_surface *surface ) { InterlockedIncrement( &surface->ref ); }
-W32KAPI void window_surface_release( struct window_surface *surface ) +void window_surface_release( struct window_surface *surface ) { ULONG ret = InterlockedDecrement( &surface->ref ); if (!ret) @@ -571,19 +571,19 @@ W32KAPI void window_surface_release( struct window_surface *surface ) } }
-W32KAPI void window_surface_lock( struct window_surface *surface ) +void window_surface_lock( struct window_surface *surface ) { if (surface == &dummy_surface) return; pthread_mutex_lock( &surface->mutex ); }
-W32KAPI void window_surface_unlock( struct window_surface *surface ) +void window_surface_unlock( struct window_surface *surface ) { if (surface == &dummy_surface) return; pthread_mutex_unlock( &surface->mutex ); }
-void *window_surface_get_color( struct window_surface *surface, BITMAPINFO *info ) +static void *window_surface_get_color( struct window_surface *surface, BITMAPINFO *info ) { struct bitblt_coords coords = {0}; struct gdi_image_bits gdi_bits; @@ -606,7 +606,7 @@ void *window_surface_get_color( struct window_surface *surface, BITMAPINFO *info return gdi_bits.ptr; }
-W32KAPI void window_surface_flush( struct window_surface *surface ) +void window_surface_flush( struct window_surface *surface ) { char color_buf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; char shape_buf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; @@ -641,7 +641,7 @@ W32KAPI void window_surface_flush( struct window_surface *surface ) window_surface_unlock( surface ); }
-W32KAPI void window_surface_set_layered( struct window_surface *surface, COLORREF color_key, UINT alpha_bits, UINT alpha_mask ) +void window_surface_set_layered( struct window_surface *surface, COLORREF color_key, UINT alpha_bits, UINT alpha_mask ) { char color_buf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *color_info = (BITMAPINFO *)color_buf; @@ -670,7 +670,7 @@ W32KAPI void window_surface_set_layered( struct window_surface *surface, COLORRE window_surface_unlock( surface ); }
-W32KAPI void window_surface_set_clip( struct window_surface *surface, HRGN clip_region ) +void window_surface_set_clip( struct window_surface *surface, HRGN clip_region ) { window_surface_lock( surface );
@@ -703,7 +703,7 @@ W32KAPI void window_surface_set_clip( struct window_surface *surface, HRGN clip_ window_surface_unlock( surface ); }
-W32KAPI void window_surface_set_shape( struct window_surface *surface, HRGN shape_region ) +void window_surface_set_shape( struct window_surface *surface, HRGN shape_region ) { window_surface_lock( surface );
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 4c7ce21d5b4..60c3edb787b 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -54,7 +54,12 @@ extern void move_window_bits_surface( HWND hwnd, const RECT *window_rect, struct const RECT *old_visible_rect, const RECT *valid_rects ); extern void register_window_surface( struct window_surface *old, struct window_surface *new ); -extern void *window_surface_get_color( struct window_surface *surface, BITMAPINFO *info ); + +extern void window_surface_lock( struct window_surface *surface ); +extern void window_surface_unlock( struct window_surface *surface ); +extern void window_surface_flush( struct window_surface *surface ); +extern void window_surface_set_clip( struct window_surface *surface, HRGN clip_region ); +extern void window_surface_set_layered( struct window_surface *surface, COLORREF color_key, UINT alpha_bits, UINT alpha_mask );
/* defwnd.c */ extern BOOL adjust_window_rect( RECT *rect, DWORD style, BOOL menu, DWORD ex_style, UINT dpi ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index abf1b699cab..ef264cace97 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -317,13 +317,7 @@ W32KAPI struct window_surface *window_surface_create( UINT size, const struct wi const RECT *rect, BITMAPINFO *info, HBITMAP bitmap ); W32KAPI void window_surface_add_ref( struct window_surface *surface ); W32KAPI void window_surface_release( struct window_surface *surface ); -W32KAPI void window_surface_lock( struct window_surface *surface ); -W32KAPI void window_surface_unlock( struct window_surface *surface ); -W32KAPI void window_surface_set_layered( struct window_surface *surface, COLORREF color_key, UINT alpha_bits, UINT alpha_mask ); -W32KAPI void window_surface_flush( struct window_surface *surface ); -W32KAPI void window_surface_set_clip( struct window_surface *surface, HRGN clip_region ); W32KAPI void window_surface_set_shape( struct window_surface *surface, HRGN shape_region ); -W32KAPI void window_surface_set_layered( struct window_surface *surface, COLORREF color_key, UINT alpha_bits, UINT alpha_mask );
/* display manager interface, used to initialize display device registry data */
From: Rémi Bernon rbernon@codeweavers.com
Every 33ms on every toplevel window with a non-dummy, non-offscreen window surface. --- dlls/win32u/dce.c | 5 +++++ dlls/win32u/message.c | 2 ++ dlls/win32u/win32u_private.h | 1 + dlls/win32u/window.c | 2 +- include/ntuser.h | 1 + server/protocol.def | 1 + server/queue.c | 16 +++++++++------- server/user.h | 2 ++ server/window.c | 21 +++++++++++++++++++++ 9 files changed, 43 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index be31b909b3f..71ee85d64e1 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -725,6 +725,11 @@ void window_surface_set_shape( struct window_surface *surface, HRGN shape_region window_surface_flush( surface ); }
+void process_wine_present( HWND hwnd ) +{ + FIXME( "stub!\n" ); +} + /******************************************************************* * register_window_surface * diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 51a173a1173..139a6d32fe9 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2735,6 +2735,8 @@ static BOOL process_hardware_message( MSG *msg, UINT hw_id, const struct hardwar process_wine_clipcursor( msg->hwnd, msg->wParam, msg->lParam ); else if (msg->message == WM_WINE_SETCURSOR) process_wine_setcursor( msg->hwnd, (HWND)msg->wParam, (HCURSOR)msg->lParam ); + else if (msg->message == WM_WINE_PRESENT) + process_wine_present( msg->hwnd ); else ERR( "unknown message type %x\n", msg->message ); set_thread_dpi_awareness_context( context ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 60c3edb787b..21e4b3e8f8a 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -55,6 +55,7 @@ extern void move_window_bits_surface( HWND hwnd, const RECT *window_rect, struct extern void register_window_surface( struct window_surface *old, struct window_surface *new );
+extern void process_wine_present( HWND hwnd ); extern void window_surface_lock( struct window_surface *surface ); extern void window_surface_unlock( struct window_surface *surface ); extern void window_surface_flush( struct window_surface *surface ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 4345c7b7ff4..5825dd8b5a2 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2142,6 +2142,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru req->previous = wine_server_user_handle( insert_after ); req->swp_flags = swp_flags; req->monitor_dpi = monitor_dpi; + req->refresh_rate = !is_child && new_surface && new_surface != &dummy_surface ? 30 : 0; req->window = wine_server_rectangle( new_rects->window ); req->client = wine_server_rectangle( new_rects->client ); if (!EqualRect( &new_rects->window, &new_rects->visible ) || new_surface || valid_rects) @@ -2545,7 +2546,6 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_ window_surface_set_layered( surface, key, -1, 0xff000000 );
user_driver->pUpdateLayeredWindow( hwnd, blend->SourceConstantAlpha, flags ); - window_surface_flush( surface ); }
done: diff --git a/include/ntuser.h b/include/ntuser.h index ef09d7e97bb..5e9bb545410 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -641,6 +641,7 @@ enum wine_internal_message WM_WINE_FIRST_DRIVER_MSG = 0x80001000, /* range of messages reserved for the USER driver */ WM_WINE_CLIPCURSOR = 0x80001ff0, /* internal driver notification messages */ WM_WINE_SETCURSOR, + WM_WINE_PRESENT, WM_WINE_LAST_DRIVER_MSG = 0x80001fff };
diff --git a/server/protocol.def b/server/protocol.def index b87b7d6515a..6d97375a0bd 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2719,6 +2719,7 @@ enum message_type @REQ(set_window_pos) unsigned short swp_flags; /* SWP_* flags */ unsigned short paint_flags; /* paint flags (see below) */ + unsigned short refresh_rate; /* window surface refresh rate (fps) */ unsigned int monitor_dpi; /* DPI of the window's monitor */ user_handle_t handle; /* handle to the window */ user_handle_t previous; /* previous window in Z order */ diff --git a/server/queue.c b/server/queue.c index c3d80ed7f2d..d3cfadc075a 100644 --- a/server/queue.c +++ b/server/queue.c @@ -485,8 +485,8 @@ static int is_cursor_clipped( struct desktop *desktop ) return !is_rect_equal( &clip_rect, &top_rect ); }
-static void queue_cursor_message( struct desktop *desktop, user_handle_t win, unsigned int message, - lparam_t wparam, lparam_t lparam ) +void queue_internal_message( struct desktop *desktop, user_handle_t win, unsigned int message, + lparam_t wparam, lparam_t lparam ) { static const struct hw_msg_source source = { IMDT_UNAVAILABLE, IMO_SYSTEM }; desktop_shm_t *desktop_shm = desktop->shared; @@ -529,8 +529,8 @@ static int update_desktop_cursor_window( struct desktop *desktop, user_handle_t input_shm_t *input_shm = input->shared; user_handle_t handle = input_shm->cursor_count < 0 ? 0 : input_shm->cursor; /* when clipping send the message to the foreground window as well, as some driver have an artificial overlay window */ - if (is_cursor_clipped( desktop )) queue_cursor_message( desktop, 0, WM_WINE_SETCURSOR, win, handle ); - queue_cursor_message( desktop, win, WM_WINE_SETCURSOR, win, handle ); + if (is_cursor_clipped( desktop )) queue_internal_message( desktop, 0, WM_WINE_SETCURSOR, win, handle ); + queue_internal_message( desktop, win, WM_WINE_SETCURSOR, win, handle ); }
return updated; @@ -567,8 +567,8 @@ static void update_desktop_cursor_handle( struct desktop *desktop, struct thread { user_handle_t win = desktop->cursor_win; /* when clipping send the message to the foreground window as well, as some driver have an artificial overlay window */ - if (is_cursor_clipped( desktop )) queue_cursor_message( desktop, 0, WM_WINE_SETCURSOR, win, handle ); - queue_cursor_message( desktop, win, WM_WINE_SETCURSOR, win, handle ); + if (is_cursor_clipped( desktop )) queue_internal_message( desktop, 0, WM_WINE_SETCURSOR, win, handle ); + queue_internal_message( desktop, win, WM_WINE_SETCURSOR, win, handle ); } }
@@ -652,7 +652,7 @@ void set_clip_rectangle( struct desktop *desktop, const struct rectangle *rect,
/* notify foreground thread of reset, clipped, or released cursor rect */ if (reset || flags != SET_CURSOR_NOCLIP || old_flags != SET_CURSOR_NOCLIP) - queue_cursor_message( desktop, 0, WM_WINE_CLIPCURSOR, flags, reset ); + queue_internal_message( desktop, 0, WM_WINE_CLIPCURSOR, flags, reset ); }
/* change the foreground input and reset the cursor clip rect */ @@ -802,6 +802,7 @@ static inline int get_hardware_msg_bit( unsigned int message ) if (message >= WM_KEYFIRST && message <= WM_KEYLAST) return QS_KEY; if (message == WM_WINE_CLIPCURSOR) return QS_RAWINPUT; if (message == WM_WINE_SETCURSOR) return QS_RAWINPUT; + if (message == WM_WINE_PRESENT) return QS_RAWINPUT; return QS_MOUSEBUTTON; }
@@ -925,6 +926,7 @@ static int merge_message( struct thread_input *input, const struct message *msg if (msg->msg == WM_MOUSEMOVE) return merge_mousemove( input, msg ); if (msg->msg == WM_WINE_CLIPCURSOR) return merge_unique_message( input, WM_WINE_CLIPCURSOR, msg ); if (msg->msg == WM_WINE_SETCURSOR) return merge_unique_message( input, WM_WINE_SETCURSOR, msg ); + if (msg->msg == WM_WINE_PRESENT) return merge_unique_message( input, WM_WINE_PRESENT, msg ); return 0; }
diff --git a/server/user.h b/server/user.h index 0ebda06b49b..9dd901b6666 100644 --- a/server/user.h +++ b/server/user.h @@ -129,6 +129,8 @@ extern void post_message( user_handle_t win, unsigned int message, lparam_t wparam, lparam_t lparam ); extern void send_notify_message( user_handle_t win, unsigned int message, lparam_t wparam, lparam_t lparam ); +extern void queue_internal_message( struct desktop *desktop, user_handle_t win, unsigned int message, + lparam_t wparam, lparam_t lparam ); extern void post_win_event( struct thread *thread, unsigned int event, user_handle_t win, unsigned int object_id, unsigned int child_id, client_ptr_t proc, diff --git a/server/window.c b/server/window.c index e237d40a153..2500cc130a4 100644 --- a/server/window.c +++ b/server/window.c @@ -73,6 +73,8 @@ struct window struct rectangle client_rect; /* client rectangle (relative to parent client area) */ struct region *win_region; /* region for shaped windows (relative to window rect) */ struct region *update_region; /* update region (relative to window rect) */ + unsigned int refresh_rate; /* window surface refresh rate (fps) */ + struct timeout_user *present; /* present timeout user */ unsigned int style; /* window style */ unsigned int ex_style; /* window extended style */ lparam_t id; /* window id */ @@ -172,6 +174,7 @@ static void window_destroy( struct object *obj ) release_object( win->parent ); }
+ if (win->present) remove_timeout_user( win->present ); if (win->win_region) free_region( win->win_region ); if (win->update_region) free_region( win->update_region ); if (win->class) release_class( win->class ); @@ -655,6 +658,8 @@ static struct window *create_window( struct window *parent, struct window *owner win->desktop = desktop; win->class = class; win->atom = atom; + win->refresh_rate = 0; + win->present = NULL; win->win_region = NULL; win->update_region = NULL; win->style = 0; @@ -2636,6 +2641,18 @@ DECL_HANDLER(get_window_tree) if ((ptr = get_last_child( win ))) reply->last_child = ptr->handle; }
+static void queue_window_present( void *private ) +{ + timeout_t timeout = -TICKS_PER_SEC, rate; + struct window *win = private; + + if (!(rate = win->refresh_rate)) win->present = NULL; + else + { + queue_internal_message( win->desktop, win->handle, WM_WINE_PRESENT, 0, 0 ); + win->present = add_timeout_user( (timeout + rate / 2) / rate, queue_window_present, win ); + } +}
/* set the position and Z order of a window */ DECL_HANDLER(set_window_pos) @@ -2720,6 +2737,10 @@ DECL_HANDLER(set_window_pos)
if (win->paint_flags & SET_WINPOS_LAYERED_WINDOW) validate_whole_window( win );
+ win->refresh_rate = req->refresh_rate; + if (win->present) remove_timeout_user( win->present ); + queue_window_present( win ); + reply->new_style = win->style; reply->new_ex_style = win->ex_style;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 50 ++++++++++++++++-------------------- dlls/win32u/dibdrv/dc.c | 18 ++----------- dlls/win32u/input.c | 4 +-- dlls/win32u/message.c | 5 ---- dlls/win32u/win32u_private.h | 2 -- dlls/win32u/window.c | 1 - 6 files changed, 25 insertions(+), 55 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 71ee85d64e1..79561b109af 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -53,6 +53,8 @@ static struct list dce_list = LIST_INIT(dce_list); static struct list window_surfaces = LIST_INIT( window_surfaces ); static pthread_mutex_t surfaces_lock = PTHREAD_MUTEX_INITIALIZER;
+static void window_surface_flush( struct window_surface *surface ); + /******************************************************************* * Dummy window surface for windows that shouldn't get painted. */ @@ -270,6 +272,18 @@ static RECT get_surface_rect( RECT rect ) return rect; }
+static struct window_surface *window_get_surface( HWND hwnd ) +{ + struct window_surface *surface; + WND *win; + + if (!(win = get_win_ptr( hwnd ))) return NULL; + if ((surface = win->surface)) window_surface_add_ref( surface ); + release_win_ptr( win ); + + return surface; +} + void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *surface_rect, UINT monitor_dpi, struct window_surface **window_surface ) { @@ -606,7 +620,7 @@ static void *window_surface_get_color( struct window_surface *surface, BITMAPINF return gdi_bits.ptr; }
-void window_surface_flush( struct window_surface *surface ) +static void window_surface_flush( struct window_surface *surface ) { char color_buf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; char shape_buf[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; @@ -721,13 +735,17 @@ void window_surface_set_shape( struct window_surface *surface, HRGN shape_region }
window_surface_unlock( surface ); - - window_surface_flush( surface ); }
void process_wine_present( HWND hwnd ) { - FIXME( "stub!\n" ); + struct window_surface *surface; + + TRACE( "hwnd %p\n", hwnd ); + + if (!(surface = window_get_surface( hwnd ))) return; + window_surface_flush( surface ); + window_surface_release( surface ); }
/******************************************************************* @@ -746,29 +764,6 @@ void register_window_surface( struct window_surface *old, struct window_surface pthread_mutex_unlock( &surfaces_lock ); }
-/******************************************************************* - * flush_window_surfaces - * - * Flush pending output from all window surfaces. - */ -void flush_window_surfaces( BOOL idle ) -{ - static DWORD last_idle; - DWORD now; - struct window_surface *surface; - - pthread_mutex_lock( &surfaces_lock ); - now = NtGetTickCount(); - if (idle) last_idle = now; - /* if not idle, we only flush if there's evidence that the app never goes idle */ - else if ((int)(now - last_idle) < 50) goto done; - - LIST_FOR_EACH_ENTRY( surface, &window_surfaces, struct window_surface, entry ) - window_surface_flush( surface ); -done: - pthread_mutex_unlock( &surfaces_lock ); -} - /*********************************************************************** * dump_rdw_flags */ @@ -1729,7 +1724,6 @@ HDC WINAPI NtUserBeginPaint( HWND hwnd, PAINTSTRUCT *ps ) BOOL WINAPI NtUserEndPaint( HWND hwnd, const PAINTSTRUCT *ps ) { NtUserShowCaret( hwnd ); - flush_window_surfaces( FALSE ); if (!ps) return FALSE; release_dc( hwnd, ps->hdc, TRUE ); return TRUE; diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c index 8a72d9789ea..e50c2e9245e 100644 --- a/dlls/win32u/dibdrv/dc.c +++ b/dlls/win32u/dibdrv/dc.c @@ -496,8 +496,6 @@ const struct gdi_dc_funcs dib_driver = * can paint to the same window. */
-#define FLUSH_PERIOD 50 /* time in ms since drawing started for forcing a surface flush */ - struct windrv_physdev { struct gdi_physdev dev; @@ -517,25 +515,13 @@ static inline struct windrv_physdev *get_windrv_physdev( PHYSDEV dev ) static inline void lock_surface( struct windrv_physdev *dev ) { struct window_surface *surface = dev->surface; - - if (!dev->lock_count++) - { - window_surface_lock( surface ); - if (IsRectEmpty( dev->dibdrv->bounds ) || !surface->draw_start_ticks) - surface->draw_start_ticks = NtGetTickCount(); - } + if (!dev->lock_count++) window_surface_lock( surface ); }
static inline void unlock_surface( struct windrv_physdev *dev ) { struct window_surface *surface = dev->surface; - - if (!--dev->lock_count) - { - DWORD ticks = NtGetTickCount() - surface->draw_start_ticks; - window_surface_unlock( surface ); - if (ticks > FLUSH_PERIOD) window_surface_flush( dev->surface ); - } + if (!--dev->lock_count) window_surface_unlock( surface ); }
static inline void lock_surfaces( struct windrv_physdev *dst_dev, struct windrv_physdev *src_dev ) diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index c718bd1cbbc..b5ad3d1c027 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -796,9 +796,7 @@ static void check_for_events( UINT flags ) }; MSG msg;
- if (!user_driver->pProcessEvents( flags )) - flush_window_surfaces( TRUE ); - + user_driver->pProcessEvents( flags ); peek_message( &msg, &filter ); }
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 139a6d32fe9..b596b5a03df 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -3130,7 +3130,6 @@ static inline void check_for_driver_events(void) { if (get_user_thread_info()->last_driver_time != get_driver_check_time()) { - flush_window_surfaces( FALSE ); user_driver->pProcessEvents( QS_ALLINPUT ); get_user_thread_info()->last_driver_time = get_driver_check_time(); } @@ -3208,8 +3207,6 @@ static DWORD wait_objects( DWORD count, const HANDLE *handles, DWORD timeout, { assert( count ); /* we must have at least the server queue */
- flush_window_surfaces( TRUE ); - if (!check_queue_masks( wake_mask, changed_mask )) { SERVER_START_REQ( set_queue_mask ) @@ -3340,8 +3337,6 @@ BOOL WINAPI NtUserPeekMessage( MSG *msg_out, HWND hwnd, UINT first, UINT last, U void *ret_ptr; ULONG ret_len;
- flush_window_surfaces( TRUE ); - if (!KeUserDispatchCallback( ¶ms.dispatch, sizeof(params), &ret_ptr, &ret_len ) && ret_len == sizeof(params.locks)) { diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 21e4b3e8f8a..29a3782ed76 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -48,7 +48,6 @@ extern void create_window_surface( HWND hwnd, BOOL create_layered, const RECT *s struct window_surface **window_surface ); extern struct window_surface *get_driver_window_surface( struct window_surface *surface, UINT monitor_dpi ); extern void erase_now( HWND hwnd, UINT rdw_flags ); -extern void flush_window_surfaces( BOOL idle ); extern void move_window_bits( HWND hwnd, const struct window_rects *rects, const RECT *valid_rects ); extern void move_window_bits_surface( HWND hwnd, const RECT *window_rect, struct window_surface *old_surface, const RECT *old_visible_rect, const RECT *valid_rects ); @@ -58,7 +57,6 @@ extern void register_window_surface( struct window_surface *old, extern void process_wine_present( HWND hwnd ); extern void window_surface_lock( struct window_surface *surface ); extern void window_surface_unlock( struct window_surface *surface ); -extern void window_surface_flush( struct window_surface *surface ); extern void window_surface_set_clip( struct window_surface *surface, HRGN clip_region ); extern void window_surface_set_layered( struct window_surface *surface, COLORREF color_key, UINT alpha_bits, UINT alpha_mask );
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 5825dd8b5a2..ccb561e9b77 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2292,7 +2292,6 @@ static BOOL expose_window_surface( HWND hwnd, UINT flags, const RECT *rect, UINT add_bounds_rect( &surface->bounds, &exposed_rect ); } window_surface_unlock( surface ); - if (surface->alpha_mask) window_surface_flush( surface ); window_surface_release( surface ); return TRUE; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 19 ------------------- dlls/win32u/win32u_private.h | 2 -- dlls/win32u/window.c | 13 ++----------- 3 files changed, 2 insertions(+), 32 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 79561b109af..72e48c76e55 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -50,9 +50,6 @@ static struct list dce_list = LIST_INIT(dce_list);
#define DCE_CACHE_SIZE 64
-static struct list window_surfaces = LIST_INIT( window_surfaces ); -static pthread_mutex_t surfaces_lock = PTHREAD_MUTEX_INITIALIZER; - static void window_surface_flush( struct window_surface *surface );
/******************************************************************* @@ -748,22 +745,6 @@ void process_wine_present( HWND hwnd ) window_surface_release( surface ); }
-/******************************************************************* - * register_window_surface - * - * Register a window surface in the global list, possibly replacing another one. - */ -void register_window_surface( struct window_surface *old, struct window_surface *new ) -{ - if (old == &dummy_surface) old = NULL; - if (new == &dummy_surface) new = NULL; - if (old == new) return; - pthread_mutex_lock( &surfaces_lock ); - if (old) list_remove( &old->entry ); - if (new) list_add_tail( &window_surfaces, &new->entry ); - pthread_mutex_unlock( &surfaces_lock ); -} - /*********************************************************************** * dump_rdw_flags */ diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 29a3782ed76..77699b003c4 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -51,8 +51,6 @@ extern void erase_now( HWND hwnd, UINT rdw_flags ); extern void move_window_bits( HWND hwnd, const struct window_rects *rects, const RECT *valid_rects ); extern void move_window_bits_surface( HWND hwnd, const RECT *window_rect, struct window_surface *old_surface, const RECT *old_visible_rect, const RECT *valid_rects ); -extern void register_window_surface( struct window_surface *old, - struct window_surface *new );
extern void process_wine_present( HWND hwnd ); extern void window_surface_lock( struct window_surface *surface ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index ccb561e9b77..c4a1ceb1d37 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2198,7 +2198,6 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru if (ret) { TRACE( "win %p surface %p -> %p\n", hwnd, old_surface, new_surface ); - register_window_surface( old_surface, new_surface ); if (old_surface) { if (valid_rects) @@ -5178,11 +5177,7 @@ LRESULT destroy_window( HWND hwnd )
NtUserDestroyMenu( menu ); NtUserDestroyMenu( sys_menu ); - if (surface) - { - register_window_surface( surface, NULL ); - window_surface_release( surface ); - } + if (surface) window_surface_release( surface );
detach_client_surfaces( hwnd ); if (win->opengl_drawable) opengl_drawable_release( win->opengl_drawable ); @@ -5345,11 +5340,7 @@ void destroy_thread_windows(void)
NtUserDestroyMenu( entry->menu ); NtUserDestroyMenu( entry->sys_menu ); - if (entry->surface) - { - register_window_surface( entry->surface, NULL ); - window_surface_release( entry->surface ); - } + if (entry->surface) window_surface_release( entry->surface ); free( entry ); } }
v2: Fix a use after free when present timeout was set and is set again, release it before clearing or setting it.
Looks like it slows down the tests a lot because it makes us return from MsgWaitForMultipleObjects (in flush_events) much more often...
This is going to be tricky to make efficient, trying something different instead.
This merge request was closed by Rémi Bernon.