Report the MDM VNC keys to the UI and bound the copyrect tile-hash map

This commit is contained in:
Viktor Liu
2026-09-22 19:53:43 +02:00
parent 24f832e032
commit 67c786b4f4
4 changed files with 87 additions and 2 deletions
+16 -2
View File
@@ -126,13 +126,27 @@ func (d *copyRectDetector) updateDirty(frame *image.RGBA, w, h int, dirty [][4]i
if tx+ts > w || ty+ts > h {
continue
}
idx := (ty/ts)*d.cols + (tx / ts)
pos := [2]int{tx, ty}
sum := d.hashTile(frame, tx, ty)
d.tileHash[(ty/ts)*d.cols+(tx/ts)] = sum
// Retire the hash this tile used to carry. Without this the map keeps
// one entry per distinct hash the tile has ever had, so a long session
// over changing content grows it without bound. Only drop the entry
// while it still points here: another tile may have claimed that hash
// since, and its mapping is live.
if old := d.tileHash[idx]; old != sum {
if owner, ok := d.prevTiles[old]; ok && owner == pos {
delete(d.prevTiles, old)
}
}
d.tileHash[idx] = sum
// Latest-wins on collision: ensures the most recent owner of this
// hash is the one we'll return on lookup. The previous owner's
// entry, if any, gets shadowed; if its content has changed it's
// stale anyway and findTileMatch's verification will skip it.
d.prevTiles[sum] = [2]int{tx, ty}
d.prevTiles[sum] = pos
}
}
+30
View File
@@ -5,6 +5,8 @@ package server
import (
"image"
"testing"
"github.com/stretchr/testify/assert"
)
// fillTile paints a tileSize×tileSize block of img at (x,y) with the colour
@@ -223,3 +225,31 @@ func TestEncodeCopyRectBody_Layout(t *testing.T) {
t.Fatalf("bad src bytes: % x", got[12:16])
}
}
// prevTiles maps a tile hash to the position that carries it, so it can hold
// at most one entry per tile. Rehashing the same tile with fresh content must
// retire the hash it used to carry: a session over changing content otherwise
// accumulates one dead entry per distinct hash it has ever seen, for as long
// as the session lives.
func TestCopyRectDetector_PrevTilesStaysBounded(t *testing.T) {
const w, h = 128, 128 // 2x2 tiles at 64px
const ts = 64
const tiles = 4
frame := image.NewRGBA(image.Rect(0, 0, w, h))
d := newCopyRectDetector(ts)
d.rebuild(frame, w, h)
dirty := [][4]int{{0, 0, ts, ts}, {ts, 0, ts, ts}, {0, ts, ts, ts}, {ts, ts, ts, ts}}
for i := range 200 {
for ty := range 2 {
for tx := range 2 {
fillTile(frame, tx*ts, ty*ts, ts, byte(i), byte(i*3), byte(tx+ty))
}
}
d.updateDirty(frame, w, h, dirty)
}
assert.LessOrEqual(t, len(d.prevTiles), tiles,
"prevTiles must not grow past one entry per tile across repeated content changes")
}