internal/graphicscommand: remove an image from imageWithBuffers whenever possible

This commit is contained in:
Hajime Hoshi 2023-10-08 19:38:09 +09:00
parent 810b62f83e
commit 9ed3c89594
2 changed files with 35 additions and 5 deletions

View File

@ -4231,3 +4231,22 @@ func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
t.Errorf("got: (%0.2f, %0.2f), want: (0, 0)", x, y)
}
}
func TestImageWritePixelAndDispose(t *testing.T) {
const (
w = 16
h = 16
)
img := ebiten.NewImage(w, h)
pix := make([]byte, 4*w*h)
for i := range pix {
pix[i] = 0xff
}
img.WritePixels(pix)
img.Dispose()
// Confirm that any pixel information is invalidated after Dispose is called.
if got, want := img.At(0, 0), (color.RGBA{}); got != want {
t.Errorf("got: %v, want: %v", got, want)
}
}

View File

@ -55,21 +55,28 @@ func genNextID() int {
}
// imagesWithBuffers is the set of an image with buffers.
var imagesWithBuffers []*Image
var imagesWithBuffers = map[*Image]struct{}{}
// addImageWithBuffer adds an image to the list of images with unflushed buffers.
func addImageWithBuffer(img *Image) {
imagesWithBuffers = append(imagesWithBuffers, img)
imagesWithBuffers[img] = struct{}{}
}
// removeImageWithBuffer removes an image from the list of images with unflushed buffers.
func removeImageWithBuffer(img *Image) {
delete(imagesWithBuffers, img)
}
// flushImageBuffers flushes all the image buffers and send to the command queue.
// flushImageBuffers should be called before flushing commands.
func flushImageBuffers() {
for i, img := range imagesWithBuffers {
for img := range imagesWithBuffers {
img.flushBufferedWritePixels()
imagesWithBuffers[i] = nil
}
imagesWithBuffers = imagesWithBuffers[:0]
if len(imagesWithBuffers) != 0 {
panic("graphicscommand: len(imagesWithBuffers) must be empty after flushing")
}
}
// NewImage returns a new image.
@ -103,6 +110,8 @@ func (i *Image) flushBufferedWritePixels() {
theCommandQueueManager.enqueueCommand(c)
i.bufferedWritePixelsArgs = nil
removeImageWithBuffer(i)
}
func (i *Image) Dispose() {
@ -111,6 +120,8 @@ func (i *Image) Dispose() {
target: i,
}
theCommandQueueManager.enqueueCommand(c)
removeImageWithBuffer(i)
}
func (i *Image) InternalSize() (int, int) {