internal/restorable: revive pixelsForRestore

pixelsForRestore was removed at 09e0320309
as the regions for restoring were minimized. However, this caused a
regression and increased allocations on Android.

This fix revives pixelsForRestore, but as a map with region keys and
byte slice values. pixelsForRestore no longer represents a byte slice
for an entire image.

Updates #2375
This commit is contained in:
Hajime Hoshi 2023-03-08 14:50:13 +09:00
parent bd457da9be
commit 7f3cff5e7c

View File

@ -124,6 +124,13 @@ type Image struct {
// staleRegions is not used when AlwaysReadPixelsFromGPU() returns true. // staleRegions is not used when AlwaysReadPixelsFromGPU() returns true.
staleRegions []image.Rectangle staleRegions []image.Rectangle
// pixelsForRestore is cached byte slices for pixels.
// pixelsForRestore is just a cache to avoid allocations (#2375).
// pixelsForRestore is used only at restore.
//
// A key is the region and a value is a byte slice for the region.
pixelsForRestore map[image.Rectangle][]byte
imageType ImageType imageType ImageType
} }
@ -593,11 +600,21 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
if len(i.drawTrianglesHistory) > 0 { if len(i.drawTrianglesHistory) > 0 {
var rs []image.Rectangle var rs []image.Rectangle
rs = i.appendRegionsForDrawTriangles(rs) rs = i.appendRegionsForDrawTriangles(rs)
for _, r := range rs { for _, r := range rs {
if r.Empty() { if r.Empty() {
continue continue
} }
pix := make([]byte, 4*r.Dx()*r.Dy())
if i.pixelsForRestore == nil {
i.pixelsForRestore = map[image.Rectangle][]byte{}
}
pix, ok := i.pixelsForRestore[r]
if !ok {
pix = make([]byte, 4*r.Dx()*r.Dy())
i.pixelsForRestore[r] = pix
}
if err := gimg.ReadPixels(graphicsDriver, pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil { if err := gimg.ReadPixels(graphicsDriver, pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil {
return err return err
} }
@ -620,6 +637,7 @@ func (i *Image) Dispose() {
i.image.Dispose() i.image.Dispose()
i.image = nil i.image = nil
i.basePixels = Pixels{} i.basePixels = Pixels{}
i.pixelsForRestore = nil
i.clearDrawTrianglesHistory() i.clearDrawTrianglesHistory()
i.stale = false i.stale = false
i.staleRegions = i.staleRegions[:0] i.staleRegions = i.staleRegions[:0]