gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/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/gpu"
    10  	"gioui.org/internal/gl"
    11  )
    12  
    13  type glContext struct {
    14  	ctx js.Value
    15  	cnv js.Value
    16  	w   *window
    17  }
    18  
    19  func newContext(w *window) (*glContext, 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  	ctx := w.cnv.Call("getContext", "webgl2", args)
    27  	if ctx.IsNull() {
    28  		ctx = w.cnv.Call("getContext", "webgl", args)
    29  	}
    30  	if ctx.IsNull() {
    31  		return nil, errors.New("app: webgl is not supported")
    32  	}
    33  	c := &glContext{
    34  		ctx: ctx,
    35  		cnv: w.cnv,
    36  		w:   w,
    37  	}
    38  	return c, nil
    39  }
    40  
    41  func (c *glContext) RenderTarget() (gpu.RenderTarget, error) {
    42  	if c.w.contextStatus != contextStatusOkay {
    43  		return nil, gpu.ErrDeviceLost
    44  	}
    45  	return gpu.OpenGLRenderTarget{}, nil
    46  }
    47  
    48  func (c *glContext) API() gpu.API {
    49  	return gpu.OpenGL{Context: gl.Context(c.ctx)}
    50  }
    51  
    52  func (c *glContext) Release() {
    53  }
    54  
    55  func (c *glContext) Present() error {
    56  	return nil
    57  }
    58  
    59  func (c *glContext) Lock() error {
    60  	return nil
    61  }
    62  
    63  func (c *glContext) Unlock() {}
    64  
    65  func (c *glContext) Refresh() error {
    66  	switch c.w.contextStatus {
    67  	case contextStatusLost:
    68  		return errOutOfDate
    69  	case contextStatusRestored:
    70  		c.w.contextStatus = contextStatusOkay
    71  		return gpu.ErrDeviceLost
    72  	default:
    73  		return nil
    74  	}
    75  }
    76  
    77  func (w *window) NewContext() (context, error) {
    78  	return newContext(w)
    79  }