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: Windows event handling back-pressure #17325

Open
egonelbre opened this Issue Oct 3, 2016 · 1 comment

Comments

Projects
None yet
4 participants
@egonelbre
Contributor

egonelbre commented Oct 3, 2016

Using go 1.7.1/Windows 7/amd64. x/mobile at 16fd47fa04e0a40c643b41876f91f3d06dded396 + fix from #16991.

This is issue can easily be seen when resizing the window: basic and centering.

theApp event queue contains an infinite buffer in x\mobile\app\app.go and when Windows sends messages at a high rate -- e.g. during a window resize -- the whole interface becomes laggy.

Windows sends events as fast as you let it -- but since there is no back-pressure in x\mobile\app\shiny.go the queue gets flooded with Paint and Resize events.

PS: It could become an issue in shiny as well, because it also contains async handling of messages. However ATM there is no infinite queue, at least I couldn't find one, hence it provides some back-pressure which prevents Windows from flooding the queue.

@quentinmit quentinmit modified the milestone: Unreleased Oct 4, 2016

@egonelbre

This comment has been minimized.

Contributor

egonelbre commented Mar 7, 2017

Note, this buffering can be avoided by detaching handling paint event and other events from doing the actual painting:

func main() {
	app.Main(func(a app.App) {
		var glctx gl.Context
		var sz size.Event 
		tick := time.NewTicker(15 * time.Millisecond)
		events := a.Events()
		for {
			select {
			case e := <-events:
				switch e := a.Filter(e).(type) {
					case lifecycle.Event:
						switch e.Crosses(lifecycle.StageVisible) {
						case lifecycle.CrossOn:
							glctx, _ = e.DrawContext.(gl.Context)
							onStart(glctx)
						case lifecycle.CrossOff:
							onStop(glctx)
							glctx = nil
						}
					case size.Event:
						sz = e
						touchX = float32(sz.WidthPx / 2)
						touchY = float32(sz.HeightPx / 2)
					case paint.Event:
						// nothing to do here
					case touch.Event:
						touchX = e.X
						touchY = e.Y
					} 
			case <-tick:
				if glctx != nil {
					onPaint(glctx, sz)
					a.Publish()
				}
			}
		}
	})
}

However, here the painting is not timed correctly together with resizing, which can cause some distortion and we cannot handle inside size.Event due to potential flooding. There's also a potential for not handling frames at the correct time.

@gopherbot gopherbot added the mobile label Jul 20, 2017

@bradfitz bradfitz added the OS-Windows label Nov 21, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment