Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/mobile: application freeze after resumed from suspend state on iOS #27483

Open
ntop001 opened this issue Sep 4, 2018 · 5 comments
Open

x/mobile: application freeze after resumed from suspend state on iOS #27483

ntop001 opened this issue Sep 4, 2018 · 5 comments
Labels
mobile Android, iOS, and x/mobile
Milestone

Comments

@ntop001
Copy link

ntop001 commented Sep 4, 2018

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.8.1 darwin/amd64

Does this issue reproduce with the latest release?

YES

What did you do?

Git clone the basic example, change the lifecycle code to:

switch e.Crosses(lifecycle.StageAlive) {
	case lifecycle.CrossOn:
		glctx, _ = e.DrawContext.(gl.Context)
		onStart(glctx)
		a.Send(paint.Event{})
	case lifecycle.CrossOff:
		onStop(glctx)
		glctx = nil
	}

In the original code, use switch e.Crosses(lifecycle. StageVisible) to manage lifecycle, but this code will result in create/destroy gl resource each time the application resume/pause. In practical app, we should use e.Crosses(lifecycle.StageAlive), but this will result in application freeze if app just resumed from suspend state in iOS. I have written a native iOS app with Obj-C/GLKView, but it doesn't have the problem, it must be a bug in gomobile .

(PS: Android will just lost glContext, I have created another issue for Android).

What did you expect to see?

The example don't freeze after resumed from suspend state on iOS.

What did you see instead?

The example freezed.

@gopherbot gopherbot added this to the Unreleased milestone Sep 4, 2018
@gopherbot gopherbot added the mobile Android, iOS, and x/mobile label Sep 4, 2018
@ntop001
Copy link
Author

ntop001 commented Sep 4, 2018

I have made some experiments, in the 'darwin_ios.m' file, we can see the swapBuffers method:

void swapBuffers(GLintptr context) {
	__block EAGLContext* ctx = (EAGLContext*)context;
	dispatch_sync(dispatch_get_main_queue(), ^{
		[EAGLContext setCurrentContext:ctx];
		[ctx presentRenderbuffer:GL_RENDERBUFFER];
	});
}

If the App just resumed from the background, we can call [glview display] manually to restore GLKView' state, then very thing works well. There must be some code in the method, like bind framebuffer/renderbuffer... But gomobile didn't do these in the swapBuffers method.

But call [glview display] manually will has some unpredictable behavior, some times the app will just cash. In the old implementation, gomobile use ViewController's update loop:

- (void)update {
	drawgl((GoUintptr)self.context);
}

But in the current implementation, it use a custom for loop:

func (a *app) loop(ctx C.GLintptr) {
	runtime.LockOSThread()
	C.makeCurrentContext(ctx)

	workAvailable := a.worker.WorkAvailable()

	for {
		select {
		case <-workAvailable:
			a.worker.DoWork()
		case <-theApp.publish:
		loop1:
			for {
				select {
				case <-workAvailable:
					a.worker.DoWork()
				default:
					break loop1
				}
			}
			C.swapBuffers(ctx)
			theApp.publishResult <- PublishResult{}
		}
	}
}

And in cocos2dx, they use the CADisplayLink's loop(Apple best practice). So, is there any special reasons to use custom loop, and is there any quick way to fix this bug? @eliasnaur @crawshaw

@andydotxyz
Copy link
Contributor

Has anyone made progress on this?
I took the suggestion of @ntop001 but by calling [glview display] I found that more often than not the restoring app would crash.
Of course after that it comes back to life so perversely it's a small improvement over the frozen option...

@ntop001
Copy link
Author

ntop001 commented Aug 23, 2019

@andydotxyz You can see my fixes here: KorokEngine/mobile@744fe39 . I have test it on Mac/PC/Android/iOS, it works well.

@andydotxyz
Copy link
Contributor

Oh you're a life saver. I hope you don't mind but I cherry-picked your fixes on top of the latest golang.org/x/mobile along with my own compile fixes - that's all at fyne-io/mobile, check it out if you like.

@gopherbot
Copy link

Change https://golang.org/cl/350211 mentions this issue: app: use system render loop on iOS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mobile Android, iOS, and x/mobile
Projects
None yet
Development

No branches or pull requests

3 participants