mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 04:48:36 +00:00
winemac: Push window surface image updates to the main thread.
This commit is contained in:
parent
e7a82cc24b
commit
66051c2aa1
|
@ -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,12 @@ - (void) updateLayer
|
|||
}
|
||||
}
|
||||
|
||||
- (void) setColorImage:(CGImageRef)image
|
||||
{
|
||||
CGImageRelease(colorImage);
|
||||
colorImage = CGImageRetain(image);
|
||||
}
|
||||
|
||||
- (void) viewWillDraw
|
||||
{
|
||||
[super viewWillDraw];
|
||||
|
@ -3493,19 +3516,26 @@ 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, CGImageRef image, CGRect rect, CGRect dirty)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
WineWindow* window = (WineWindow*)w;
|
||||
|
||||
CGImageRetain(image);
|
||||
|
||||
OnMainThreadAsync(^{
|
||||
[[window contentView] setNeedsDisplayInRect:NSRectFromCGRect(cgrect_mac_from_win(rect))];
|
||||
WineContentView *view = [window contentView];
|
||||
|
||||
[view setColorImage:image];
|
||||
[view setNeedsDisplayInRect:NSRectFromCGRect(cgrect_mac_from_win(dirty))];
|
||||
|
||||
CGImageRelease(image);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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, CGImageRef image, CGRect rect, CGRect dirty);
|
||||
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,
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
@ -115,17 +108,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, image, cgrect_from_rect(*rect), cgrect_from_rect(*dirty));
|
||||
CGImageRelease(image);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -136,7 +130,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);
|
||||
}
|
||||
|
@ -231,52 +224,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
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue