-- v3: win32u: Use a helper to flush window surface, factor locking and bounds reset. wineandroid: Hold the lock while reading window surface bits. winemac: Get rid of unnecessary blit_data / drawn surface members. win32u: Move window surface bounds to the window_surface base struct. win32u: Use helpers to lock/unlock window surfaces. win32u: Move the window surface mutex to the surface header. win32u: Introduce a new window_surface_init helper.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 25 +++++++++++++++++++++---- dlls/wineandroid.drv/window.c | 5 ++--- dlls/winemac.drv/surface.c | 4 +--- dlls/winewayland.drv/window_surface.c | 5 ++--- dlls/winex11.drv/bitblt.c | 5 ++--- include/wine/gdi_driver.h | 14 +++----------- 6 files changed, 31 insertions(+), 27 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 491c21f0ff5..f8e9b0bbe6e 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -219,10 +219,7 @@ void create_offscreen_window_surface( const RECT *visible_rect, struct window_su *surface = NULL; size = surface_rect.right * surface_rect.bottom * 4; if (!(impl = calloc(1, offsetof( struct offscreen_window_surface, info.bmiColors[0] ) + size))) return; - - impl->header.funcs = &offscreen_window_surface_funcs; - impl->header.ref = 1; - impl->header.rect = surface_rect; + window_surface_init( &impl->header, &offscreen_window_surface_funcs, &surface_rect );
pthread_mutex_init( &impl->mutex, NULL );
@@ -242,6 +239,26 @@ void create_offscreen_window_surface( const RECT *visible_rect, struct window_su *surface = &impl->header; }
+/* window surface common helpers */ + +W32KAPI void window_surface_init( struct window_surface *surface, const struct window_surface_funcs *funcs, const RECT *rect ) +{ + surface->funcs = funcs; + surface->ref = 1; + surface->rect = *rect; +} + +W32KAPI void window_surface_add_ref( struct window_surface *surface ) +{ + InterlockedIncrement( &surface->ref ); +} + +W32KAPI void window_surface_release( struct window_surface *surface ) +{ + ULONG ret = InterlockedDecrement( &surface->ref ); + if (!ret) surface->funcs->destroy( surface ); +} + /******************************************************************* * register_window_surface * diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 0ba9123c1ba..7397e1758f4 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -905,6 +905,8 @@ static struct window_surface *create_surface( HWND hwnd, const RECT *rect,
surface = calloc( 1, FIELD_OFFSET( struct android_window_surface, info.bmiColors[3] )); if (!surface) return NULL; + window_surface_init( &surface->header, &android_surface_funcs, rect ); + set_color_info( &surface->info, src_alpha ); surface->info.bmiHeader.biWidth = width; surface->info.bmiHeader.biHeight = -height; /* top-down */ @@ -913,9 +915,6 @@ static struct window_surface *create_surface( HWND hwnd, const RECT *rect,
pthread_mutex_init( &surface->mutex, NULL );
- surface->header.funcs = &android_surface_funcs; - surface->header.rect = *rect; - surface->header.ref = 1; surface->hwnd = hwnd; surface->window = get_ioctl_window( hwnd ); surface->alpha = alpha; diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 65da12912c2..5ec83dd9ebb 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -251,6 +251,7 @@ struct window_surface *create_surface(macdrv_window window, const RECT *rect,
surface = calloc(1, FIELD_OFFSET(struct macdrv_window_surface, info.bmiColors[3])); if (!surface) return NULL; + window_surface_init(&surface->header, &macdrv_surface_funcs, rect);
if ((err = pthread_mutex_init(&surface->mutex, NULL))) { @@ -272,9 +273,6 @@ struct window_surface *create_surface(macdrv_window window, const RECT *rect, colors[1] = 0x0000ff00; colors[2] = 0x000000ff;
- surface->header.funcs = &macdrv_surface_funcs; - surface->header.rect = *rect; - surface->header.ref = 1; surface->window = window; reset_bounds(&surface->bounds); if (old_mac_surface && old_mac_surface->drawn) diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index cb5e1539072..37858c825ca 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -512,6 +512,8 @@ struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect
wws = calloc(1, sizeof(*wws)); if (!wws) return NULL; + window_surface_init(&wws->header, &wayland_window_surface_funcs, rect); + wws->info.bmiHeader.biSize = sizeof(wws->info.bmiHeader); wws->info.bmiHeader.biClrUsed = 0; wws->info.bmiHeader.biBitCount = 32; @@ -523,9 +525,6 @@ struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect
pthread_mutex_init(&wws->mutex, NULL);
- wws->header.funcs = &wayland_window_surface_funcs; - wws->header.rect = *rect; - wws->header.ref = 1; wws->hwnd = hwnd; reset_bounds(&wws->bounds);
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 5eccc4a2eb7..a814fdb94b0 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -2021,6 +2021,8 @@ struct window_surface *create_surface( Window window, const XVisualInfo *vis, co
surface = calloc( 1, FIELD_OFFSET( struct x11drv_window_surface, info.bmiColors[colors] )); if (!surface) return NULL; + window_surface_init( &surface->header, &x11drv_surface_funcs, rect ); + surface->info.bmiHeader.biSize = sizeof(surface->info.bmiHeader); surface->info.bmiHeader.biWidth = width; surface->info.bmiHeader.biHeight = -height; /* top-down */ @@ -2031,9 +2033,6 @@ struct window_surface *create_surface( Window window, const XVisualInfo *vis, co
pthread_mutex_init( &surface->mutex, NULL );
- surface->header.funcs = &x11drv_surface_funcs; - surface->header.rect = *rect; - surface->header.ref = 1; surface->window = window; surface->is_argb = (use_alpha && vis->depth == 32 && surface->info.bmiHeader.biCompression == BI_RGB); set_color_key( surface, color_key ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 4639a409dab..e1a7f2bbffc 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -223,17 +223,9 @@ struct window_surface /* driver-specific fields here */ };
-static inline ULONG window_surface_add_ref( struct window_surface *surface ) -{ - return InterlockedIncrement( &surface->ref ); -} - -static inline ULONG window_surface_release( struct window_surface *surface ) -{ - ULONG ret = InterlockedDecrement( &surface->ref ); - if (!ret) surface->funcs->destroy( surface ); - return ret; -} +W32KAPI void window_surface_init( struct window_surface *surface, const struct window_surface_funcs *funcs, const RECT *rect ); +W32KAPI void window_surface_add_ref( struct window_surface *surface ); +W32KAPI void window_surface_release( struct window_surface *surface );
/* display manager interface, used to initialize display device registry data */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 23 +++++++++++------------ dlls/wineandroid.drv/window.c | 14 +++----------- dlls/winemac.drv/surface.c | 21 ++++----------------- dlls/winewayland.drv/window_surface.c | 12 +++--------- dlls/winex11.drv/bitblt.c | 14 +++----------- include/wine/gdi_driver.h | 9 +++++++++ 6 files changed, 33 insertions(+), 60 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index f8e9b0bbe6e..f62cddd2116 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -116,7 +116,7 @@ static const struct window_surface_funcs dummy_surface_funcs = dummy_surface_destroy };
-struct window_surface dummy_surface = { &dummy_surface_funcs, { NULL, NULL }, 1, { 0, 0, 1, 1 } }; +struct window_surface dummy_surface = { &dummy_surface_funcs, { NULL, NULL }, 1, { 0, 0, 1, 1 }, PTHREAD_MUTEX_INITIALIZER };
/******************************************************************* * Off-screen window surface. @@ -125,7 +125,6 @@ struct window_surface dummy_surface = { &dummy_surface_funcs, { NULL, NULL }, 1, struct offscreen_window_surface { struct window_surface header; - pthread_mutex_t mutex; RECT bounds; char *bits; BITMAPINFO info; @@ -139,16 +138,14 @@ static struct offscreen_window_surface *impl_from_window_surface( struct window_ return CONTAINING_RECORD( base, struct offscreen_window_surface, header ); }
-static void offscreen_window_surface_lock( struct window_surface *base ) +static void offscreen_window_surface_lock( struct window_surface *surface ) { - struct offscreen_window_surface *impl = impl_from_window_surface( base ); - pthread_mutex_lock( &impl->mutex ); + pthread_mutex_lock( &surface->mutex ); }
-static void offscreen_window_surface_unlock( struct window_surface *base ) +static void offscreen_window_surface_unlock( struct window_surface *surface ) { - struct offscreen_window_surface *impl = impl_from_window_surface( base ); - pthread_mutex_unlock( &impl->mutex ); + pthread_mutex_unlock( &surface->mutex ); }
static RECT *offscreen_window_surface_get_bounds( struct window_surface *base ) @@ -179,7 +176,6 @@ static void offscreen_window_surface_flush( struct window_surface *base ) static void offscreen_window_surface_destroy( struct window_surface *base ) { struct offscreen_window_surface *impl = impl_from_window_surface( base ); - pthread_mutex_destroy( &impl->mutex ); free( impl ); }
@@ -221,8 +217,6 @@ void create_offscreen_window_surface( const RECT *visible_rect, struct window_su if (!(impl = calloc(1, offsetof( struct offscreen_window_surface, info.bmiColors[0] ) + size))) return; window_surface_init( &impl->header, &offscreen_window_surface_funcs, &surface_rect );
- pthread_mutex_init( &impl->mutex, NULL ); - reset_bounds( &impl->bounds );
impl->bits = (char *)&impl->info.bmiColors[0]; @@ -246,6 +240,7 @@ W32KAPI void window_surface_init( struct window_surface *surface, const struct w surface->funcs = funcs; surface->ref = 1; surface->rect = *rect; + pthread_mutex_init( &surface->mutex, NULL ); }
W32KAPI void window_surface_add_ref( struct window_surface *surface ) @@ -256,7 +251,11 @@ W32KAPI void window_surface_add_ref( struct window_surface *surface ) W32KAPI void window_surface_release( struct window_surface *surface ) { ULONG ret = InterlockedDecrement( &surface->ref ); - if (!ret) surface->funcs->destroy( surface ); + if (!ret) + { + if (surface != &dummy_surface) pthread_mutex_destroy( &surface->mutex ); + surface->funcs->destroy( surface ); + } }
/******************************************************************* diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 7397e1758f4..ac6b211a34c 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -580,7 +580,6 @@ struct android_window_surface BYTE alpha; COLORREF color_key; void *bits; - pthread_mutex_t mutex; BITMAPINFO info; /* variable size, must be last */ };
@@ -651,9 +650,7 @@ static void apply_line_region( DWORD *dst, int width, int x, int y, const RECT * */ static void android_surface_lock( struct window_surface *window_surface ) { - struct android_window_surface *surface = get_android_surface( window_surface ); - - pthread_mutex_lock( &surface->mutex ); + pthread_mutex_lock( &window_surface->mutex ); }
/*********************************************************************** @@ -661,9 +658,7 @@ static void android_surface_lock( struct window_surface *window_surface ) */ static void android_surface_unlock( struct window_surface *window_surface ) { - struct android_window_surface *surface = get_android_surface( window_surface ); - - pthread_mutex_unlock( &surface->mutex ); + pthread_mutex_unlock( &window_surface->mutex ); }
/*********************************************************************** @@ -807,7 +802,6 @@ static void android_surface_destroy( struct window_surface *window_surface ) if (surface->region) NtGdiDeleteObjectApp( surface->region ); release_ioctl_window( surface->window ); free( surface->bits ); - pthread_mutex_destroy( &surface->mutex ); free( surface ); }
@@ -913,8 +907,6 @@ static struct window_surface *create_surface( HWND hwnd, const RECT *rect, surface->info.bmiHeader.biPlanes = 1; surface->info.bmiHeader.biSizeImage = get_dib_image_size( &surface->info );
- pthread_mutex_init( &surface->mutex, NULL ); - surface->hwnd = hwnd; surface->window = get_ioctl_window( hwnd ); surface->alpha = alpha; @@ -931,7 +923,7 @@ static struct window_surface *create_surface( HWND hwnd, const RECT *rect, return &surface->header;
failed: - android_surface_destroy( &surface->header ); + window_surface_release( &surface->header ); return NULL; }
diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 5ec83dd9ebb..d2c156adb5d 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -70,7 +70,6 @@ struct macdrv_window_surface BOOL use_alpha; RGNDATA *blit_data; BYTE *bits; - pthread_mutex_t mutex; BITMAPINFO info; /* variable size, must be last */ };
@@ -102,9 +101,7 @@ static void update_blit_data(struct macdrv_window_surface *surface) */ static void macdrv_surface_lock(struct window_surface *window_surface) { - struct macdrv_window_surface *surface = get_mac_surface(window_surface); - - pthread_mutex_lock(&surface->mutex); + pthread_mutex_lock(&window_surface->mutex); }
/*********************************************************************** @@ -112,9 +109,7 @@ static void macdrv_surface_lock(struct window_surface *window_surface) */ static void macdrv_surface_unlock(struct window_surface *window_surface) { - struct macdrv_window_surface *surface = get_mac_surface(window_surface); - - pthread_mutex_unlock(&surface->mutex); + pthread_mutex_unlock(&window_surface->mutex); }
/*********************************************************************** @@ -215,7 +210,6 @@ static void macdrv_surface_destroy(struct window_surface *window_surface) if (surface->drawn) NtGdiDeleteObjectApp(surface->drawn); free(surface->blit_data); free(surface->bits); - pthread_mutex_destroy(&surface->mutex); free(surface); }
@@ -246,19 +240,12 @@ struct window_surface *create_surface(macdrv_window window, const RECT *rect, struct macdrv_window_surface *old_mac_surface = get_mac_surface(old_surface); int width = rect->right - rect->left, height = rect->bottom - rect->top; DWORD *colors; - int err; DWORD window_background;
surface = calloc(1, FIELD_OFFSET(struct macdrv_window_surface, info.bmiColors[3])); if (!surface) return NULL; window_surface_init(&surface->header, &macdrv_surface_funcs, rect);
- if ((err = pthread_mutex_init(&surface->mutex, NULL))) - { - free(surface); - return NULL; - } - surface->info.bmiHeader.biSize = sizeof(surface->info.bmiHeader); surface->info.bmiHeader.biWidth = width; surface->info.bmiHeader.biHeight = -height; /* top-down */ @@ -298,7 +285,7 @@ struct window_surface *create_surface(macdrv_window window, const RECT *rect, return &surface->header;
failed: - macdrv_surface_destroy(&surface->header); + window_surface_release(&surface->header); return NULL; }
@@ -317,7 +304,7 @@ void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha void set_window_surface(macdrv_window window, struct window_surface *window_surface) { struct macdrv_window_surface *surface = get_mac_surface(window_surface); - macdrv_set_window_surface(window, window_surface, surface ? &surface->mutex : NULL); + macdrv_set_window_surface(window, window_surface, surface ? &window_surface->mutex : NULL); }
/*********************************************************************** diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 37858c825ca..47ccb8c0213 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -48,7 +48,6 @@ struct wayland_window_surface struct wayland_buffer_queue *wayland_buffer_queue; RECT bounds; void *bits; - pthread_mutex_t mutex; BITMAPINFO info; };
@@ -224,8 +223,7 @@ static void wayland_buffer_queue_add_damage(struct wayland_buffer_queue *queue, */ static void wayland_window_surface_lock(struct window_surface *window_surface) { - struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface); - pthread_mutex_lock(&wws->mutex); + pthread_mutex_lock(&window_surface->mutex); }
/*********************************************************************** @@ -233,8 +231,7 @@ static void wayland_window_surface_lock(struct window_surface *window_surface) */ static void wayland_window_surface_unlock(struct window_surface *window_surface) { - struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface); - pthread_mutex_unlock(&wws->mutex); + pthread_mutex_unlock(&window_surface->mutex); }
/*********************************************************************** @@ -481,7 +478,6 @@ static void wayland_window_surface_destroy(struct window_surface *window_surface
TRACE("surface=%p\n", wws);
- pthread_mutex_destroy(&wws->mutex); if (wws->wayland_buffer_queue) wayland_buffer_queue_destroy(wws->wayland_buffer_queue); free(wws->bits); @@ -523,8 +519,6 @@ struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect wws->info.bmiHeader.biPlanes = 1; wws->info.bmiHeader.biSizeImage = width * height * 4;
- pthread_mutex_init(&wws->mutex, NULL); - wws->hwnd = hwnd; reset_bounds(&wws->bounds);
@@ -537,7 +531,7 @@ struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect return &wws->header;
failed: - wayland_window_surface_destroy(&wws->header); + window_surface_release(&wws->header); return NULL; }
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index a814fdb94b0..bb4b11be866 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1587,7 +1587,6 @@ struct x11drv_window_surface #ifdef HAVE_LIBXXSHM XShmSegmentInfo shminfo; #endif - pthread_mutex_t mutex; BITMAPINFO info; /* variable size, must be last */ };
@@ -1833,9 +1832,7 @@ failed: */ static void x11drv_surface_lock( struct window_surface *window_surface ) { - struct x11drv_window_surface *surface = get_x11_surface( window_surface ); - - pthread_mutex_lock( &surface->mutex ); + pthread_mutex_lock( &window_surface->mutex ); }
/*********************************************************************** @@ -1843,9 +1840,7 @@ static void x11drv_surface_lock( struct window_surface *window_surface ) */ static void x11drv_surface_unlock( struct window_surface *window_surface ) { - struct x11drv_window_surface *surface = get_x11_surface( window_surface ); - - pthread_mutex_unlock( &surface->mutex ); + pthread_mutex_unlock( &window_surface->mutex ); }
/*********************************************************************** @@ -1993,7 +1988,6 @@ static void x11drv_surface_destroy( struct window_surface *window_surface ) } if (surface->region) NtGdiDeleteObjectApp( surface->region );
- pthread_mutex_destroy( &surface->mutex ); free( surface ); }
@@ -2031,8 +2025,6 @@ struct window_surface *create_surface( Window window, const XVisualInfo *vis, co surface->info.bmiHeader.biSizeImage = get_dib_image_size( &surface->info ); if (format->bits_per_pixel > 8) set_color_info( vis, &surface->info, use_alpha );
- pthread_mutex_init( &surface->mutex, NULL ); - surface->window = window; surface->is_argb = (use_alpha && vis->depth == 32 && surface->info.bmiHeader.biCompression == BI_RGB); set_color_key( surface, color_key ); @@ -2072,7 +2064,7 @@ struct window_surface *create_surface( Window window, const XVisualInfo *vis, co return &surface->header;
failed: - x11drv_surface_destroy( &surface->header ); + window_surface_release( &surface->header ); return NULL; }
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index e1a7f2bbffc..53555db972b 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -25,6 +25,13 @@ #error The GDI driver can only be used on the Unix side #endif
+#include <stdarg.h> +#include <stddef.h> + +#include <pthread.h> + +#include "windef.h" +#include "winbase.h" #include "winternl.h" #include "ntuser.h" #include "immdev.h" @@ -219,6 +226,8 @@ struct window_surface struct list entry; /* entry in global list managed by user32 */ LONG ref; /* reference count */ RECT rect; /* constant, no locking needed */ + + pthread_mutex_t mutex; DWORD draw_start_ticks; /* start ticks of fresh draw */ /* driver-specific fields here */ };
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 44 ++++++++++----------------- dlls/win32u/dibdrv/dc.c | 4 +-- dlls/wineandroid.drv/window.c | 42 ++++++++----------------- dlls/winemac.drv/surface.c | 30 ++++-------------- dlls/winemac.drv/window.c | 12 ++++---- dlls/winewayland.drv/window_surface.c | 26 +++------------- dlls/winex11.drv/bitblt.c | 34 +++++---------------- dlls/winex11.drv/window.c | 4 +-- include/wine/gdi_driver.h | 4 +-- 9 files changed, 58 insertions(+), 142 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index f62cddd2116..2fa149d8d90 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -56,16 +56,6 @@ static pthread_mutex_t surfaces_lock = PTHREAD_MUTEX_INITIALIZER; * Dummy window surface for windows that shouldn't get painted. */
-static void dummy_surface_lock( struct window_surface *window_surface ) -{ - /* nothing to do */ -} - -static void dummy_surface_unlock( struct window_surface *window_surface ) -{ - /* nothing to do */ -} - static void *dummy_surface_get_bitmap_info( struct window_surface *window_surface, BITMAPINFO *info ) { static DWORD dummy_data; @@ -107,8 +97,6 @@ static void dummy_surface_destroy( struct window_surface *window_surface )
static const struct window_surface_funcs dummy_surface_funcs = { - dummy_surface_lock, - dummy_surface_unlock, dummy_surface_get_bitmap_info, dummy_surface_get_bounds, dummy_surface_set_region, @@ -138,16 +126,6 @@ static struct offscreen_window_surface *impl_from_window_surface( struct window_ return CONTAINING_RECORD( base, struct offscreen_window_surface, header ); }
-static void offscreen_window_surface_lock( struct window_surface *surface ) -{ - pthread_mutex_lock( &surface->mutex ); -} - -static void offscreen_window_surface_unlock( struct window_surface *surface ) -{ - pthread_mutex_unlock( &surface->mutex ); -} - static RECT *offscreen_window_surface_get_bounds( struct window_surface *base ) { struct offscreen_window_surface *impl = impl_from_window_surface( base ); @@ -168,9 +146,9 @@ static void offscreen_window_surface_set_region( struct window_surface *base, HR static void offscreen_window_surface_flush( struct window_surface *base ) { struct offscreen_window_surface *impl = impl_from_window_surface( base ); - base->funcs->lock( base ); + window_surface_lock( base ); reset_bounds( &impl->bounds ); - base->funcs->unlock( base ); + window_surface_unlock( base ); }
static void offscreen_window_surface_destroy( struct window_surface *base ) @@ -181,8 +159,6 @@ static void offscreen_window_surface_destroy( struct window_surface *base )
static const struct window_surface_funcs offscreen_window_surface_funcs = { - offscreen_window_surface_lock, - offscreen_window_surface_unlock, offscreen_window_surface_get_bitmap_info, offscreen_window_surface_get_bounds, offscreen_window_surface_set_region, @@ -258,6 +234,18 @@ W32KAPI void window_surface_release( struct window_surface *surface ) } }
+W32KAPI 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 ) +{ + if (surface == &dummy_surface) return; + pthread_mutex_unlock( &surface->mutex ); +} + /******************************************************************* * register_window_surface * @@ -1171,12 +1159,12 @@ static void copy_bits_from_surface( HWND hwnd, struct window_surface *surface, else { bits = surface->funcs->get_info( surface, info ); - surface->funcs->lock( surface ); + window_surface_lock( surface ); NtGdiSetDIBitsToDeviceInternal( hdc, dst->left, dst->top, dst->right - dst->left, dst->bottom - dst->top, src->left - surface->rect.left, surface->rect.bottom - src->bottom, 0, surface->rect.bottom - surface->rect.top, bits, info, DIB_RGB_COLORS, 0, 0, FALSE, NULL ); - surface->funcs->unlock( surface ); + window_surface_unlock( surface ); }
NtUserReleaseDC( hwnd, hdc ); diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c index 48cbe51d708..f1e5f2c9d6b 100644 --- a/dlls/win32u/dibdrv/dc.c +++ b/dlls/win32u/dibdrv/dc.c @@ -751,7 +751,7 @@ static inline void lock_surface( struct windrv_physdev *dev )
if (!dev->lock_count++) { - surface->funcs->lock( surface ); + window_surface_lock( surface ); if (IsRectEmpty( dev->dibdrv->bounds ) || !surface->draw_start_ticks) surface->draw_start_ticks = NtGetTickCount(); } @@ -764,7 +764,7 @@ static inline void unlock_surface( struct windrv_physdev *dev ) if (!--dev->lock_count) { DWORD ticks = NtGetTickCount() - surface->draw_start_ticks; - surface->funcs->unlock( surface ); + window_surface_unlock( surface ); if (ticks > FLUSH_PERIOD) surface->funcs->flush( dev->surface ); } } diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index ac6b211a34c..669ad7a6b2e 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -645,22 +645,6 @@ static void apply_line_region( DWORD *dst, int width, int x, int y, const RECT * if (width > 0) memset( dst, 0, width * sizeof(*dst) ); }
-/*********************************************************************** - * android_surface_lock - */ -static void android_surface_lock( struct window_surface *window_surface ) -{ - pthread_mutex_lock( &window_surface->mutex ); -} - -/*********************************************************************** - * android_surface_unlock - */ -static void android_surface_unlock( struct window_surface *window_surface ) -{ - pthread_mutex_unlock( &window_surface->mutex ); -} - /*********************************************************************** * android_surface_get_bitmap_info */ @@ -691,7 +675,7 @@ static void android_surface_set_region( struct window_surface *window_surface, H
TRACE( "updating surface %p hwnd %p with %p\n", surface, surface->hwnd, region );
- window_surface->funcs->lock( window_surface ); + window_surface_lock( window_surface ); if (!region) { if (surface->region) NtGdiDeleteObjectApp( surface->region ); @@ -702,7 +686,7 @@ static void android_surface_set_region( struct window_surface *window_surface, H if (!surface->region) surface->region = NtGdiCreateRectRgn( 0, 0, 0, 0 ); NtGdiCombineRgn( surface->region, region, 0, RGN_COPY ); } - window_surface->funcs->unlock( window_surface ); + window_surface_unlock( window_surface ); set_surface_region( &surface->header, (HRGN)1 ); }
@@ -717,12 +701,12 @@ static void android_surface_flush( struct window_surface *window_surface ) RECT rect; BOOL needs_flush;
- window_surface->funcs->lock( window_surface ); + window_surface_lock( window_surface ); SetRect( &rect, 0, 0, surface->header.rect.right - surface->header.rect.left, surface->header.rect.bottom - surface->header.rect.top ); needs_flush = intersect_rect( &rect, &rect, &surface->bounds ); reset_bounds( &surface->bounds ); - window_surface->funcs->unlock( window_surface ); + window_surface_unlock( window_surface ); if (!needs_flush) return;
TRACE( "flushing %p hwnd %p surface %s rect %s bits %p alpha %02x key %08x region %u rects\n", @@ -807,8 +791,6 @@ static void android_surface_destroy( struct window_surface *window_surface )
static const struct window_surface_funcs android_surface_funcs = { - android_surface_lock, - android_surface_unlock, android_surface_get_bitmap_info, android_surface_get_bounds, android_surface_set_region, @@ -880,11 +862,11 @@ static void set_surface_region( struct window_surface *window_surface, HRGN win_ }
done: - window_surface->funcs->lock( window_surface ); + window_surface_lock( window_surface ); free( surface->region_data ); surface->region_data = data; *window_surface->funcs->get_bounds( window_surface ) = surface->header.rect; - window_surface->funcs->unlock( window_surface ); + window_surface_unlock( window_surface ); if (region != win_region) NtGdiDeleteObjectApp( region ); }
@@ -938,14 +920,14 @@ static void set_surface_layered( struct window_surface *window_surface, BYTE alp
if (window_surface->funcs != &android_surface_funcs) return; /* we may get the null surface */
- window_surface->funcs->lock( window_surface ); + window_surface_lock( window_surface ); prev_key = surface->color_key; prev_alpha = surface->alpha; surface->alpha = alpha; set_color_key( surface, color_key ); if (alpha != prev_alpha || surface->color_key != prev_key) /* refresh */ *window_surface->funcs->get_bounds( window_surface ) = surface->header.rect; - window_surface->funcs->unlock( window_surface ); + window_surface_unlock( window_surface ); }
/*********************************************************************** @@ -1577,7 +1559,7 @@ BOOL ANDROID_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info
NtGdiSelectBitmap( hdc, dib );
- surface->funcs->lock( surface ); + window_surface_lock( surface );
if (info->prcDirty) { @@ -1600,7 +1582,7 @@ BOOL ANDROID_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info add_bounds_rect( surface->funcs->get_bounds( surface ), &rect ); }
- surface->funcs->unlock( surface ); + window_surface_unlock( surface ); surface->funcs->flush( surface );
done: @@ -1630,9 +1612,9 @@ LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) struct window_surface *surface = data->surface; if (surface) { - surface->funcs->lock( surface ); + window_surface_lock( surface ); *surface->funcs->get_bounds( surface ) = surface->rect; - surface->funcs->unlock( surface ); + window_surface_unlock( surface ); if (is_argb_surface( surface )) surface->funcs->flush( surface ); } release_win_data( data ); diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index d2c156adb5d..82cf7f57eb7 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -96,22 +96,6 @@ static void update_blit_data(struct macdrv_window_surface *surface) } }
-/*********************************************************************** - * macdrv_surface_lock - */ -static void macdrv_surface_lock(struct window_surface *window_surface) -{ - pthread_mutex_lock(&window_surface->mutex); -} - -/*********************************************************************** - * macdrv_surface_unlock - */ -static void macdrv_surface_unlock(struct window_surface *window_surface) -{ - pthread_mutex_unlock(&window_surface->mutex); -} - /*********************************************************************** * macdrv_surface_get_bitmap_info */ @@ -143,7 +127,7 @@ static void macdrv_surface_set_region(struct window_surface *window_surface, HRG
TRACE("updating surface %p with %p\n", surface, region);
- window_surface->funcs->lock(window_surface); + window_surface_lock(window_surface);
if (region) { @@ -157,7 +141,7 @@ static void macdrv_surface_set_region(struct window_surface *window_surface, HRG } update_blit_data(surface);
- window_surface->funcs->unlock(window_surface); + window_surface_unlock(window_surface); }
/*********************************************************************** @@ -169,7 +153,7 @@ static void macdrv_surface_flush(struct window_surface *window_surface) CGRect rect; HRGN region;
- window_surface->funcs->lock(window_surface); + window_surface_lock(window_surface);
TRACE("flushing %p %s bounds %s bits %p\n", surface, wine_dbgstr_rect(&surface->header.rect), wine_dbgstr_rect(&surface->bounds), surface->bits); @@ -192,7 +176,7 @@ static void macdrv_surface_flush(struct window_surface *window_surface) update_blit_data(surface); reset_bounds(&surface->bounds);
- window_surface->funcs->unlock(window_surface); + window_surface_unlock(window_surface);
if (!CGRectIsEmpty(rect)) macdrv_window_needs_display(surface->window, rect); @@ -215,8 +199,6 @@ static void macdrv_surface_destroy(struct window_surface *window_surface)
static const struct window_surface_funcs macdrv_surface_funcs = { - macdrv_surface_lock, - macdrv_surface_unlock, macdrv_surface_get_bitmap_info, macdrv_surface_get_bounds, macdrv_surface_set_region, @@ -427,7 +409,7 @@ void surface_clip_to_visible_rect(struct window_surface *window_surface, const R struct macdrv_window_surface *surface = get_mac_surface(window_surface);
if (!surface) return; - window_surface->funcs->lock(window_surface); + window_surface_lock(window_surface);
if (surface->drawn) { @@ -446,5 +428,5 @@ void surface_clip_to_visible_rect(struct window_surface *window_surface, const R } }
- window_surface->funcs->unlock(window_surface); + window_surface_unlock(window_surface); } diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index a04ff5fd4c9..d04ebe39bfa 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -509,10 +509,10 @@ static void sync_window_opacity(struct macdrv_win_data *data, COLORREF key, BYTE
rect = data->whole_rect; OffsetRect(&rect, -data->whole_rect.left, -data->whole_rect.top); - data->surface->funcs->lock(data->surface); + window_surface_lock(data->surface); bounds = data->surface->funcs->get_bounds(data->surface); add_bounds_rect(bounds, &rect); - data->surface->funcs->unlock(data->surface); + window_surface_unlock(data->surface); } }
@@ -1964,9 +1964,9 @@ BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, if (info->prcDirty) { intersect_rect(&rect, &rect, info->prcDirty); - surface->funcs->lock(surface); + window_surface_lock(surface); memcpy(src_bits, dst_bits, bmi->bmiHeader.biSizeImage); - surface->funcs->unlock(surface); + window_surface_unlock(surface); NtGdiPatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, BLACKNESS); } src_rect = rect; @@ -1983,10 +1983,10 @@ BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, { if (surface == data->surface) { - surface->funcs->lock(surface); + window_surface_lock(surface); memcpy(dst_bits, src_bits, bmi->bmiHeader.biSizeImage); add_bounds_rect(surface->funcs->get_bounds(surface), &rect); - surface->funcs->unlock(surface); + window_surface_unlock(surface); surface->funcs->flush(surface); }
diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 47ccb8c0213..4c8d3956408 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -218,22 +218,6 @@ static void wayland_buffer_queue_add_damage(struct wayland_buffer_queue *queue, } }
-/*********************************************************************** - * wayland_window_surface_lock - */ -static void wayland_window_surface_lock(struct window_surface *window_surface) -{ - pthread_mutex_lock(&window_surface->mutex); -} - -/*********************************************************************** - * wayland_window_surface_unlock - */ -static void wayland_window_surface_unlock(struct window_surface *window_surface) -{ - pthread_mutex_unlock(&window_surface->mutex); -} - /*********************************************************************** * wayland_window_surface_get_bitmap_info */ @@ -376,7 +360,7 @@ static void wayland_window_surface_flush(struct window_surface *window_surface) HRGN surface_damage_region = NULL; HRGN copy_from_window_region;
- wayland_window_surface_lock(window_surface); + window_surface_lock(window_surface);
if (!intersect_rect(&damage_rect, &wws->header.rect, &wws->bounds)) goto done;
@@ -466,7 +450,7 @@ static void wayland_window_surface_flush(struct window_surface *window_surface) done: if (flushed) reset_bounds(&wws->bounds); if (surface_damage_region) NtGdiDeleteObjectApp(surface_damage_region); - wayland_window_surface_unlock(window_surface); + window_surface_unlock(window_surface); }
/*********************************************************************** @@ -486,8 +470,6 @@ static void wayland_window_surface_destroy(struct window_surface *window_surface
static const struct window_surface_funcs wayland_window_surface_funcs = { - wayland_window_surface_lock, - wayland_window_surface_unlock, wayland_window_surface_get_bitmap_info, wayland_window_surface_get_bounds, wayland_window_surface_set_region, @@ -543,7 +525,7 @@ void wayland_window_surface_update_wayland_surface(struct window_surface *window { struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface);
- wayland_window_surface_lock(window_surface); + window_surface_lock(window_surface);
TRACE("surface=%p hwnd=%p wayland_surface=%p\n", wws, wws->hwnd, wayland_surface);
@@ -562,5 +544,5 @@ void wayland_window_surface_update_wayland_surface(struct window_surface *window wws->wayland_buffer_queue = NULL; }
- wayland_window_surface_unlock(window_surface); + window_surface_unlock(window_surface); } diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index bb4b11be866..c19836c31a3 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1827,22 +1827,6 @@ failed: } #endif /* HAVE_LIBXXSHM */
-/*********************************************************************** - * x11drv_surface_lock - */ -static void x11drv_surface_lock( struct window_surface *window_surface ) -{ - pthread_mutex_lock( &window_surface->mutex ); -} - -/*********************************************************************** - * x11drv_surface_unlock - */ -static void x11drv_surface_unlock( struct window_surface *window_surface ) -{ - pthread_mutex_unlock( &window_surface->mutex ); -} - /*********************************************************************** * x11drv_surface_get_bitmap_info */ @@ -1874,7 +1858,7 @@ static void x11drv_surface_set_region( struct window_surface *window_surface, HR
TRACE( "updating surface %p with %p\n", surface, region );
- window_surface->funcs->lock( window_surface ); + window_surface_lock( window_surface ); if (!region) { if (surface->region) NtGdiDeleteObjectApp( surface->region ); @@ -1892,7 +1876,7 @@ static void x11drv_surface_set_region( struct window_surface *window_surface, HR free( data ); } } - window_surface->funcs->unlock( window_surface ); + window_surface_unlock( window_surface ); }
/*********************************************************************** @@ -1905,7 +1889,7 @@ static void x11drv_surface_flush( struct window_surface *window_surface ) unsigned char *dst = (unsigned char *)surface->image->data; struct bitblt_coords coords;
- window_surface->funcs->lock( window_surface ); + window_surface_lock( window_surface ); coords.x = 0; coords.y = 0; coords.width = surface->header.rect.right - surface->header.rect.left; @@ -1959,7 +1943,7 @@ static void x11drv_surface_flush( struct window_surface *window_surface ) XFlush( gdi_display ); } reset_bounds( &surface->bounds ); - window_surface->funcs->unlock( window_surface ); + window_surface_unlock( window_surface ); }
/*********************************************************************** @@ -1993,8 +1977,6 @@ static void x11drv_surface_destroy( struct window_surface *window_surface )
static const struct window_surface_funcs x11drv_surface_funcs = { - x11drv_surface_lock, - x11drv_surface_unlock, x11drv_surface_get_bitmap_info, x11drv_surface_get_bounds, x11drv_surface_set_region, @@ -2078,11 +2060,11 @@ void set_surface_color_key( struct window_surface *window_surface, COLORREF colo
if (window_surface->funcs != &x11drv_surface_funcs) return; /* we may get the null surface */
- window_surface->funcs->lock( window_surface ); + window_surface_lock( window_surface ); prev = surface->color_key; set_color_key( surface, color_key ); if (surface->color_key != prev) update_surface_region( surface ); - window_surface->funcs->unlock( window_surface ); + window_surface_unlock( window_surface ); }
/*********************************************************************** @@ -2096,7 +2078,7 @@ HRGN expose_surface( struct window_surface *window_surface, const RECT *rect )
if (window_surface->funcs != &x11drv_surface_funcs) return 0; /* we may get the null surface */
- window_surface->funcs->lock( window_surface ); + window_surface_lock( window_surface ); OffsetRect( &rc, -window_surface->rect.left, -window_surface->rect.top ); add_bounds_rect( &surface->bounds, &rc ); if (surface->region) @@ -2108,6 +2090,6 @@ HRGN expose_surface( struct window_surface *window_surface, const RECT *rect ) region = 0; } } - window_surface->funcs->unlock( window_surface ); + window_surface_unlock( window_surface ); return region; } diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index c6bf49c6ec8..eb9c5d4d8a8 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -3026,7 +3026,7 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info,
NtGdiSelectBitmap( hdc, dib );
- surface->funcs->lock( surface ); + window_surface_lock( surface );
if (info->prcDirty) { @@ -3049,7 +3049,7 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, add_bounds_rect( surface->funcs->get_bounds( surface ), &rect ); }
- surface->funcs->unlock( surface ); + window_surface_unlock( surface ); surface->funcs->flush( surface );
done: diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 53555db972b..0104cdbe8ba 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -211,8 +211,6 @@ struct window_surface;
struct window_surface_funcs { - void (*lock)( struct window_surface *surface ); - void (*unlock)( struct window_surface *surface ); void* (*get_info)( struct window_surface *surface, BITMAPINFO *info ); RECT* (*get_bounds)( struct window_surface *surface ); void (*set_region)( struct window_surface *surface, HRGN region ); @@ -235,6 +233,8 @@ struct window_surface W32KAPI void window_surface_init( struct window_surface *surface, const struct window_surface_funcs *funcs, const RECT *rect ); 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 );
/* display manager interface, used to initialize display device registry data */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 27 +++++---------------------- dlls/win32u/dibdrv/dc.c | 2 +- dlls/wineandroid.drv/window.c | 25 ++++++------------------- dlls/winemac.drv/surface.c | 25 ++++++------------------- dlls/winemac.drv/window.c | 6 ++---- dlls/winewayland.drv/window_surface.c | 18 +++--------------- dlls/winex11.drv/bitblt.c | 24 +++++------------------- dlls/winex11.drv/window.c | 2 +- include/wine/gdi_driver.h | 2 +- 9 files changed, 30 insertions(+), 101 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 2fa149d8d90..a97a21d072c 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -74,12 +74,6 @@ static void *dummy_surface_get_bitmap_info( struct window_surface *window_surfac return &dummy_data; }
-static RECT *dummy_surface_get_bounds( struct window_surface *window_surface ) -{ - static RECT dummy_bounds; - return &dummy_bounds; -} - static void dummy_surface_set_region( struct window_surface *window_surface, HRGN region ) { /* nothing to do */ @@ -98,7 +92,6 @@ static void dummy_surface_destroy( struct window_surface *window_surface ) static const struct window_surface_funcs dummy_surface_funcs = { dummy_surface_get_bitmap_info, - dummy_surface_get_bounds, dummy_surface_set_region, dummy_surface_flush, dummy_surface_destroy @@ -113,7 +106,6 @@ struct window_surface dummy_surface = { &dummy_surface_funcs, { NULL, NULL }, 1, struct offscreen_window_surface { struct window_surface header; - RECT bounds; char *bits; BITMAPINFO info; }; @@ -126,12 +118,6 @@ static struct offscreen_window_surface *impl_from_window_surface( struct window_ return CONTAINING_RECORD( base, struct offscreen_window_surface, header ); }
-static RECT *offscreen_window_surface_get_bounds( struct window_surface *base ) -{ - struct offscreen_window_surface *impl = impl_from_window_surface( base ); - return &impl->bounds; -} - static void *offscreen_window_surface_get_bitmap_info( struct window_surface *base, BITMAPINFO *info ) { struct offscreen_window_surface *impl = impl_from_window_surface( base ); @@ -143,12 +129,11 @@ static void offscreen_window_surface_set_region( struct window_surface *base, HR { }
-static void offscreen_window_surface_flush( struct window_surface *base ) +static void offscreen_window_surface_flush( struct window_surface *surface ) { - struct offscreen_window_surface *impl = impl_from_window_surface( base ); - window_surface_lock( base ); - reset_bounds( &impl->bounds ); - window_surface_unlock( base ); + window_surface_lock( surface ); + reset_bounds( &surface->bounds ); + window_surface_unlock( surface ); }
static void offscreen_window_surface_destroy( struct window_surface *base ) @@ -160,7 +145,6 @@ static void offscreen_window_surface_destroy( struct window_surface *base ) static const struct window_surface_funcs offscreen_window_surface_funcs = { offscreen_window_surface_get_bitmap_info, - offscreen_window_surface_get_bounds, offscreen_window_surface_set_region, offscreen_window_surface_flush, offscreen_window_surface_destroy @@ -193,8 +177,6 @@ void create_offscreen_window_surface( const RECT *visible_rect, struct window_su if (!(impl = calloc(1, offsetof( struct offscreen_window_surface, info.bmiColors[0] ) + size))) return; window_surface_init( &impl->header, &offscreen_window_surface_funcs, &surface_rect );
- reset_bounds( &impl->bounds ); - impl->bits = (char *)&impl->info.bmiColors[0]; impl->info.bmiHeader.biSize = sizeof( impl->info ); impl->info.bmiHeader.biWidth = surface_rect.right; @@ -217,6 +199,7 @@ W32KAPI void window_surface_init( struct window_surface *surface, const struct w surface->ref = 1; surface->rect = *rect; pthread_mutex_init( &surface->mutex, NULL ); + reset_bounds( &surface->bounds ); }
W32KAPI void window_surface_add_ref( struct window_surface *surface ) diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c index f1e5f2c9d6b..6050923b9c4 100644 --- a/dlls/win32u/dibdrv/dc.c +++ b/dlls/win32u/dibdrv/dc.c @@ -806,7 +806,7 @@ void dibdrv_set_window_surface( DC *dc, struct window_surface *surface ) init_dib_info_from_bitmapinfo( &dibdrv->dib, info, bits ); dibdrv->dib.rect = dc->attr->vis_rect; OffsetRect( &dibdrv->dib.rect, -dc->device_rect.left, -dc->device_rect.top ); - dibdrv->bounds = surface->funcs->get_bounds( surface ); + dibdrv->bounds = &surface->bounds; DC_InitDC( dc ); } else if (windev) diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 669ad7a6b2e..8314876f1c4 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -573,7 +573,6 @@ struct android_window_surface struct window_surface header; HWND hwnd; ANativeWindow *window; - RECT bounds; BOOL byteswap; RGNDATA *region_data; HRGN region; @@ -656,16 +655,6 @@ static void *android_surface_get_bitmap_info( struct window_surface *window_surf return surface->bits; }
-/*********************************************************************** - * android_surface_get_bounds - */ -static RECT *android_surface_get_bounds( struct window_surface *window_surface ) -{ - struct android_window_surface *surface = get_android_surface( window_surface ); - - return &surface->bounds; -} - /*********************************************************************** * android_surface_set_region */ @@ -704,8 +693,8 @@ static void android_surface_flush( struct window_surface *window_surface ) window_surface_lock( window_surface ); SetRect( &rect, 0, 0, surface->header.rect.right - surface->header.rect.left, surface->header.rect.bottom - surface->header.rect.top ); - needs_flush = intersect_rect( &rect, &rect, &surface->bounds ); - reset_bounds( &surface->bounds ); + needs_flush = intersect_rect( &rect, &rect, &window_surface->bounds ); + reset_bounds( &window_surface->bounds ); window_surface_unlock( window_surface ); if (!needs_flush) return;
@@ -792,7 +781,6 @@ static void android_surface_destroy( struct window_surface *window_surface ) static const struct window_surface_funcs android_surface_funcs = { android_surface_get_bitmap_info, - android_surface_get_bounds, android_surface_set_region, android_surface_flush, android_surface_destroy @@ -865,7 +853,7 @@ done: window_surface_lock( window_surface ); free( surface->region_data ); surface->region_data = data; - *window_surface->funcs->get_bounds( window_surface ) = surface->header.rect; + window_surface->bounds = surface->header.rect; window_surface_unlock( window_surface ); if (region != win_region) NtGdiDeleteObjectApp( region ); } @@ -894,7 +882,6 @@ static struct window_surface *create_surface( HWND hwnd, const RECT *rect, surface->alpha = alpha; set_color_key( surface, color_key ); set_surface_region( &surface->header, (HRGN)1 ); - reset_bounds( &surface->bounds );
if (!(surface->bits = malloc( surface->info.bmiHeader.biSizeImage ))) goto failed; @@ -926,7 +913,7 @@ static void set_surface_layered( struct window_surface *window_surface, BYTE alp surface->alpha = alpha; set_color_key( surface, color_key ); if (alpha != prev_alpha || surface->color_key != prev_key) /* refresh */ - *window_surface->funcs->get_bounds( window_surface ) = surface->header.rect; + window_surface->bounds = surface->header.rect; window_surface_unlock( window_surface ); }
@@ -1579,7 +1566,7 @@ BOOL ANDROID_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info if (ret) { memcpy( dst_bits, src_bits, bmi->bmiHeader.biSizeImage ); - add_bounds_rect( surface->funcs->get_bounds( surface ), &rect ); + add_bounds_rect( &surface->bounds, &rect ); }
window_surface_unlock( surface ); @@ -1613,7 +1600,7 @@ LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) if (surface) { window_surface_lock( surface ); - *surface->funcs->get_bounds( surface ) = surface->rect; + surface->bounds = surface->rect; window_surface_unlock( surface ); if (is_argb_surface( surface )) surface->funcs->flush( surface ); } diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 82cf7f57eb7..314e9e68542 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -64,7 +64,6 @@ struct macdrv_window_surface { struct window_surface header; macdrv_window window; - RECT bounds; HRGN region; HRGN drawn; BOOL use_alpha; @@ -108,16 +107,6 @@ static void *macdrv_surface_get_bitmap_info(struct window_surface *window_surfac return surface->bits; }
-/*********************************************************************** - * macdrv_surface_get_bounds - */ -static RECT *macdrv_surface_get_bounds(struct window_surface *window_surface) -{ - struct macdrv_window_surface *surface = get_mac_surface(window_surface); - - return &surface->bounds; -} - /*********************************************************************** * macdrv_surface_set_region */ @@ -156,14 +145,14 @@ static void macdrv_surface_flush(struct window_surface *window_surface) window_surface_lock(window_surface);
TRACE("flushing %p %s bounds %s bits %p\n", surface, wine_dbgstr_rect(&surface->header.rect), - wine_dbgstr_rect(&surface->bounds), surface->bits); + wine_dbgstr_rect(&window_surface->bounds), surface->bits);
- rect = cgrect_from_rect(surface->bounds); + rect = cgrect_from_rect(window_surface->bounds); rect = CGRectOffset(rect, surface->header.rect.left, surface->header.rect.top);
- if (!IsRectEmpty(&surface->bounds) && - (region = NtGdiCreateRectRgn(surface->bounds.left, surface->bounds.top, - surface->bounds.right, surface->bounds.bottom))) + if (!IsRectEmpty(&window_surface->bounds) && + (region = NtGdiCreateRectRgn(window_surface->bounds.left, window_surface->bounds.top, + window_surface->bounds.right, window_surface->bounds.bottom))) { if (surface->drawn) { @@ -174,7 +163,7 @@ static void macdrv_surface_flush(struct window_surface *window_surface) surface->drawn = region; } update_blit_data(surface); - reset_bounds(&surface->bounds); + reset_bounds(&window_surface->bounds);
window_surface_unlock(window_surface);
@@ -200,7 +189,6 @@ static void macdrv_surface_destroy(struct window_surface *window_surface) static const struct window_surface_funcs macdrv_surface_funcs = { macdrv_surface_get_bitmap_info, - macdrv_surface_get_bounds, macdrv_surface_set_region, macdrv_surface_flush, macdrv_surface_destroy, @@ -243,7 +231,6 @@ struct window_surface *create_surface(macdrv_window window, const RECT *rect, colors[2] = 0x000000ff;
surface->window = window; - reset_bounds(&surface->bounds); if (old_mac_surface && old_mac_surface->drawn) { surface->drawn = NtGdiCreateRectRgn(rect->left, rect->top, rect->right, rect->bottom); diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index d04ebe39bfa..05ba3e994d7 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -504,14 +504,12 @@ static void sync_window_opacity(struct macdrv_win_data *data, COLORREF key, BYTE
if (needs_flush && data->surface) { - RECT *bounds; RECT rect;
rect = data->whole_rect; OffsetRect(&rect, -data->whole_rect.left, -data->whole_rect.top); window_surface_lock(data->surface); - bounds = data->surface->funcs->get_bounds(data->surface); - add_bounds_rect(bounds, &rect); + add_bounds_rect(&data->surface->bounds, &rect); window_surface_unlock(data->surface); } } @@ -1985,7 +1983,7 @@ BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, { window_surface_lock(surface); memcpy(dst_bits, src_bits, bmi->bmiHeader.biSizeImage); - add_bounds_rect(surface->funcs->get_bounds(surface), &rect); + add_bounds_rect(&surface->bounds, &rect); window_surface_unlock(surface); surface->funcs->flush(surface); } diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 4c8d3956408..adcbf593984 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -46,7 +46,6 @@ struct wayland_window_surface HWND hwnd; struct wayland_surface *wayland_surface; struct wayland_buffer_queue *wayland_buffer_queue; - RECT bounds; void *bits; BITMAPINFO info; }; @@ -231,15 +230,6 @@ static void *wayland_window_surface_get_bitmap_info(struct window_surface *windo return surface->bits; }
-/*********************************************************************** - * wayland_window_surface_get_bounds - */ -static RECT *wayland_window_surface_get_bounds(struct window_surface *window_surface) -{ - struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface); - return &wws->bounds; -} - /*********************************************************************** * wayland_window_surface_set_region */ @@ -362,7 +352,7 @@ static void wayland_window_surface_flush(struct window_surface *window_surface)
window_surface_lock(window_surface);
- if (!intersect_rect(&damage_rect, &wws->header.rect, &wws->bounds)) goto done; + if (!intersect_rect(&damage_rect, &wws->header.rect, &window_surface->bounds)) goto done;
if (!wws->wayland_surface || !wws->wayland_buffer_queue) { @@ -372,7 +362,7 @@ static void wayland_window_surface_flush(struct window_surface *window_surface) }
TRACE("surface=%p hwnd=%p surface_rect=%s bounds=%s\n", wws, wws->hwnd, - wine_dbgstr_rect(&wws->header.rect), wine_dbgstr_rect(&wws->bounds)); + wine_dbgstr_rect(&wws->header.rect), wine_dbgstr_rect(&window_surface->bounds));
surface_damage_region = NtGdiCreateRectRgn(damage_rect.left, damage_rect.top, damage_rect.right, damage_rect.bottom); @@ -448,7 +438,7 @@ static void wayland_window_surface_flush(struct window_surface *window_surface) wayland_shm_buffer_ref((wws->wayland_surface->latest_window_buffer = shm_buffer));
done: - if (flushed) reset_bounds(&wws->bounds); + if (flushed) reset_bounds(&window_surface->bounds); if (surface_damage_region) NtGdiDeleteObjectApp(surface_damage_region); window_surface_unlock(window_surface); } @@ -471,7 +461,6 @@ static void wayland_window_surface_destroy(struct window_surface *window_surface static const struct window_surface_funcs wayland_window_surface_funcs = { wayland_window_surface_get_bitmap_info, - wayland_window_surface_get_bounds, wayland_window_surface_set_region, wayland_window_surface_flush, wayland_window_surface_destroy @@ -502,7 +491,6 @@ struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect wws->info.bmiHeader.biSizeImage = width * height * 4;
wws->hwnd = hwnd; - reset_bounds(&wws->bounds);
if (!(wws->bits = malloc(wws->info.bmiHeader.biSizeImage))) goto failed; diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index c19836c31a3..ad262d84496 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1577,7 +1577,6 @@ struct x11drv_window_surface Window window; GC gc; XImage *image; - RECT bounds; BOOL byteswap; BOOL is_argb; DWORD alpha_bits; @@ -1838,16 +1837,6 @@ static void *x11drv_surface_get_bitmap_info( struct window_surface *window_surfa return surface->bits; }
-/*********************************************************************** - * x11drv_surface_get_bounds - */ -static RECT *x11drv_surface_get_bounds( struct window_surface *window_surface ) -{ - struct x11drv_window_surface *surface = get_x11_surface( window_surface ); - - return &surface->bounds; -} - /*********************************************************************** * x11drv_surface_set_region */ @@ -1895,11 +1884,10 @@ static void x11drv_surface_flush( struct window_surface *window_surface ) coords.width = surface->header.rect.right - surface->header.rect.left; coords.height = surface->header.rect.bottom - surface->header.rect.top; SetRect( &coords.visrect, 0, 0, coords.width, coords.height ); - if (intersect_rect( &coords.visrect, &coords.visrect, &surface->bounds )) + if (intersect_rect( &coords.visrect, &coords.visrect, &window_surface->bounds )) { - TRACE( "flushing %p %dx%d bounds %s bits %p\n", - surface, coords.width, coords.height, - wine_dbgstr_rect( &surface->bounds ), surface->bits ); + TRACE( "flushing %p %dx%d bounds %s bits %p\n", surface, coords.width, coords.height, + wine_dbgstr_rect( &window_surface->bounds ), surface->bits );
if (surface->is_argb || surface->color_key != CLR_INVALID) update_surface_region( surface );
@@ -1942,7 +1930,7 @@ static void x11drv_surface_flush( struct window_surface *window_surface ) coords.visrect.bottom - coords.visrect.top ); XFlush( gdi_display ); } - reset_bounds( &surface->bounds ); + reset_bounds( &window_surface->bounds ); window_surface_unlock( window_surface ); }
@@ -1978,7 +1966,6 @@ static void x11drv_surface_destroy( struct window_surface *window_surface ) static const struct window_surface_funcs x11drv_surface_funcs = { x11drv_surface_get_bitmap_info, - x11drv_surface_get_bounds, x11drv_surface_set_region, x11drv_surface_flush, x11drv_surface_destroy @@ -2010,7 +1997,6 @@ struct window_surface *create_surface( Window window, const XVisualInfo *vis, co surface->window = window; surface->is_argb = (use_alpha && vis->depth == 32 && surface->info.bmiHeader.biCompression == BI_RGB); set_color_key( surface, color_key ); - reset_bounds( &surface->bounds );
#ifdef HAVE_LIBXXSHM surface->image = create_shm_image( vis, width, height, &surface->shminfo ); @@ -2080,7 +2066,7 @@ HRGN expose_surface( struct window_surface *window_surface, const RECT *rect )
window_surface_lock( window_surface ); OffsetRect( &rc, -window_surface->rect.left, -window_surface->rect.top ); - add_bounds_rect( &surface->bounds, &rc ); + add_bounds_rect( &window_surface->bounds, &rc ); if (surface->region) { region = NtGdiCreateRectRgn( rect->left, rect->top, rect->right, rect->bottom ); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index eb9c5d4d8a8..27f4b10011c 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -3046,7 +3046,7 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, if (ret) { memcpy( dst_bits, src_bits, bmi->bmiHeader.biSizeImage ); - add_bounds_rect( surface->funcs->get_bounds( surface ), &rect ); + add_bounds_rect( &surface->bounds, &rect ); }
window_surface_unlock( surface ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 0104cdbe8ba..cd3e8c6abdc 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -212,7 +212,6 @@ struct window_surface; struct window_surface_funcs { void* (*get_info)( struct window_surface *surface, BITMAPINFO *info ); - RECT* (*get_bounds)( struct window_surface *surface ); void (*set_region)( struct window_surface *surface, HRGN region ); void (*flush)( struct window_surface *surface ); void (*destroy)( struct window_surface *surface ); @@ -226,6 +225,7 @@ struct window_surface RECT rect; /* constant, no locking needed */
pthread_mutex_t mutex; + RECT bounds; /* dirty area rect, requires locking */ DWORD draw_start_ticks; /* start ticks of fresh draw */ /* driver-specific fields here */ };
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/cocoa_window.m | 29 +++---- dlls/winemac.drv/macdrv.h | 1 - dlls/winemac.drv/macdrv_cocoa.h | 7 +- dlls/winemac.drv/surface.c | 146 +++++--------------------------- dlls/winemac.drv/window.c | 4 +- 5 files changed, 38 insertions(+), 149 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 9d2a53c60ae..61a6ab2cd4e 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -409,7 +409,6 @@ @interface WineWindow () @property (retain, readwrite, nonatomic) WineEventQueue* queue;
@property (nonatomic) void* surface; -@property (nonatomic) pthread_mutex_t* surface_mutex;
@property (nonatomic) BOOL shapeChangedSinceLastDraw; @property (readonly, nonatomic) BOOL needsTransparency; @@ -525,21 +524,16 @@ - (void) updateLayer if ([window contentView] != self) return;
- if (window.closing || !window.surface || !window.surface_mutex) + if (window.closing || !window.surface) return;
- pthread_mutex_lock(window.surface_mutex); - if (get_surface_blit_rects(window.surface, NULL, NULL)) - { - imageRect = layer.bounds; - imageRect.origin.x *= layer.contentsScale; - imageRect.origin.y *= layer.contentsScale; - imageRect.size.width *= layer.contentsScale; - imageRect.size.height *= layer.contentsScale; - image = create_surface_image(window.surface, &imageRect, FALSE, window.colorKeyed, - window.colorKeyRed, window.colorKeyGreen, window.colorKeyBlue); - } - pthread_mutex_unlock(window.surface_mutex); + imageRect = layer.bounds; + imageRect.origin.x *= layer.contentsScale; + imageRect.origin.y *= layer.contentsScale; + imageRect.size.width *= layer.contentsScale; + imageRect.size.height *= layer.contentsScale; + image = macdrv_get_surface_display_image(window.surface, &imageRect, FALSE, window.colorKeyed, + window.colorKeyRed, window.colorKeyGreen, window.colorKeyBlue);
if (image) { @@ -1004,7 +998,7 @@ @implementation WineWindow
@synthesize disabled, noForeground, preventsAppActivation, floating, fullscreen, fakingClose, closing, latentParentWindow, hwnd, queue; @synthesize drawnSinceShown; - @synthesize surface, surface_mutex; + @synthesize surface; @synthesize shapeChangedSinceLastDraw; @synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue; @synthesize usePerPixelAlpha; @@ -3486,15 +3480,14 @@ void macdrv_set_cocoa_parent_window(macdrv_window w, macdrv_window parent) /*********************************************************************** * macdrv_set_window_surface */ -void macdrv_set_window_surface(macdrv_window w, void *surface, pthread_mutex_t *mutex) +void macdrv_set_window_surface(macdrv_window w, struct window_surface *window_surface) { @autoreleasepool { WineWindow* window = (WineWindow*)w;
OnMainThread(^{ - window.surface = surface; - window.surface_mutex = mutex; + window.surface = window_surface; }); } } diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index bbc9b83e8e2..d1101a4a228 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -210,7 +210,6 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p extern void activate_on_following_focus(void); extern struct window_surface *create_surface(macdrv_window window, const RECT *rect, struct window_surface *old_surface, BOOL use_alpha); -extern void set_window_surface(macdrv_window window, struct window_surface *window_surface); extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha); extern void surface_clip_to_visible_rect(struct window_surface *window_surface, const RECT *visible_rect);
diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index 0c010d6e097..ba5803f88dc 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -534,6 +534,8 @@ extern int macdrv_register_hot_key(macdrv_event_queue q, unsigned int vkey, unsi unsigned int maximized:1; };
+struct window_surface; + extern macdrv_window macdrv_create_cocoa_window(const struct macdrv_window_features* wf, CGRect frame, void* hwnd, macdrv_event_queue queue); extern void macdrv_destroy_cocoa_window(macdrv_window w); @@ -550,10 +552,9 @@ extern void macdrv_order_cocoa_window(macdrv_window w, macdrv_window prev, extern void macdrv_set_cocoa_window_frame(macdrv_window w, const CGRect* new_frame); extern void macdrv_get_cocoa_window_frame(macdrv_window w, CGRect* out_frame); extern void macdrv_set_cocoa_parent_window(macdrv_window w, macdrv_window parent); -extern void macdrv_set_window_surface(macdrv_window w, void *surface, pthread_mutex_t *mutex); -extern CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_data, int color_keyed, +extern void macdrv_set_window_surface(macdrv_window w, struct window_surface *window_surface); +extern CGImageRef macdrv_get_surface_display_image(struct window_surface *window_surface, CGRect *rect, int copy_data, int color_keyed, CGFloat key_red, CGFloat key_green, CGFloat key_blue); -extern int get_surface_blit_rects(void *window_surface, const CGRect **rects, int *count); extern void macdrv_window_needs_display(macdrv_window w, CGRect rect); extern void macdrv_set_window_shape(macdrv_window w, const CGRect *rects, int count); extern void macdrv_set_window_alpha(macdrv_window w, CGFloat alpha); diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 314e9e68542..3edbe783b10 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -65,36 +65,13 @@ struct macdrv_window_surface struct window_surface header; macdrv_window window; HRGN region; - HRGN drawn; BOOL use_alpha; - RGNDATA *blit_data; BYTE *bits; BITMAPINFO info; /* variable size, must be last */ };
static struct macdrv_window_surface *get_mac_surface(struct window_surface *surface);
-/*********************************************************************** - * update_blit_data - */ -static void update_blit_data(struct macdrv_window_surface *surface) -{ - free(surface->blit_data); - surface->blit_data = NULL; - - if (surface->drawn) - { - HRGN blit = NtGdiCreateRectRgn(0, 0, 0, 0); - - if (NtGdiCombineRgn(blit, surface->drawn, 0, RGN_COPY) > NULLREGION && - (!surface->region || NtGdiCombineRgn(blit, blit, surface->region, RGN_AND) > NULLREGION) && - NtGdiOffsetRgn(blit, surface->header.rect.left, surface->header.rect.top) > NULLREGION) - surface->blit_data = get_region_data(blit, 0); - - NtGdiDeleteObjectApp(blit); - } -} - /*********************************************************************** * macdrv_surface_get_bitmap_info */ @@ -128,7 +105,6 @@ static void macdrv_surface_set_region(struct window_surface *window_surface, HRG if (surface->region) NtGdiDeleteObjectApp(surface->region); surface->region = 0; } - update_blit_data(surface);
window_surface_unlock(window_surface); } @@ -139,36 +115,18 @@ static void macdrv_surface_set_region(struct window_surface *window_surface, HRG static void macdrv_surface_flush(struct window_surface *window_surface) { struct macdrv_window_surface *surface = get_mac_surface(window_surface); - CGRect rect; - HRGN region; + RECT rect = window_surface->rect; + OffsetRect(&rect, -rect.left, -rect.top);
window_surface_lock(window_surface);
TRACE("flushing %p %s bounds %s bits %p\n", surface, wine_dbgstr_rect(&surface->header.rect), wine_dbgstr_rect(&window_surface->bounds), surface->bits);
- rect = cgrect_from_rect(window_surface->bounds); - rect = CGRectOffset(rect, surface->header.rect.left, surface->header.rect.top); - - if (!IsRectEmpty(&window_surface->bounds) && - (region = NtGdiCreateRectRgn(window_surface->bounds.left, window_surface->bounds.top, - window_surface->bounds.right, window_surface->bounds.bottom))) - { - if (surface->drawn) - { - NtGdiCombineRgn(surface->drawn, surface->drawn, region, RGN_OR); - NtGdiDeleteObjectApp(region); - } - else - surface->drawn = region; - } - update_blit_data(surface); - reset_bounds(&window_surface->bounds); + if (intersect_rect(&rect, &rect, &window_surface->bounds)) + macdrv_window_needs_display(surface->window, cgrect_from_rect(rect));
window_surface_unlock(window_surface); - - if (!CGRectIsEmpty(rect)) - macdrv_window_needs_display(surface->window, rect); }
/*********************************************************************** @@ -180,8 +138,6 @@ static void macdrv_surface_destroy(struct window_surface *window_surface)
TRACE("freeing %p bits %p\n", surface, surface->bits); if (surface->region) NtGdiDeleteObjectApp(surface->region); - if (surface->drawn) NtGdiDeleteObjectApp(surface->drawn); - free(surface->blit_data); free(surface->bits); free(surface); } @@ -207,7 +163,6 @@ struct window_surface *create_surface(macdrv_window window, const RECT *rect, struct window_surface *old_surface, BOOL use_alpha) { struct macdrv_window_surface *surface; - struct macdrv_window_surface *old_mac_surface = get_mac_surface(old_surface); int width = rect->right - rect->left, height = rect->bottom - rect->top; DWORD *colors; DWORD window_background; @@ -231,17 +186,7 @@ struct window_surface *create_surface(macdrv_window window, const RECT *rect, colors[2] = 0x000000ff;
surface->window = window; - if (old_mac_surface && old_mac_surface->drawn) - { - surface->drawn = NtGdiCreateRectRgn(rect->left, rect->top, rect->right, rect->bottom); - NtGdiOffsetRgn(surface->drawn, -rect->left, -rect->top); - if (NtGdiCombineRgn(surface->drawn, surface->drawn, old_mac_surface->drawn, RGN_AND) <= NULLREGION) - { - NtGdiDeleteObjectApp(surface->drawn); - surface->drawn = 0; - } - } - update_blit_data(surface); + if (old_surface) surface->header.bounds = old_surface->bounds; surface->use_alpha = use_alpha; surface->bits = malloc(surface->info.bmiHeader.biSizeImage); if (!surface->bits) goto failed; @@ -267,48 +212,6 @@ void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha if (surface) surface->use_alpha = use_alpha; }
-/*********************************************************************** - * set_window_surface - */ -void set_window_surface(macdrv_window window, struct window_surface *window_surface) -{ - struct macdrv_window_surface *surface = get_mac_surface(window_surface); - macdrv_set_window_surface(window, window_surface, surface ? &window_surface->mutex : NULL); -} - -/*********************************************************************** - * get_surface_blit_rects - * - * Caller must hold the surface lock. Indirectly returns the surface - * blit region rects. Returns zero if the surface has nothing to blit; - * returns non-zero if the surface does have rects to blit (drawn area - * which isn't clipped away by a surface region). - * - * IMPORTANT: This function is called from non-Wine threads, so it - * must not use Win32 or Wine functions, including debug - * logging. - */ -int get_surface_blit_rects(void *window_surface, const CGRect **rects, int *count) -{ - struct macdrv_window_surface *surface = get_mac_surface(window_surface); - - if (rects && count) - { - if (surface->blit_data) - { - *rects = (const CGRect*)surface->blit_data->Buffer; - *count = surface->blit_data->rdh.nCount; - } - else - { - *rects = NULL; - *count = 0; - } - } - - return (surface->blit_data != NULL && surface->blit_data->rdh.nCount > 0); -} - /*********************************************************************** * create_surface_image * @@ -324,16 +227,20 @@ int get_surface_blit_rects(void *window_surface, const CGRect **rects, int *coun * must not use Win32 or Wine functions, including debug * logging. */ -CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_data, int color_keyed, +CGImageRef macdrv_get_surface_display_image(struct window_surface *window_surface, CGRect *rect, int copy_data, int color_keyed, CGFloat key_red, CGFloat key_green, CGFloat key_blue) { CGImageRef cgimage = NULL; struct macdrv_window_surface *surface = get_mac_surface(window_surface); + RECT surface_rect = window_surface->rect; int width, height;
- width = surface->header.rect.right - surface->header.rect.left; - height = surface->header.rect.bottom - surface->header.rect.top; - *rect = CGRectIntersection(cgrect_from_rect(surface->header.rect), *rect); + pthread_mutex_lock(&window_surface->mutex); + if (IsRectEmpty(&window_surface->bounds)) goto done; + + width = surface_rect.right - surface_rect.left; + height = surface_rect.bottom - surface_rect.top; + *rect = CGRectIntersection(cgrect_from_rect(surface_rect), *rect); if (!CGRectIsEmpty(*rect)) { CGRect visrect; @@ -342,7 +249,7 @@ CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_dat int bytes_per_row, offset, size; CGImageAlphaInfo alphaInfo;
- visrect = CGRectOffset(*rect, -surface->header.rect.left, -surface->header.rect.top); + visrect = CGRectOffset(*rect, -surface_rect.left, -surface_rect.top);
colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); bytes_per_row = get_dib_stride(width, 32); @@ -382,6 +289,9 @@ CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_dat } }
+done: + reset_bounds(&window_surface->bounds); + pthread_mutex_unlock(&window_surface->mutex); return cgimage; }
@@ -394,26 +304,12 @@ CGImageRef create_surface_image(void *window_surface, CGRect *rect, int copy_dat void surface_clip_to_visible_rect(struct window_surface *window_surface, const RECT *visible_rect) { struct macdrv_window_surface *surface = get_mac_surface(window_surface); + RECT rect = *visible_rect; + OffsetRect(&rect, -rect.left, -rect.top);
if (!surface) return; - window_surface_lock(window_surface); - - if (surface->drawn) - { - RECT rect; - HRGN region; - - rect = *visible_rect; - OffsetRect(&rect, -rect.left, -rect.top); - - if ((region = NtGdiCreateRectRgn(rect.left, rect.top, rect.right, rect.bottom))) - { - NtGdiCombineRgn(surface->drawn, surface->drawn, region, RGN_AND); - NtGdiDeleteObjectApp(region); - - update_blit_data(surface); - } - }
+ window_surface_lock(window_surface); + intersect_rect(&window_surface->bounds, &window_surface->bounds, &rect); window_surface_unlock(window_surface); } diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 05ba3e994d7..f498914588a 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1916,7 +1916,7 @@ BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, if (!surface || !EqualRect(&surface->rect, &rect)) { data->surface = create_surface(data->cocoa_window, &rect, NULL, TRUE); - set_window_surface(data->cocoa_window, data->surface); + macdrv_set_window_surface(data->cocoa_window, data->surface); if (surface) window_surface_release(surface); surface = data->surface; if (data->unminimized_surface) @@ -2138,7 +2138,7 @@ void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, } else { - set_window_surface(data->cocoa_window, surface); + macdrv_set_window_surface(data->cocoa_window, surface); if (data->unminimized_surface) { window_surface_release(data->unminimized_surface);
From: Rémi Bernon rbernon@codeweavers.com
To avoid hiding the change in the next commit. --- dlls/wineandroid.drv/window.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 8314876f1c4..d1c93b5ceff 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -695,8 +695,12 @@ static void android_surface_flush( struct window_surface *window_surface ) surface->header.rect.bottom - surface->header.rect.top ); needs_flush = intersect_rect( &rect, &rect, &window_surface->bounds ); reset_bounds( &window_surface->bounds ); - window_surface_unlock( window_surface ); - if (!needs_flush) return; + + if (!needs_flush) + { + window_surface_unlock( window_surface ); + return; + }
TRACE( "flushing %p hwnd %p surface %s rect %s bits %p alpha %02x key %08x region %u rects\n", surface, surface->hwnd, wine_dbgstr_rect( &surface->header.rect ), @@ -760,6 +764,8 @@ static void android_surface_flush( struct window_surface *window_surface ) } else TRACE( "Unable to lock surface %p window %p buffer %p\n", surface, surface->hwnd, surface->window ); + + window_surface_unlock( window_surface ); }
/***********************************************************************
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 27 +++++++-- dlls/win32u/dibdrv/dc.c | 2 +- dlls/wineandroid.drv/window.c | 65 +++++++--------------- dlls/winemac.drv/surface.c | 16 +----- dlls/winemac.drv/window.c | 2 +- dlls/winewayland.drv/window.c | 2 +- dlls/winewayland.drv/window_surface.c | 16 +----- dlls/winex11.drv/bitblt.c | 80 ++++++++++----------------- dlls/winex11.drv/event.c | 2 +- dlls/winex11.drv/window.c | 6 +- include/wine/gdi_driver.h | 3 +- 11 files changed, 86 insertions(+), 135 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index a97a21d072c..d8a26b655ef 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -79,9 +79,10 @@ static void dummy_surface_set_region( struct window_surface *window_surface, HRG /* nothing to do */ }
-static void dummy_surface_flush( struct window_surface *window_surface ) +static BOOL dummy_surface_flush( struct window_surface *window_surface, const RECT *rect, const RECT *dirty ) { /* nothing to do */ + return TRUE; }
static void dummy_surface_destroy( struct window_surface *window_surface ) @@ -129,11 +130,9 @@ static void offscreen_window_surface_set_region( struct window_surface *base, HR { }
-static void offscreen_window_surface_flush( struct window_surface *surface ) +static BOOL offscreen_window_surface_flush( struct window_surface *base, const RECT *rect, const RECT *dirty ) { - window_surface_lock( surface ); - reset_bounds( &surface->bounds ); - window_surface_unlock( surface ); + return TRUE; }
static void offscreen_window_surface_destroy( struct window_surface *base ) @@ -229,6 +228,22 @@ W32KAPI void window_surface_unlock( struct window_surface *surface ) pthread_mutex_unlock( &surface->mutex ); }
+W32KAPI void window_surface_flush( struct window_surface *surface ) +{ + RECT dirty = surface->rect; + + window_surface_lock( surface ); + + if (intersect_rect( &dirty, &dirty, &surface->bounds )) + { + TRACE( "Flushing surface %p %s, bounds %s, dirty %s\n", surface, wine_dbgstr_rect( &surface->rect ), + wine_dbgstr_rect( &surface->bounds ), wine_dbgstr_rect( &dirty ) ); + if (surface->funcs->flush( surface, &surface->rect, &dirty )) reset_bounds( &surface->bounds ); + } + + window_surface_unlock( surface ); +} + /******************************************************************* * register_window_surface * @@ -263,7 +278,7 @@ void flush_window_surfaces( BOOL idle ) else if ((int)(now - last_idle) < 50) goto done;
LIST_FOR_EACH_ENTRY( surface, &window_surfaces, struct window_surface, entry ) - surface->funcs->flush( surface ); + window_surface_flush( surface ); done: pthread_mutex_unlock( &surfaces_lock ); } diff --git a/dlls/win32u/dibdrv/dc.c b/dlls/win32u/dibdrv/dc.c index 6050923b9c4..48320f5b676 100644 --- a/dlls/win32u/dibdrv/dc.c +++ b/dlls/win32u/dibdrv/dc.c @@ -765,7 +765,7 @@ static inline void unlock_surface( struct windrv_physdev *dev ) { DWORD ticks = NtGetTickCount() - surface->draw_start_ticks; window_surface_unlock( surface ); - if (ticks > FLUSH_PERIOD) surface->funcs->flush( dev->surface ); + if (ticks > FLUSH_PERIOD) window_surface_flush( dev->surface ); } }
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index d1c93b5ceff..ddb46c0d4cd 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -587,12 +587,6 @@ static struct android_window_surface *get_android_surface( struct window_surface return (struct android_window_surface *)surface; }
-static inline void reset_bounds( RECT *bounds ) -{ - bounds->left = bounds->top = INT_MAX; - bounds->right = bounds->bottom = INT_MIN; -} - static inline void add_bounds_rect( RECT *bounds, const RECT *rect ) { if (rect->left >= rect->right || rect->top >= rect->bottom) return; @@ -682,60 +676,41 @@ static void android_surface_set_region( struct window_surface *window_surface, H /*********************************************************************** * android_surface_flush */ -static void android_surface_flush( struct window_surface *window_surface ) +static BOOL android_surface_flush( struct window_surface *window_surface, const RECT *rect, const RECT *dirty ) { struct android_window_surface *surface = get_android_surface( window_surface ); ANativeWindow_Buffer buffer; ARect rc; - RECT rect; - BOOL needs_flush; - - window_surface_lock( window_surface ); - SetRect( &rect, 0, 0, surface->header.rect.right - surface->header.rect.left, - surface->header.rect.bottom - surface->header.rect.top ); - needs_flush = intersect_rect( &rect, &rect, &window_surface->bounds ); - reset_bounds( &window_surface->bounds ); - - if (!needs_flush) - { - window_surface_unlock( window_surface ); - return; - }
- TRACE( "flushing %p hwnd %p surface %s rect %s bits %p alpha %02x key %08x region %u rects\n", - surface, surface->hwnd, wine_dbgstr_rect( &surface->header.rect ), - wine_dbgstr_rect( &rect ), surface->bits, surface->alpha, (int)surface->color_key, - surface->region_data ? (int)surface->region_data->rdh.nCount : 0 ); - - rc.left = rect.left; - rc.top = rect.top; - rc.right = rect.right; - rc.bottom = rect.bottom; + rc.left = dirty->left; + rc.top = dirty->top; + rc.right = dirty->right; + rc.bottom = dirty->bottom;
if (!surface->window->perform( surface->window, NATIVE_WINDOW_LOCK, &buffer, &rc )) { const RECT *rgn_rect = NULL, *end = NULL; DWORD *src, *dst; int x, y, width; + RECT locked;
- rect.left = rc.left; - rect.top = rc.top; - rect.right = rc.right; - rect.bottom = rc.bottom; - intersect_rect( &rect, &rect, &surface->header.rect ); + locked.left = rc.left; + locked.top = rc.top; + locked.right = rc.right; + locked.bottom = rc.bottom; + intersect_rect( &locked, &locked, rect );
if (surface->region_data) { rgn_rect = (RECT *)surface->region_data->Buffer; end = rgn_rect + surface->region_data->rdh.nCount; } - src = (DWORD *)surface->bits - + (rect.top - surface->header.rect.top) * surface->info.bmiHeader.biWidth - + (rect.left - surface->header.rect.left); - dst = (DWORD *)buffer.bits + rect.top * buffer.stride + rect.left; - width = min( rect.right - rect.left, buffer.stride ); + src = (DWORD *)surface->bits + (locked.top - rect->top) * surface->info.bmiHeader.biWidth + + (locked.left - rect->left); + dst = (DWORD *)buffer.bits + locked.top * buffer.stride + locked.left; + width = min( locked.right - locked.left, buffer.stride );
- for (y = rect.top; y < min( buffer.height, rect.bottom); y++) + for (y = locked.top; y < min( buffer.height, locked.bottom ); y++) { if (surface->info.bmiHeader.biCompression == BI_RGB) memcpy( dst, src, width * sizeof(*dst) ); @@ -754,7 +729,7 @@ static void android_surface_flush( struct window_surface *window_surface ) if (rgn_rect) { while (rgn_rect < end && rgn_rect->bottom <= y) rgn_rect++; - apply_line_region( dst, width, rect.left, y, rgn_rect, end ); + apply_line_region( dst, width, locked.left, y, rgn_rect, end ); }
src += surface->info.bmiHeader.biWidth; @@ -765,7 +740,7 @@ static void android_surface_flush( struct window_surface *window_surface ) else TRACE( "Unable to lock surface %p window %p buffer %p\n", surface, surface->hwnd, surface->window );
- window_surface_unlock( window_surface ); + return TRUE; }
/*********************************************************************** @@ -1576,7 +1551,7 @@ BOOL ANDROID_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info }
window_surface_unlock( surface ); - surface->funcs->flush( surface ); + window_surface_flush( surface );
done: window_surface_release( surface ); @@ -1608,7 +1583,7 @@ LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) window_surface_lock( surface ); surface->bounds = surface->rect; window_surface_unlock( surface ); - if (is_argb_surface( surface )) surface->funcs->flush( surface ); + if (is_argb_surface( surface )) window_surface_flush( surface ); } release_win_data( data ); } diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 3edbe783b10..7e296f33a62 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -112,21 +112,11 @@ static void macdrv_surface_set_region(struct window_surface *window_surface, HRG /*********************************************************************** * macdrv_surface_flush */ -static void macdrv_surface_flush(struct window_surface *window_surface) +static BOOL macdrv_surface_flush(struct window_surface *window_surface, const RECT *rect, const RECT *dirty) { struct macdrv_window_surface *surface = get_mac_surface(window_surface); - RECT rect = window_surface->rect; - OffsetRect(&rect, -rect.left, -rect.top); - - window_surface_lock(window_surface); - - TRACE("flushing %p %s bounds %s bits %p\n", surface, wine_dbgstr_rect(&surface->header.rect), - wine_dbgstr_rect(&window_surface->bounds), surface->bits); - - if (intersect_rect(&rect, &rect, &window_surface->bounds)) - macdrv_window_needs_display(surface->window, cgrect_from_rect(rect)); - - window_surface_unlock(window_surface); + macdrv_window_needs_display(surface->window, cgrect_from_rect(*dirty)); + return FALSE; /* bounds are reset asynchronously, from macdrv_get_surface_display_image */ }
/*********************************************************************** diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index f498914588a..04eb6d00860 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1985,7 +1985,7 @@ BOOL macdrv_UpdateLayeredWindow(HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, memcpy(dst_bits, src_bits, bmi->bmiHeader.biSizeImage); add_bounds_rect(&surface->bounds, &rect); window_surface_unlock(surface); - surface->funcs->flush(surface); + window_surface_flush(surface); }
/* The ULW flags are a superset of the LWA flags. */ diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 690038fdbec..3706b6afb97 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -756,7 +756,7 @@ void wayland_window_flush(HWND hwnd) if (!data) return;
if (data->window_surface) - data->window_surface->funcs->flush(data->window_surface); + window_surface_flush(data->window_surface);
wayland_win_data_release(data); } diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index adcbf593984..37fe9b3eb4c 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -341,19 +341,14 @@ static void wayland_shm_buffer_copy(struct wayland_shm_buffer *src, /*********************************************************************** * wayland_window_surface_flush */ -static void wayland_window_surface_flush(struct window_surface *window_surface) +static BOOL wayland_window_surface_flush(struct window_surface *window_surface, const RECT *rect, const RECT *dirty) { struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface); struct wayland_shm_buffer *shm_buffer = NULL; BOOL flushed = FALSE; - RECT damage_rect; HRGN surface_damage_region = NULL; HRGN copy_from_window_region;
- window_surface_lock(window_surface); - - if (!intersect_rect(&damage_rect, &wws->header.rect, &window_surface->bounds)) goto done; - if (!wws->wayland_surface || !wws->wayland_buffer_queue) { ERR("missing wayland surface=%p or buffer_queue=%p, returning\n", @@ -361,11 +356,7 @@ static void wayland_window_surface_flush(struct window_surface *window_surface) goto done; }
- TRACE("surface=%p hwnd=%p surface_rect=%s bounds=%s\n", wws, wws->hwnd, - wine_dbgstr_rect(&wws->header.rect), wine_dbgstr_rect(&window_surface->bounds)); - - surface_damage_region = NtGdiCreateRectRgn(damage_rect.left, damage_rect.top, - damage_rect.right, damage_rect.bottom); + surface_damage_region = NtGdiCreateRectRgn(dirty->left, dirty->top, dirty->right, dirty->bottom); if (!surface_damage_region) { ERR("failed to create surface damage region\n"); @@ -438,9 +429,8 @@ static void wayland_window_surface_flush(struct window_surface *window_surface) wayland_shm_buffer_ref((wws->wayland_surface->latest_window_buffer = shm_buffer));
done: - if (flushed) reset_bounds(&window_surface->bounds); if (surface_damage_region) NtGdiDeleteObjectApp(surface_damage_region); - window_surface_unlock(window_surface); + return flushed; }
/*********************************************************************** diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index ad262d84496..f0d523b6f9c 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -1871,67 +1871,47 @@ static void x11drv_surface_set_region( struct window_surface *window_surface, HR /*********************************************************************** * x11drv_surface_flush */ -static void x11drv_surface_flush( struct window_surface *window_surface ) +static BOOL x11drv_surface_flush( struct window_surface *window_surface, const RECT *rect, const RECT *dirty ) { struct x11drv_window_surface *surface = get_x11_surface( window_surface ); unsigned char *src = surface->bits; unsigned char *dst = (unsigned char *)surface->image->data; - struct bitblt_coords coords;
- window_surface_lock( window_surface ); - coords.x = 0; - coords.y = 0; - coords.width = surface->header.rect.right - surface->header.rect.left; - coords.height = surface->header.rect.bottom - surface->header.rect.top; - SetRect( &coords.visrect, 0, 0, coords.width, coords.height ); - if (intersect_rect( &coords.visrect, &coords.visrect, &window_surface->bounds )) - { - TRACE( "flushing %p %dx%d bounds %s bits %p\n", surface, coords.width, coords.height, - wine_dbgstr_rect( &window_surface->bounds ), surface->bits ); + if (surface->is_argb || surface->color_key != CLR_INVALID) update_surface_region( surface );
- if (surface->is_argb || surface->color_key != CLR_INVALID) update_surface_region( surface ); + if (src != dst) + { + int map[256], *mapping = get_window_surface_mapping( surface->image->bits_per_pixel, map ); + int width_bytes = surface->image->bytes_per_line;
- if (src != dst) - { - int map[256], *mapping = get_window_surface_mapping( surface->image->bits_per_pixel, map ); - int width_bytes = surface->image->bytes_per_line; - - src += coords.visrect.top * width_bytes; - dst += coords.visrect.top * width_bytes; - copy_image_byteswap( &surface->info, src, dst, width_bytes, width_bytes, - coords.visrect.bottom - coords.visrect.top, - surface->byteswap, mapping, ~0u, surface->alpha_bits ); - } - else if (surface->alpha_bits) - { - int x, y, stride = surface->image->bytes_per_line / sizeof(ULONG); - ULONG *ptr = (ULONG *)dst + coords.visrect.top * stride; + src += dirty->top * width_bytes; + dst += dirty->top * width_bytes; + copy_image_byteswap( &surface->info, src, dst, width_bytes, width_bytes, dirty->bottom - dirty->top, + surface->byteswap, mapping, ~0u, surface->alpha_bits ); + } + else if (surface->alpha_bits) + { + int x, y, stride = surface->image->bytes_per_line / sizeof(ULONG); + ULONG *ptr = (ULONG *)dst + dirty->top * stride;
- for (y = coords.visrect.top; y < coords.visrect.bottom; y++, ptr += stride) - for (x = coords.visrect.left; x < coords.visrect.right; x++) - ptr[x] |= surface->alpha_bits; - } + for (y = dirty->top; y < dirty->bottom; y++, ptr += stride) + for (x = dirty->left; x < dirty->right; x++) + ptr[x] |= surface->alpha_bits; + }
#ifdef HAVE_LIBXXSHM - if (surface->shminfo.shmid != -1) - XShmPutImage( gdi_display, surface->window, surface->gc, surface->image, - coords.visrect.left, coords.visrect.top, - surface->header.rect.left + coords.visrect.left, - surface->header.rect.top + coords.visrect.top, - coords.visrect.right - coords.visrect.left, - coords.visrect.bottom - coords.visrect.top, False ); - else + if (surface->shminfo.shmid != -1) + XShmPutImage( gdi_display, surface->window, surface->gc, surface->image, dirty->left, + dirty->top, rect->left + dirty->left, rect->top + dirty->top, + dirty->right - dirty->left, dirty->bottom - dirty->top, False ); + else #endif - XPutImage( gdi_display, surface->window, surface->gc, surface->image, - coords.visrect.left, coords.visrect.top, - surface->header.rect.left + coords.visrect.left, - surface->header.rect.top + coords.visrect.top, - coords.visrect.right - coords.visrect.left, - coords.visrect.bottom - coords.visrect.top ); - XFlush( gdi_display ); - } - reset_bounds( &window_surface->bounds ); - window_surface_unlock( window_surface ); + XPutImage( gdi_display, surface->window, surface->gc, surface->image, dirty->left, + dirty->top, rect->left + dirty->left, rect->top + dirty->top, + dirty->right - dirty->left, dirty->bottom - dirty->top ); + XFlush( gdi_display ); + + return TRUE; }
/*********************************************************************** diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 2070d942056..3e9e0254c91 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -906,7 +906,7 @@ static BOOL X11DRV_Expose( HWND hwnd, XEvent *xev ) data->whole_rect.top - data->client_rect.top );
if (data->vis.visualid != default_visual.visualid) - data->surface->funcs->flush( data->surface ); + window_surface_flush( data->surface ); } OffsetRect( &rect, data->whole_rect.left - data->client_rect.left, data->whole_rect.top - data->client_rect.top ); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 27f4b10011c..823a17e3998 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1236,7 +1236,7 @@ static void map_window( HWND hwnd, DWORD new_style ) XMapWindow( data->display, data->whole_window ); XFlush( data->display ); if (data->surface && data->vis.visualid != default_visual.visualid) - data->surface->funcs->flush( data->surface ); + window_surface_flush( data->surface ); } else set_xembed_flags( data, XEMBED_MAPPED );
@@ -2803,7 +2803,7 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags,
XFlush( data->display ); /* make sure changes are done before we start painting again */ if (data->surface && data->vis.visualid != default_visual.visualid) - data->surface->funcs->flush( data->surface ); + window_surface_flush( data->surface );
release_win_data( data ); } @@ -3050,7 +3050,7 @@ BOOL X11DRV_UpdateLayeredWindow( HWND hwnd, const UPDATELAYEREDWINDOWINFO *info, }
window_surface_unlock( surface ); - surface->funcs->flush( surface ); + window_surface_flush( surface );
done: window_surface_release( surface ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index cd3e8c6abdc..2721083c6ad 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -213,7 +213,7 @@ struct window_surface_funcs { void* (*get_info)( struct window_surface *surface, BITMAPINFO *info ); void (*set_region)( struct window_surface *surface, HRGN region ); - void (*flush)( struct window_surface *surface ); + BOOL (*flush)( struct window_surface *surface, const RECT *rect, const RECT *dirty ); void (*destroy)( struct window_surface *surface ); };
@@ -235,6 +235,7 @@ 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_flush( struct window_surface *surface );
/* display manager interface, used to initialize display device registry data */
I've updated the MR with a dedicated commit for the `wineandroid` behavior change, to make it more obvious, in case it breaks anything.
If I understand correctly, the perform triggers some ioctl on a dedicated thread? If we need the flush to be done asynchronously, we could also do that the same way as winemac is doing, notifying the drawing thread asynchronously, then, taking the surface lock and reading the data from that thread.
I think it's in the right ballpark. Although it's something to worry if current MR proves problematic