v0.4.2 settle an unchanged row with one compare before per-cell scan
This commit is contained in:
1 parent
01a81100bb
commit
bc1021a454
1 file changed
+21
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/lixenwraith/color"
|
"github.com/lixenwraith/color"
|
||||||
)
|
)
|
||||||
@@ -71,6 +72,22 @@ func cellEqual(a, b Cell) bool {
|
|||||||
a.Attrs == b.Attrs
|
a.Attrs == b.Attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cell has no padding, so a row compares as the bytes it occupies; the assertion
|
||||||
|
// fails to compile should a field change leave padding behind
|
||||||
|
var _ [0]struct{} = [unsafe.Sizeof(Cell{}) - unsafe.Sizeof(rune(0)) - 2*unsafe.Sizeof(color.RGB{}) - unsafe.Sizeof(Attr(0))]struct{}{}
|
||||||
|
|
||||||
|
// rowEqual reports whether two rows of cells hold the same cells, as one memcmp
|
||||||
|
func rowEqual(a, b []Cell) bool {
|
||||||
|
if len(a) != len(b) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(a) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
n := len(a) * int(unsafe.Sizeof(Cell{}))
|
||||||
|
return bytes.Equal(unsafe.Slice((*byte)(unsafe.Pointer(&a[0])), n), unsafe.Slice((*byte)(unsafe.Pointer(&b[0])), n))
|
||||||
|
}
|
||||||
|
|
||||||
// flush renders the back buffer into buf, diffing against front buffer
|
// flush renders the back buffer into buf, diffing against front buffer
|
||||||
func (o *outputBuffer) flush(cells []Cell, width, height int) {
|
func (o *outputBuffer) flush(cells []Cell, width, height int) {
|
||||||
if width != o.width || height != o.height {
|
if width != o.width || height != o.height {
|
||||||
@@ -86,6 +103,10 @@ func (o *outputBuffer) flush(cells []Cell, width, height int) {
|
|||||||
|
|
||||||
for y := 0; y < height; y++ {
|
for y := 0; y < height; y++ {
|
||||||
rowStart := y * width
|
rowStart := y * width
|
||||||
|
// Most rows of a frame are unchanged; one compare settles each of those
|
||||||
|
if rowEqual(cells[rowStart:rowStart+width], o.front[rowStart:rowStart+width]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
rowEnd := width
|
rowEnd := width
|
||||||
for rowEnd > 0 && cellEqual(cells[rowStart+rowEnd-1], o.front[rowStart+rowEnd-1]) {
|
for rowEnd > 0 && cellEqual(cells[rowStart+rowEnd-1], o.front[rowStart+rowEnd-1]) {
|
||||||
|
|||||||
Reference in new issue
Block a user