internal/atlas: bug fix: (*Image).Deallocate (*Shader).Deallocate were not concurrent-safe

Updates #2162
This commit is contained in:
Hajime Hoshi 2023-11-03 16:59:59 +09:00
parent bdd8916bb1
commit 8a44ef4f6c
5 changed files with 22 additions and 4 deletions

View File

@ -547,6 +547,14 @@ func (i *Image) MarkDisposed() {
backendsM.Lock()
defer backendsM.Unlock()
if !inFrame {
appendDeferred(func() {
i.deallocate()
runtime.SetFinalizer(i, nil)
})
return
}
i.deallocate()
runtime.SetFinalizer(i, nil)
}

View File

@ -50,6 +50,16 @@ func (s *Shader) ensureShader() *restorable.Shader {
// Deallocate deallocates the internal state.
func (s *Shader) Deallocate() {
backendsM.Lock()
defer backendsM.Unlock()
if !inFrame {
appendDeferred(func() {
s.deallocate()
})
return
}
s.deallocate()
}

View File

@ -56,10 +56,10 @@ func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
return fmt.Errorf("phase: %d, got: %v, want: %v", g.phase, got, want)
}
// Dispose the shader. When a new shader is created in the next phase, the underlying shader ID might be reused.
// Deallocate the shader. When a new shader is created in the next phase, the underlying shader ID might be reused.
// This test checks that the new shader works in this situation.
// The actual disposal will happen after this frame and before the next frame in the current implementation.
s.Dispose()
s.Deallocate()
g.phase++

View File

@ -41,7 +41,7 @@ func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
if err != nil {
panic(err)
}
s.Dispose()
s.Deallocate()
}()
return nil
}

View File

@ -28,7 +28,7 @@ func Fragment(dstPos vec4, srcPos vec2, color vec4) vec4 {
if err != nil {
panic(err)
}
s.Dispose()
s.Deallocate()
}
type Game struct {