mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-01-11 19:48:54 +01:00
internal/atlas: bug fix: copy the image slice before iterating it
Closes #2729
This commit is contained in:
parent
269fc2bd4d
commit
7ea3cd4738
@ -826,4 +826,41 @@ func TestDestinationCountOverflow(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Issue #2729
|
||||
func TestIteratingImagesToPutOnSourceBackend(t *testing.T) {
|
||||
const w, h = 16, 16
|
||||
src := atlas.NewImage(w, h, atlas.ImageTypeRegular)
|
||||
defer src.MarkDisposed()
|
||||
srcs := make([]*atlas.Image, 10)
|
||||
for i := range srcs {
|
||||
srcs[i] = atlas.NewImage(w, h, atlas.ImageTypeRegular)
|
||||
defer srcs[i].MarkDisposed()
|
||||
}
|
||||
dst := atlas.NewImage(w, h, atlas.ImageTypeRegular)
|
||||
defer dst.MarkDisposed()
|
||||
|
||||
// Use srcs as detinations once.
|
||||
vs := quadVertices(w, h, 0, 0, 1)
|
||||
is := graphics.QuadIndices()
|
||||
dr := graphicsdriver.Region{
|
||||
X: 0,
|
||||
Y: 0,
|
||||
Width: w,
|
||||
Height: h,
|
||||
}
|
||||
for _, img := range srcs {
|
||||
img.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, graphicsdriver.Region{}, [graphics.ShaderImageCount - 1][2]float32{}, atlas.NearestFilterShader, nil, false)
|
||||
}
|
||||
atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting())
|
||||
|
||||
// Use srcs as sources. This will register an image to imagesToPutOnSourceBackend.
|
||||
// Check iterating the registered image works correctly.
|
||||
for i := 0; i < 100; i++ {
|
||||
for _, src := range srcs {
|
||||
dst.DrawTriangles([graphics.ShaderImageCount]*atlas.Image{src}, vs, is, graphicsdriver.BlendCopy, dr, graphicsdriver.Region{}, [graphics.ShaderImageCount - 1][2]float32{}, atlas.NearestFilterShader, nil, false)
|
||||
}
|
||||
atlas.PutImagesOnSourceBackendForTesting(ui.GraphicsDriverForTesting())
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add tests to extend image on an atlas out of the main loop
|
||||
|
@ -19,9 +19,14 @@ package atlas
|
||||
// If the number of items is big, a map might be better than a slice.
|
||||
type smallImageSet struct {
|
||||
s []*Image
|
||||
|
||||
tmp []*Image
|
||||
}
|
||||
|
||||
func (s *smallImageSet) add(image *Image) {
|
||||
if image == nil {
|
||||
panic("atlas: nil image cannot be added")
|
||||
}
|
||||
for _, img := range s.s {
|
||||
if img == image {
|
||||
return
|
||||
@ -42,9 +47,18 @@ func (s *smallImageSet) remove(image *Image) {
|
||||
}
|
||||
|
||||
func (s *smallImageSet) forEach(f func(*Image)) {
|
||||
for _, img := range s.s {
|
||||
// Copy images to a temporary buffer since f might modify the original slice s.s (#2729).
|
||||
s.tmp = append(s.tmp, s.s...)
|
||||
|
||||
for _, img := range s.tmp {
|
||||
f(img)
|
||||
}
|
||||
|
||||
// Clear the temporary buffer.
|
||||
for i := range s.tmp {
|
||||
s.tmp[i] = nil
|
||||
}
|
||||
s.tmp = s.tmp[:0]
|
||||
}
|
||||
|
||||
func (s *smallImageSet) clear() {
|
||||
|
Loading…
Reference in New Issue
Block a user