graphics: Avoid all copying pixels

This is a breaking change: ReplacePixels now takes the ownership
of the given pixels.

Fixes #983
This commit is contained in:
Hajime Hoshi 2019-11-16 01:51:32 +09:00
parent 77a8ece691
commit c60a32a479
4 changed files with 10 additions and 23 deletions

View File

@ -432,6 +432,9 @@ func (i *Image) Dispose() error {
//
// The given p must represent RGBA pre-multiplied alpha values. len(p) must equal to 4 * (image width) * (image height).
//
// ReplacePixels takes the ownership of the given p. This means that p must not be modified after ReplacePixels is
// called.
//
// ReplacePixels may be slow (as for implementation, this calls glTexSubImage2D).
//
// When len(p) is not appropriate, ReplacePixels panics.

View File

@ -354,19 +354,8 @@ func TestImageReplacePixels(t *testing.T) {
t.Fatal(err)
return
}
// Even if p is changed after calling ReplacePixel, img0 uses the original values.
for i := range p {
p[i] = 0
}
for j := 0; j < img0.Bounds().Size().Y; j++ {
for i := 0; i < img0.Bounds().Size().X; i++ {
got := img0.At(i, j)
want := color.RGBA{0x80, 0x80, 0x80, 0x80}
if got != want {
t.Errorf("img0 At(%d, %d): got %#v; want %#v", i, j, got, want)
}
}
}
// p cannot be modified as of 1.11.0-alpha.
}
func TestImageReplacePixelsNil(t *testing.T) {

View File

@ -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,

View File

@ -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
}
}