diff --git a/internal/graphicsdriver/metal/graphics_darwin.go b/internal/graphicsdriver/metal/graphics_darwin.go index 69e104c60..f2a7d9648 100644 --- a/internal/graphicsdriver/metal/graphics_darwin.go +++ b/internal/graphicsdriver/metal/graphics_darwin.go @@ -19,6 +19,7 @@ import ( "math" "sort" "strings" + "sync" "unsafe" "github.com/hajimehoshi/ebiten/v2/internal/graphics" @@ -346,28 +347,31 @@ const ( noStencil ) -// isMetalAvailable reports whether Metal is available or not. -var isMetalAvailable bool - -func init() { - if !supportsMetal() { - return - } - - // Initialize isMetalAvailable on the main thread. - // On old mac devices like iMac 2011, Metal is not supported (#779). - // TODO: Is there a better way to check whether Metal is available or not? - // It seems OK to call MTLCreateSystemDefaultDevice multiple times, so this should be fine. - if _, ok := mtl.CreateSystemDefaultDevice(); !ok { - return - } - - isMetalAvailable = true -} +var ( + // isMetalAvailable reports whether Metal is available or not. + isMetalAvailable bool + isMetalAvailableOnce sync.Once +) var theGraphics Graphics func Get() *Graphics { + isMetalAvailableOnce.Do(func() { + if !supportsMetal() { + return + } + + // Initialize isMetalAvailable on the main thread. + // TODO: Now ui.chooseGraphicsDriver is called on the main thread. Add an assertion. + + // On old mac devices like iMac 2011, Metal is not supported (#779). + // TODO: Is there a better way to check whether Metal is available or not? + // It seems OK to call MTLCreateSystemDefaultDevice multiple times, so this should be fine. + if _, ok := mtl.CreateSystemDefaultDevice(); !ok { + return + } + isMetalAvailable = true + }) if !isMetalAvailable { return nil }