Added more efficient damage buffer method
This commit is contained in:
parent
754017a2db
commit
51fbd8acef
@ -46,9 +46,8 @@ func (backend *Backend) drawCells (forceRedraw bool) (areas []image.Rectangle) {
|
|||||||
for y := 0; y < height; y ++ {
|
for y := 0; y < height; y ++ {
|
||||||
for x := 0; x < width; x ++ {
|
for x := 0; x < width; x ++ {
|
||||||
if !forceRedraw && backend.application.Clean(x, y) { continue }
|
if !forceRedraw && backend.application.Clean(x, y) { continue }
|
||||||
backend.application.MarkClean(x, y)
|
|
||||||
|
|
||||||
cell := backend.application.Cell(x, y)
|
cell := backend.application.GetForRendering(x, y)
|
||||||
content := cell.Rune()
|
content := cell.Rune()
|
||||||
|
|
||||||
if forceRedraw && content < 32 { continue }
|
if forceRedraw && content < 32 { continue }
|
||||||
@ -93,13 +92,24 @@ func (backend *Backend) drawRune (
|
|||||||
if character < 32 { return }
|
if character < 32 { return }
|
||||||
|
|
||||||
origin := backend.originOfCell(x, y + 1)
|
origin := backend.originOfCell(x, y + 1)
|
||||||
destinationRectangle, mask, maskPoint, _, _ := backend.font.face.Glyph (
|
destinationRectangle, mask, maskPoint, _, ok := backend.font.face.Glyph (
|
||||||
fixed.Point26_6 {
|
fixed.Point26_6 {
|
||||||
X: fixed.I(origin.X),
|
X: fixed.I(origin.X),
|
||||||
Y: fixed.I(origin.Y - backend.metrics.descent),
|
Y: fixed.I(origin.Y - backend.metrics.descent),
|
||||||
},
|
},
|
||||||
character)
|
character)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
println("warning")
|
||||||
|
strokeRectangle (
|
||||||
|
&image.Uniform {
|
||||||
|
C: backend.config.Color(stone.ColorForeground),
|
||||||
|
},
|
||||||
|
backend.canvas,
|
||||||
|
backend.boundsOfCell(x, y))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if backend.drawCellBounds {
|
if backend.drawCellBounds {
|
||||||
strokeRectangle (
|
strokeRectangle (
|
||||||
&image.Uniform {
|
&image.Uniform {
|
||||||
|
38
buffer.go
38
buffer.go
@ -69,8 +69,8 @@ type Buffer interface {
|
|||||||
// dirty by default, are only clean when marked as clean, and become dirty again
|
// dirty by default, are only clean when marked as clean, and become dirty again
|
||||||
// when they are altered in some way.
|
// when they are altered in some way.
|
||||||
type DamageBuffer struct {
|
type DamageBuffer struct {
|
||||||
content []Cell
|
content []Cell
|
||||||
clean []bool
|
onScreen []Cell
|
||||||
|
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
@ -127,9 +127,7 @@ func (buffer *DamageBuffer) SetColor (x, y int, color Color) {
|
|||||||
defer buffer.lock.RUnlock()
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
index := x + y * buffer.width
|
buffer.content[x + y * buffer.width].color = color
|
||||||
buffer.clean[index] = buffer.content[index].color == color
|
|
||||||
buffer.content[index].color = color
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSize sets the width and height of the buffer. This clears all data in the
|
// SetSize sets the width and height of the buffer. This clears all data in the
|
||||||
@ -139,10 +137,10 @@ func (buffer *DamageBuffer) SetSize (width, height int) {
|
|||||||
defer buffer.lock.Unlock()
|
defer buffer.lock.Unlock()
|
||||||
|
|
||||||
if width < 0 || height < 0 { return }
|
if width < 0 || height < 0 { return }
|
||||||
buffer.width = width
|
buffer.width = width
|
||||||
buffer.height = height
|
buffer.height = height
|
||||||
buffer.content = make([]Cell, width * height)
|
buffer.content = make([]Cell, width * height)
|
||||||
buffer.clean = make([]bool, width * height)
|
buffer.onScreen = make([]Cell, width * height)
|
||||||
for index := 0; index < len(buffer.content); index ++ {
|
for index := 0; index < len(buffer.content); index ++ {
|
||||||
buffer.content[index].color = ColorForeground
|
buffer.content[index].color = ColorForeground
|
||||||
}
|
}
|
||||||
@ -154,9 +152,7 @@ func (buffer *DamageBuffer) SetStyle (x, y int, style Style) {
|
|||||||
defer buffer.lock.RUnlock()
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
index := x + y * buffer.width
|
buffer.content[x + y * buffer.width].style = style
|
||||||
buffer.clean[index] = buffer.content[index].style == style
|
|
||||||
buffer.content[index].style = style
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetRune sets the rune of the cell at the specified x and y coordinates.
|
// SetRune sets the rune of the cell at the specified x and y coordinates.
|
||||||
@ -173,7 +169,6 @@ func (buffer *DamageBuffer) Clear () {
|
|||||||
defer buffer.lock.RUnlock()
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
for index := 0; index < len(buffer.content); index ++ {
|
for index := 0; index < len(buffer.content); index ++ {
|
||||||
buffer.clean[index] = false
|
|
||||||
buffer.content[index] = Cell {
|
buffer.content[index] = Cell {
|
||||||
color: ColorForeground,
|
color: ColorForeground,
|
||||||
}
|
}
|
||||||
@ -182,9 +177,7 @@ func (buffer *DamageBuffer) Clear () {
|
|||||||
|
|
||||||
func (buffer *DamageBuffer) setRune (x, y int, content rune) {
|
func (buffer *DamageBuffer) setRune (x, y int, content rune) {
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
index := x + y * buffer.width
|
buffer.content[x + y * buffer.width].content = content
|
||||||
buffer.clean[index] = buffer.content[index].content == content
|
|
||||||
buffer.content[index].content = content
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes data stored in a byte slice to the buffer at the current dot
|
// Write writes data stored in a byte slice to the buffer at the current dot
|
||||||
@ -212,15 +205,20 @@ func (buffer *DamageBuffer) Clean (x, y int) (clean bool) {
|
|||||||
defer buffer.lock.RUnlock()
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
clean = buffer.clean[x + y * buffer.width]
|
index := x + y * buffer.width
|
||||||
|
clean = buffer.content[index] == buffer.onScreen[index]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkClean marks the cell at the specified x and y coordinates as clean.
|
// GetForRendering returns the cell at the specified x and y coordinates and
|
||||||
func (buffer *DamageBuffer) MarkClean (x, y int) {
|
// marks it as clean.
|
||||||
|
func (buffer *DamageBuffer) GetForRendering (x, y int) (cell Cell) {
|
||||||
buffer.lock.RLock()
|
buffer.lock.RLock()
|
||||||
defer buffer.lock.RUnlock()
|
defer buffer.lock.RUnlock()
|
||||||
|
|
||||||
if buffer.isOutOfBounds(x, y) { return }
|
if buffer.isOutOfBounds(x, y) { return }
|
||||||
buffer.clean[x + y * buffer.width] = true
|
index := x + y * buffer.width
|
||||||
|
buffer.onScreen[index] = buffer.content[index]
|
||||||
|
cell = buffer.content[index]
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user