diff --git a/internal/restorable/images.go b/internal/restorable/images.go index 42e2348d6..cd9c41509 100644 --- a/internal/restorable/images.go +++ b/internal/restorable/images.go @@ -16,6 +16,7 @@ package restorable import ( "image" + "sync" "github.com/hajimehoshi/ebiten/internal/graphicscommand" ) @@ -42,6 +43,8 @@ func EnableRestoringForTesting() { type images struct { images map[*Image]struct{} lastTarget *Image + + m sync.Mutex } // theImages represents the images for the current process. @@ -72,8 +75,15 @@ func Restore() error { } func Images() []image.Image { + return theImages.images() +} + +func (i *images) images() []image.Image { + i.m.Lock() + defer i.m.Unlock() + var imgs []image.Image - for img := range theImages.images { + for img := range i.images { if img.volatile { continue } @@ -103,21 +113,27 @@ func Images() []image.Image { // add adds img to the images. func (i *images) add(img *Image) { + i.m.Lock() i.images[img] = struct{}{} + i.m.Unlock() } // remove removes img from the images. func (i *images) remove(img *Image) { + i.m.Lock() i.makeStaleIfDependingOnImpl(img) delete(i.images, img) + i.m.Unlock() } // resolveStaleImages resolves stale images. func (i *images) resolveStaleImages() { + i.m.Lock() i.lastTarget = nil for img := range i.images { img.resolveStale() } + i.m.Unlock() } // makeStaleIfDependingOn makes all the images stale that depend on target. @@ -125,8 +141,10 @@ func (i *images) resolveStaleImages() { // When target is changed, all images depending on target can't be restored with target. // makeStaleIfDependingOn is called in such situation. func (i *images) makeStaleIfDependingOn(target *Image) { + i.m.Lock() // Avoid defer for performance i.makeStaleIfDependingOnImpl(target) + i.m.Unlock() } func (i *images) makeStaleIfDependingOnImpl(target *Image) { @@ -150,6 +168,9 @@ func (i *images) restore() error { panic("restorable: restore cannot be called when restoring is disabled") } + i.m.Lock() + defer i.m.Unlock() + // Dispose image explicitly for img := range i.images { img.image.Dispose()