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 a0f65f642c2..656d555ffa4 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);