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

Only allocate PIUs for drawable glyphs. Increase the size of the glyph texture...

Only allocate PIUs for drawable glyphs. Increase the size of the glyph texture atlas to fit multipart glyphs
parent 5ae7b294
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -19,5 +19,9 @@
 
// vector_float4
@property (nonatomic, strong) NSMutableData *backgroundColorData;
// Number of elements in preceding arrays to use.
@property (nonatomic) int numberOfDrawableGlyphs;
@end
 
Loading
Loading
@@ -18,7 +18,9 @@
if (self) {
_width = width;
_height = height;
_cellsPerRow = MAX(1, ceil(sqrt(length)));
CGFloat pixelsNeeded = (double)width * (double)height * (double)length;
CGFloat minimumEdgeLength = ceil(sqrt(pixelsNeeded));
_cellsPerRow = MAX(1, ceil(minimumEdgeLength / width));
 
MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init];
 
Loading
Loading
Loading
Loading
@@ -10,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong) id<MTLTexture> backgroundTexture;
 
- (void)setGlyphKeysData:(NSData *)glyphKeysData
count:(int)count
attributesData:(NSData *)attributesData
row:(int)row
creation:(NSImage *(NS_NOESCAPE ^)(int x))creation;
Loading
Loading
Loading
Loading
@@ -15,6 +15,8 @@ extern "C" {
 
@property (nonatomic, readonly) NSIndexSet *indexes;
@property (nonatomic, strong) iTermTextureMap *textureMap;
@property (nonatomic, readonly) NSInteger numberOfInstances;
- (void)addIndex:(NSInteger)index;
 
@end
Loading
Loading
@@ -49,24 +51,30 @@ extern "C" {
}
 
- (NSUInteger)sizeOfNewPIUBuffer {
return sizeof(iTermTextPIU) * self.cellConfiguration.gridSize.width * self.cellConfiguration.gridSize.height;
// Reserve enough space for each cell to take 9 spots (cell plus all 8 neighbors)
return sizeof(iTermTextPIU) * self.cellConfiguration.gridSize.width * self.cellConfiguration.gridSize.height * 9;
}
 
 
- (void)setGlyphKeysData:(NSData *)glyphKeysData
count:(int)count
attributesData:(NSData *)attributesData
row:(int)row
creation:(NSImage *(NS_NOESCAPE ^)(int x))creation {
const int width = self.cellConfiguration.gridSize.width;
assert(count <= width);
const iTermMetalGlyphKey *glyphKeys = (iTermMetalGlyphKey *)glyphKeysData.bytes;
const iTermMetalGlyphAttributes *attributes = (iTermMetalGlyphAttributes *)attributesData.bytes;
const float w = 1.0 / _textureMap.array.atlasSize.width;
const float h = 1.0 / _textureMap.array.atlasSize.height;
iTermTextureArray *array = _textureMap.array;
iTermTextPIU *pius = (iTermTextPIU *)self.pius.contents;
const float yOffset = (self.cellConfiguration.gridSize.height - row - 1) * self.cellConfiguration.cellSize.height;
 
NSInteger lastIndex = 0;
for (int x = 0; x < width; x++) {
for (int x = 0; x < count; x++) {
pius[_numberOfInstances].offset = simd_make_float2(x * self.cellConfiguration.cellSize.width,
yOffset);
NSInteger index;
if (x > 0 && !memcmp(&glyphKeys[x], &glyphKeys[x-1], sizeof(*glyphKeys))) {
index = lastIndex;
Loading
Loading
@@ -76,8 +84,7 @@ extern "C" {
creation:creation];
}
if (index >= 0) {
const size_t i = x + row * self.cellConfiguration.gridSize.width;
iTermTextPIU *piu = &pius[i];
iTermTextPIU *piu = &pius[_numberOfInstances];
MTLOrigin origin = [array offsetForIndex:index];
piu->textureOffset = (vector_float2){ origin.x * w, origin.y * h };
piu->textColor = attributes[x].foregroundColor;
Loading
Loading
@@ -100,21 +107,9 @@ extern "C" {
return _modelData;
}
 
- (void)initializePIUBytes:(void *)bytes {
iTermTextPIU *pius = (iTermTextPIU *)bytes;
NSInteger i = 0;
#warning TODO: There is no reason to do this unless the grid size changes.
for (NSInteger y = 0; y < self.cellConfiguration.gridSize.height; y++) {
const float yOffset = (self.cellConfiguration.gridSize.height - y - 1) * self.cellConfiguration.cellSize.height;
for (NSInteger x = 0; x < self.cellConfiguration.gridSize.width; x++) {
pius[i++].offset = simd_make_float2(x * self.cellConfiguration.cellSize.width,
yOffset);
}
}
}
- (void)addIndex:(NSInteger)index {
[_indexes addIndex:index];
_numberOfInstances++;
}
 
#pragma mark - Debugging
Loading
Loading
@@ -190,7 +185,10 @@ extern "C" {
- (void)initializeTransientState:(iTermTextRendererTransientState *)tState
commandBuffer:(id<MTLCommandBuffer>)commandBuffer
completion:(void (^)(__kindof iTermMetalCellRendererTransientState * _Nonnull))completion {
const NSInteger capacity = tState.cellConfiguration.gridSize.width * tState.cellConfiguration.gridSize.height * 2;
// Allocate enough space for every glyph to touch the cell plus eight adjacent cells.
// If I run out of texture memory this is the first place to cut.
#warning It's easy for the texture to exceed Metal's limit of 16384*16384. I will need multiple textures to handle this case.
const NSInteger capacity = tState.cellConfiguration.gridSize.width * tState.cellConfiguration.gridSize.height * 9;
if (_textureMap == nil ||
!CGSizeEqualToSize(_textureMap.cellSize, tState.cellConfiguration.cellSize) ||
_textureMap.capacity != capacity) {
Loading
Loading
@@ -207,7 +205,6 @@ extern "C" {
tState.vertexBuffer = [self newQuadOfSize:tState.cellConfiguration.cellSize];
tState.pius = [_cellRenderer.device newBufferWithLength:tState.sizeOfNewPIUBuffer
options:MTLResourceStorageModeShared];
[tState initializePIUBytes:tState.pius.contents];
 
[tState prepareForDrawWithCommandBuffer:commandBuffer completion:^{
completion(tState);
Loading
Loading
@@ -250,7 +247,7 @@ extern "C" {
[_cellRenderer drawWithTransientState:tState
renderEncoder:renderEncoder
numberOfVertices:6
numberOfPIUs:tState.cellConfiguration.gridSize.width * tState.cellConfiguration.gridSize.height
numberOfPIUs:tState.numberOfInstances
vertexBuffers:@{ @(iTermVertexInputIndexVertices): tState.vertexBuffer,
@(iTermVertexInputIndexPerInstanceUniforms): tState.pius,
@(iTermVertexInputIndexOffset): tState.offsetBuffer }
Loading
Loading
Loading
Loading
@@ -31,7 +31,8 @@ NS_ASSUME_NONNULL_BEGIN
attributes:(iTermMetalGlyphAttributes *)attributes
background:(vector_float4 *)backgrounds
row:(int)row
width:(int)width;
width:(int)width
drawableGlyphs:(int *)drawableGlyphsPtr;
 
- (nullable iTermMetalCursorInfo *)metalDriverCursorInfo;
 
Loading
Loading
Loading
Loading
@@ -259,11 +259,14 @@ static const NSInteger iTermMetalDriverMaximumNumberOfFramesInFlight = 3;
rowData.attributesData = [NSMutableData dataWithLength:sizeof(iTermMetalGlyphAttributes) * _columns];
rowData.backgroundColorData = [NSMutableData dataWithLength:sizeof(vector_float4) * _columns];
iTermMetalGlyphKey *glyphKeys = (iTermMetalGlyphKey *)rowData.keysData.mutableBytes;
int drawableGlyphs = 0;
[frameData.perFrameState metalGetGlyphKeys:glyphKeys
attributes:rowData.attributesData.mutableBytes
background:rowData.backgroundColorData.mutableBytes
row:y
width:_columns];
width:_columns
drawableGlyphs:&drawableGlyphs];
rowData.numberOfDrawableGlyphs = drawableGlyphs;
}
}];
 
Loading
Loading
@@ -312,6 +315,7 @@ static const NSInteger iTermMetalDriverMaximumNumberOfFramesInFlight = 3;
[frameData.rows enumerateObjectsUsingBlock:^(iTermMetalRowData * _Nonnull rowData, NSUInteger idx, BOOL * _Nonnull stop) {
iTermMetalGlyphKey *glyphKeys = (iTermMetalGlyphKey *)rowData.keysData.mutableBytes;
[textState setGlyphKeysData:rowData.keysData
count:rowData.numberOfDrawableGlyphs
attributesData:rowData.attributesData
row:rowData.y
creation:^NSImage *(int x) {
Loading
Loading
Loading
Loading
@@ -52,6 +52,39 @@ static NSColor *ColorForVector(vector_float4 v) {
return [NSColor colorWithRed:v.x green:v.y blue:v.z alpha:v.w];
}
 
#warning TODO: This is copied from drawing helper
static BOOL iTermTextDrawingHelperIsCharacterDrawable(screen_char_t *c,
BOOL hasStringRepresentation,
BOOL blinkingItemsVisible,
BOOL blinkAllowed) {
const unichar code = c->code;
if ((code == DWC_RIGHT ||
code == DWC_SKIP ||
code == TAB_FILLER) && !c->complexChar) {
return NO;
}
if (blinkingItemsVisible || !(blinkAllowed && c->blink)) {
// This char is either not blinking or during the "on" cycle of the
// blink. It should be drawn.
if (c->complexChar) {
// TODO: Not all composed/surrogate pair grapheme clusters are drawable
return hasStringRepresentation;
} else {
// Non-complex char
// TODO: There are other spaces in unicode that should be supported.
return (code != 0 &&
code != '\t' &&
!(code >= ITERM2_PRIVATE_BEGIN && code <= ITERM2_PRIVATE_END));
}
} else {
// Chatacter hidden because of blinking.
return NO;
}
}
@interface iTermMetalGlue()
// Screen-relative cursor location on last frame
@property (nonatomic) VT100GridCoord oldCursorScreenCoord;
Loading
Loading
@@ -95,6 +128,7 @@ static NSColor *ColorForVector(vector_float4 v) {
BOOL _cursorVisible;
BOOL _cursorBlinking;
BOOL _blinkingItemsVisible;
BOOL _blinkAllowed;
NSRange _inputMethodMarkedRange;
NSTimeInterval _timeSinceCursorMoved;
 
Loading
Loading
@@ -173,6 +207,7 @@ static NSColor *ColorForVector(vector_float4 v) {
_numberOfScrollbackLines = textView.dataSource.numberOfScrollbackLines;
_cursorVisible = textView.drawingHelper.cursorVisible;
_cursorBlinking = textView.isCursorBlinking;
_blinkAllowed = textView.blinkAllowed;
_blinkingItemsVisible = textView.drawingHelper.blinkingItemsVisible;
_inputMethodMarkedRange = textView.drawingHelper.inputMethodMarkedRange;
 
Loading
Loading
@@ -263,7 +298,8 @@ static NSColor *ColorForVector(vector_float4 v) {
attributes:(iTermMetalGlyphAttributes *)attributes
background:(vector_float4 *)background
row:(int)row
width:(int)width {
width:(int)width
drawableGlyphs:(int *)drawableGlyphsPtr {
screen_char_t *line = (screen_char_t *)_lines[row].bytes;
NSIndexSet *selectedIndexes = _selectedIndexes[row];
NSData *findMatches = _matches[@(row)];
Loading
Loading
@@ -272,6 +308,7 @@ static NSColor *ColorForVector(vector_float4 v) {
iTermTextColorKey *previousColorKey = &keys[1];
iTermBackgroundColorKey lastBackgroundKey;
 
int lastDrawableGlyph = -1;
for (int x = 0; x < width; x++) {
BOOL selected = [selectedIndexes containsIndex:x];
BOOL findMatch = NO;
Loading
Loading
@@ -361,8 +398,17 @@ static NSColor *ColorForVector(vector_float4 v) {
glyphKeys[x].image = line[x].image;
glyphKeys[x].boxDrawing = NO;
glyphKeys[x].thinStrokes = [self useThinStrokesWithAttributes:&attributes[x]];
if (iTermTextDrawingHelperIsCharacterDrawable(&line[x],
ScreenCharToStr(&line[x]) != nil,
_blinkingItemsVisible,
_blinkAllowed)) {
lastDrawableGlyph = x;
}
}
 
*drawableGlyphsPtr = lastDrawableGlyph + 1;
// Tweak the text color for the cell that has a box cursor.
if (_cursorInfo.cursorVisible &&
_cursorInfo.type == CURSOR_BOX &&
Loading
Loading
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