Skip to content

Commit

Permalink
fix: fix problems with destroying WebGL context
Browse files Browse the repository at this point in the history
fix problems with destroying WebGL
context.(phoboslab/jsmpeg@924acfb)
  • Loading branch information
cycjimmy committed Sep 22, 2022
1 parent 8dc1c3b commit 558c02e
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 26 deletions.
12 changes: 10 additions & 2 deletions src/lib/canvas2d.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import { Fill } from '../utils';
/* eslint class-methods-use-this: ["error", { "exceptMethods": ["destroy"] }] */
export default class CanvasRenderer {
constructor(options) {
this.canvas = options.canvas || document.createElement('canvas');
if (options.canvas) {
this.canvas = options.canvas;
this.ownsCanvasElement = false;
} else {
this.canvas = document.createElement('canvas');
this.ownsCanvasElement = true;
}
this.width = this.canvas.width;
this.height = this.canvas.height;
this.enabled = true;
Expand All @@ -12,7 +18,9 @@ export default class CanvasRenderer {
}

destroy() {
// Nothing to do here
if (this.ownsCanvasElement) {
this.canvas.remove();
}
}

resize(width, height) {
Expand Down
41 changes: 17 additions & 24 deletions src/lib/webgl.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
class WebGLRenderer {
constructor(options) {
this.canvas = options.canvas || document.createElement('canvas');
if (options.canvas) {
this.canvas = options.canvas;
this.ownsCanvasElement = false;
} else {
this.canvas = document.createElement('canvas');
this.ownsCanvasElement = true;
}
this.width = this.canvas.width;
this.height = this.canvas.height;
this.enabled = true;
this.contextLost = false;

this.hasTextureData = {};

Expand All @@ -24,20 +29,11 @@ class WebGLRenderer {
throw new Error('Failed to get WebGL Context');
}

// WebGLRenderer.destroy() will explicitly lose the GL context. Calling
// .getContext('webgl') on a Canvas element whose GL context has previously
// been lost, will return an un-restored GL context. So we try to catch this
// case here and try restore the GL context.
if (this.gl.isContextLost()) {
this.gl.getExtension('WEBGL_lose_context').restoreContext();
}
this.handleContextLostBound = this.handleContextLost.bind(this);
this.handleContextRestoredBound = this.handleContextRestored.bind(this);

this.canvas.addEventListener('webglcontextlost', this.handleContextLost.bind(this), false);
this.canvas.addEventListener(
'webglcontextrestored',
this.handleContextRestored.bind(this),
false,
);
this.canvas.addEventListener('webglcontextlost', this.handleContextLostBound, false);
this.canvas.addEventListener('webglcontextrestored', this.handleContextRestoredBound, false);

this.initGL();
}
Expand Down Expand Up @@ -88,15 +84,9 @@ class WebGLRenderer {

handleContextRestored() {
this.initGL();
this.contextLost = false;
}

destroy() {
if (this.contextLost) {
// Nothing to do here
return;
}

const { gl } = this;

this.deleteTexture(gl.TEXTURE0, this.textureY);
Expand All @@ -110,9 +100,12 @@ class WebGLRenderer {
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.deleteBuffer(this.vertexBuffer);

gl.getExtension('WEBGL_lose_context').loseContext();
this.canvas.remove();
this.contextLost = true;
this.canvas.removeEventListener('webglcontextlost', this.handleContextLostBound, false);
this.canvas.removeEventListener('webglcontextrestored', this.handleContextRestoredBound, false);

if (this.ownsCanvasElement) {
this.canvas.remove();
}
}

resize(width, height) {
Expand Down

0 comments on commit 558c02e

Please sign in to comment.