Chip Davis : winemac.drv: Use a mask layer to support window regions.
Module: wine Branch: master Commit: 01f027b2db3196a8fe43be3d6718227794362985 URL: https://source.winehq.org/git/wine.git/?a=commit;h=01f027b2db3196a8fe43be3d6... Author: Chip Davis <cdavis(a)codeweavers.com> Date: Wed Sep 1 09:28:21 2021 -0500 winemac.drv: Use a mask layer to support window regions. Signed-off-by: Chip Davis <cdavis(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/winemac.drv/cocoa_window.h | 2 - dlls/winemac.drv/cocoa_window.m | 90 ++++++++++++++++++++--------------------- 2 files changed, 45 insertions(+), 47 deletions(-) diff --git a/dlls/winemac.drv/cocoa_window.h b/dlls/winemac.drv/cocoa_window.h index f9c3902dc36..d04961f8251 100644 --- a/dlls/winemac.drv/cocoa_window.h +++ b/dlls/winemac.drv/cocoa_window.h @@ -51,8 +51,6 @@ NSRect wineFrame; NSRect roundedWineFrame; - NSBezierPath* shape; - NSData* shapeData; BOOL shapeChangedSinceLastDraw; BOOL colorKeyed; diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 29a5abe6344..013af035a12 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -321,6 +321,22 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi #endif +(a)interface CAShapeLayer (WineShapeMaskExtensions) + +(a)property(readonly, nonatomic, getter=isEmptyShaped) BOOL emptyShaped; + +(a)end + +(a)implementation CAShapeLayer (WineShapeMaskExtensions) + + - (BOOL) isEmptyShaped + { + return CGRectEqualToRect(CGPathGetBoundingBox(self.path), CGRectZero); + } + +(a)end + + @interface WineBaseView : NSView @end @@ -388,8 +404,6 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi @property (nonatomic) void* surface; @property (nonatomic) pthread_mutex_t* surface_mutex; -(a)property (copy, nonatomic) NSBezierPath* shape; -(a)property (copy, nonatomic) NSData* shapeData; @property (nonatomic) BOOL shapeChangedSinceLastDraw; @property (readonly, nonatomic) BOOL needsTransparency; @@ -402,6 +416,8 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi @property (readonly, copy, nonatomic) NSArray* childWineWindows; + - (void) setShape:(CGPathRef)newShape; + - (void) updateForGLSubviews; - (BOOL) becameEligibleParentOrChild; @@ -494,17 +510,6 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi if ([window contentView] != self) return; - if (window.drawnSinceShown && window.shapeChangedSinceLastDraw && window.shape && !window.colorKeyed && !window.usePerPixelAlpha) - { - [[NSColor clearColor] setFill]; - NSRectFill(rect); - - [window.shape addClip]; - - [[NSColor windowBackgroundColor] setFill]; - NSRectFill(rect); - } - if (window.surface && window.surface_mutex && !pthread_mutex_lock(window.surface_mutex)) { @@ -517,8 +522,6 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi CGContextRef context; int i; - [window.shape addClip]; - context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; CGContextSetBlendMode(context, kCGBlendModeCopy); CGContextSetInterpolationQuality(context, retina_on ? kCGInterpolationHigh : kCGInterpolationNone); @@ -968,7 +971,7 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi @synthesize disabled, noActivate, floating, fullscreen, fakingClose, latentParentWindow, hwnd, queue; @synthesize drawnSinceShown; @synthesize surface, surface_mutex; - @synthesize shape, shapeData, shapeChangedSinceLastDraw; + @synthesize shapeChangedSinceLastDraw; @synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue; @synthesize usePerPixelAlpha; @synthesize imeData, commandDone; @@ -1069,8 +1072,6 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi [queue release]; [latentChildWindows release]; [latentParentWindow release]; - [shape release]; - [shapeData release]; [super dealloc]; } @@ -2011,7 +2012,7 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi - (BOOL) needsTransparency { - return self.shape || self.colorKeyed || self.usePerPixelAlpha || + return self.contentView.layer.mask || self.colorKeyed || self.usePerPixelAlpha || (gl_surface_mode == GL_SURFACE_BEHIND && [(WineContentView*)self.contentView hasGLDescendant]); } @@ -2033,22 +2034,27 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi } } - - (void) setShape:(NSBezierPath*)newShape + - (void) setShape:(CGPathRef)newShape { - if (shape == newShape) return; + CALayer* layer = [[self contentView] layer]; + CAShapeLayer* mask = (CAShapeLayer*)layer.mask; + if (CGPathEqualToPath(newShape, mask.path)) return; - if (shape) - { - [[self contentView] setNeedsDisplayInRect:[shape bounds]]; - [shape release]; - } + if (newShape && !layer.mask) + layer.mask = mask = [CAShapeLayer layer]; + else if (!newShape) + layer.mask = mask = nil; + + if (mask.path) + [[self contentView] setNeedsDisplayInRect:NSRectFromCGRect(CGPathGetBoundingBox(mask.path))]; if (newShape) - [[self contentView] setNeedsDisplayInRect:[newShape bounds]]; + [[self contentView] setNeedsDisplayInRect:NSRectFromCGRect(CGPathGetBoundingBox(newShape))]; - shape = [newShape copy]; + mask.path = newShape; self.shapeChangedSinceLastDraw = TRUE; [self checkTransparency]; + [self checkEmptyShaped]; } - (void) makeFocused:(BOOL)activate @@ -2245,7 +2251,8 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi - (BOOL) isEmptyShaped { - return (self.shapeData.length == sizeof(CGRectZero) && !memcmp(self.shapeData.bytes, &CGRectZero, sizeof(CGRectZero))); + CAShapeLayer* mask = (CAShapeLayer*)[[self contentView] layer].mask; + return ([mask isEmptyShaped]); } - (BOOL) canProvideSnapshot @@ -2648,8 +2655,7 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi [transform scaleBy:scale]; - if (shape) - [shape transformUsingAffineTransform:transform]; + [[self contentView] layer].mask.contentsScale = mode ? 2.0 : 1.0; for (WineBaseView* subview in [self.contentView subviews]) { @@ -3453,25 +3459,19 @@ void macdrv_set_window_shape(macdrv_window w, const CGRect *rects, int count) OnMainThread(^{ if (!rects || !count) { - window.shape = nil; - window.shapeData = nil; + [window setShape:NULL]; [window checkEmptyShaped]; } else { - size_t length = sizeof(*rects) * count; - if (window.shapeData.length != length || memcmp(window.shapeData.bytes, rects, length)) - { - NSBezierPath* path; - unsigned int i; + CGMutablePathRef path; + unsigned int i; - path = [NSBezierPath bezierPath]; - for (i = 0; i < count; i++) - [path appendBezierPathWithRect:NSRectFromCGRect(cgrect_mac_from_win(rects[i]))]; - window.shape = path; - window.shapeData = [NSData dataWithBytes:rects length:length]; - [window checkEmptyShaped]; - } + path = CGPathCreateMutable(); + for (i = 0; i < count; i++) + CGPathAddRect(path, NULL, cgrect_mac_from_win(rects[i])); + [window setShape:path]; + CGPathRelease(path); } });
participants (1)
-
Alexandre Julliard