mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 10:25:37 +00:00
app: don't touch the frame after returning from FrameEvent.Frame
It was already true that the GPU wouldn't touch the frame after calling GPU.Draw. This change makes FrameEvent.Frame block until GPU.Draw is complete. Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
+15
-2
@@ -36,6 +36,7 @@ type Window struct {
|
|||||||
ack chan struct{}
|
ack chan struct{}
|
||||||
invalidates chan struct{}
|
invalidates chan struct{}
|
||||||
frames chan *op.Ops
|
frames chan *op.Ops
|
||||||
|
frameAck chan struct{}
|
||||||
|
|
||||||
stage system.Stage
|
stage system.Stage
|
||||||
animating bool
|
animating bool
|
||||||
@@ -95,6 +96,7 @@ func NewWindow(options ...Option) *Window {
|
|||||||
ack: make(chan struct{}),
|
ack: make(chan struct{}),
|
||||||
invalidates: make(chan struct{}, 1),
|
invalidates: make(chan struct{}, 1),
|
||||||
frames: make(chan *op.Ops),
|
frames: make(chan *op.Ops),
|
||||||
|
frameAck: make(chan struct{}),
|
||||||
}
|
}
|
||||||
w.callbacks.w = w
|
w.callbacks.w = w
|
||||||
go w.run(opts)
|
go w.run(opts)
|
||||||
@@ -118,6 +120,7 @@ func (w *Window) Queue() *Queue {
|
|||||||
// the window state from previous calls.
|
// the window state from previous calls.
|
||||||
func (w *Window) update(frame *op.Ops) {
|
func (w *Window) update(frame *op.Ops) {
|
||||||
w.frames <- frame
|
w.frames <- frame
|
||||||
|
<-w.frameAck
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) draw(size image.Point, frame *op.Ops) {
|
func (w *Window) draw(size image.Point, frame *op.Ops) {
|
||||||
@@ -279,17 +282,27 @@ func (w *Window) run(opts *window.Options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var frame *op.Ops
|
var frame *op.Ops
|
||||||
// Wait for either a frame or the ack event,
|
// Wait for either a frame or an ack event to go
|
||||||
// which meant that the client didn't draw.
|
// through, which means that the client didn't give us
|
||||||
|
// a frame.
|
||||||
|
gotFrame := false
|
||||||
select {
|
select {
|
||||||
case frame = <-w.frames:
|
case frame = <-w.frames:
|
||||||
|
gotFrame = true
|
||||||
case w.out <- ackEvent:
|
case w.out <- ackEvent:
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if gotFrame {
|
||||||
|
w.frameAck <- struct{}{}
|
||||||
|
}
|
||||||
w.destroy(err)
|
w.destroy(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if gotFrame {
|
||||||
w.draw(e2.Size, frame)
|
w.draw(e2.Size, frame)
|
||||||
|
// We're done with frame, let the client continue.
|
||||||
|
w.frameAck <- struct{}{}
|
||||||
|
}
|
||||||
if e2.Sync {
|
if e2.Sync {
|
||||||
if err := w.gpu.Flush(); err != nil {
|
if err := w.gpu.Flush(); err != nil {
|
||||||
w.gpu.Release()
|
w.gpu.Release()
|
||||||
|
|||||||
Reference in New Issue
Block a user