gioui.org/ui@v0.0.0-20190926171558-ce74bc0cbaea/app/gl_js.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 package app 4 5 import ( 6 "errors" 7 "syscall/js" 8 9 "gioui.org/ui/app/internal/gl" 10 ) 11 12 type context struct { 13 ctx js.Value 14 cnv js.Value 15 f *gl.Functions 16 srgbFBO *gl.SRGBFBO 17 } 18 19 func newContext(w *window) (*context, error) { 20 args := map[string]interface{}{ 21 // Enable low latency rendering. 22 // See https://developers.google.com/web/updates/2019/05/desynchronized. 23 "desynchronized": true, 24 "preserveDrawingBuffer": true, 25 } 26 version := 2 27 ctx := w.cnv.Call("getContext", "webgl2", args) 28 if ctx == js.Null() { 29 version = 1 30 ctx = w.cnv.Call("getContext", "webgl", args) 31 } 32 if ctx == js.Null() { 33 return nil, errors.New("app: webgl is not supported") 34 } 35 f := &gl.Functions{Ctx: ctx} 36 if err := f.Init(version); err != nil { 37 return nil, err 38 } 39 c := &context{ 40 ctx: ctx, 41 cnv: w.cnv, 42 f: f, 43 } 44 return c, nil 45 } 46 47 func (c *context) Functions() *gl.Functions { 48 return c.f 49 } 50 51 func (c *context) Release() { 52 if c.srgbFBO != nil { 53 c.srgbFBO.Release() 54 c.srgbFBO = nil 55 } 56 } 57 58 func (c *context) Present() error { 59 if c.srgbFBO != nil { 60 c.srgbFBO.Blit() 61 } 62 if c.srgbFBO != nil { 63 c.srgbFBO.AfterPresent() 64 } 65 if c.ctx.Call("isContextLost").Bool() { 66 return errors.New("context lost") 67 } 68 return nil 69 } 70 71 func (c *context) Lock() {} 72 73 func (c *context) Unlock() {} 74 75 func (c *context) MakeCurrent() error { 76 if c.srgbFBO == nil { 77 var err error 78 c.srgbFBO, err = gl.NewSRGBFBO(c.f) 79 if err != nil { 80 c.Release() 81 c.srgbFBO = nil 82 return err 83 } 84 } 85 w, h := c.cnv.Get("width").Int(), c.cnv.Get("height").Int() 86 if err := c.srgbFBO.Refresh(w, h); err != nil { 87 c.Release() 88 return err 89 } 90 return nil 91 }