From 07d29fa729ccbc8aa6c6b522722bd5d528c3e13e Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Mon, 9 Sep 2024 16:27:54 +0900 Subject: [PATCH] cmd/ebitenmobile: bug fix: consider EbitenSurfaceView recreation On Android Emulator (Small Desktop API 32), EbitenRenderer can be easily recreated by resizing the window. Thus, EbitenRenderer should not have any flags like strictContextRestoration. Also, the flag onceSurfaceCreated_ doesn't work there. --- .../_files/EbitenSurfaceView.java | 20 +++++-------------- internal/ui/ui_mobile.go | 13 +++++++----- mobile/ebitenmobileview/mobile.go | 4 ++++ 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/cmd/ebitenmobile/_files/EbitenSurfaceView.java b/cmd/ebitenmobile/_files/EbitenSurfaceView.java index 63a82d995..f645ddb0a 100644 --- a/cmd/ebitenmobile/_files/EbitenSurfaceView.java +++ b/cmd/ebitenmobile/_files/EbitenSurfaceView.java @@ -59,12 +59,13 @@ class EbitenSurfaceView extends GLSurfaceView implements Renderer { @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { - if (!onceSurfaceCreated_) { - onceSurfaceCreated_ = true; + // As EbitenSurfaceView can be recreated anytime, this flag for strict context restoration must be checked every time. + if (Ebitenmobileview.usesStrictContextRestoration()) { + Ebitenmobileview.onContextLost(); return; } - if (hasStrictContextRestoration()) { - Ebitenmobileview.onContextLost(); + if (!onceSurfaceCreated_) { + onceSurfaceCreated_ = true; return; } contextLost_ = true; @@ -81,8 +82,6 @@ class EbitenSurfaceView extends GLSurfaceView implements Renderer { } } - private boolean strictContextRestoration_ = false; - public EbitenSurfaceView(Context context) { super(context); initialize(); @@ -123,15 +122,6 @@ class EbitenSurfaceView extends GLSurfaceView implements Renderer { } } - @Override - public synchronized void setStrictContextRestoration(boolean strictContextRestoration) { - strictContextRestoration_ = strictContextRestoration; - } - - private synchronized boolean hasStrictContextRestoration() { - return strictContextRestoration_; - } - @Override public synchronized void requestRenderIfNeeded() { if (getRenderMode() == RENDERMODE_WHEN_DIRTY) { diff --git a/internal/ui/ui_mobile.go b/internal/ui/ui_mobile.go index be0ed62bb..d755798e3 100644 --- a/internal/ui/ui_mobile.go +++ b/internal/ui/ui_mobile.go @@ -101,7 +101,7 @@ type userInterfaceImpl struct { fpsMode atomic.Int32 renderer Renderer - strictContextRestoration bool + strictContextRestoration atomic.Bool strictContextRestorationOnce sync.Once m sync.RWMutex @@ -156,11 +156,11 @@ func (u *UserInterface) runMobile(game Game, options *RunOptions) (err error) { u.graphicsDriver = g u.setGraphicsLibrary(lib) close(u.graphicsLibraryInitCh) - u.strictContextRestoration = options.StrictContextRestoration - if !u.strictContextRestoration { + if options.StrictContextRestoration { + u.strictContextRestoration.Store(true) + } else { restorable.Disable() } - u.renderer.SetStrictContextRestoration(u.strictContextRestoration) for { if err := u.update(); err != nil { @@ -312,7 +312,6 @@ func (u *UserInterface) UpdateInput(keys map[Key]struct{}, runes []rune, touches type Renderer interface { SetExplicitRenderingMode(explicitRendering bool) - SetStrictContextRestoration(strictContextRestoration bool) RequestRenderIfNeeded() } @@ -331,6 +330,10 @@ func (u *UserInterface) updateIconIfNeeded() error { return nil } +func (u *UserInterface) UsesStrictContextRestoration() bool { + return u.strictContextRestoration.Load() +} + func IsScreenTransparentAvailable() bool { return false } diff --git a/mobile/ebitenmobileview/mobile.go b/mobile/ebitenmobileview/mobile.go index 9c3ad5ff5..7344b817e 100644 --- a/mobile/ebitenmobileview/mobile.go +++ b/mobile/ebitenmobileview/mobile.go @@ -132,3 +132,7 @@ func SetRenderer(renderer Renderer) { func SetSetGameNotifier(setGameNotifier SetGameNotifier) { theState.setSetGameNotifier(setGameNotifier) } + +func UsesStrictContextRestoration() bool { + return ui.Get().UsesStrictContextRestoration() +}