mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-12 20:18:59 +01:00
internal/graphicscommand: bug fix: buffered write pixel args might never be released
Closes #3036
This commit is contained in:
parent
46d171c3c5
commit
7b46df44ee
@ -59,6 +59,15 @@ func (m *ManagedBytes) GetAndRelease() ([]byte, func()) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release releases the underlying byte slice.
|
||||||
|
//
|
||||||
|
// After Release is called, the underlying byte slice is no longer available.
|
||||||
|
func (m *ManagedBytes) Release() {
|
||||||
|
m.pool.put(m.bytes)
|
||||||
|
m.bytes = nil
|
||||||
|
runtime.SetFinalizer(m, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// NewManagedBytes returns a managed byte slice initialized by the given constructor f.
|
// NewManagedBytes returns a managed byte slice initialized by the given constructor f.
|
||||||
//
|
//
|
||||||
// The byte slice is not zero-cleared at the constructor.
|
// The byte slice is not zero-cleared at the constructor.
|
||||||
|
@ -161,7 +161,23 @@ func (i *Image) ReadPixels(graphicsDriver graphicsdriver.Graphics, args []graphi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) WritePixels(pixels *graphics.ManagedBytes, region image.Rectangle) {
|
func (i *Image) WritePixels(pixels *graphics.ManagedBytes, region image.Rectangle) {
|
||||||
i.bufferedWritePixelsArgs = append(i.bufferedWritePixelsArgs, writePixelsCommandArgs{
|
// Release the previous pixels if the region is included by the new region.
|
||||||
|
// Successive WritePixels calls might accumulate the pixels and never release,
|
||||||
|
// especially when the image is unmanaged (#3036).
|
||||||
|
var cur int
|
||||||
|
for idx := 0; idx < len(i.bufferedWritePixelsArgs); idx++ {
|
||||||
|
arg := i.bufferedWritePixelsArgs[idx]
|
||||||
|
if arg.region.In(region) {
|
||||||
|
arg.pixels.Release()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i.bufferedWritePixelsArgs[cur] = arg
|
||||||
|
cur++
|
||||||
|
}
|
||||||
|
for idx := cur; idx < len(i.bufferedWritePixelsArgs); idx++ {
|
||||||
|
i.bufferedWritePixelsArgs[idx] = writePixelsCommandArgs{}
|
||||||
|
}
|
||||||
|
i.bufferedWritePixelsArgs = append(i.bufferedWritePixelsArgs[:cur], writePixelsCommandArgs{
|
||||||
pixels: pixels,
|
pixels: pixels,
|
||||||
region: region,
|
region: region,
|
||||||
})
|
})
|
||||||
|
@ -135,3 +135,54 @@ func TestShader(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #3036
|
||||||
|
func TestSuccessiveWritePixels(t *testing.T) {
|
||||||
|
const w, h = 32, 32
|
||||||
|
dst := graphicscommand.NewImage(w, h, false)
|
||||||
|
|
||||||
|
dst.WritePixels(graphics.NewManagedBytes(4, func(bs []byte) {
|
||||||
|
for i := range bs {
|
||||||
|
bs[i] = 0
|
||||||
|
}
|
||||||
|
}), image.Rect(0, 0, 1, 1))
|
||||||
|
if got, want := len(dst.BufferedWritePixelsArgsForTesting()), 1; got != want {
|
||||||
|
t.Errorf("len(dst.BufferedWritePixelsArgsForTesting()): got %d, want: %d", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.WritePixels(graphics.NewManagedBytes(4, func(bs []byte) {
|
||||||
|
for i := range bs {
|
||||||
|
bs[i] = 0
|
||||||
|
}
|
||||||
|
}), image.Rect(1, 1, 2, 2))
|
||||||
|
if got, want := len(dst.BufferedWritePixelsArgsForTesting()), 2; got != want {
|
||||||
|
t.Errorf("len(dst.BufferedWritePixelsArgsForTesting()): got %d, want: %d", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.WritePixels(graphics.NewManagedBytes(4, func(bs []byte) {
|
||||||
|
for i := range bs {
|
||||||
|
bs[i] = 0
|
||||||
|
}
|
||||||
|
}), image.Rect(0, 0, 1, 1))
|
||||||
|
if got, want := len(dst.BufferedWritePixelsArgsForTesting()), 2; got != want {
|
||||||
|
t.Errorf("len(dst.BufferedWritePixelsArgsForTesting()): got %d, want: %d", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.WritePixels(graphics.NewManagedBytes(4, func(bs []byte) {
|
||||||
|
for i := range bs {
|
||||||
|
bs[i] = 0
|
||||||
|
}
|
||||||
|
}), image.Rect(0, 0, 1, 1))
|
||||||
|
if got, want := len(dst.BufferedWritePixelsArgsForTesting()), 2; got != want {
|
||||||
|
t.Errorf("len(dst.BufferedWritePixelsArgsForTesting()): got %d, want: %d", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.WritePixels(graphics.NewManagedBytes(4, func(bs []byte) {
|
||||||
|
for i := range bs {
|
||||||
|
bs[i] = 0
|
||||||
|
}
|
||||||
|
}), image.Rect(0, 0, 2, 2))
|
||||||
|
if got, want := len(dst.BufferedWritePixelsArgsForTesting()), 1; got != want {
|
||||||
|
t.Errorf("len(dst.BufferedWritePixelsArgsForTesting()): got %d, want: %d", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user