mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
internal/ui: re-enable skipping to render the final screen when possible
With Metal, nextDrawable could return immediately when a command buffer is empty. To avoid high CPU usage, this change adds a slight sleep in this case. With DirectX, Present waits for a while even though nothing is updated, then that's fine. Updates #2341 Updates #2342 Updates #2520
This commit is contained in:
parent
edb952c9e7
commit
7418576c16
@ -19,6 +19,7 @@ import (
|
||||
"math"
|
||||
"runtime"
|
||||
"sort"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/internal/cocoa"
|
||||
@ -58,6 +59,8 @@ type Graphics struct {
|
||||
maxImageSize int
|
||||
tmpTextures []mtl.Texture
|
||||
|
||||
lastFlush time.Time
|
||||
|
||||
pool cocoa.NSAutoreleasePool
|
||||
}
|
||||
|
||||
@ -211,14 +214,26 @@ func (g *Graphics) flushIfNeeded(present bool) {
|
||||
if g.cb == (mtl.CommandBuffer{}) && !present {
|
||||
return
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
defer func() {
|
||||
g.lastFlush = now
|
||||
}()
|
||||
|
||||
g.flushRenderCommandEncoderIfNeeded()
|
||||
|
||||
if present {
|
||||
// This check is necessary when skipping to render the screen (SetScreenClearedEveryFrame(false)).
|
||||
if g.screenDrawable == (ca.MetalDrawable{}) {
|
||||
// nextDrawable can return immediately when the command buffer is empty.
|
||||
// TODO: Can we wait for a while to get the next drawable? (#2520)
|
||||
g.screenDrawable = g.view.nextDrawable()
|
||||
if g.cb != (mtl.CommandBuffer{}) {
|
||||
g.screenDrawable = g.view.nextDrawable()
|
||||
} else {
|
||||
if delta := time.Second/60 - now.Sub(g.lastFlush); delta > 0 {
|
||||
// nextDrawable can return immediately when the command buffer is empty.
|
||||
// To avoid busy, sleep instead (#2520).
|
||||
time.Sleep(delta)
|
||||
}
|
||||
}
|
||||
}
|
||||
if g.screenDrawable != (ca.MetalDrawable{}) {
|
||||
g.cb.PresentDrawable(g.screenDrawable)
|
||||
|
@ -198,11 +198,7 @@ func (c *context) drawGame(graphicsDriver graphicsdriver.Graphics, forceDraw boo
|
||||
c.skipCount = 0
|
||||
}
|
||||
|
||||
skippable := c.skipCount >= maxSkipCount
|
||||
|
||||
// TODO: Metal (and maybe DirectX) cannot vsync without swapping the buffer by rendering the screen framebuffer (#2520).
|
||||
// Implement this skipping appropriately for Metal and DirectX.
|
||||
if !skippable || !graphicsDriver.IsGL() {
|
||||
if c.skipCount < maxSkipCount {
|
||||
if graphicsDriver.NeedsClearingScreen() {
|
||||
// This clear is needed for fullscreen mode or some mobile platforms (#622).
|
||||
c.screen.clear()
|
||||
|
Loading…
Reference in New Issue
Block a user