shareable: Bug fix: Defer Dispose so that ClearPixels doesn't affect other images later

Updates #913
This commit is contained in:
Hajime Hoshi 2019-08-12 19:37:20 +09:00
parent 613b9bc02a
commit eb5ab57cdc

View File

@ -50,6 +50,7 @@ func init() {
hooks.AppendHookOnBeforeUpdate(func() error {
backendsM.Lock()
defer backendsM.Unlock()
once.Do(func() {
if len(theBackends) != 0 {
panic("shareable: all the images must be not-shared before the game starts")
@ -64,11 +65,23 @@ func init() {
maxSize = 512
}
})
resolveDeferred()
makeImagesShared()
return nil
})
}
func resolveDeferred() {
deferredM.Lock()
defer deferredM.Unlock()
for _, f := range deferred {
f()
}
deferred = nil
}
// MaxCountForShare represents the time duration when the image can become shared.
//
// This value is expoted for testing.
@ -137,6 +150,9 @@ var (
theBackends = []*backend{}
imagesToMakeShared = map[*Image]struct{}{}
deferred []func()
deferredM sync.Mutex
)
// isShareable reports whether the new allocation can use the shareable backends.
@ -367,9 +383,17 @@ func (i *Image) at(x, y int) (byte, byte, byte, byte) {
}
func (i *Image) Dispose() {
backendsM.Lock()
defer backendsM.Unlock()
i.dispose(true)
deferredM.Lock()
defer deferredM.Unlock()
// Defer actual disposing until disposing can finish completely.
// Otherwise, ClearPixels can be deferred in between frames, and delayed ClearPixels can affect other images.
// (#913)
//
// TODO: Other operations should be deferred too?
deferred = append(deferred, func() {
i.dispose(true)
})
}
func (i *Image) dispose(markDisposed bool) {