Skip to content

Commit

Permalink
* MinimapBuffers reuse improved
Browse files Browse the repository at this point in the history
* undersample large files (there is still a problem with the tokenizer update at the start)
  • Loading branch information
lxsk committed Oct 15, 2019
1 parent 63d2e74 commit 1ccb600
Showing 1 changed file with 62 additions and 22 deletions.
84 changes: 62 additions & 22 deletions src/vs/editor/browser/viewParts/minimap/minimap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ class MinimapLayout {
* used space beween the lines in line data
*/
public readonly emptySpaceBetweenLines: number;
/**
* how many lines to skip per line rendered
*/
public readonly skipLines: number;
/**
* used fontScaling for rendering characters
*/
Expand Down Expand Up @@ -241,6 +245,7 @@ class MinimapLayout {
usedRenderMinimap: RenderMinimap,
usedRenderLineHeight: RenderMinimap,
emptySpaceBetweenLines: number,
skipLines: number,
fontScale: number,
coversAllLines: boolean,
lineCount: number,
Expand All @@ -258,6 +263,7 @@ class MinimapLayout {
this.renderMinimap = usedRenderMinimap;
this.renderLineHeight = usedRenderLineHeight;
this.emptySpaceBetweenLines = emptySpaceBetweenLines;
this.skipLines = skipLines;
this.fontScale = fontScale;
this.coversAllLines = coversAllLines;
this.lineCount = lineCount;
Expand All @@ -280,6 +286,7 @@ class MinimapLayout {
this.endLineNumber,
this.displayLineHeight,
this.emptySpaceBetweenLines,
this.skipLines,
this.fontScale,
this.renderMinimap,
this.renderLineHeight,
Expand All @@ -300,6 +307,10 @@ class MinimapLayout {
return Math.round((pageY - this.sliderHeight / 2) / this._computedSliderRatio);
}

public fromRealLineNumberToImageDataLineNumer(lineNumber: number): number {
return Math.max(1, Math.floor((lineNumber - 1) / (1 + this.skipLines)) + 1);
}

public static create(
options: MinimapOptions,
viewportStartLineNumber: number,
Expand Down Expand Up @@ -404,7 +415,7 @@ class MinimapLayout {
return new MinimapLayout(scrollTop, scrollHeight
, computedSliderRatio, sliderTop, maxMinimapSliderTop, sliderHeight
, startLineNumber, endLineNumber, minimapLineHeight
, renderMinimap, renderLineHeight, emptySpaceBetweenLines, fontScale
, renderMinimap, renderLineHeight, emptySpaceBetweenLines, 0, fontScale
, coversAllLines, lineCount, options);
} else {
let startLineNumber = Math.max(1, Math.floor(viewportStartLineNumber - sliderTop * pixelRatio / minimapLineHeight));
Expand All @@ -423,11 +434,12 @@ class MinimapLayout {
}

const endLineNumber = Math.min(lineCount, startLineNumber + minimapLinesFitting - 1);
const skipLines = Math.max(0, Math.floor(1 / minimapLineHeight) - 1);

return new MinimapLayout(scrollTop, scrollHeight
, computedSliderRatio, sliderTop, maxMinimapSliderTop, sliderHeight
, startLineNumber, endLineNumber, minimapLineHeight
, renderMinimap, renderLineHeight, emptySpaceBetweenLines, fontScale
, renderMinimap, renderLineHeight, emptySpaceBetweenLines, skipLines, fontScale
, coversAllLines, lineCount, options);
}
}
Expand Down Expand Up @@ -511,16 +523,29 @@ class RenderData {
}

public onLinesChanged(e: viewEvents.ViewLinesChangedEvent): boolean {
return this._renderedLines.onLinesChanged(e.fromLineNumber, e.toLineNumber);
return this._renderedLines.onLinesChanged(
this.renderedLayout.fromRealLineNumberToImageDataLineNumer(e.fromLineNumber),
this.renderedLayout.fromRealLineNumberToImageDataLineNumer(e.toLineNumber));
}
public onLinesDeleted(e: viewEvents.ViewLinesDeletedEvent): void {
this._renderedLines.onLinesDeleted(e.fromLineNumber, e.toLineNumber);
this._renderedLines.onLinesDeleted(
this.renderedLayout.fromRealLineNumberToImageDataLineNumer(e.fromLineNumber),
this.renderedLayout.fromRealLineNumberToImageDataLineNumer(e.toLineNumber));
}
public onLinesInserted(e: viewEvents.ViewLinesInsertedEvent): void {
this._renderedLines.onLinesInserted(e.fromLineNumber, e.toLineNumber);
this._renderedLines.onLinesInserted(
this.renderedLayout.fromRealLineNumberToImageDataLineNumer(e.fromLineNumber),
this.renderedLayout.fromRealLineNumberToImageDataLineNumer(e.toLineNumber));
}
public onTokensChanged(e: viewEvents.ViewTokensChangedEvent): boolean {
return this._renderedLines.onTokensChanged(e.ranges);
const ranges: { fromLineNumber: number; toLineNumber: number; }[] = [];
for (let i = 0; i < e.ranges.length; ++i) {
ranges[i] = {
fromLineNumber: this.renderedLayout.fromRealLineNumberToImageDataLineNumer(e.ranges[i].fromLineNumber),
toLineNumber: this.renderedLayout.fromRealLineNumberToImageDataLineNumer(e.ranges[i].toLineNumber)
};
}
return this._renderedLines.onTokensChanged(ranges);
}
}

Expand All @@ -545,9 +570,8 @@ class MinimapBuffers {
this._lastUsedBuffer = 0;
}

public hasSameSize(WIDTH: number, HEIGHT: number): boolean {
return (this._buffers[0].width === WIDTH) && (this._buffers[0].height === HEIGHT);
}
public getWidth(): number { return this._buffers[1 - this._lastUsedBuffer].width; }
public getHeight(): number { return this._buffers[1 - this._lastUsedBuffer].height; }

public getBuffer(): ImageData {
// rotate buffers
Expand Down Expand Up @@ -799,11 +823,13 @@ export class Minimap extends ViewPart {
}

private _getBuffer(WIDTH: number, HEIGHT: number): ImageData {
if (!this._buffers || !this._buffers.hasSameSize(WIDTH, HEIGHT)) {
if (!this._buffers
|| (this._buffers.getWidth() !== WIDTH)
|| (this._buffers.getHeight() < HEIGHT)) {
this._buffers = new MinimapBuffers(
this._canvas.domNode.getContext('2d')!,
WIDTH,
HEIGHT,
HEIGHT + 64, // overallocate so, chances are we won't need a new buffer soon
this._tokensColorTracker.getColor(ColorId.DefaultBackground)
);
}
Expand Down Expand Up @@ -1038,8 +1064,8 @@ export class Minimap extends ViewPart {

private renderLines(layout: MinimapLayout): RenderData {
const renderMinimap = layout.renderMinimap;
const startLineNumber = layout.startLineNumber;
const endLineNumber = layout.endLineNumber;
const startLineNumber2 = layout.fromRealLineNumberToImageDataLineNumer(layout.startLineNumber);
const endLineNumber2 = layout.fromRealLineNumberToImageDataLineNumer(layout.endLineNumber);
const minimapLineHeight = layout.renderLineHeight;

if (this._lastRenderData
Expand All @@ -1062,20 +1088,32 @@ export class Minimap extends ViewPart {
// Oh well!! We need to repaint some lines...

const width = this._options.canvasInnerWidth;
const height = layout.options.entireDocument ? layout.lineCount * (minimapLineHeight + layout.emptySpaceBetweenLines) : this._options.canvasInnerHeight;
let height = this._options.canvasInnerHeight;
if (layout.options.entireDocument) {
height = Math.floor(layout.lineCount * (minimapLineHeight + layout.emptySpaceBetweenLines) / (1 + layout.skipLines));
}
const imageData = this._getBuffer(width, height);

// Render untouched lines by using last rendered data.
let [_dirtyY1, _dirtyY2, needed] = Minimap._renderUntouchedLines(
imageData,
startLineNumber,
endLineNumber,
startLineNumber2,
endLineNumber2,
minimapLineHeight + layout.emptySpaceBetweenLines,
this._lastRenderData
);

const needed2: boolean[] = [];
for (let i = 0; i < needed.length; ++i) {
let i2 = i * (1 + layout.skipLines);
needed2[i2] = needed[i];
for (let j = 1; j <= layout.skipLines; ++j) {
needed2[i2 + j] = false;
}
}

// Fetch rendering info from view model for rest of lines that need rendering.
const lineInfo = this._context.model.getMinimapLinesRenderingData(startLineNumber, endLineNumber, needed);
const lineInfo = this._context.model.getMinimapLinesRenderingData(layout.startLineNumber, layout.endLineNumber, needed2);
const tabSize = lineInfo.tabSize;
const background = this._tokensColorTracker.getColor(ColorId.DefaultBackground);
const useLighterFont = this._tokensColorTracker.backgroundIsLight();
Expand All @@ -1084,7 +1122,7 @@ export class Minimap extends ViewPart {
// Render the rest of lines
let dy = 0;
const renderedLines: MinimapLine[] = [];
for (let lineIndex = 0, lineCount = endLineNumber - startLineNumber + 1; lineIndex < lineCount; lineIndex++) {
for (let lineIndex = 0, lineCount = endLineNumber2 - startLineNumber2 + 1; lineIndex < lineCount; lineIndex++) {
if (needed[lineIndex]) {
Minimap._renderLine(
imageData,
Expand All @@ -1096,7 +1134,7 @@ export class Minimap extends ViewPart {
dy + layout.emptySpaceBetweenLines,
tabSize,
oneline,
lineInfo.data[lineIndex]!,
lineInfo.data[lineIndex * (1 + layout.skipLines)]!,
layout.fontScale
);
}
Expand All @@ -1112,15 +1150,17 @@ export class Minimap extends ViewPart {
// this fill rect could be reduced to only the empty part below the minimap
// and droped completely if "Scroll Beyond Last Line" is disabled
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
let bitmap = createImageBitmap(imageData);
bitmap.then((bitmap: ImageBitmap) =>
let bitmap = createImageBitmap(imageData, 0, 0, width, height);
bitmap.then((bitmap: ImageBitmap) => {
ctx.drawImage(bitmap,
0, 0,
width,
height,
0, 0,
width,
Math.min(this._options.canvasInnerHeight, layout.displayLineHeight * layout.endLineNumber)));
Math.min(this._options.canvasInnerHeight, layout.displayLineHeight * layout.endLineNumber));
bitmap.close();
});
} else {
const dirtyY1 = (_dirtyY1 === -1 ? 0 : _dirtyY1);
const dirtyY2 = (_dirtyY2 === -1 ? imageData.height : _dirtyY2);
Expand Down

0 comments on commit 1ccb600

Please sign in to comment.