Compare commits

..

6 Commits

Author SHA1 Message Date
Bertrand Jung
3bd9149d4b
Merge 1dd96726c4 into a786f23e28 2024-09-09 15:54:30 +03:00
Hajime Hoshi
a786f23e28 cmd/ebitenmobile: add comments 2024-09-09 20:55:03 +09:00
Hajime Hoshi
2a4374e012 cmd/ebitenmobile: remove setStrictContextRestoration from EbitenViewController 2024-09-09 18:05:18 +09:00
Hajime Hoshi
7cc2f8ffcd cmd/ebitenmobile: add comments 2024-09-09 17:41:17 +09:00
Hajime Hoshi
07d29fa729 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.
2024-09-09 16:42:57 +09:00
Hajime Hoshi
fcef0a7c29 cmd/ebitenmobile: call setPreserveEGLContextOnPause(true) whatever the option is
We found that an app freezes for a little while when resuming it.
In order to improve user experience, always use
setPreserveEGLContextOnPause(true) whichever StrictContextRestoration is
true or false.
2024-09-09 15:20:04 +09:00
5 changed files with 29 additions and 32 deletions

View File

@ -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();
@ -96,8 +95,8 @@ class EbitenSurfaceView extends GLSurfaceView implements Renderer {
private void initialize() {
setEGLContextClientVersion(3);
setEGLConfigChooser(8, 8, 8, 8, 0, 0);
// setRenderer must be called before setRenderRequester.
// Or, the application crashes.
setPreserveEGLContextOnPause(true);
// setRenderer must be called before setRenderer. Or, setRenderMode in setExplicitRenderingMode will crash.
setRenderer(new EbitenRenderer());
Ebitenmobileview.setRenderer(this);
@ -115,6 +114,8 @@ class EbitenSurfaceView extends GLSurfaceView implements Renderer {
@Override
public synchronized void setExplicitRenderingMode(boolean explicitRendering) {
// TODO: Remove this logic when FPSModeVsyncOffMinimum is removed.
// This doesn't work when EbitenSurfaceView is recreated anyway.
if (explicitRendering) {
setRenderMode(RENDERMODE_WHEN_DIRTY);
} else {
@ -122,16 +123,6 @@ class EbitenSurfaceView extends GLSurfaceView implements Renderer {
}
}
@Override
public synchronized void setStrictContextRestoration(boolean strictContextRestoration) {
strictContextRestoration_ = strictContextRestoration;
setPreserveEGLContextOnPause(!strictContextRestoration);
}
private synchronized boolean hasStrictContextRestoration() {
return strictContextRestoration_;
}
@Override
public synchronized void requestRenderIfNeeded() {
if (getRenderMode() == RENDERMODE_WHEN_DIRTY) {

View File

@ -364,10 +364,6 @@
}
}
- (void)setStrictContextRestoration:(BOOL)strictContextRestoration {
// Do nothing.
}
- (void)setExplicitRenderingMode:(BOOL)explicitRendering {
@synchronized(self) {
explicitRendering_ = explicitRendering;

View File

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

View File

@ -132,3 +132,7 @@ func SetRenderer(renderer Renderer) {
func SetSetGameNotifier(setGameNotifier SetGameNotifier) {
theState.setSetGameNotifier(setGameNotifier)
}
func UsesStrictContextRestoration() bool {
return ui.Get().UsesStrictContextRestoration()
}

13
run.go
View File

@ -302,17 +302,20 @@ type RunGameOptions struct {
//
// StrictContextRestration is available only on Android. Otherwise, StrictContextRestration is ignored.
//
// When StrictContextRestration is false, Ebitengine tries to rely on the OS to restore the context.
// In Android, Ebitengien uses `GLSurfaceView`'s `setPreserveEGLContextOnPause(true)`.
// This works in most cases, but it is still possible that the context is lost in some minor cases.
// With StrictContextRestration false, the activity's launch mode should be singleInstance,
// or the activity no longer works correctly after the context is lost.
//
// When StrictContextRestration is true, Ebitengine tries to restore the context more strictly.
// This is useful when you want to restore the context in any case.
// When StrictContextRestration is true, Ebitengine tries to restore the context more strictly
// for such minor cases.
// However, this might cause a performance issue since Ebitengine tries to keep all the information
// to restore the context.
//
// When StrictContextRestration is false, Ebitengine does nothing special to restore the context and
// relies on the OS's behavior.
//
// As a side note, especially when StrictContextRestration is false, the activity's launch mode should
// be singleInstance, or the activity no longer works correctly after the context is lost.
//
// The default (zero) value is false.
StrictContextRestration bool
}