graphicsdriver/metal: Use NSAutoreleasePool to release drawable correctly

Fixes #847
This commit is contained in:
Hajime Hoshi 2019-04-20 15:17:59 +09:00
parent bfe1d2208e
commit a064955a13
4 changed files with 46 additions and 0 deletions

View File

@ -20,6 +20,8 @@ import (
)
type Graphics interface {
Begin()
End()
SetWindow(window uintptr)
SetVertices(vertices []float32, indices []uint16)
Flush()

View File

@ -159,6 +159,8 @@ func (q *commandQueue) Flush() {
if recordLog() {
fmt.Println("--")
}
theGraphicsDriver.Begin()
for len(q.commands) > 0 {
nv := 0
ne := 0
@ -199,6 +201,7 @@ func (q *commandQueue) Flush() {
}
q.commands = q.commands[nc:]
}
theGraphicsDriver.End()
q.commands = nil
q.nvertices = 0
q.nindices = 0

View File

@ -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 <Foundation/Foundation.h>
//
// static void* allocAutoreleasePool() {
// return [[NSAutoreleasePool alloc] init];
// }
//
// static void releaseAutoreleasePool(void* pool) {
// [(NSAutoreleasePool*)pool release];
// }
import "C"
const source = `#include <metal_stdlib>
#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.

View File

@ -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.
}