diff --git a/internal/graphicscommand/command.go b/internal/graphicscommand/command.go index bfec24afb..8dca3e963 100644 --- a/internal/graphicscommand/command.go +++ b/internal/graphicscommand/command.go @@ -150,6 +150,8 @@ func (q *commandQueue) Flush() { if recordLog() { fmt.Println("--") } + + Driver().Begin() for len(q.commands) > 0 { nv := 0 ne := 0 @@ -190,6 +192,7 @@ func (q *commandQueue) Flush() { } q.commands = q.commands[nc:] } + Driver().End() q.commands = nil q.nvertices = 0 q.nindices = 0 diff --git a/internal/graphicsdriver/graphicsdriver.go b/internal/graphicsdriver/graphicsdriver.go index 987074239..018c7e779 100644 --- a/internal/graphicsdriver/graphicsdriver.go +++ b/internal/graphicsdriver/graphicsdriver.go @@ -20,6 +20,8 @@ import ( ) type GraphicsDriver interface { + Begin() + End() SetWindow(window uintptr) SetVertices(vertices []float32, indices []uint16) Flush() diff --git a/internal/graphicsdriver/metal/driver.go b/internal/graphicsdriver/metal/driver.go index 5b6a21cb1..eea3a32b5 100644 --- a/internal/graphicsdriver/metal/driver.go +++ b/internal/graphicsdriver/metal/driver.go @@ -30,6 +30,20 @@ import ( "github.com/hajimehoshi/ebiten/internal/mainthread" ) +// #cgo CFLAGS: -x objective-c -mmacosx-version-min=10.11 +// #cgo LDFLAGS: -framework Foundation +// +// #import +// +// static void* allocAutoreleasePool() { +// return [[NSAutoreleasePool alloc] init]; +// } +// +// static void releaseAutoreleasePool(void* pool) { +// [(NSAutoreleasePool*)pool release]; +// } +import "C" + const source = `#include #define FILTER_NEAREST {{.FilterNearest}} @@ -287,6 +301,8 @@ type Driver struct { dst *Image maxImageSize int + + pool unsafe.Pointer } var theDriver Driver @@ -295,6 +311,23 @@ func Get() *Driver { return &theDriver } +func (d *Driver) Begin() { + // NSAutoreleasePool is required to release drawable correctly (#847). + // https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/MTLBestPracticesGuide/Drawables.html + mainthread.Run(func() error { + d.pool = C.allocAutoreleasePool() + return nil + }) +} + +func (d *Driver) End() { + mainthread.Run(func() error { + C.releaseAutoreleasePool(d.pool) + d.pool = nil + return nil + }) +} + func (d *Driver) SetWindow(window uintptr) { mainthread.Run(func() error { // Note that [NSApp mainWindow] returns nil when the window is borderless. diff --git a/internal/graphicsdriver/opengl/driver.go b/internal/graphicsdriver/opengl/driver.go index 25ddaf506..8f999a131 100644 --- a/internal/graphicsdriver/opengl/driver.go +++ b/internal/graphicsdriver/opengl/driver.go @@ -33,6 +33,14 @@ type Driver struct { context context } +func (d *Driver) Begin() { + // Do nothing. +} + +func (d *Driver) End() { + // Do nothing. +} + func (d *Driver) SetWindow(window uintptr) { // Do nothing. }