2
0
mirror of synced 2025-02-20 13:38:20 +00:00

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 <hyangah@gmail.com>
This commit is contained in:
David Crawshaw 2015-10-06 12:17:06 -04:00
parent 1bbb04430a
commit 8a578fa6ca
4 changed files with 18 additions and 29 deletions

View File

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

View File

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

View File

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

View File

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