internal/graphicsdriver/metal: bug fix: use 3 drawables for fullscreen

Closes #2880
This commit is contained in:
Hajime Hoshi 2024-01-02 22:13:57 +09:00
parent dddfb7317b
commit 3c7bcf3035
3 changed files with 46 additions and 15 deletions

View File

@ -22,16 +22,16 @@ import (
)
type view struct {
window uintptr
uiview uintptr
windowChanged bool
vsyncDisabled bool
device mtl.Device
ml ca.MetalLayer
maximumDrawableCount int
once sync.Once
viewPlatform
}
func (v *view) setDrawableSize(width, height int) {
@ -52,14 +52,24 @@ func (v *view) setDisplaySyncEnabled(enabled bool) {
func (v *view) forceSetDisplaySyncEnabled(enabled bool) {
v.ml.SetDisplaySyncEnabled(enabled)
v.vsyncDisabled = !enabled
v.updateMaximumDrawableCount()
}
if v.vsyncDisabled {
func (v *view) updateMaximumDrawableCount() {
var count int
if v.vsyncDisabled || v.isFullscreen() {
// Apparently 2 makes FPS half. Use 3.
v.ml.SetMaximumDrawableCount(3)
count = 3
} else {
// Use 2 in a usual case not to cause rendering delays (#2822).
v.ml.SetMaximumDrawableCount(2)
count = 2
}
if v.maximumDrawableCount == count {
return
}
v.ml.SetMaximumDrawableCount(count)
v.maximumDrawableCount = count
}
func (v *view) colorPixelFormat() mtl.PixelFormat {

View File

@ -42,6 +42,10 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal/mtl"
)
type viewPlatform struct {
uiview uintptr
}
func (v *view) setWindow(window uintptr) {
panic("metal: setWindow is not available on iOS")
}
@ -60,6 +64,10 @@ func (v *view) update() {
C.setFrame(v.ml.Layer(), unsafe.Pointer(v.uiview))
}
func (v *view) isFullscreen() bool {
return false
}
const (
storageMode = mtl.StorageModeShared
resourceStorageMode = mtl.ResourceStorageModeShared

View File

@ -23,9 +23,15 @@ import (
"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal/mtl"
)
type viewPlatform struct {
window cocoa.NSWindow
windowChanged bool
fullscreen bool
}
func (v *view) setWindow(window uintptr) {
// NSView can be updated e.g., fullscreen-state is switched.
v.window = window
v.window = cocoa.NSWindow{ID: objc.ID(window)}
v.windowChanged = true
}
@ -34,15 +40,22 @@ func (v *view) setUIView(uiview uintptr) {
}
func (v *view) update() {
if !v.windowChanged {
return
if v.windowChanged {
// TODO: Should this be called on the main thread?
v.window.ContentView().SetLayer(uintptr(v.ml.Layer()))
v.window.ContentView().SetWantsLayer(true)
v.windowChanged = false
}
// TODO: Should this be called on the main thread?
cocoaWindow := cocoa.NSWindow{ID: objc.ID(v.window)}
cocoaWindow.ContentView().SetLayer(uintptr(v.ml.Layer()))
cocoaWindow.ContentView().SetWantsLayer(true)
v.windowChanged = false
fullscreen := v.window.StyleMask()&cocoa.NSWindowStyleMaskFullScreen != 0
if v.fullscreen != fullscreen {
v.fullscreen = fullscreen
v.updateMaximumDrawableCount()
}
}
func (v *view) isFullscreen() bool {
return v.fullscreen
}
const (