Instead of accessing the surface with macdrv_get_surface_display_image.
-- v4: winemac: Remove now unnecessary cocoa window surface pointer. winemac: Push window surface image updates to the main thread. winemac: Create window surface CGImageRef on surface flush. winemac: Create a provider for the surface and a HBITMAP wrapping it. winemac: Remove unused macdrv_get_surface_display_image copy_data parameter.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/cocoa_window.m | 2 +- dlls/winemac.drv/macdrv_cocoa.h | 2 +- dlls/winemac.drv/surface.c | 12 ++---------- 3 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 61a6ab2cd4e..34c39bb3d76 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -532,7 +532,7 @@ - (void) updateLayer 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, + image = macdrv_get_surface_display_image(window.surface, &imageRect, window.colorKeyed, window.colorKeyRed, window.colorKeyGreen, window.colorKeyBlue);
if (image) diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index ba5803f88dc..bdc7d9980e1 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -553,7 +553,7 @@ extern void macdrv_order_cocoa_window(macdrv_window w, macdrv_window prev, 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, 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, +extern CGImageRef macdrv_get_surface_display_image(struct window_surface *window_surface, CGRect *rect, int color_keyed, CGFloat key_red, CGFloat key_green, CGFloat key_blue); 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); diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 37e2c466926..4e8b3c4824f 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -191,7 +191,7 @@ void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha * must not use Win32 or Wine functions, including debug * logging. */ -CGImageRef macdrv_get_surface_display_image(struct window_surface *window_surface, CGRect *rect, int copy_data, int color_keyed, +CGImageRef macdrv_get_surface_display_image(struct window_surface *window_surface, CGRect *rect, int color_keyed, CGFloat key_red, CGFloat key_green, CGFloat key_blue) { CGImageRef cgimage = NULL; @@ -220,15 +220,7 @@ CGImageRef macdrv_get_surface_display_image(struct window_surface *window_surfac offset = CGRectGetMinX(visrect) * 4 + CGRectGetMinY(visrect) * bytes_per_row; size = min(CGRectGetHeight(visrect) * bytes_per_row, surface->info.bmiHeader.biSizeImage - offset); - - if (copy_data) - { - CFDataRef data = CFDataCreate(NULL, (UInt8 *)window_surface->color_bits + offset, size); - provider = CGDataProviderCreateWithCFData(data); - CFRelease(data); - } - else - provider = CGDataProviderCreateWithData(NULL, (UInt8 *)window_surface->color_bits + offset, size, NULL); + provider = CGDataProviderCreateWithData(NULL, (UInt8 *)window_surface->color_bits + offset, size, NULL);
alphaInfo = surface->use_alpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst; cgimage = CGImageCreate(CGRectGetWidth(visrect), CGRectGetHeight(visrect),
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/surface.c | 55 ++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-)
diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 4e8b3c4824f..d215e126110 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -65,11 +65,31 @@ struct macdrv_window_surface struct window_surface header; macdrv_window window; BOOL use_alpha; + CGDataProviderRef provider; BITMAPINFO info; /* variable size, must be last */ };
static struct macdrv_window_surface *get_mac_surface(struct window_surface *surface);
+static void data_provider_destroy(void *info, const void *data, size_t size) +{ + free(info); +} + +static CGDataProviderRef data_provider_create(size_t size, void **bits) +{ + CGDataProviderRef provider; + void *data; + + if (!(data = malloc(size))) return NULL; + + provider = CGDataProviderCreateWithData(data, data, size, data_provider_destroy); + if (!provider) free(data); + else *bits = data; + + return provider; +} + /*********************************************************************** * macdrv_surface_get_bitmap_info */ @@ -107,6 +127,7 @@ static void macdrv_surface_destroy(struct window_surface *window_surface) struct macdrv_window_surface *surface = get_mac_surface(window_surface);
TRACE("freeing %p\n", surface); + CGDataProviderRelease(surface->provider); free(surface); }
@@ -130,11 +151,16 @@ static struct macdrv_window_surface *get_mac_surface(struct window_surface *surf struct window_surface *create_surface(HWND hwnd, macdrv_window window, const RECT *rect, struct window_surface *old_surface, BOOL use_alpha) { - struct macdrv_window_surface *surface; + struct macdrv_window_surface *surface = NULL; int width = rect->right - rect->left, height = rect->bottom - rect->top; DWORD window_background; + D3DKMT_CREATEDCFROMMEMORY desc = {.Format = D3DDDIFMT_A8R8G8B8}; char buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; BITMAPINFO *info = (BITMAPINFO *)buffer; + CGDataProviderRef provider; + HBITMAP bitmap = 0; + UINT status; + void *bits;
memset(info, 0, sizeof(*info)); info->bmiHeader.biSize = sizeof(info->bmiHeader); @@ -145,14 +171,31 @@ struct window_surface *create_surface(HWND hwnd, macdrv_window window, const REC info->bmiHeader.biSizeImage = get_dib_image_size(info); info->bmiHeader.biCompression = BI_RGB;
- surface = calloc(1, FIELD_OFFSET(struct macdrv_window_surface, info.bmiColors[3])); - if (!surface) return NULL; - if (!window_surface_init(&surface->header, &macdrv_surface_funcs, hwnd, rect, info, 0)) goto failed; + if (!(provider = data_provider_create(info->bmiHeader.biSizeImage, &bits))) return NULL; + + /* wrap the data in a HBITMAP so we can write to the surface pixels directly */ + desc.Width = info->bmiHeader.biWidth; + desc.Height = abs(info->bmiHeader.biHeight); + desc.Pitch = info->bmiHeader.biSizeImage / abs(info->bmiHeader.biHeight); + desc.pMemory = bits; + desc.hDeviceDc = NtUserGetDCEx(hwnd, 0, DCX_CACHE | DCX_WINDOW); + if ((status = NtGdiDdDDICreateDCFromMemory(&desc))) + ERR("Failed to create HBITMAP, status %#x\n", status); + else + { + bitmap = desc.hBitmap; + NtGdiDeleteObjectApp(desc.hDc); + } + if (desc.hDeviceDc) NtUserReleaseDC(hwnd, desc.hDeviceDc); + + if (!(surface = calloc(1, FIELD_OFFSET(struct macdrv_window_surface, info.bmiColors[3])))) goto failed; + if (!window_surface_init(&surface->header, &macdrv_surface_funcs, hwnd, rect, info, bitmap)) goto failed; memcpy(&surface->info, info, offsetof(BITMAPINFO, bmiColors[3]));
surface->window = window; if (old_surface) surface->header.bounds = old_surface->bounds; surface->use_alpha = use_alpha; + surface->provider = provider;
window_background = macdrv_window_background_color(); memset_pattern4(surface->header.color_bits, &window_background, info->bmiHeader.biSizeImage); @@ -163,7 +206,9 @@ struct window_surface *create_surface(HWND hwnd, macdrv_window window, const REC return &surface->header;
failed: - window_surface_release(&surface->header); + if (surface) window_surface_release(&surface->header); + if (bitmap) NtGdiDeleteObjectApp(bitmap); + CGDataProviderRelease(provider); return NULL; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/cocoa_window.m | 42 ++++++++++++++++---- dlls/winemac.drv/macdrv_cocoa.h | 4 +- dlls/winemac.drv/surface.c | 69 ++++----------------------------- 3 files changed, 44 insertions(+), 71 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 34c39bb3d76..f8204d50911 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -365,6 +365,8 @@ - (id) initWithFrame:(NSRect)frame device:(id<MTLDevice>)device;
@interface WineContentView : WineBaseView <NSTextInputClient, NSViewLayerContentScaleDelegate> { + CGImageRef colorImage; + NSMutableArray* glContexts; NSMutableArray* pendingGlContexts; BOOL _everHadGLContext; @@ -501,6 +503,7 @@ - (void) dealloc [markedText release]; [glContexts release]; [pendingGlContexts release]; + CGImageRelease(colorImage); [super dealloc]; }
@@ -517,7 +520,7 @@ - (BOOL) wantsUpdateLayer - (void) updateLayer { WineWindow* window = (WineWindow*)[self window]; - CGImageRef image = NULL; + CGImageRef image; CGRect imageRect; CALayer* layer = [self layer];
@@ -532,8 +535,22 @@ - (void) updateLayer imageRect.origin.y *= layer.contentsScale; imageRect.size.width *= layer.contentsScale; imageRect.size.height *= layer.contentsScale; - image = macdrv_get_surface_display_image(window.surface, &imageRect, window.colorKeyed, - window.colorKeyRed, window.colorKeyGreen, window.colorKeyBlue); + + image = CGImageCreateWithImageInRect(colorImage, imageRect); + + if (window.colorKeyed) + { + CGImageRef maskedImage; + CGFloat components[] = { window.colorKeyRed - 0.5, window.colorKeyRed + 0.5, + window.colorKeyGreen - 0.5, window.colorKeyGreen + 0.5, + window.colorKeyBlue - 0.5, window.colorKeyBlue + 0.5 }; + maskedImage = CGImageCreateWithMaskingColors(image, components); + if (maskedImage) + { + CGImageRelease(image); + image = maskedImage; + } + }
if (image) { @@ -552,6 +569,13 @@ - (void) updateLayer } }
+ - (CGImageRef) setColorImage:(CGImageRef)image + { + CGImageRef previous = colorImage; + colorImage = image; + return previous; + } + - (void) viewWillDraw { [super viewWillDraw]; @@ -3493,19 +3517,23 @@ void macdrv_set_window_surface(macdrv_window w, struct window_surface *window_su }
/*********************************************************************** - * macdrv_window_needs_display + * macdrv_window_set_color_image * - * Mark a window as needing display in a specified rect (in non-client + * Push a window surface color pixel update in a specified rect (in non-client * area coordinates). */ -void macdrv_window_needs_display(macdrv_window w, CGRect rect) +void macdrv_window_set_color_image(macdrv_window w, CGRect rect, CGImageRef image) { @autoreleasepool { WineWindow* window = (WineWindow*)w;
+ CGImageRetain(image); + OnMainThreadAsync(^{ - [[window contentView] setNeedsDisplayInRect:NSRectFromCGRect(cgrect_mac_from_win(rect))]; + WineContentView *view = [window contentView]; + CGImageRelease([view setColorImage:image]); + [view setNeedsDisplayInRect:NSRectFromCGRect(cgrect_mac_from_win(rect))]; }); } } diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index bdc7d9980e1..ee88f99002a 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -553,9 +553,7 @@ extern void macdrv_order_cocoa_window(macdrv_window w, macdrv_window prev, 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, struct window_surface *window_surface); -extern CGImageRef macdrv_get_surface_display_image(struct window_surface *window_surface, CGRect *rect, int color_keyed, - CGFloat key_red, CGFloat key_green, CGFloat key_blue); -extern void macdrv_window_needs_display(macdrv_window w, CGRect rect); +extern void macdrv_window_set_color_image(macdrv_window w, CGRect rect, CGImageRef image); 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); extern void macdrv_set_window_color_key(macdrv_window w, CGFloat keyRed, CGFloat keyGreen, diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 5082bd2ebe2..56bdf5eeb30 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -53,12 +53,6 @@ static inline int get_dib_image_size(const BITMAPINFO *info) * abs(info->bmiHeader.biHeight); }
-static inline void reset_bounds(RECT *bounds) -{ - bounds->left = bounds->top = INT_MAX; - bounds->right = bounds->bottom = INT_MIN; -} -
struct macdrv_window_surface { @@ -66,7 +60,6 @@ struct macdrv_window_surface macdrv_window window; BOOL use_alpha; CGDataProviderRef provider; - CGImageRef color_image; BITMAPINFO info; /* variable size, must be last */ };
@@ -119,17 +112,18 @@ static BOOL macdrv_surface_flush(struct window_surface *window_surface, const RE CGImageAlphaInfo alpha_info = (surface->use_alpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst); BITMAPINFO *color_info = &surface->info; CGColorSpaceRef colorspace; - - if (surface->color_image) CGImageRelease(surface->color_image); + CGImageRef image;
colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); - surface->color_image = CGImageCreate(color_info->bmiHeader.biWidth, abs(color_info->bmiHeader.biHeight), 8, 32, - color_info->bmiHeader.biSizeImage / abs(color_info->bmiHeader.biHeight), colorspace, - alpha_info | kCGBitmapByteOrder32Little, surface->provider, NULL, retina_on, kCGRenderingIntentDefault); + image = CGImageCreate(color_info->bmiHeader.biWidth, abs(color_info->bmiHeader.biHeight), 8, 32, + color_info->bmiHeader.biSizeImage / abs(color_info->bmiHeader.biHeight), colorspace, + alpha_info | kCGBitmapByteOrder32Little, surface->provider, NULL, retina_on, kCGRenderingIntentDefault); CGColorSpaceRelease(colorspace);
- macdrv_window_needs_display(surface->window, cgrect_from_rect(*dirty)); - return FALSE; /* bounds are reset asynchronously, from macdrv_get_surface_display_image */ + macdrv_window_set_color_image(surface->window, cgrect_from_rect(*dirty), image); + CGImageRelease(image); + + return TRUE; }
/*********************************************************************** @@ -140,7 +134,6 @@ static void macdrv_surface_destroy(struct window_surface *window_surface) struct macdrv_window_surface *surface = get_mac_surface(window_surface);
TRACE("freeing %p\n", surface); - if (surface->color_image) CGImageRelease(surface->color_image); CGDataProviderRelease(surface->provider); free(surface); } @@ -235,52 +228,6 @@ void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha if (surface) surface->use_alpha = use_alpha; }
-/*********************************************************************** - * create_surface_image - * - * Caller must hold the surface lock. On input, *rect is the requested - * image rect, relative to the window whole_rect, a.k.a. visible_rect. - * On output, it's been intersected with that part backed by the surface - * and is the actual size of the returned image. copy_data indicates if - * the caller will keep the returned image beyond the point where the - * surface bits can be guaranteed to remain valid and unchanged. If so, - * the bits are copied instead of merely referenced by the image. - * - * IMPORTANT: This function is called from non-Wine threads, so it - * must not use Win32 or Wine functions, including debug - * logging. - */ -CGImageRef macdrv_get_surface_display_image(struct window_surface *window_surface, CGRect *rect, 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); - - pthread_mutex_lock(&window_surface->mutex); - if (surface->color_image && !IsRectEmpty(&window_surface->bounds)) - { - cgimage = CGImageCreateWithImageInRect(surface->color_image, *rect); - - if (color_keyed) - { - CGImageRef maskedImage; - CGFloat components[] = { key_red - 0.5, key_red + 0.5, - key_green - 0.5, key_green + 0.5, - key_blue - 0.5, key_blue + 0.5 }; - maskedImage = CGImageCreateWithMaskingColors(cgimage, components); - if (maskedImage) - { - CGImageRelease(cgimage); - cgimage = maskedImage; - } - } - } - - reset_bounds(&window_surface->bounds); - pthread_mutex_unlock(&window_surface->mutex); - return cgimage; -} - /*********************************************************************** * surface_clip_to_visible_rect *
From: Rémi Bernon rbernon@codeweavers.com
Avoid accessing the surface color bits field from macdrv_get_surface_display_image. --- dlls/winemac.drv/surface.c | 47 +++++++++++++------------------------- 1 file changed, 16 insertions(+), 31 deletions(-)
diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index d215e126110..5082bd2ebe2 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -66,6 +66,7 @@ struct macdrv_window_surface macdrv_window window; BOOL use_alpha; CGDataProviderRef provider; + CGImageRef color_image; BITMAPINFO info; /* variable size, must be last */ };
@@ -115,6 +116,18 @@ static void macdrv_surface_set_clip(struct window_surface *window_surface, const 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); + CGImageAlphaInfo alpha_info = (surface->use_alpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst); + BITMAPINFO *color_info = &surface->info; + CGColorSpaceRef colorspace; + + if (surface->color_image) CGImageRelease(surface->color_image); + + colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); + surface->color_image = CGImageCreate(color_info->bmiHeader.biWidth, abs(color_info->bmiHeader.biHeight), 8, 32, + color_info->bmiHeader.biSizeImage / abs(color_info->bmiHeader.biHeight), colorspace, + alpha_info | kCGBitmapByteOrder32Little, surface->provider, NULL, retina_on, kCGRenderingIntentDefault); + CGColorSpaceRelease(colorspace); + macdrv_window_needs_display(surface->window, cgrect_from_rect(*dirty)); return FALSE; /* bounds are reset asynchronously, from macdrv_get_surface_display_image */ } @@ -127,6 +140,7 @@ static void macdrv_surface_destroy(struct window_surface *window_surface) struct macdrv_window_surface *surface = get_mac_surface(window_surface);
TRACE("freeing %p\n", surface); + if (surface->color_image) CGImageRelease(surface->color_image); CGDataProviderRelease(surface->provider); free(surface); } @@ -241,39 +255,11 @@ CGImageRef macdrv_get_surface_display_image(struct window_surface *window_surfac { CGImageRef cgimage = NULL; struct macdrv_window_surface *surface = get_mac_surface(window_surface); - RECT surface_rect = window_surface->rect; - int width, height;
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)) + if (surface->color_image && !IsRectEmpty(&window_surface->bounds)) { - CGRect visrect; - CGColorSpaceRef colorspace; - CGDataProviderRef provider; - int bytes_per_row, offset, size; - CGImageAlphaInfo alphaInfo; - - visrect = CGRectOffset(*rect, -surface_rect.left, -surface_rect.top); - - colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); - bytes_per_row = get_dib_stride(width, 32); - offset = CGRectGetMinX(visrect) * 4 + CGRectGetMinY(visrect) * bytes_per_row; - size = min(CGRectGetHeight(visrect) * bytes_per_row, - surface->info.bmiHeader.biSizeImage - offset); - provider = CGDataProviderCreateWithData(NULL, (UInt8 *)window_surface->color_bits + offset, size, NULL); - - alphaInfo = surface->use_alpha ? kCGImageAlphaPremultipliedFirst : kCGImageAlphaNoneSkipFirst; - cgimage = CGImageCreate(CGRectGetWidth(visrect), CGRectGetHeight(visrect), - 8, 32, bytes_per_row, colorspace, - alphaInfo | kCGBitmapByteOrder32Little, - provider, NULL, retina_on, kCGRenderingIntentDefault); - CGDataProviderRelease(provider); - CGColorSpaceRelease(colorspace); + cgimage = CGImageCreateWithImageInRect(surface->color_image, *rect);
if (color_keyed) { @@ -290,7 +276,6 @@ CGImageRef macdrv_get_surface_display_image(struct window_surface *window_surfac } }
-done: reset_bounds(&window_surface->bounds); pthread_mutex_unlock(&window_surface->mutex); return cgimage;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/cocoa_window.h | 3 --- dlls/winemac.drv/cocoa_window.m | 19 +------------------ dlls/winemac.drv/macdrv_cocoa.h | 1 - dlls/winemac.drv/window.c | 2 -- 4 files changed, 1 insertion(+), 24 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.h b/dlls/winemac.drv/cocoa_window.h index 9539e4ebdd7..b5168d0c128 100644 --- a/dlls/winemac.drv/cocoa_window.h +++ b/dlls/winemac.drv/cocoa_window.h @@ -44,9 +44,6 @@ @interface WineWindow : NSPanel <NSWindowDelegate> void* hwnd; WineEventQueue* queue;
- void* surface; - pthread_mutex_t* surface_mutex; - CGDirectDisplayID _lastDisplayID; NSTimeInterval _lastDisplayTime;
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index f8204d50911..09e9b2a3a9e 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -410,8 +410,6 @@ @interface WineWindow () @property (nonatomic) void* hwnd; @property (retain, readwrite, nonatomic) WineEventQueue* queue;
-@property (nonatomic) void* surface; - @property (nonatomic) BOOL shapeChangedSinceLastDraw; @property (readonly, nonatomic) BOOL needsTransparency;
@@ -527,7 +525,7 @@ - (void) updateLayer if ([window contentView] != self) return;
- if (window.closing || !window.surface) + if (window.closing) return;
imageRect = layer.bounds; @@ -1022,7 +1020,6 @@ @implementation WineWindow
@synthesize disabled, noForeground, preventsAppActivation, floating, fullscreen, fakingClose, closing, latentParentWindow, hwnd, queue; @synthesize drawnSinceShown; - @synthesize surface; @synthesize shapeChangedSinceLastDraw; @synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue; @synthesize usePerPixelAlpha; @@ -3501,20 +3498,6 @@ void macdrv_set_cocoa_parent_window(macdrv_window w, macdrv_window parent) }); }
-/*********************************************************************** - * macdrv_set_window_surface - */ -void macdrv_set_window_surface(macdrv_window w, struct window_surface *window_surface) -{ -@autoreleasepool -{ - WineWindow* window = (WineWindow*)w; - - OnMainThread(^{ - window.surface = window_surface; - }); -} -}
/*********************************************************************** * macdrv_window_set_color_image diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h index ee88f99002a..abf01888bdb 100644 --- a/dlls/winemac.drv/macdrv_cocoa.h +++ b/dlls/winemac.drv/macdrv_cocoa.h @@ -552,7 +552,6 @@ 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, struct window_surface *window_surface); extern void macdrv_window_set_color_image(macdrv_window w, CGRect rect, CGImageRef image); 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/window.c b/dlls/winemac.drv/window.c index 2f3d937b83c..81c3bb593e5 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1884,7 +1884,6 @@ BOOL macdrv_CreateLayeredWindow(HWND hwnd, const RECT *window_rect, COLORREF col if (!surface || !EqualRect(&surface->rect, &rect)) { data->surface = create_surface(data->hwnd, data->cocoa_window, &rect, NULL, TRUE); - macdrv_set_window_surface(data->cocoa_window, data->surface); if (surface) window_surface_release(surface); surface = data->surface; if (data->unminimized_surface) @@ -2057,7 +2056,6 @@ void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, } else { - macdrv_set_window_surface(data->cocoa_window, surface); if (data->unminimized_surface) { window_surface_release(data->unminimized_surface);
v3: Don't use a property, manually retain / release the image refs, remove a couple of NULL checks as CGImage functions allow NULL pointers.
Brendan Shanks (@bshanks) commented about dlls/winemac.drv/cocoa_window.m:
} }
- (CGImageRef) setColorImage:(CGImageRef)image
- {
CGImageRef previous = colorImage;
colorImage = image;
return previous;
I think it would be better to do the release/retain calls here in the setter, rather than in `macdrv_window_set_color_image()`. Then the setter can also return void.
Brendan Shanks (@bshanks) commented about dlls/winemac.drv/surface.c:
+}
+static CGDataProviderRef data_provider_create(size_t size, void **bits) +{
- CGDataProviderRef provider;
- void *data;
- if (!(data = malloc(size))) return NULL;
- provider = CGDataProviderCreateWithData(data, data, size, data_provider_destroy);
- if (!provider) free(data);
- else *bits = data;
- return provider;
+}
Not a big deal, but you could avoid needing the destroy callback by using a CFMutableData instead of malloc(). Create a CFMutableData, set the length, set *bits to the byte ptr, create the CGDataProvider with the CFMutableData, then release it.
On Fri Jun 14 19:01:33 2024 +0000, Rémi Bernon wrote:
Fwiw I'm recreating the images on flush because I think they are supposed to be immutable, and there's some caching that prevent updates from being displayed otherwise. The data provider should not have this restriction and can still own the data. This should work for now, but it also means that we won't be able to use shared NT sections to back the image data that way later on, as the last provider reference may be released from a non-Wine thread. We'll have to figure to do that another way, or make copies somewhere.
I haven't done any work on this, but I've had the idea of making the main thread into a Wine thread before it runs the Mac runloop. This would also allow use of Wine logging functions and avoid signal handlers crashing if the main thread segfaults, which would both be nice improvements.