From 8a578fa6caebfe37737209387c5fd07cb2038f59 Mon Sep 17 00:00:00 2001 From: David Crawshaw Date: Tue, 6 Oct 2015 12:17:06 -0400 Subject: [PATCH] app: move glctx into app.App Also move the initialization of glctx to an init function, removing the data race mentioned in golang/go#12718. (Unfortunately the data race is not the cause of the bug.) Change-Id: If5f1fd7755d5645cf25ccc780ee8d138011c8f10 Reviewed-on: https://go-review.googlesource.com/15460 Reviewed-by: Hyang-Ah Hana Kim --- app/android.go | 7 ++----- app/app.go | 12 +++++++----- app/darwin_amd64.go | 13 +++++-------- app/darwin_armx.go | 15 ++++----------- 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/app/android.go b/app/android.go index 9e18c1a..30cc6f1 100644 --- a/app/android.go +++ b/app/android.go @@ -64,7 +64,6 @@ import ( "golang.org/x/mobile/event/size" "golang.org/x/mobile/event/touch" "golang.org/x/mobile/geom" - "golang.org/x/mobile/gl" "golang.org/x/mobile/internal/mobileinit" ) @@ -268,9 +267,7 @@ func main(f func(App)) { var mainUserFn func(App) func mainUI(vm, jniEnv, ctx uintptr) error { - var worker gl.Worker - glctx, worker = gl.NewContext() - workAvailable := worker.WorkAvailable() + workAvailable := theApp.worker.WorkAvailable() donec := make(chan struct{}) go func() { @@ -331,7 +328,7 @@ func mainUI(vm, jniEnv, ctx uintptr) error { C.surface = nil theApp.sendLifecycle(lifecycle.StageAlive) case <-workAvailable: - worker.DoWork() + theApp.worker.DoWork() case <-theApp.publish: // TODO: compare a generation number to redrawGen for stale paints? if C.surface != nil { diff --git a/app/app.go b/app/app.go index 44cca84..720dba4 100644 --- a/app/app.go +++ b/app/app.go @@ -67,10 +67,9 @@ var theApp = &app{ publishResult: make(chan PublishResult), } -var glctx gl.Context // TODO: move into theApp - func init() { theApp.eventsIn = pump(theApp.eventsOut) + theApp.glctx, theApp.worker = gl.NewContext() } func (a *app) sendLifecycle(to lifecycle.Stage) { @@ -80,7 +79,7 @@ func (a *app) sendLifecycle(to lifecycle.Stage) { a.eventsIn <- lifecycle.Event{ From: a.lifecycleStage, To: to, - DrawContext: glctx, + DrawContext: a.glctx, } a.lifecycleStage = to } @@ -93,6 +92,9 @@ type app struct { lifecycleStage lifecycle.Stage publish chan struct{} publishResult chan PublishResult + + glctx gl.Context + worker gl.Worker } func (a *app) Events() <-chan interface{} { @@ -111,7 +113,7 @@ func (a *app) Publish() PublishResult { // // This enforces that the final receive (for this paint cycle) on // gl.WorkAvailable happens before the send on endPaint. - glctx.Flush() + a.glctx.Flush() a.publish <- struct{}{} return <-a.publishResult } @@ -199,7 +201,7 @@ func pump(dst chan interface{}) (src chan interface{}) { func (a *app) registerGLViewportFilter() { a.RegisterFilter(func(e interface{}) interface{} { if e, ok := e.(size.Event); ok { - glctx.Viewport(0, 0, e.WidthPx, e.HeightPx) + a.glctx.Viewport(0, 0, e.WidthPx, e.HeightPx) } return e }) diff --git a/app/darwin_amd64.go b/app/darwin_amd64.go index 9351c82..dcee145 100644 --- a/app/darwin_amd64.go +++ b/app/darwin_amd64.go @@ -34,7 +34,6 @@ import ( "golang.org/x/mobile/event/size" "golang.org/x/mobile/event/touch" "golang.org/x/mobile/geom" - "golang.org/x/mobile/gl" ) var initThreadID uint64 @@ -75,23 +74,21 @@ func main(f func(App)) { // draw events is the CVDisplayLink timer, which is tied to the display // vsync. Secondary draw events come from [NSView drawRect:] when the // window is resized. -func loop(ctx C.GLintptr) { +func (a *app) loop(ctx C.GLintptr) { runtime.LockOSThread() C.makeCurrentContext(ctx) - var worker gl.Worker - glctx, worker = gl.NewContext() - workAvailable := worker.WorkAvailable() + workAvailable := a.worker.WorkAvailable() for { select { case <-workAvailable: - worker.DoWork() + a.worker.DoWork() case <-draw: loop1: for { select { case <-workAvailable: - worker.DoWork() + a.worker.DoWork() case <-theApp.publish: C.CGLFlushDrawable(C.CGLGetCurrentContext()) theApp.publishResult <- PublishResult{} @@ -116,7 +113,7 @@ func drawgl() { //export startloop func startloop(ctx C.GLintptr) { - go loop(ctx) + go theApp.loop(ctx) } var windowHeightPx float32 diff --git a/app/darwin_armx.go b/app/darwin_armx.go index 01f43ee..5344e27 100644 --- a/app/darwin_armx.go +++ b/app/darwin_armx.go @@ -34,7 +34,6 @@ import ( "golang.org/x/mobile/event/size" "golang.org/x/mobile/event/touch" "golang.org/x/mobile/geom" - "golang.org/x/mobile/gl" ) var initThreadID uint64 @@ -166,19 +165,13 @@ func sendTouch(cTouch, cTouchType uintptr, x, y float32) { } } -var ( - worker gl.Worker - workAvailable <-chan struct{} -) +var workAvailable <-chan struct{} //export drawgl func drawgl(ctx uintptr) { - if glctx == nil { + if workAvailable == nil { C.setContext(unsafe.Pointer(ctx)) - - glctx, worker = gl.NewContext() - workAvailable = worker.WorkAvailable() - + workAvailable = theApp.worker.WorkAvailable() // TODO(crawshaw): not just on process start. theApp.sendLifecycle(lifecycle.StageFocused) } @@ -190,7 +183,7 @@ func drawgl(ctx uintptr) { for { select { case <-workAvailable: - worker.DoWork() + theApp.worker.DoWork() case <-theApp.publish: theApp.publishResult <- PublishResult{} return