func windowDraw(w *C.ANativeWindow, queue *C.AInputQueue, donec chan struct{}) (done bool) { C.createEGLWindow(w) // TODO: is this needed if we also have the "case <-windowRedrawNeeded:" below?? sendLifecycle(lifecycle.StageFocused) eventsIn <- config.Event{ Width: geom.Pt(float32(C.windowWidth) / pixelsPerPt), Height: geom.Pt(float32(C.windowHeight) / pixelsPerPt), PixelsPerPt: pixelsPerPt, } if firstWindowDraw { firstWindowDraw = false // TODO: be more principled about when to send a paint event. eventsIn <- paint.Event{} } for { processEvents(queue) select { case <-donec: return true case <-windowRedrawNeeded: // Re-query the width and height. C.querySurfaceWidthAndHeight() sendLifecycle(lifecycle.StageFocused) eventsIn <- config.Event{ Width: geom.Pt(float32(C.windowWidth) / pixelsPerPt), Height: geom.Pt(float32(C.windowHeight) / pixelsPerPt), PixelsPerPt: pixelsPerPt, } case <-windowDestroyed: sendLifecycle(lifecycle.StageAlive) return false case <-gl.WorkAvailable: gl.DoWork() case <-endDraw: // eglSwapBuffers blocks until vsync. C.eglSwapBuffers(C.display, C.surface) eventsIn <- paint.Event{} } } }
func windowDraw(w *C.ANativeWindow, queue *C.AInputQueue, donec chan struct{}) (done bool) { C.createEGLWindow(w) // TODO: is this needed if we also have the "case <-windowRedrawNeeded:" below?? sendLifecycle(event.LifecycleStageFocused) eventsIn <- event.Config{ Width: geom.Pt(float32(C.windowWidth) / pixelsPerPt), Height: geom.Pt(float32(C.windowHeight) / pixelsPerPt), PixelsPerPt: pixelsPerPt, } if firstWindowDraw { firstWindowDraw = false // TODO: be more principled about when to send a draw event. eventsIn <- event.Draw{} } for { processEvents(queue) select { case <-donec: return true case <-windowRedrawNeeded: // Re-query the width and height. C.querySurfaceWidthAndHeight() sendLifecycle(event.LifecycleStageFocused) eventsIn <- event.Config{ Width: geom.Pt(float32(C.windowWidth) / pixelsPerPt), Height: geom.Pt(float32(C.windowHeight) / pixelsPerPt), PixelsPerPt: pixelsPerPt, } // This gl.Viewport call has to be in a separate goroutine because any gl // call can block until gl.DoWork is called, but this goroutine is the one // responsible for calling gl.DoWork. // TODO: again, should x/mobile/app be responsible for calling GL code, or // should package gl instead call event.RegisterFilter? { c := make(chan struct{}) go func() { gl.Viewport(0, 0, int(C.windowWidth), int(C.windowHeight)) close(c) }() loop1: for { select { case <-gl.WorkAvailable: gl.DoWork() case <-c: break loop1 } } } case <-windowDestroyed: sendLifecycle(event.LifecycleStageAlive) return false case <-gl.WorkAvailable: gl.DoWork() case <-endDraw: // eglSwapBuffers blocks until vsync. C.eglSwapBuffers(C.display, C.surface) eventsIn <- event.Draw{} } } }