diff --git a/internal/graphicscommand/image.go b/internal/graphicscommand/image.go index 94f29e3c1..ef6f89f55 100644 --- a/internal/graphicscommand/image.go +++ b/internal/graphicscommand/image.go @@ -155,15 +155,13 @@ func (i *Image) Pixels() []byte { return c.result } -func (i *Image) ReplacePixels(p []byte, x, y, width, height int) { +func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) { // ReplacePixels for a part might invalidate the current image that are drawn by DrawTriangles (#593, #738). if i.lastCommand == lastCommandDrawTriangles { if x != 0 || y != 0 || i.width != width || i.height != height { panic("graphicscommand: ReplacePixels for a part after DrawTriangles is forbidden") } } - pixels := make([]byte, len(p)) - copy(pixels, p) c := &replacePixelsCommand{ dst: i, pixels: pixels, diff --git a/internal/restorable/image.go b/internal/restorable/image.go index bebd978ff..e037bdd24 100644 --- a/internal/restorable/image.go +++ b/internal/restorable/image.go @@ -328,8 +328,15 @@ 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. theImages.makeStaleIfDependingOn(i) + // TODO: Avoid copying if possible (#983) + var copiedPixels []byte if pixels != nil { - i.image.ReplacePixels(pixels, x, y, width, height) + copiedPixels = make([]byte, len(pixels)) + copy(copiedPixels, pixels) + } + + if pixels != nil { + i.image.ReplacePixels(copiedPixels, x, y, width, height) } else { // 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. @@ -339,7 +346,7 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) { if x == 0 && y == 0 && width == w && height == h { if pixels != nil { - i.basePixels.AddOrReplace(pixels, 0, 0, w, h) + i.basePixels.AddOrReplace(copiedPixels, 0, 0, w, h) } else { i.basePixels.Remove(0, 0, w, h) } @@ -361,7 +368,7 @@ func (i *Image) ReplacePixels(pixels []byte, x, y, width, height int) { } if pixels != nil { - i.basePixels.AddOrReplace(pixels, x, y, width, height) + i.basePixels.AddOrReplace(copiedPixels, x, y, width, height) } else { i.basePixels.Remove(x, y, width, height) } diff --git a/internal/restorable/rect.go b/internal/restorable/rect.go index 842d43e8c..54088d7c4 100644 --- a/internal/restorable/rect.go +++ b/internal/restorable/rect.go @@ -37,16 +37,13 @@ func (rtp *rectToPixels) addOrReplace(pixels []byte, x, y, width, height int) { rtp.m = map[image.Rectangle][]byte{} } - copied := make([]byte, len(pixels)) - copy(copied, pixels) - newr := image.Rect(x, y, x+width, y+height) for r := range rtp.m { if r == newr { // Replace the region. - rtp.m[r] = copied + rtp.m[r] = pixels if r == rtp.lastR { - rtp.lastPix = copied + rtp.lastPix = pixels } return } @@ -56,9 +53,9 @@ func (rtp *rectToPixels) addOrReplace(pixels []byte, x, y, width, height int) { } // Add the region. - rtp.m[newr] = copied + rtp.m[newr] = pixels if newr == rtp.lastR { - rtp.lastPix = copied + rtp.lastPix = pixels } }