internal/ui: bug fix: an offscreen was broken with SetScreenClearedEveryFrame(false)

Updates #2500
Closes #2510
This commit is contained in:
Hajime Hoshi 2022-12-29 14:41:54 +09:00
parent cba6905c57
commit 5e17791e4e
2 changed files with 12 additions and 7 deletions

View File

@ -204,6 +204,7 @@ func (g *Graphics) flushIfNeeded(present bool) {
} }
g.flushRenderCommandEncoderIfNeeded() g.flushRenderCommandEncoderIfNeeded()
// This logic is necessary when skipping clearing the framebuffer.
if present && g.screenDrawable == (ca.MetalDrawable{}) { if present && g.screenDrawable == (ca.MetalDrawable{}) {
g.screenDrawable = g.view.nextDrawable() g.screenDrawable = g.view.nextDrawable()
} }

View File

@ -152,11 +152,19 @@ func (c *context) updateFrameImpl(graphicsDriver graphicsdriver.Graphics, update
return nil return nil
} }
func (c *context) newOffscreenImage(w, h int) *Image {
img := c.game.NewOffscreenImage(w, h)
img.modifyCallback = func() {
c.isOffscreenModified = true
}
return img
}
func (c *context) drawGame(graphicsDriver graphicsdriver.Graphics, forceDraw bool) error { func (c *context) drawGame(graphicsDriver graphicsdriver.Graphics, forceDraw bool) error {
if (c.offscreen.imageType == atlas.ImageTypeVolatile) != theGlobalState.isScreenClearedEveryFrame() { if (c.offscreen.imageType == atlas.ImageTypeVolatile) != theGlobalState.isScreenClearedEveryFrame() {
w, h := c.offscreen.width, c.offscreen.height w, h := c.offscreen.width, c.offscreen.height
c.offscreen.MarkDisposed() c.offscreen.MarkDisposed()
c.offscreen = c.game.NewOffscreenImage(w, h) c.offscreen = c.newOffscreenImage(w, h)
} }
// isOffscreenModified is updated when an offscreen's modifyCallback. // isOffscreenModified is updated when an offscreen's modifyCallback.
@ -173,8 +181,7 @@ func (c *context) drawGame(graphicsDriver graphicsdriver.Graphics, forceDraw boo
return err return err
} }
// 180 might be too big but this is a enough value to consider exiting from fullscreen on macOS (#2500). const maxSkipCount = 3
const maxSkipCount = 180
if !forceDraw && !c.isOffscreenModified { if !forceDraw && !c.isOffscreenModified {
if c.skipCount < maxSkipCount { if c.skipCount < maxSkipCount {
@ -234,10 +241,7 @@ func (c *context) layoutGame(outsideWidth, outsideHeight float64, deviceScaleFac
} }
} }
if c.offscreen == nil { if c.offscreen == nil {
c.offscreen = c.game.NewOffscreenImage(ow, oh) c.offscreen = c.newOffscreenImage(ow, oh)
c.offscreen.modifyCallback = func() {
c.isOffscreenModified = true
}
} }
return ow, oh return ow, oh