github.com/gop9/olt@v0.0.0-20200202132135-d956aad50b08/gio/app/internal/window/gl_js.go (about)

     1  // SPDX-License-Identifier: Unlicense OR MIT
     2  
     3  package window
     4  
     5  import (
     6  	"errors"
     7  	"syscall/js"
     8  
     9  	"github.com/gop9/olt/gio/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.IsNull() {
    29  		version = 1
    30  		ctx = w.cnv.Call("getContext", "webgl", args)
    31  	}
    32  	if ctx.IsNull() {
    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  }
    92  
    93  func (w *window) NewContext() (Context, error) {
    94  	return newContext(w)
    95  }