buffered, restorable: Remove copying pixels

Instead, the callers (ebiten.NewImageFromImage and
(*ebiten.Image).ReplacePixels) have responsibility to copy the
pixels now. This change should reduce unnecessary copying pixels.

Updates #1222
This commit is contained in:
Hajime Hoshi 2020-07-01 02:56:37 +09:00
parent 5d092ae022
commit 4c640d2500
3 changed files with 15 additions and 15 deletions

View File

@ -548,7 +548,13 @@ func (i *Image) ReplacePixels(pix []byte) error {
return nil return nil
} }
r := i.Bounds() r := i.Bounds()
if err := i.buffered.ReplacePixels(pix, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil {
// Copy the pixels as restorable package might reuse the pixels later.
// TODO: Would it be possible to avoid copying? (#1222)
copied := make([]byte, len(pix))
copy(copied, pix)
if err := i.buffered.ReplacePixels(copied, r.Min.X, r.Min.Y, r.Dx(), r.Dy()); err != nil {
theUIContext.setError(err) theUIContext.setError(err)
} }
return nil return nil
@ -632,7 +638,10 @@ func NewImageFromImage(source image.Image, filter Filter) (*Image, error) {
} }
i.addr = i i.addr = i
_ = i.ReplacePixels(copyImage(source)) // Call (*buffered.Image).ReplacePixels directly to avoid copying.
if err := i.buffered.ReplacePixels(copyImage(source), 0, 0, width, height); err != nil {
theUIContext.setError(err)
}
return i, nil return i, nil
} }

View File

@ -192,10 +192,8 @@ func (i *Image) ReplacePixels(pix []byte, x, y, width, height int) error {
} }
if maybeCanAddDelayedCommand() { if maybeCanAddDelayedCommand() {
copied := make([]byte, len(pix))
copy(copied, pix)
if tryAddDelayedCommand(func() error { if tryAddDelayedCommand(func() error {
i.ReplacePixels(copied, x, y, width, height) i.ReplacePixels(pix, x, y, width, height)
return nil return nil
}) { }) {
return nil return nil

View File

@ -300,15 +300,8 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
// For this purpuse, images should remember which part of that is used for DrawTriangles. // For this purpuse, images should remember which part of that is used for DrawTriangles.
theImages.makeStaleIfDependingOn(i) theImages.makeStaleIfDependingOn(i)
// TODO: Avoid copying if possible (#983)
var copiedPixels []byte
if pixels != nil { if pixels != nil {
copiedPixels = make([]byte, len(pixels)) i.image.ReplacePixels(pixels, x, y, width, height)
copy(copiedPixels, pixels)
}
if pixels != nil {
i.image.ReplacePixels(copiedPixels, x, y, width, height)
} else { } else {
// TODO: When pixels == nil, we don't have to care the pixel state there. In such cases, the image // TODO: When pixels == nil, we don't have to care the pixel state there. In such cases, the image
// accepts only ReplacePixels and not Fill or DrawTriangles. // accepts only ReplacePixels and not Fill or DrawTriangles.
@ -318,7 +311,7 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
if x == 0 && y == 0 && width == w && height == h { if x == 0 && y == 0 && width == w && height == h {
if pixels != nil { if pixels != nil {
i.basePixels.AddOrReplace(copiedPixels, 0, 0, w, h) i.basePixels.AddOrReplace(pixels, 0, 0, w, h)
} else { } else {
i.basePixels.Remove(0, 0, w, h) i.basePixels.Remove(0, 0, w, h)
} }
@ -340,7 +333,7 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) {
} }
if pixels != nil { if pixels != nil {
i.basePixels.AddOrReplace(copiedPixels, x, y, width, height) i.basePixels.AddOrReplace(pixels, x, y, width, height)
} else { } else {
i.basePixels.Remove(x, y, width, height) i.basePixels.Remove(x, y, width, height)
} }