Skip to content

Commit

Permalink
Fix rendering issues when built against the 10.14 SDK.
Browse files Browse the repository at this point in the history
Before this commit, the Core Text renderer relied on a legacy behavior
of NSView to keep its content across draws. setNeedsDisplayInRect: could
be used to draw over parts of the existing content as drawing commands
were received without needing to redraw old content.

Layer-backed views lose this behavior and may be asked to redraw any or
all of their content at any time, and layer backing becomes the default
for apps built against the macOS 10.14 SDK.

This change adds a way to draw to an intermediate NSImageRep and then
draw that to the view. It's similar to the CGLayer path, but I wasn't
able to get the CGLayer path to work without hanging or crashing when I
scrolled. My best guess from looking at stack traces is that using
CGContextDrawLayerInRect to draw a layer into itself doesn't actually
copy pixels, but adds the self-draw as an action to be performed when
the CGLayer is drawn into a bitmap context. Scrolling stacks these
actions, which either hang or overflow the stack when drawn.

The new code is controlled by the MMDrawToImage user default, which is
on by default in this change. Fixes macvim-dev#751.
  • Loading branch information
s4y committed Nov 23, 2018
1 parent 8e5b2b5 commit f65660b
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/MacVim/MMAppController.m
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ + (void)initialize
[NSNumber numberWithBool:YES], MMNativeFullScreenKey,
[NSNumber numberWithDouble:0.25], MMFullScreenFadeTimeKey,
[NSNumber numberWithBool:NO], MMUseCGLayerAlwaysKey,
[NSNumber numberWithBool:YES], MMDrawToImageKey,
[NSNumber numberWithBool:YES], MMShareFindPboardKey,
nil];

Expand Down
2 changes: 2 additions & 0 deletions src/MacVim/MMCoreTextView.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
CGContextRef cgLayerContext;
NSLock *cgLayerLock;

NSBitmapImageRep *contentsImageRep;

// These are used in MMCoreTextView+ToolTip.m
id trackingRectOwner_; // (not retained)
void *trackingRectUserData_;
Expand Down
58 changes: 50 additions & 8 deletions src/MacVim/MMCoreTextView.m
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ - (void)dealloc
[drawData release]; drawData = nil;
[fontCache release]; fontCache = nil;

[contentsImageRep release]; contentsImageRep = nil;

[helper setTextView:nil];
[helper release]; helper = nil;

Expand Down Expand Up @@ -444,11 +446,18 @@ - (BOOL)_wantsKeyDownForEvent:(id)event
}

- (void)setFrameSize:(NSSize)newSize {
if (!drawPending && !NSEqualSizes(newSize, self.frame.size) && drawData.count == 0) {
if (NSEqualSizes(newSize, self.bounds.size))
return;
if (!drawPending) {
[NSAnimationContext beginGrouping];
drawPending = YES;
}
[super setFrameSize:newSize];
if (contentsImageRep || [[NSUserDefaults standardUserDefaults]
boolForKey:MMDrawToImageKey]) {
[contentsImageRep release];
contentsImageRep = [[self bitmapImageRepForCachingDisplayInRect:self.bounds] retain];
}
}

- (void)keyDown:(NSEvent *)event
Expand Down Expand Up @@ -611,7 +620,19 @@ - (void)drawRect:(NSRect)rect
NSGraphicsContext *context = [NSGraphicsContext currentContext];
[context setShouldAntialias:antialias];

if (cgLayerEnabled && drawData.count == 0) {
if (contentsImageRep) {
const NSRect *rects;
NSInteger count;
[self getRectsBeingDrawn:&rects count:&count];
for (size_t i = 0; i < count; i++) {
[contentsImageRep drawInRect:rects[i]
fromRect:rects[i]
operation:NSCompositingOperationCopy
fraction:1.0
respectFlipped:YES
hints:nil];
}
} else if (cgLayerEnabled && drawData.count == 0) {
// during a live resize, we will have around a stale layer until the
// refresh messages travel back from the vim process. We push the old
// layer in at an offset to get rid of jitter due to lines changing
Expand Down Expand Up @@ -653,7 +674,12 @@ - (void)drawRect:(NSRect)rect

- (void)performBatchDrawWithData:(NSData *)data
{
if (cgLayerEnabled && drawData.count == 0 && [self getCGContext]) {
if (contentsImageRep) {
[NSGraphicsContext saveGraphicsState];
NSGraphicsContext.currentContext = [NSGraphicsContext graphicsContextWithBitmapImageRep:contentsImageRep];
[self batchDrawData:data];
[NSGraphicsContext restoreGraphicsState];
} else if (cgLayerEnabled && drawData.count == 0 && [self getCGContext]) {
[cgLayerLock lock];
[self batchDrawData:data];
[cgLayerLock unlock];
Expand All @@ -662,13 +688,20 @@ - (void)performBatchDrawWithData:(NSData *)data
[self setNeedsDisplay:YES];
}
if (drawPending) {
[NSAnimationContext endGrouping];
drawPending = NO;
int r = maxRows, c = maxColumns;
[self constrainRows:&r columns:&c toSize:[self desiredSize]];
if (r == maxRows && c == maxColumns) {
[NSAnimationContext endGrouping];
drawPending = NO;
}
}
}

- (void)setCGLayerEnabled:(BOOL)enabled
{
if (contentsImageRep)
return;

cgLayerEnabled = enabled;

if (!cgLayerEnabled)
Expand Down Expand Up @@ -710,13 +743,13 @@ - (CGContextRef)getCGContext

- (void)setNeedsDisplayCGLayerInRect:(CGRect)rect
{
if (cgLayerEnabled)
if (cgLayerEnabled || contentsImageRep)
[self setNeedsDisplayInRect:rect];
}

- (void)setNeedsDisplayCGLayer:(BOOL)flag
{
if (cgLayerEnabled)
if (cgLayerEnabled || contentsImageRep)
[self setNeedsDisplay:flag];
}

Expand Down Expand Up @@ -1491,7 +1524,16 @@ - (void)drawString:(const UniChar *)chars length:(UniCharCount)length

- (void)scrollRect:(NSRect)rect lineCount:(int)count
{
if (cgLayerEnabled) {
if (contentsImageRep) {
NSRect toRect = NSOffsetRect(rect, 0, -count * cellSize.height);
[contentsImageRep drawInRect:toRect
fromRect:rect
operation:NSCompositingOperationCopy
fraction:1.0
respectFlipped:NO
hints:nil];
[self setNeedsDisplayCGLayerInRect:toRect];
} else if (cgLayerEnabled) {
CGContextRef context = [self getCGContext];
int yOffset = count * cellSize.height;
NSRect clipRect = rect;
Expand Down
1 change: 1 addition & 0 deletions src/MacVim/Miscellaneous.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ extern NSString *MMNativeFullScreenKey;
extern NSString *MMUseMouseTimeKey;
extern NSString *MMFullScreenFadeTimeKey;
extern NSString *MMUseCGLayerAlwaysKey;
extern NSString *MMDrawToImageKey;


// Enum for MMUntitledWindowKey
Expand Down
1 change: 1 addition & 0 deletions src/MacVim/Miscellaneous.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
NSString *MMUseMouseTimeKey = @"MMUseMouseTime";
NSString *MMFullScreenFadeTimeKey = @"MMFullScreenFadeTime";
NSString *MMUseCGLayerAlwaysKey = @"MMUseCGLayerAlways";
NSString *MMDrawToImageKey = @"MMDrawToImage";



Expand Down

0 comments on commit f65660b

Please sign in to comment.