From 9126da41f453f9999d7f766b2f33189810fe319d Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Fri, 1 Nov 2019 19:38:13 +0100 Subject: [PATCH] app: accept pending frame before reporting error If creating a GPU instance fails for some reason, we need to receive the incoming frame from the application before reporting the error in a DestroyEvent. If we don't, the a deadlock will occur where the app is waiting for FrameEvent.Frame to complete, while the Window waits for the app the receive a DestroyEvent. Signed-off-by: Elias Naur --- app/window.go | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/app/window.go b/app/window.go index 509b3d19..eb3ab233 100644 --- a/app/window.go +++ b/app/window.go @@ -8,6 +8,7 @@ import ( "image" "time" + "gioui.org/app/internal/gl" "gioui.org/app/internal/gpu" "gioui.org/app/internal/input" "gioui.org/app/internal/window" @@ -261,26 +262,20 @@ func (w *Window) run(opts *window.Options) { w.hasNextFrame = false e2.Frame = w.update w.out <- e2.FrameEvent + var err error if w.gpu != nil { if e2.Sync { w.gpu.Refresh() } - if err := w.gpu.Flush(); err != nil { + if err = w.gpu.Flush(); err != nil { w.gpu.Release() w.gpu = nil - w.destroy(err) - return } } else { - ctx, err := w.driver.NewContext() - if err != nil { - w.destroy(err) - return - } - w.gpu, err = gpu.NewGPU(ctx) - if err != nil { - w.destroy(err) - return + var ctx gl.Context + ctx, err = w.driver.NewContext() + if err == nil { + w.gpu, err = gpu.NewGPU(ctx) } } var frame *op.Ops @@ -290,6 +285,10 @@ func (w *Window) run(opts *window.Options) { case frame = <-w.frames: case w.out <- ackEvent: } + if err != nil { + w.destroy(err) + return + } w.draw(e2.Size, frame) if e2.Sync { if err := w.gpu.Flush(); err != nil {