forked from joejulian/gio
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 <mail@eliasnaur.com>
This commit is contained in:
+11
-12
@@ -8,6 +8,7 @@ import (
|
|||||||
"image"
|
"image"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"gioui.org/app/internal/gl"
|
||||||
"gioui.org/app/internal/gpu"
|
"gioui.org/app/internal/gpu"
|
||||||
"gioui.org/app/internal/input"
|
"gioui.org/app/internal/input"
|
||||||
"gioui.org/app/internal/window"
|
"gioui.org/app/internal/window"
|
||||||
@@ -261,26 +262,20 @@ func (w *Window) run(opts *window.Options) {
|
|||||||
w.hasNextFrame = false
|
w.hasNextFrame = false
|
||||||
e2.Frame = w.update
|
e2.Frame = w.update
|
||||||
w.out <- e2.FrameEvent
|
w.out <- e2.FrameEvent
|
||||||
|
var err error
|
||||||
if w.gpu != nil {
|
if w.gpu != nil {
|
||||||
if e2.Sync {
|
if e2.Sync {
|
||||||
w.gpu.Refresh()
|
w.gpu.Refresh()
|
||||||
}
|
}
|
||||||
if err := w.gpu.Flush(); err != nil {
|
if err = w.gpu.Flush(); err != nil {
|
||||||
w.gpu.Release()
|
w.gpu.Release()
|
||||||
w.gpu = nil
|
w.gpu = nil
|
||||||
w.destroy(err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx, err := w.driver.NewContext()
|
var ctx gl.Context
|
||||||
if err != nil {
|
ctx, err = w.driver.NewContext()
|
||||||
w.destroy(err)
|
if err == nil {
|
||||||
return
|
w.gpu, err = gpu.NewGPU(ctx)
|
||||||
}
|
|
||||||
w.gpu, err = gpu.NewGPU(ctx)
|
|
||||||
if err != nil {
|
|
||||||
w.destroy(err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var frame *op.Ops
|
var frame *op.Ops
|
||||||
@@ -290,6 +285,10 @@ func (w *Window) run(opts *window.Options) {
|
|||||||
case frame = <-w.frames:
|
case frame = <-w.frames:
|
||||||
case w.out <- ackEvent:
|
case w.out <- ackEvent:
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
w.destroy(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
w.draw(e2.Size, frame)
|
w.draw(e2.Size, frame)
|
||||||
if e2.Sync {
|
if e2.Sync {
|
||||||
if err := w.gpu.Flush(); err != nil {
|
if err := w.gpu.Flush(); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user