internal/restorable: remove duplicated regions from i.staleRegions

Updates #2375
Updates #2581
This commit is contained in:
Hajime Hoshi 2023-03-09 17:13:38 +09:00
parent 22d74e78b2
commit 367606f274

View File

@ -256,6 +256,9 @@ func (i *Image) makeStale(rect image.Rectangle) {
i.basePixels.Clear(r.Min.X, r.Min.Y, r.Dx(), r.Dy()) i.basePixels.Clear(r.Min.X, r.Min.Y, r.Dx(), r.Dy())
} }
// Remove duplicated regions to avoid unnecessary reading pixels from GPU.
i.staleRegions = removeDuplicatedRegions(i.staleRegions)
// Don't have to call makeStale recursively here. // Don't have to call makeStale recursively here.
// Restoring is done after topological sorting is done. // Restoring is done after topological sorting is done.
// If an image depends on another stale image, this means that // If an image depends on another stale image, this means that
@ -732,3 +735,29 @@ func regionToRectangle(region graphicsdriver.Region) image.Rectangle {
int(math.Ceil(float64(region.X+region.Width))), int(math.Ceil(float64(region.X+region.Width))),
int(math.Ceil(float64(region.Y+region.Height)))) int(math.Ceil(float64(region.Y+region.Height))))
} }
// removeDuplicatedRegions removes duplicated regions and returns a shrunk slice.
// If a region covers preceding regions, the covered regions are removed.
func removeDuplicatedRegions(regions []image.Rectangle) []image.Rectangle {
for i, r := range regions {
if r.Empty() {
continue
}
for j, rr := range regions[:i] {
if rr.In(r) {
regions[j] = image.Rectangle{}
}
}
}
n := 0
for _, r := range regions {
if r.Empty() {
continue
}
regions[n] = r
n++
}
return regions[:n]
}