Skip to content
Snippets Groups Projects
Commit 8a2ccf06 authored by George Nachman's avatar George Nachman
Browse files

Basic proof of concept is working.

parent d88b43ff
No related branches found
No related tags found
No related merge requests found
Showing
with 990 additions and 62 deletions
//
// iTermMetalClipView.h
// iTerm2SharedARC
//
// Created by George Nachman on 10/2/17.
//
#import <Cocoa/Cocoa.h>
@class MTKView;
@interface iTermMetalClipView : NSClipView
@property (nonatomic, weak) MTKView *metalView;
@end
//
// iTermMetalClipView.m
// iTerm2SharedARC
//
// Created by George Nachman on 10/2/17.
//
#import "iTermMetalClipView.h"
#import <MetalKit/MetalKit.h>
@implementation iTermMetalClipView
- (instancetype)initWithFrame:(NSRect)frameRect {
self = [super initWithFrame:frameRect];
if (self) {
self.copiesOnScroll = NO;
}
return self;
}
/*
- (void)scrollToPoint:(NSPoint)newOrigin {
[super scrollToPoint:newOrigin];
NSRect frame = _metalView.frame;
frame.origin.y = newOrigin.y;
_metalView.frame = frame;
}
*/
@end
#import "VT100GridTypes.h"
#import "iTermCursor.h"
#include "iTermMetalGlyphKey.h"
@import MetalKit;
NS_ASSUME_NONNULL_BEGIN
@interface iTermMetalCursorInfo : NSObject
@property (nonatomic) BOOL cursorVisible;
@property (nonatomic) VT100GridCoord coord;
@property (nonatomic) ITermCursorType type;
@property (nonatomic, strong) NSColor *cursorColor;
@end
@protocol iTermMetalDriverDataSourcePerFrameState<NSObject>
- (void)metalGetGlyphKeys:(iTermMetalGlyphKey *)glyphKeys
attributes:(iTermMetalGlyphAttributes *)attributes
background:(vector_float4 *)backgrounds
row:(int)row
width:(int)width;
- (nullable iTermMetalCursorInfo *)metalDriverCursorInfo;
- (NSImage *)metalImageForGlyphKey:(iTermMetalGlyphKey *)glyphKey
size:(CGSize)size
scale:(CGFloat)scale;
@end
@protocol iTermMetalDriverDataSource<NSObject>
- (nullable id<iTermMetalDriverDataSourcePerFrameState>)metalDriverWillBeginDrawingFrame;
@end
// Our platform independent render class
NS_CLASS_AVAILABLE(10_11, NA)
@interface iTermMetalDriver : NSObject<MTKViewDelegate>
@property (nullable, nonatomic, weak) id<iTermMetalDriverDataSource> dataSource;
- (nullable instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView;
- (void)setCellSize:(CGSize)cellSize gridSize:(VT100GridSize)gridSize scale:(CGFloat)scale;
@end
NS_ASSUME_NONNULL_END
This diff is collapsed.
Loading
Loading
@@ -7,6 +7,7 @@
//
 
#import <Cocoa/Cocoa.h>
#import <simd/simd.h>
 
// Keys of -dictionaryValue. Use -[NSDictionary colorVaue] to convert to color.
extern NSString *const kEncodedColorDictionaryRedComponent;
Loading
Loading
@@ -19,6 +20,11 @@ extern NSString *const kEncodedColorDictionaryColorSpace; // Optional, defaults
extern NSString *const kEncodedColorDictionarySRGBColorSpace;
extern NSString *const kEncodedColorDictionaryCalibratedColorSpace;
 
static float SIMDPerceivedBrightness(vector_float4 x) {
static const vector_float4 y = (vector_float4){ 0.30, 0.59, 0.11, 0 };
return simd_dot(x, y);
}
@interface NSColor (iTerm)
 
@property(nonatomic, readonly) CGFloat perceivedBrightness;
Loading
Loading
Loading
Loading
@@ -22,6 +22,15 @@
 
+ (PTYFontInfo *)fontInfoWithFont:(NSFont *)font;
 
+ (PTYFontInfo *)fontForAsciiCharacter:(BOOL)isAscii
asciiFont:(PTYFontInfo *)asciiFont
nonAsciiFont:(PTYFontInfo *)nonAsciiFont
useBoldFont:(BOOL)useBoldFont
useItalicFont:(BOOL)useItalicFont
usesNonAsciiFont:(BOOL)useNonAsciiFont
renderBold:(BOOL *)renderBold
renderItalic:(BOOL *)renderItalic;
// Returns a new autorelased PTYFontInfo with a bold version of this font (or
// nil if none is available).
- (PTYFontInfo *)computedBoldVersion;
Loading
Loading
Loading
Loading
@@ -73,6 +73,54 @@
@synthesize boldVersion = boldVersion_;
@synthesize italicVersion = italicVersion_;
 
+ (PTYFontInfo *)fontForAsciiCharacter:(BOOL)isAscii
asciiFont:(PTYFontInfo *)asciiFont
nonAsciiFont:(PTYFontInfo *)nonAsciiFont
useBoldFont:(BOOL)useBoldFont
useItalicFont:(BOOL)useItalicFont
usesNonAsciiFont:(BOOL)useNonAsciiFont
renderBold:(BOOL *)renderBold
renderItalic:(BOOL *)renderItalic {
BOOL isBold = *renderBold && useBoldFont;
BOOL isItalic = *renderItalic && useItalicFont;
*renderBold = NO;
*renderItalic = NO;
PTYFontInfo *theFont;
BOOL usePrimary = !useNonAsciiFont || isAscii;
PTYFontInfo *rootFontInfo = usePrimary ? asciiFont : nonAsciiFont;
theFont = rootFontInfo;
if (isBold && isItalic) {
theFont = rootFontInfo.boldItalicVersion;
if (!theFont && rootFontInfo.boldVersion) {
theFont = rootFontInfo.boldVersion;
*renderItalic = YES;
} else if (!theFont && rootFontInfo.italicVersion) {
theFont = rootFontInfo.italicVersion;
*renderBold = YES;
} else if (!theFont) {
theFont = rootFontInfo;
*renderBold = YES;
*renderItalic = YES;
}
} else if (isBold) {
theFont = rootFontInfo.boldVersion;
if (!theFont) {
theFont = rootFontInfo;
*renderBold = YES;
}
} else if (isItalic) {
theFont = rootFontInfo.italicVersion;
if (!theFont) {
theFont = rootFontInfo;
*renderItalic = YES;
}
}
return theFont;
}
+ (PTYFontInfo *)fontInfoWithFont:(NSFont *)font {
PTYFontInfo *fontInfo = [[[PTYFontInfo alloc] init] autorelease];
fontInfo.font = font;
Loading
Loading
Loading
Loading
@@ -23,6 +23,8 @@
#import "iTermInitialDirectory.h"
#import "iTermKeyBindingMgr.h"
#import "iTermKeyLabels.h"
#import "iTermMetalGlue.h"
#import "iTermMetalDriver.h"
#import "iTermMenuOpener.h"
#import "iTermMouseCursor.h"
#import "iTermPasteHelper.h"
Loading
Loading
@@ -462,6 +464,8 @@ static const NSUInteger kMaxHosts = 100;
long long _statusChangedAbsLine;
 
iTermUpdateCadenceController *_cadenceController;
iTermMetalGlue *_metalGlue;
}
 
+ (void)registerSessionInArrangement:(NSDictionary *)arrangement {
Loading
Loading
@@ -545,6 +549,8 @@ static const NSUInteger kMaxHosts = 100;
_customEscapeSequenceNotifications = [[NSMutableDictionary alloc] init];
 
_statusChangedAbsLine = -1;
_metalGlue = [[iTermMetalGlue alloc] init];
_metalGlue.screen = _screen;
 
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(coprocessChanged)
Loading
Loading
@@ -607,6 +613,7 @@ ITERM_WEAKLY_REFERENCEABLE
 
- (void)iterm_dealloc {
[_view release];
[_metalGlue release];
[self stopTailFind]; // This frees the substring in the tail find context, if needed.
_shell.delegate = nil;
dispatch_release(_executionSemaphore);
Loading
Loading
@@ -1300,6 +1307,9 @@ ITERM_WEAKLY_REFERENCEABLE
NSDictionary *liveArrangement = arrangement[SESSION_ARRANGEMENT_LIVE_SESSION];
if (liveArrangement) {
SessionView *liveView = [[[SessionView alloc] initWithFrame:sessionView.frame] autorelease];
if (@available(macOS 10.11, *)) {
liveView.driver.dataSource = aSession->_metalGlue;
}
[delegate addHiddenLiveView:liveView];
aSession.liveSession = [self sessionFromArrangement:liveArrangement
inView:liveView
Loading
Loading
@@ -1351,6 +1361,9 @@ ITERM_WEAKLY_REFERENCEABLE
// Allocate the root per-session view.
if (!_view) {
self.view = [[[SessionView alloc] initWithFrame:NSMakeRect(0, 0, aRect.size.width, aRect.size.height)] autorelease];
if (@available(macOS 10.11, *)) {
self.view.driver.dataSource = _metalGlue;
}
[[_view findViewController] setDelegate:self];
}
 
Loading
Loading
@@ -1362,6 +1375,7 @@ ITERM_WEAKLY_REFERENCEABLE
 
_textview = [[PTYTextView alloc] initWithFrame: NSMakeRect(0, [iTermAdvancedSettingsModel terminalVMargin], aSize.width, aSize.height)
colorMap:_colorMap];
_metalGlue.textView = _textview;
_colorMap.dimOnlyText = [iTermPreferences boolForKey:kPreferenceKeyDimOnlyText];
[_textview setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
[_textview setFont:[ITAddressBookMgr fontWithDesc:[_profile objectForKey:KEY_NORMAL_FONT]]
Loading
Loading
@@ -1412,6 +1426,13 @@ ITERM_WEAKLY_REFERENCEABLE
_newOutput = NO;
[_view updateScrollViewFrame];
[self useTransparencyDidChange];
if (@available(macOS 10.11, *)) {
[_view.driver setCellSize:CGSizeMake(_textview.charWidth, _textview.lineHeight)
gridSize:_screen.currentGrid.size
scale:_view.window.screen.backingScaleFactor];
}
return YES;
}
 
Loading
Loading
@@ -1500,6 +1521,11 @@ ITERM_WEAKLY_REFERENCEABLE
[_delegate sessionBelongsToVisibleTab]) {
[self beginTailFind];
}
if (@available(macOS 10.11, *)) {
[_view.driver setCellSize:CGSizeMake(_textview.charWidth, _textview.lineHeight)
gridSize:_screen.currentGrid.size
scale:_view.window.screen.backingScaleFactor];
}
}
 
- (void)setSplitSelectionMode:(SplitSelectionMode)mode move:(BOOL)move {
Loading
Loading
@@ -1906,6 +1932,7 @@ ITERM_WEAKLY_REFERENCEABLE
[_textview setDelegate:nil];
[_textview removeFromSuperview];
_textview = nil;
_metalGlue.textView = nil;
}
 
- (void)jumpToLocationWhereCurrentStatusChanged {
Loading
Loading
@@ -3688,6 +3715,9 @@ ITERM_WEAKLY_REFERENCEABLE
[_view autorelease];
_view = [newView retain];
newView.delegate = self;
if (@available(macOS 10.11, *)) {
newView.driver.dataSource = _metalGlue;
}
[newView updateTitleFrame];
[[_view findViewController] setDelegate:self];
}
Loading
Loading
@@ -6223,6 +6253,11 @@ ITERM_WEAKLY_REFERENCEABLE
[self notifyTmuxFontChange];
}
[_view updateScrollViewFrame];
if (@available(macOS 10.11, *)) {
[_view.driver setCellSize:CGSizeMake(_textview.charWidth, _textview.lineHeight)
gridSize:_screen.currentGrid.size
scale:_view.window.screen.backingScaleFactor];
}
}
 
- (BOOL)textViewHasBackgroundImage {
Loading
Loading
@@ -8996,6 +9031,14 @@ ITERM_WEAKLY_REFERENCEABLE
[self.textview.window makeFirstResponder:self.textview];
}
 
- (void)sessionViewDidChangeWindow {
if (@available(macOS 10.11, *)) {
[_view.driver setCellSize:CGSizeMake(_textview.charWidth, _textview.lineHeight)
gridSize:_screen.currentGrid.size
scale:_view.window.screen.backingScaleFactor];
}
}
#pragma mark - iTermCoprocessDelegate
 
- (void)coprocess:(Coprocess *)coprocess didTerminateWithErrorOutput:(NSString *)errors {
Loading
Loading
@@ -9251,4 +9294,5 @@ ITERM_WEAKLY_REFERENCEABLE
return response;
}
 
@end
Loading
Loading
@@ -272,6 +272,9 @@ typedef NS_ENUM(NSInteger, PTYTextViewSelectionExtensionUnit) {
@property(nonatomic, readonly) NSFont *font;
@property(nonatomic, readonly) NSFont *nonAsciiFont;
 
@property(nonatomic, readonly) PTYFontInfo *primaryFont;
@property(nonatomic, readonly) PTYFontInfo *secondaryFont; // non-ascii font, only used if self.useNonAsciiFont is set.
// Returns the non-ascii font, even if it's not being used.
@property(nonatomic, readonly) NSFont *nonAsciiFontEvenIfNotUsed;
 
Loading
Loading
@@ -324,6 +327,11 @@ typedef void (^PTYTextViewDrawingHookBlock)(iTermTextDrawingHelper *);
// Lines that are currently visible on the screen.
@property(nonatomic, readonly) VT100GridRange rangeOfVisibleLines;
 
// Helps drawing text and background.
@property (nonatomic, readonly) iTermTextDrawingHelper *drawingHelper;
@property (nonatomic, readonly) double transparencyAlpha;
// Returns the size of a cell for a given font. hspace and vspace are multipliers and the width
// and height.
+ (NSSize)charSizeForFont:(NSFont*)aFont
Loading
Loading
@@ -488,7 +496,7 @@ typedef void (^PTYTextViewDrawingHookBlock)(iTermTextDrawingHelper *);
suffix:(NSString *)suffix;
 
- (PTYFontInfo*)getFontForChar:(UniChar)ch
isComplex:(BOOL)complex
isComplex:(BOOL)isComplex
renderBold:(BOOL*)renderBold
renderItalic:(BOOL*)renderItalic;
 
Loading
Loading
Loading
Loading
@@ -156,9 +156,6 @@ static const int kDragThreshold = 3;
 
NSDictionary *_markedTextAttributes;
 
PTYFontInfo *_primaryFont;
PTYFontInfo *_secondaryFont; // non-ascii font, only used if self.useNonAsciiFont is set.
BOOL _mouseDown;
BOOL _mouseDragged;
BOOL _mouseDownOnSelection;
Loading
Loading
@@ -306,7 +303,11 @@ static const int kDragThreshold = 3;
selector:@selector(imageDidLoad:)
name:iTermImageDidLoad
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(boundsDidChange:)
name:NSViewBoundsDidChangeNotification
object:nil];
_semanticHistoryController = [[iTermSemanticHistoryController alloc] init];
_semanticHistoryController.delegate = self;
_semanticHistoryDragged = NO;
Loading
Loading
@@ -349,6 +350,24 @@ static const int kDragThreshold = 3;
return self;
}
 
- (void)setNeedsDisplay:(BOOL)needsDisplay {
[super setNeedsDisplay:needsDisplay];
if (needsDisplay) {
[_delegate textViewNeedsDisplayInRect:self.bounds];
}
}
- (void)setNeedsDisplayInRect:(NSRect)invalidRect {
[super setNeedsDisplayInRect:invalidRect];
[_delegate textViewNeedsDisplayInRect:invalidRect];
}
- (void)boundsDidChange:(NSNotification *)notification {
if (notification.object == self.enclosingScrollView.contentView) {
NSLog(@"Bounds changed %@", NSStringFromRect(self.enclosingScrollView.contentView.bounds));
}
}
- (void)removeAllTrackingAreas {
while (self.trackingAreas.count) {
[self removeTrackingArea:self.trackingAreas[0]];
Loading
Loading
@@ -1049,6 +1068,56 @@ static const int kDragThreshold = 3;
return _primaryFont.underlineOffset;
}
 
- (iTermTextDrawingHelper *)drawingHelper {
// Try to use a saved grid if one is available. If it succeeds, that implies that the cursor was
// recently hidden and what we're drawing is how the screen looked just before the cursor was
// hidden. Therefore, we'll temporarily show the cursor, but we'll need to restore cursorVisible's
// value when we're done.
if ([_dataSource setUseSavedGridIfAvailable:YES]) {
_drawingHelper.cursorVisible = YES;
}
_drawingHelper.showStripes = (_showStripesWhenBroadcastingInput &&
[_delegate textViewSessionIsBroadcastingInput]);
_drawingHelper.cursorBlinking = [self isCursorBlinking];
_drawingHelper.excess = [self excess];
_drawingHelper.selection = _selection;
_drawingHelper.ambiguousIsDoubleWidth = [_delegate textViewAmbiguousWidthCharsAreDoubleWidth];
_drawingHelper.normalization = [_delegate textViewUnicodeNormalizationForm];
_drawingHelper.hasBackgroundImage = [_delegate textViewHasBackgroundImage];
_drawingHelper.cursorGuideColor = [_delegate textViewCursorGuideColor];
_drawingHelper.gridSize = VT100GridSizeMake(_dataSource.width, _dataSource.height);
_drawingHelper.numberOfLines = _dataSource.numberOfLines;
_drawingHelper.cursorCoord = VT100GridCoordMake(_dataSource.cursorX - 1,
_dataSource.cursorY - 1);
_drawingHelper.totalScrollbackOverflow = [_dataSource totalScrollbackOverflow];
_drawingHelper.numberOfScrollbackLines = [_dataSource numberOfScrollbackLines];
_drawingHelper.reverseVideo = [[_dataSource terminal] reverseVideo];
_drawingHelper.textViewIsActiveSession = [self.delegate textViewIsActiveSession];
_drawingHelper.isInKeyWindow = [self isInKeyWindow];
// Draw the cursor filled in when we're inactive if there's a popup open or key focus was stolen.
_drawingHelper.shouldDrawFilledInCursor = ([self.delegate textViewShouldDrawFilledInCursor] || _keyFocusStolenCount);
_drawingHelper.isFrontTextView = (self == [[iTermController sharedInstance] frontTextView]);
_drawingHelper.transparencyAlpha = [self transparencyAlpha];
_drawingHelper.now = [NSDate timeIntervalSinceReferenceDate];
_drawingHelper.drawMarkIndicators = [_delegate textViewShouldShowMarkIndicators];
_drawingHelper.thinStrokes = _thinStrokes;
_drawingHelper.showSearchingCursor = _showSearchingCursor;
_drawingHelper.baselineOffset = [self minimumBaselineOffset];
_drawingHelper.underlineOffset = [self minimumUnderlineOffset];
_drawingHelper.boldAllowed = _useBoldFont;
_drawingHelper.unicodeVersion = [_delegate textViewUnicodeVersion];
_drawingHelper.asciiLigatures = _primaryFont.hasDefaultLigatures || _asciiLigatures;
_drawingHelper.nonAsciiLigatures = _secondaryFont.hasDefaultLigatures || _nonAsciiLigatures;
_drawingHelper.copyMode = _delegate.textViewCopyMode;
_drawingHelper.copyModeSelecting = _delegate.textViewCopyModeSelecting;
_drawingHelper.copyModeCursorCoord = _delegate.textViewCopyModeCursorCoord;
_drawingHelper.passwordInput = _delegate.textViewPasswordInput;
return _drawingHelper;
}
/*
- (void)drawRect:(NSRect)rect {
if (_dataSource.width <= 0) {
ITCriticalError(_dataSource.width < 0, @"Negative datasource width of %@", @(_dataSource.width));
Loading
Loading
@@ -1136,6 +1205,7 @@ static const int kDragThreshold = 3;
[_dataSource setUseSavedGridIfAvailable:NO];
_drawingHelper.cursorVisible = savedCursorVisible;
}
*/
 
- (BOOL)getAndResetDrawingAnimatedImageFlag {
BOOL result = _drawingHelper.animated;
Loading
Loading
@@ -5794,47 +5864,17 @@ static double EuclideanDistance(NSPoint p1, NSPoint p2) {
}
 
- (PTYFontInfo *)getFontForChar:(UniChar)ch
isComplex:(BOOL)complex
isComplex:(BOOL)isComplex
renderBold:(BOOL *)renderBold
renderItalic:(BOOL *)renderItalic {
BOOL isBold = *renderBold && _useBoldFont;
BOOL isItalic = *renderItalic && _useItalicFont;
*renderBold = NO;
*renderItalic = NO;
PTYFontInfo* theFont;
BOOL usePrimary = !_useNonAsciiFont || (!complex && (ch < 128));
PTYFontInfo *rootFontInfo = usePrimary ? _primaryFont : _secondaryFont;
theFont = rootFontInfo;
if (isBold && isItalic) {
theFont = rootFontInfo.boldItalicVersion;
if (!theFont && rootFontInfo.boldVersion) {
theFont = rootFontInfo.boldVersion;
*renderItalic = YES;
} else if (!theFont && rootFontInfo.italicVersion) {
theFont = rootFontInfo.italicVersion;
*renderBold = YES;
} else if (!theFont) {
theFont = rootFontInfo;
*renderBold = YES;
*renderItalic = YES;
}
} else if (isBold) {
theFont = rootFontInfo.boldVersion;
if (!theFont) {
theFont = rootFontInfo;
*renderBold = YES;
}
} else if (isItalic) {
theFont = rootFontInfo.italicVersion;
if (!theFont) {
theFont = rootFontInfo;
*renderItalic = YES;
}
}
return theFont;
return [PTYFontInfo fontForAsciiCharacter:(!isComplex && (ch < 128))
asciiFont:_primaryFont
nonAsciiFont:_secondaryFont
useBoldFont:_useBoldFont
useItalicFont:_useItalicFont
usesNonAsciiFont:_useNonAsciiFont
renderBold:renderBold
renderItalic:renderItalic];
}
 
#pragma mark - Private methods
Loading
Loading
@@ -5989,10 +6029,10 @@ static double EuclideanDistance(NSPoint p1, NSPoint p2) {
}
 
- (PTYCharType)classifyChar:(unichar)ch
isComplex:(BOOL)complex
isComplex:(BOOL)isComplex
{
NSString* aString = CharToStr(ch, complex);
UTF32Char longChar = CharToLongChar(ch, complex);
NSString* aString = CharToStr(ch, isComplex);
UTF32Char longChar = CharToLongChar(ch, isComplex);
 
if (longChar == DWC_RIGHT || longChar == DWC_SKIP) {
return CHARTYPE_DW_FILLER;
Loading
Loading
@@ -6011,10 +6051,10 @@ static double EuclideanDistance(NSPoint p1, NSPoint p2) {
}
 
- (BOOL)shouldSelectCharForWord:(unichar)ch
isComplex:(BOOL)complex
isComplex:(BOOL)isComplex
selectWordChars:(BOOL)selectWordChars
{
switch ([self classifyChar:ch isComplex:complex]) {
switch ([self classifyChar:ch isComplex:isComplex]) {
case CHARTYPE_WHITESPACE:
return !selectWordChars;
break;
Loading
Loading
@@ -7074,11 +7114,11 @@ static double EuclideanDistance(NSPoint p1, NSPoint p2) {
}
 
- (PTYFontInfo *)drawingHelperFontForChar:(UniChar)ch
isComplex:(BOOL)complex
isComplex:(BOOL)isComplex
renderBold:(BOOL *)renderBold
renderItalic:(BOOL *)renderItalic {
return [self getFontForChar:ch
isComplex:complex
isComplex:isComplex
renderBold:renderBold
renderItalic:renderItalic];
}
Loading
Loading
Loading
Loading
@@ -40,7 +40,7 @@ typedef struct {
SEL alternateSelector; // opt+click
SEL openAllSelector; // open all bookmarks
SEL alternateOpenAllSelector; // opt+open all bookmarks
id target; // receiver of selector
void *target; // receiver of selector (actually an __unsafe_unretained id)
} JournalParams;
 
@interface ProfileModel : NSObject {
Loading
Loading
Loading
Loading
@@ -33,6 +33,7 @@
#import "SplitSelectionView.h"
 
@class iTermAnnouncementViewController;
@class iTermMetalDriver;
@class PTYSession;
@class SplitSelectionView;
@class SessionTitleView;
Loading
Loading
@@ -113,6 +114,9 @@
// Make the textview the first responder
- (void)sessionViewBecomeFirstResponder;
 
// Current window changed.
- (void)sessionViewDidChangeWindow;
@end
 
@interface SessionView : NSView <SessionTitleViewDelegate>
Loading
Loading
@@ -125,6 +129,7 @@
@property(nonatomic, assign) id<iTermSessionViewDelegate> delegate;
@property(nonatomic, readonly) PTYScrollView *scrollview;
@property(nonatomic, assign) BOOL useSubviewWithLayer;
@property(nonatomic, readonly) iTermMetalDriver *driver NS_AVAILABLE_MAC(10_11);
 
+ (double)titleHeight;
+ (NSDate*)lastResizeDate;
Loading
Loading
Loading
Loading
@@ -5,6 +5,7 @@
#import "FutureMethods.h"
#import "iTermAdvancedSettingsModel.h"
#import "iTermAnnouncementViewController.h"
#import "iTermMetalClipView.h"
#import "iTermPreferences.h"
#import "NSView+iTerm.h"
#import "MovePaneController.h"
Loading
Loading
@@ -15,6 +16,9 @@
#import "PTYTextView.h"
#import "SessionTitleView.h"
#import "SplitSelectionView.h"
#import "iTermMetalDriver.h"
#import <MetalKit/MetalKit.h>
 
static int nextViewId;
static const double kTitleHeight = 22;
Loading
Loading
@@ -82,6 +86,9 @@ static NSDate* lastResizeDate_;
 
NSView *_hoverURLView;
NSTextField *_hoverURLTextField;
iTermMetalDriver *_driver NS_AVAILABLE_MAC(10_11);
MTKView *_metalView NS_AVAILABLE_MAC(10_11);
}
 
+ (double)titleHeight {
Loading
Loading
@@ -118,20 +125,36 @@ static NSDate* lastResizeDate_;
// Assign a globally unique view ID.
_viewId = nextViewId++;
 
// Allocate a scrollview
_scrollview = [[PTYScrollView alloc] initWithFrame:NSMakeRect(0,
0,
aRect.size.width,
aRect.size.height)
hasVerticalScroller:NO];
// Add a metal view
if (@available(macOS 10.11, *)) {
_metalView = [[MTKView alloc] initWithFrame:_scrollview.contentView.frame
device:MTLCreateSystemDefaultDevice()];
[self addSubview:_metalView];
_driver = [[iTermMetalDriver alloc] initWithMetalKitView:_metalView];
[_driver mtkView:_metalView drawableSizeWillChange:_metalView.drawableSize];
_metalView.delegate = _driver;
}
// Allocate a scrollview
[_scrollview setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
 
if (@available(macOS 10.11, *)) {
iTermMetalClipView *metalClipView = [[[iTermMetalClipView alloc] initWithFrame:_scrollview.contentView.frame] autorelease];
metalClipView.metalView = _metalView;
_scrollview.contentView = metalClipView;
_scrollview.drawsBackground = NO;
}
_scrollview.contentView.copiesOnScroll = NO;
// assign the main view
[self addSubview:_scrollview];
// setCopiesOnScroll is off because there is a top and bottom margin in the PTYTextView and
// we would not want that copied.
[[_scrollview contentView] setCopiesOnScroll:NO];
}
return self;
}
Loading
Loading
@@ -238,6 +261,9 @@ static NSDate* lastResizeDate_;
frame.origin = NSMakePoint(horizontalPadding, verticalPadding);
_hoverURLTextField.frame = frame;
}
_metalView.frame = _scrollview.contentView.frame;
[_driver mtkView:_metalView drawableSizeWillChange:_metalView.drawableSize];
}
 
- (void)setDelegate:(id<iTermSessionViewDelegate>)delegate {
Loading
Loading
@@ -550,6 +576,10 @@ static NSDate* lastResizeDate_;
[self updateLayout];
}
 
- (void)viewDidMoveToWindow {
[_delegate sessionViewDidChangeWindow];
}
#pragma mark NSDraggingSource protocol
 
- (void)draggedImage:(NSImage *)draggedImage movedTo:(NSPoint)screenPoint {
Loading
Loading
Loading
Loading
@@ -12,7 +12,6 @@
@property(nonatomic, retain) NSColor *color;
 
- (instancetype)initWithFrame:(NSRect)frame color:(NSColor*)color;
- (void)drawRect:(NSRect)dirtyRect;
- (void)setFlipped:(BOOL)value;
 
@end
Loading
Loading
@@ -29,12 +29,13 @@
[self class], self, NSStringFromRect(self.frame), @(self.isHidden), @(self.alphaValue)];
}
 
/*
- (void)drawRect:(NSRect)dirtyRect {
[_color setFill];
NSRectFill(dirtyRect);
[super drawRect:dirtyRect];
}
*/
- (void)setColor:(NSColor*)color {
[_color autorelease];
_color = [color retain];
Loading
Loading
Loading
Loading
@@ -249,7 +249,7 @@ void UnblockTaskNotifier(void) {
// Unblock pipe to interrupt select() whenever a PTYTask register/unregisters
highfd = unblockPipeR;
FD_SET(unblockPipeR, &rfds);
NSMutableSet* handledFds = [[NSMutableSet alloc] initWithCapacity:_tasks.count];
NSMutableSet* handledFds = [[NSMutableSet alloc] initWithCapacity:256];
 
// Add all the PTYTask pipes
PtyTaskDebugLog(@"run1: lock");
Loading
Loading
Loading
Loading
@@ -85,7 +85,7 @@
rmlen:&rmlen
incidentals:vector
token:token
encoding:_encoding
encoding:self.encoding
savedState:_savedStateForPartialParse
dcsHooked:&_dcsHooked];
if (token->type != VT100_WAIT) {
Loading
Loading
Loading
Loading
@@ -7,6 +7,7 @@
//
 
#import <Cocoa/Cocoa.h>
#include <simd/vector_types.h>
 
// This would be an enum except lldb doesn't handle enums very well.
// (lldb) po [_colorMap colorForKey:kColorMapBackground]
Loading
Loading
@@ -67,7 +68,7 @@ extern const int kColorMap24bitBase;
// self.dimmingAmount towards a neutral gray, and is used to indicate a session's inactivity. Muting
// moves colors towards the background color and is used by the "cursor boost" feature to make the
// cursor stand out more.
@interface iTermColorMap : NSObject
@interface iTermColorMap : NSObject<NSCopying>
 
@property(nonatomic, assign) BOOL dimOnlyText;
@property(nonatomic, assign) double dimmingAmount;
Loading
Loading
@@ -91,6 +92,7 @@ extern const int kColorMap24bitBase;
- (NSColor *)processedTextColorForTextColor:(NSColor *)textColor
overBackgroundColor:(NSColor*)backgroundColor;
- (NSColor *)processedBackgroundColorForBackgroundColor:(NSColor *)color;
- (vector_float4)fastProcessedBackgroundColorForBackgroundColor:(vector_float4)backgroundColor;
- (NSColor *)colorByMutingColor:(NSColor *)color;
- (NSColor *)colorByDimmingTextColor:(NSColor *)color;
 
Loading
Loading
Loading
Loading
@@ -9,6 +9,7 @@
#import "iTermColorMap.h"
#import "ITAddressBookMgr.h"
#import "NSColor+iTerm.h"
#include <unordered_map>
 
const int kColorMapForeground = 0;
const int kColorMapBackground = 1;
Loading
Loading
@@ -53,6 +54,8 @@ const int kColorMapAnsiBrightModifier = 8;
// This one actually uses four components.
CGFloat _lastBackgroundComponents[4];
NSColor *_lastBackgroundColor;
std::unordered_map<int, vector_float4> *_fastMap;
}
 
+ (iTermColorMapKey)keyFor8bitRed:(int)red
Loading
Loading
@@ -65,6 +68,7 @@ const int kColorMapAnsiBrightModifier = 8;
self = [super init];
if (self) {
_map = [[NSMutableDictionary alloc] init];
_fastMap = new std::unordered_map<int, vector_float4>();
}
return self;
}
Loading
Loading
@@ -73,6 +77,7 @@ const int kColorMapAnsiBrightModifier = 8;
[_map release];
[_lastTextColor release];
[_lastBackgroundColor release];
delete _fastMap;
[super dealloc];
}
 
Loading
Loading
@@ -92,12 +97,15 @@ const int kColorMapAnsiBrightModifier = 8;
 
if (!theColor) {
[_map removeObjectForKey:@(theKey)];
_fastMap->erase(theKey);
return;
}
 
if (theColor == _map[@(theKey)])
return;
 
CGFloat components[4];
[theColor getComponents:components];
if (theKey == kColorMapBackground) {
_backgroundRed = [theColor redComponent];
_backgroundGreen = [theColor greenComponent];
Loading
Loading
@@ -111,6 +119,12 @@ const int kColorMapAnsiBrightModifier = 8;
}
 
_map[@(theKey)] = theColor;
(*_fastMap)[theKey] = (vector_float4){
(float)components[0],
(float)components[1],
(float)components[2],
(float)components[3]
};
 
[_delegate colorMap:self didChangeColorForKey:theKey];
}
Loading
Loading
@@ -147,6 +161,16 @@ const int kColorMapAnsiBrightModifier = 8;
result[3] = rgb1[3];
}
 
- (vector_float4)fastAverageComponents:(vector_float4)rgb1 with:(vector_float4)rgb2 alpha:(float)alpha {
vector_float4 result = {
rgb1.x * (1 - alpha) + rgb2.x * alpha,
rgb1.y * (1 - alpha) + rgb2.y * alpha,
rgb1.z * (1 - alpha) + rgb2.z * alpha,
rgb1.w
};
return result;
}
// There is an issue where where the passed-in color can be in a different color space than the
// default background color. It doesn't make sense to combine RGB values from different color
// spaces. The effects are generally subtle.
Loading
Loading
@@ -265,6 +289,40 @@ const int kColorMapAnsiBrightModifier = 8;
count:4];
}
 
- (vector_float4)fastProcessedBackgroundColorForBackgroundColor:(vector_float4)backgroundColor {
vector_float4 defaultBackgroundComponents = (*_fastMap)[kColorMapBackground];
const vector_float4 mutedRgb = [self fastAverageComponents:backgroundColor with:defaultBackgroundComponents alpha:_mutingAmount];
vector_float4 grayRgb { 0.5, 0.5, 0.5, 1 };
BOOL shouldDim = !_dimOnlyText && _dimmingAmount > 0;
// If dimOnlyText is set then text and non-default background colors get dimmed toward black.
if (_dimOnlyText) {
const BOOL isDefaultBackgroundColor =
(fabs(backgroundColor.x - defaultBackgroundComponents.x) < 0.01 &&
fabs(backgroundColor.y - defaultBackgroundComponents.y) < 0.01 &&
fabs(backgroundColor.z - defaultBackgroundComponents.z) < 0.01);
if (!isDefaultBackgroundColor) {
grayRgb = (vector_float4){
(float)_backgroundBrightness,
(float)_backgroundBrightness,
(float)_backgroundBrightness,
1
};
shouldDim = YES;
}
}
vector_float4 dimmedRgb;
if (shouldDim) {
dimmedRgb = [self fastAverageComponents:mutedRgb with:grayRgb alpha:_dimmingAmount];
} else {
dimmedRgb = mutedRgb;
}
dimmedRgb.w = backgroundColor.w;
return dimmedRgb;
}
// There is an issue where where the passed-in color can be in a different color space than the
// default background color. It doesn't make sense to combine RGB values from different color
// spaces. The effects are generally subtle.
Loading
Loading
@@ -383,4 +441,36 @@ const int kColorMapAnsiBrightModifier = 8;
return nil;
}
 
- (id)copyWithZone:(NSZone *)zone {
iTermColorMap *other = [[iTermColorMap alloc] init];
if (!other) {
return nil;
}
other->_backgroundBrightness = _backgroundBrightness;
other->_backgroundRed = _backgroundRed;
other->_backgroundGreen = _backgroundGreen;
other->_backgroundBlue = _backgroundBlue;
memmove(other->_lastTextComponents, _lastTextComponents, sizeof(_lastTextComponents));
other->_lastTextColor = [_lastTextColor retain];
memmove(other->_lastBackgroundComponents, _lastBackgroundComponents, sizeof(_lastBackgroundComponents));
other->_lastBackgroundColor = [_lastBackgroundColor retain];
other->_dimOnlyText = _dimOnlyText;
other->_dimmingAmount = _dimmingAmount;
other->_mutingAmount = _mutingAmount;
other->_minimumContrast = _minimumContrast;
other->_delegate = _delegate;
other->_map = [_map mutableCopy];
other->_fastMap = new std::unordered_map<int, vector_float4>(*_fastMap);
return other;
}
@end
//
// iTermMetalFrameData.h
// iTerm2SharedARC
//
// Created by George Nachman on 10/27/17.
//
#import <Foundation/Foundation.h>
#import "iTermPreciseTimer.h"
#import "VT100GridTypes.h"
typedef struct {
iTermPreciseTimerStats mainThreadStats;
iTermPreciseTimerStats getCurrentDrawableStats;
iTermPreciseTimerStats getCurrentRenderPassDescriptorStats;
iTermPreciseTimerStats dispatchStats;
iTermPreciseTimerStats prepareStats;
iTermPreciseTimerStats waitForGroup;
iTermPreciseTimerStats finalizeStats;
iTermPreciseTimerStats metalSetupStats;
iTermPreciseTimerStats renderingStats;
iTermPreciseTimerStats endToEnd;
} iTermMetalFrameDataStatsBundle;
extern void iTermMetalFrameDataStatsBundleInitialize(iTermMetalFrameDataStatsBundle *bundle);
extern void iTermMetalFrameDataStatsBundleAdd(iTermMetalFrameDataStatsBundle *dest, iTermMetalFrameDataStatsBundle *source);
@protocol iTermMetalDriverDataSourcePerFrameState;
@class iTermMetalRendererTransientState;
@class iTermMetalRowData;
@class MTKView;
@class MTLRenderPassDescriptor;
@protocol CAMetalDrawable;
@interface iTermMetalFrameData : NSObject
@property (nonatomic, strong) id<iTermMetalDriverDataSourcePerFrameState> perFrameState;
@property (nonatomic, strong) NSMutableDictionary<NSString *, __kindof iTermMetalRendererTransientState *> *transientStates;
@property (nonatomic, strong) NSMutableArray<iTermMetalRowData *> *rows;
@property (nonatomic) VT100GridSize gridSize;
@property (nonatomic) CGFloat scale;
@property (atomic, strong) NSString *status;
@property (nonatomic, strong) MTLRenderPassDescriptor *renderPassDescriptor;
@property (nonatomic, strong) id<CAMetalDrawable> drawable;
- (void)loadFromView:(MTKView *)view;
- (void)prepareWithBlock:(void (^)(void))block;
- (void)waitForUpdatesToFinishOnGroup:(dispatch_group_t)group
onQueue:(dispatch_queue_t)queue
finalize:(void (^)(void))finalize
render:(void (^)(void))render;
- (void)didComplete;
- (void)addStatsTo:(iTermMetalFrameDataStatsBundle *)dest;
@end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment