diff --git a/internal/graphicsdriver/metal/mtl/mtl.go b/internal/graphicsdriver/metal/mtl/mtl.go index 8dfef3f1f..2569716e9 100644 --- a/internal/graphicsdriver/metal/mtl/mtl.go +++ b/internal/graphicsdriver/metal/mtl/mtl.go @@ -27,6 +27,7 @@ package mtl import ( "errors" "fmt" + "sync" "unsafe" ) @@ -568,20 +569,30 @@ func (cb CommandBuffer) WaitUntilCompleted() { C.CommandBuffer_WaitUntilCompleted(cb.commandBuffer) } -var commandBufferCompletedHandlers = map[unsafe.Pointer]func(){} +var ( + commandBufferCompletedHandlers = map[unsafe.Pointer]func(){} + commandBufferCompletedHandlersM sync.Mutex +) // AddCompletedHandler registers a block of code that Metal calls immediately after the GPU finishes executing the commands in the command buffer. // // Reference: https://developer.apple.com/documentation/metal/mtlcommandbuffer/1442997-addcompletedhandler func (cb CommandBuffer) AddCompletedHandler(f func()) { + commandBufferCompletedHandlersM.Lock() commandBufferCompletedHandlers[cb.commandBuffer] = f + commandBufferCompletedHandlersM.Unlock() + C.CommandBuffer_AddCompletedHandler(cb.commandBuffer) } //export commandBufferCompletedCallback func commandBufferCompletedCallback(commandBuffer unsafe.Pointer) { f := commandBufferCompletedHandlers[commandBuffer] + + commandBufferCompletedHandlersM.Lock() delete(commandBufferCompletedHandlers, commandBuffer) + commandBufferCompletedHandlersM.Unlock() + f() }