onnxruntime

Форк
0
/
webgl-context-factory.ts 
115 строк · 3.5 Кб
1
// Copyright (c) Microsoft Corporation. All rights reserved.
2
// Licensed under the MIT License.
3

4
import { Logger } from '../../instrument';
5

6
import { WebGLContext } from './webgl-context';
7

8
const cache: { [contextId: string]: WebGLContext } = {};
9

10
/**
11
 * This factory function creates proper WebGLRenderingContext based on
12
 * the current browsers capabilities
13
 * The order is from higher/most recent versions to most basic
14
 */
15
export function createWebGLContext(contextId?: 'webgl' | 'webgl2'): WebGLContext {
16
  let context: WebGLContext | undefined;
17
  if ((!contextId || contextId === 'webgl2') && 'webgl2' in cache) {
18
    context = cache.webgl2;
19
  } else if ((!contextId || contextId === 'webgl') && 'webgl' in cache) {
20
    context = cache.webgl;
21
  }
22

23
  if (!context) {
24
    try {
25
      // try to create webgl context from an offscreen canvas
26
      const offscreenCanvas = createOffscreenCanvas();
27
      context = createNewWebGLContext(offscreenCanvas, contextId);
28
    } catch (e) {
29
      // if failed, fallback to try to use a normal canvas element
30
      const canvas = createCanvas();
31
      context = createNewWebGLContext(canvas, contextId);
32
    }
33
  }
34

35
  contextId = contextId || context.version === 1 ? 'webgl' : 'webgl2';
36
  const gl = context.gl;
37

38
  cache[contextId] = context;
39

40
  if (gl.isContextLost()) {
41
    delete cache[contextId];
42
    return createWebGLContext(contextId);
43
  }
44

45
  gl.disable(gl.DEPTH_TEST);
46
  gl.disable(gl.STENCIL_TEST);
47
  gl.disable(gl.BLEND);
48
  gl.disable(gl.DITHER);
49
  gl.disable(gl.POLYGON_OFFSET_FILL);
50
  gl.disable(gl.SAMPLE_COVERAGE);
51
  gl.enable(gl.SCISSOR_TEST);
52
  gl.enable(gl.CULL_FACE);
53
  gl.cullFace(gl.BACK);
54

55
  return context;
56
}
57

58
export function createNewWebGLContext(canvas: HTMLCanvasElement, contextId?: 'webgl' | 'webgl2'): WebGLContext {
59
  const contextAttributes: WebGLContextAttributes = {
60
    alpha: false,
61
    depth: false,
62
    antialias: false,
63
    stencil: false,
64
    preserveDrawingBuffer: false,
65
    premultipliedAlpha: false,
66
    failIfMajorPerformanceCaveat: false,
67
  };
68
  let gl: WebGLRenderingContext | null;
69
  const ca = contextAttributes;
70
  if (!contextId || contextId === 'webgl2') {
71
    gl = canvas.getContext('webgl2', ca);
72
    if (gl) {
73
      try {
74
        return new WebGLContext(gl, 2);
75
      } catch (err) {
76
        Logger.warning('GlContextFactory', `failed to create WebGLContext using contextId 'webgl2'. Error: ${err}`);
77
      }
78
    }
79
  }
80
  if (!contextId || contextId === 'webgl') {
81
    gl = canvas.getContext('webgl', ca) || (canvas.getContext('experimental-webgl', ca) as WebGLRenderingContext);
82
    if (gl) {
83
      try {
84
        return new WebGLContext(gl, 1);
85
      } catch (err) {
86
        Logger.warning(
87
          'GlContextFactory',
88
          `failed to create WebGLContext using contextId 'webgl' or 'experimental-webgl'. Error: ${err}`,
89
        );
90
      }
91
    }
92
  }
93

94
  throw new Error('WebGL is not supported');
95
}
96

97
// eslint-disable-next-line @typescript-eslint/naming-convention
98
declare let OffscreenCanvas: { new (width: number, height: number): HTMLCanvasElement };
99

100
function createCanvas(): HTMLCanvasElement {
101
  if (typeof document === 'undefined') {
102
    throw new TypeError('failed to create canvas: document is not supported');
103
  }
104
  const canvas: HTMLCanvasElement = document.createElement('canvas');
105
  canvas.width = 1;
106
  canvas.height = 1;
107
  return canvas;
108
}
109

110
function createOffscreenCanvas(): HTMLCanvasElement {
111
  if (typeof OffscreenCanvas === 'undefined') {
112
    throw new TypeError('failed to create offscreen canvas: OffscreenCanvas is not supported');
113
  }
114
  return new OffscreenCanvas(1, 1);
115
}
116

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.