forked from joejulian/gio
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d9b0c8c1c5 | |||
| 7bb7a1407f |
@@ -115,9 +115,6 @@ func (c *context) Unlock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *context) Refresh() error {
|
func (c *context) Refresh() error {
|
||||||
if C.gio_makeCurrent(c.ctx) == 0 {
|
|
||||||
return errors.New("[EAGLContext setCurrentContext] failed")
|
|
||||||
}
|
|
||||||
if !c.init {
|
if !c.init {
|
||||||
c.init = true
|
c.init = true
|
||||||
c.frameBuffer = c.c.CreateFramebuffer()
|
c.frameBuffer = c.c.CreateFramebuffer()
|
||||||
|
|||||||
@@ -111,8 +111,6 @@ func (c *glContext) Unlock() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *glContext) Refresh() error {
|
func (c *glContext) Refresh() error {
|
||||||
c.Lock()
|
|
||||||
defer c.Unlock()
|
|
||||||
C.gio_updateContext(c.ctx)
|
C.gio_updateContext(c.ctx)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,6 +165,8 @@ type frameEvent struct {
|
|||||||
Sync bool
|
Sync bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The caller must hold the context lock while using API, Refresh,
|
||||||
|
// RenderTarget, or Present.
|
||||||
type context interface {
|
type context interface {
|
||||||
API() gpu.API
|
API() gpu.API
|
||||||
RenderTarget() (gpu.RenderTarget, error)
|
RenderTarget() (gpu.RenderTarget, error)
|
||||||
|
|||||||
+41
-12
@@ -46,6 +46,10 @@ type Window struct {
|
|||||||
|
|
||||||
ctx context
|
ctx context
|
||||||
gpu gpu.GPU
|
gpu gpu.GPU
|
||||||
|
// ctxNeedsLock tracks whether the rendering context must be made
|
||||||
|
// current again before the next GPU operation. Refresh paths, surface
|
||||||
|
// loss, and explicit unlocks all invalidate the current binding.
|
||||||
|
ctxNeedsLock bool
|
||||||
// timer tracks the delayed invalidate goroutine.
|
// timer tracks the delayed invalidate goroutine.
|
||||||
timer struct {
|
timer struct {
|
||||||
// quit is shuts down the goroutine.
|
// quit is shuts down the goroutine.
|
||||||
@@ -146,9 +150,14 @@ func (w *Window) validateAndProcess(size image.Point, sync bool, frame *op.Ops,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
w.ctxNeedsLock = true
|
||||||
sync = true
|
sync = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := w.lockContext(); err != nil {
|
||||||
|
w.destroyGPU()
|
||||||
|
return err
|
||||||
|
}
|
||||||
if sync && w.ctx != nil {
|
if sync && w.ctx != nil {
|
||||||
if err := w.ctx.Refresh(); err != nil {
|
if err := w.ctx.Refresh(); err != nil {
|
||||||
if errors.Is(err, errOutOfDate) {
|
if errors.Is(err, errOutOfDate) {
|
||||||
@@ -162,9 +171,8 @@ func (w *Window) validateAndProcess(size image.Point, sync bool, frame *op.Ops,
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
w.unlockContext()
|
||||||
if w.ctx != nil {
|
if err := w.lockContext(); err != nil {
|
||||||
if err := w.ctx.Lock(); err != nil {
|
|
||||||
w.destroyGPU()
|
w.destroyGPU()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -172,7 +180,7 @@ func (w *Window) validateAndProcess(size image.Point, sync bool, frame *op.Ops,
|
|||||||
if w.gpu == nil && !w.nocontext {
|
if w.gpu == nil && !w.nocontext {
|
||||||
gpu, err := gpu.New(w.ctx.API())
|
gpu, err := gpu.New(w.ctx.API())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.ctx.Unlock()
|
w.unlockContext()
|
||||||
w.destroyGPU()
|
w.destroyGPU()
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -180,7 +188,7 @@ func (w *Window) validateAndProcess(size image.Point, sync bool, frame *op.Ops,
|
|||||||
}
|
}
|
||||||
if w.gpu != nil {
|
if w.gpu != nil {
|
||||||
if err := w.frame(frame, size); err != nil {
|
if err := w.frame(frame, size); err != nil {
|
||||||
w.ctx.Unlock()
|
w.unlockContext()
|
||||||
if errors.Is(err, errOutOfDate) {
|
if errors.Is(err, errOutOfDate) {
|
||||||
// GPU surface needs refreshing.
|
// GPU surface needs refreshing.
|
||||||
sync = true
|
sync = true
|
||||||
@@ -200,7 +208,6 @@ func (w *Window) validateAndProcess(size image.Point, sync bool, frame *op.Ops,
|
|||||||
var err error
|
var err error
|
||||||
if w.gpu != nil {
|
if w.gpu != nil {
|
||||||
err = w.ctx.Present()
|
err = w.ctx.Present()
|
||||||
w.ctx.Unlock()
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -503,16 +510,37 @@ func (c *callbacks) ActionAt(p f32.Point) (system.Action, bool) {
|
|||||||
return c.w.queue.ActionAt(p)
|
return c.w.queue.ActionAt(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Window) lockContext() error {
|
||||||
|
if w.ctx == nil || !w.ctxNeedsLock {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err := w.ctx.Lock(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
w.ctxNeedsLock = false
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) unlockContext() {
|
||||||
|
if w.ctx == nil || w.ctxNeedsLock {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.ctx.Unlock()
|
||||||
|
w.ctxNeedsLock = true
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Window) destroyGPU() {
|
func (w *Window) destroyGPU() {
|
||||||
if w.gpu != nil {
|
if w.gpu != nil {
|
||||||
w.ctx.Lock()
|
if err := w.lockContext(); err == nil {
|
||||||
w.gpu.Release()
|
w.gpu.Release()
|
||||||
w.ctx.Unlock()
|
w.unlockContext()
|
||||||
|
}
|
||||||
w.gpu = nil
|
w.gpu = nil
|
||||||
}
|
}
|
||||||
if w.ctx != nil {
|
if w.ctx != nil {
|
||||||
w.ctx.Release()
|
w.ctx.Release()
|
||||||
w.ctx = nil
|
w.ctx = nil
|
||||||
|
w.ctxNeedsLock = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,10 +683,11 @@ func (w *Window) processEvent(e event.Event) bool {
|
|||||||
w.coalesced.destroy = &e2
|
w.coalesced.destroy = &e2
|
||||||
case ViewEvent:
|
case ViewEvent:
|
||||||
if !e2.Valid() && w.gpu != nil {
|
if !e2.Valid() && w.gpu != nil {
|
||||||
w.ctx.Lock()
|
if err := w.lockContext(); err == nil {
|
||||||
w.gpu.Release()
|
w.gpu.Release()
|
||||||
|
w.unlockContext()
|
||||||
|
}
|
||||||
w.gpu = nil
|
w.gpu = nil
|
||||||
w.ctx.Unlock()
|
|
||||||
}
|
}
|
||||||
w.coalesced.view = &e2
|
w.coalesced.view = &e2
|
||||||
case ConfigEvent:
|
case ConfigEvent:
|
||||||
|
|||||||
Reference in New Issue
Block a user