Skip to content

Commit 2fb08d3

Browse files
Ben Osheroffsplhack
authored andcommitted
draw the layer from the background thread
during layer draw we know what parts of the screen will need repainting, so we can call set setNeedsDisplayInRect and do a partial draw of the screen. This brings down overall keyDown-to-drawRect(finish) latency when in "layer" mode from 17ms to 4.5ms (about what the "stock" CoreText renderer does).
1 parent 675446d commit 2fb08d3

File tree

2 files changed

+49
-19
lines changed

2 files changed

+49
-19
lines changed

src/MacVim/MMCoreTextView.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
BOOL cgLayerEnabled;
4343
CGLayerRef cgLayer;
4444
CGContextRef cgLayerContext;
45+
NSLock *cgLayerLock;
4546

4647
// These are used in MMCoreTextView+ToolTip.m
4748
id trackingRectOwner_; // (not retained)

src/MacVim/MMCoreTextView.m

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ - (id)initWithFrame:(NSRect)frame
132132
if (!(self = [super initWithFrame:frame]))
133133
return nil;
134134

135+
cgLayerLock = [NSLock new];
136+
135137
// NOTE! It does not matter which font is set here, Vim will set its
136138
// own font on startup anyway. Just set some bogus values.
137139
font = [[NSFont userFixedPitchFontOfSize:0] retain];
@@ -586,18 +588,12 @@ - (void)drawRect:(NSRect)rect
586588
NSGraphicsContext *context = [NSGraphicsContext currentContext];
587589
[context setShouldAntialias:antialias];
588590

589-
id data;
590-
NSEnumerator *e = [drawData objectEnumerator];
591-
while ((data = [e nextObject]))
592-
[self batchDrawData:data];
593-
594-
[drawData removeAllObjects];
595-
596-
if (cgLayerEnabled) {
591+
if (cgLayerEnabled && drawData.count == 0) {
597592
// during a live resize, we will have around a stale layer until the
598593
// refresh messages travel back from the vim process. We push the old
599594
// layer in at an offset to get rid of jitter due to lines changing
600595
// position.
596+
[cgLayerLock lock];
601597
CGLayerRef l = [self getCGLayer];
602598
CGSize cgLayerSize = CGLayerGetSize(l);
603599
CGSize frameSize = [self frame].size;
@@ -608,22 +604,45 @@ - (void)drawRect:(NSRect)rect
608604
cgLayerSize.height);
609605

610606
CGContextRef cgContext = [context graphicsPort];
611-
CGContextSaveGState(cgContext);
612-
CGContextSetBlendMode(cgContext, kCGBlendModeCopy);
613-
CGContextDrawLayerInRect(cgContext, drawRect, l);
614-
CGContextRestoreGState(cgContext);
607+
608+
const NSRect *rects;
609+
long count;
610+
[self getRectsBeingDrawn:&rects count:&count];
611+
612+
int i;
613+
for (i = 0; i < count; i++) {
614+
CGContextSaveGState(cgContext);
615+
CGContextClipToRect(cgContext, rects[i]);
616+
CGContextSetBlendMode(cgContext, kCGBlendModeCopy);
617+
CGContextDrawLayerInRect(cgContext, drawRect, l);
618+
CGContextRestoreGState(cgContext);
619+
}
620+
[cgLayerLock unlock];
621+
} else {
622+
id data;
623+
NSEnumerator *e = [drawData objectEnumerator];
624+
while ((data = [e nextObject]))
625+
[self batchDrawData:data];
626+
627+
[drawData removeAllObjects];
615628
}
616629
}
617630

618631
- (void)performBatchDrawWithData:(NSData *)data
619632
{
620-
[drawData addObject:data];
621-
[self setNeedsDisplay:YES];
633+
if (cgLayerEnabled && drawData.count == 0 && [self getCGContext]) {
634+
[cgLayerLock lock];
635+
[self batchDrawData:data];
636+
[cgLayerLock unlock];
637+
} else {
638+
[drawData addObject:data];
639+
[self setNeedsDisplay:YES];
622640

623-
// NOTE: During resizing, Cocoa only sends draw messages before Vim's rows
624-
// and columns are changed (due to ipc delays). Force a redraw here.
625-
if ([self inLiveResize])
626-
[self display];
641+
// NOTE: During resizing, Cocoa only sends draw messages before Vim's rows
642+
// and columns are changed (due to ipc delays). Force a redraw here.
643+
if ([self inLiveResize])
644+
[self display];
645+
}
627646
}
628647

629648
- (void)setCGLayerEnabled:(BOOL)enabled
@@ -646,11 +665,12 @@ - (void)releaseCGLayer
646665
- (CGLayerRef)getCGLayer
647666
{
648667
NSParameterAssert(cgLayerEnabled);
649-
if (!cgLayer) {
668+
if (!cgLayer && [self lockFocusIfCanDraw]) {
650669
NSGraphicsContext *context = [NSGraphicsContext currentContext];
651670
NSRect frame = [self frame];
652671
cgLayer = CGLayerCreateWithContext(
653672
[context graphicsPort], frame.size, NULL);
673+
[self unlockFocus];
654674
}
655675
return cgLayer;
656676
}
@@ -982,6 +1002,7 @@ - (void)batchDrawData:(NSData *)data
9821002
operation:NSCompositingOperationSourceOver
9831003
fraction:1.0];
9841004
}
1005+
[self setNeedsDisplayInRect:r];
9851006
} else if (DrawStringDrawType == type) {
9861007
int bg = *((int*)bytes); bytes += sizeof(int);
9871008
int fg = *((int*)bytes); bytes += sizeof(int);
@@ -1478,6 +1499,8 @@ - (void)drawString:(const UniChar *)chars length:(UniCharCount)length
14781499
if (thinStrokes)
14791500
CGContextSetFontSmoothingStyle(context, originalFontSmoothingStyle);
14801501
CGContextRestoreGState(context);
1502+
1503+
[self setNeedsDisplayInRect:clipRect];
14811504
}
14821505

14831506
- (void)scrollRect:(NSRect)rect lineCount:(int)count
@@ -1495,6 +1518,7 @@ - (void)scrollRect:(NSRect)rect lineCount:(int)count
14951518
CGContextDrawLayerAtPoint(
14961519
context, CGPointMake(0, -yOffset), [self getCGLayer]);
14971520
CGContextRestoreGState(context);
1521+
[self setNeedsDisplayInRect:clipRect];
14981522
} else {
14991523
NSSize delta={0, -count * cellSize.height};
15001524
[self scrollRect:rect by:delta];
@@ -1549,6 +1573,7 @@ - (void)clearBlockFromRow:(int)row1 column:(int)col1 toRow:(int)row2
15491573
CGContextSetBlendMode(context, kCGBlendModeCopy);
15501574
CGContextFillRect(context, *(CGRect*)&rect);
15511575
CGContextSetBlendMode(context, kCGBlendModeNormal);
1576+
[self setNeedsDisplayInRect:rect];
15521577
}
15531578

15541579
- (void)clearAll
@@ -1565,6 +1590,8 @@ - (void)clearAll
15651590
CGContextSetRGBFillColor(context, r, g, b, a);
15661591
CGContextFillRect(context, *(CGRect*)&rect);
15671592
CGContextSetBlendMode(context, kCGBlendModeNormal);
1593+
1594+
[self setNeedsDisplay:YES];
15681595
}
15691596

15701597
- (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
@@ -1612,6 +1639,7 @@ - (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
16121639
CGContextFillRect(context, *(CGRect*)&rect);
16131640
}
16141641

1642+
[self setNeedsDisplayInRect:rect];
16151643
CGContextRestoreGState(context);
16161644
}
16171645

@@ -1628,6 +1656,7 @@ - (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nrows
16281656
numColumns:ncols];
16291657
CGContextFillRect(cgctx, *(CGRect*)&rect);
16301658

1659+
[self setNeedsDisplayInRect:rect];
16311660
CGContextRestoreGState(cgctx);
16321661
}
16331662

0 commit comments

Comments
 (0)