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 dd8fa79
Showing 1 changed file with 41 additions and 18 deletions.
59 changes: 41 additions & 18 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 Down Expand Up @@ -404,7 +411,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 +430,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 @@ -545,9 +553,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 +806,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 +1047,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 = Math.max(1, Math.floor(layout.startLineNumber / (1 + layout.skipLines)));
const endLineNumber2 = Math.floor(layout.endLineNumber / (1 + layout.skipLines));
const minimapLineHeight = layout.renderLineHeight;

if (this._lastRenderData
Expand All @@ -1062,20 +1071,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 +1105,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 +1117,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 +1133,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 dd8fa79

Please sign in to comment.