Improve fancy graphics performance

- Fill holes in update map
- Join clip regions vertically
pull/2/head
cpsdqs 7 years ago
parent f7f5658685
commit 244ee72531
Signed by untrusted user: cpsdqs
GPG Key ID: 3F59586BB7448DD1
  1. 5
      js/term/debug.js
  2. 87
      js/term/screen_renderer.js

@ -203,6 +203,11 @@ module.exports = function attachDebugger (screen, connection) {
ctx.fillStyle = '#0ff'
}
if (flags & 16) {
// was filled to speed up rendering
ctx.globalAlpha /= 2
}
ctx.fillRect(x * cellSize.width, y * cellSize.height, cellSize.width, cellSize.height)
if (flags & 8) {

@ -570,6 +570,25 @@ module.exports = class CanvasRenderer extends EventEmitter {
updateMap.set(cell, didUpdate)
}
let debugFilledUpdates = []
if (this.graphics >= 1) {
// fancy graphics gets really slow when there's a lot of masks
// so here's an algorithm that fills in holes in the update map
for (let cell of updateMap.keys()) {
if (updateMap.get(cell)) continue
let previous = updateMap.get(cell - 1) || false
let next = updateMap.get(cell + 1) || false
if (previous && next) {
// set cell to true of horizontally adjacent updated
updateMap.set(cell, true)
if (this.debug && this._debug) debugFilledUpdates.push(cell)
}
}
}
// Map of (cell index) -> boolean, whether or not a cell should be redrawn
const redrawMap = new Map()
const maskedCells = new Map()
@ -621,11 +640,56 @@ module.exports = class CanvasRenderer extends EventEmitter {
// TODO: include padding in border cells
const padding = this.padding
let clipRegion = (regionStart, y, endX) => {
let regions = []
for (let y = 0; y < height; y++) {
let regionStart = null
for (let x = 0; x < width; x++) {
let cell = y * width + x
let masked = maskedCells.get(cell)
if (masked && regionStart === null) regionStart = x
if (!masked && regionStart !== null) {
regions.push([regionStart, y, x, y + 1])
regionStart = null
}
}
if (regionStart !== null) {
regions.push([regionStart, y, width, y + 1])
}
}
// join regions if possible (O(n^2-1), sorry)
let i = 0
while (i < regions.length) {
let region = regions[i]
let j = 0
while (j < regions.length) {
let other = regions[j]
if (other === region) {
j++
continue
}
if (other[0] === region[0] && other[2] === region[2] && other[3] === region[1]) {
region[1] = other[1]
regions.splice(j, 1)
if (i > j) i--
j--
}
j++
}
i++
}
console.log(regions)
ctx.save()
ctx.beginPath()
for (let region of regions) {
let [regionStart, y, endX, endY] = region
let rectX = padding + regionStart * cellWidth
let rectY = padding + y * cellHeight
let rectWidth = (endX - regionStart) * cellWidth
let rectHeight = cellHeight
let rectHeight = (endY - y) * cellHeight
// compensate for padding
if (regionStart === 0) {
@ -641,24 +705,6 @@ module.exports = class CanvasRenderer extends EventEmitter {
ctx.rect(rectX, rectY, rectWidth, rectHeight)
}
ctx.save()
ctx.beginPath()
for (let y = 0; y < height; y++) {
let regionStart = null
for (let x = 0; x < width; x++) {
let cell = y * width + x
let masked = maskedCells.get(cell)
if (masked && regionStart === null) regionStart = x
if (!masked && regionStart !== null) {
clipRegion(regionStart, y, x)
regionStart = null
}
}
if (regionStart !== null) {
clipRegion(regionStart, y, width)
}
}
ctx.clip()
}
@ -676,6 +722,7 @@ module.exports = class CanvasRenderer extends EventEmitter {
flags |= (+updateMap.get(cell)) << 1
flags |= (+maskedCells.get(cell)) << 2
flags |= (+isTextWide(text)) << 3
flags |= (+debugFilledUpdates.includes(cell)) << 4
this._debug.setCell(cell, flags)
}
}

Loading…
Cancel
Save