internal/restorable: use a cache for pixels at readPixelsFromGPU

Updates #2375
This commit is contained in:
Hajime Hoshi 2023-03-08 16:27:36 +09:00
parent 7f182e7814
commit f298b9541b

View File

@ -124,12 +124,11 @@ 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. // pixelsCache is cached byte slices for pixels.
// pixelsForRestore is just a cache to avoid allocations (#2375). // pixelsCache 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. // A key is the region and a value is a byte slice for the region.
pixelsForRestore map[image.Rectangle][]byte pixelsCache map[image.Rectangle][]byte
// regionsForRestore is cached regions. // regionsForRestore is cached regions.
// regionsForRestore is just a cache to avoid allocations (#2375). // regionsForRestore is just a cache to avoid allocations (#2375).
@ -485,7 +484,15 @@ func (i *Image) readPixelsFromGPU(graphicsDriver graphicsdriver.Graphics) error
continue continue
} }
pix := make([]byte, 4*r.Dx()*r.Dy()) if i.pixelsCache == nil {
i.pixelsCache = map[image.Rectangle][]byte{}
}
pix, ok := i.pixelsCache[r]
if !ok {
pix = make([]byte, 4*r.Dx()*r.Dy())
i.pixelsCache[r] = pix
}
if err := i.image.ReadPixels(graphicsDriver, pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil { if err := i.image.ReadPixels(graphicsDriver, pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil {
return err return err
} }
@ -612,14 +619,14 @@ func (i *Image) restore(graphicsDriver graphicsdriver.Graphics) error {
continue continue
} }
if i.pixelsForRestore == nil { if i.pixelsCache == nil {
i.pixelsForRestore = map[image.Rectangle][]byte{} i.pixelsCache = map[image.Rectangle][]byte{}
} }
pix, ok := i.pixelsForRestore[r] pix, ok := i.pixelsCache[r]
if !ok { if !ok {
pix = make([]byte, 4*r.Dx()*r.Dy()) pix = make([]byte, 4*r.Dx()*r.Dy())
i.pixelsForRestore[r] = pix i.pixelsCache[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
@ -645,7 +652,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.pixelsCache = nil
i.clearDrawTrianglesHistory() i.clearDrawTrianglesHistory()
i.stale = false i.stale = false
i.staleRegions = i.staleRegions[:0] i.staleRegions = i.staleRegions[:0]