Skip to content

Commit

Permalink
Canvas leak (google#3927)
Browse files Browse the repository at this point in the history
* fixed setTimeout leak

* dispose shadow

* make context failure throw again

* go back to catching context error

* fix GLTFParser leak
  • Loading branch information
elalish authored Nov 7, 2022
1 parent 5974288 commit 61435b8
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 10 deletions.
4 changes: 2 additions & 2 deletions packages/model-viewer/src/features/scene-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ import {Texture as ModelViewerTexture} from './scene-graph/texture';


export const $currentGLTF = Symbol('currentGLTF');
const $model = Symbol('model');
export const $originalGltfJson = Symbol('originalGltfJson');
export const $model = Symbol('model');
const $getOnUpdateMethod = Symbol('getOnUpdateMethod');
const $textureLoader = Symbol('textureLoader');
const $originalGltfJson = Symbol('originalGltfJson');

interface SceneExportOptions {
binary?: boolean, trs?: boolean, onlyVisible?: boolean,
Expand Down
3 changes: 2 additions & 1 deletion packages/model-viewer/src/model-viewer-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ export default class ModelViewerElementBase extends ReactiveElement {
renderer.unregisterScene(this[$scene]);

this[$clearModelTimeout] = self.setTimeout(() => {
this[$scene].reset();
this[$scene].dispose();
this[$clearModelTimeout] = null;
}, CLEAR_MODEL_TIMEOUT_MS);
}

Expand Down
18 changes: 15 additions & 3 deletions packages/model-viewer/src/three-components/ModelScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import {AnimationAction, AnimationClip, AnimationMixer, Box3, Camera, Euler, Event as ThreeEvent, LoopPingPong, LoopRepeat, Material, Matrix3, Mesh, Object3D, PerspectiveCamera, Raycaster, Scene, Sphere, Texture, Vector2, Vector3, WebGLRenderer} from 'three';
import {CSS2DRenderer} from 'three/examples/jsm/renderers/CSS2DRenderer.js';

import {$currentGLTF, $model, $originalGltfJson} from '../features/scene-graph.js';
import ModelViewerElementBase, {$renderer, RendererInterface} from '../model-viewer-base.js';
import {ModelViewerElement} from '../model-viewer.js';
import {normalizeUnit} from '../styles/conversions.js';
Expand Down Expand Up @@ -64,7 +65,6 @@ const ndc = new Vector2();
export class ModelScene extends Scene {
public element: ModelViewerElement;
public canvas: HTMLCanvasElement;
public context: CanvasRenderingContext2D|null = null;
public annotationRenderer = new CSS2DRenderer();
public schemaElement = document.createElement('script');
public width = 1;
Expand Down Expand Up @@ -148,8 +148,8 @@ export class ModelScene extends Scene {
* directly. This extra context is necessary to copy the renderings into when
* there are more than one.
*/
createContext() {
this.context = this.canvas.getContext('2d');
get context() {
return this.canvas.getContext('2d');
}

getCamera(): Camera {
Expand Down Expand Up @@ -236,6 +236,7 @@ export class ModelScene extends Scene {
throw error;
}

this.cancelPendingSourceChange = null;
this.reset();
this.url = url;
this._currentGLTF = gltf;
Expand Down Expand Up @@ -300,6 +301,17 @@ export class ModelScene extends Scene {
this.mixer.uncacheRoot(this);
}

dispose() {
this.reset();
if (this.shadow != null) {
this.shadow.dispose();
this.shadow = null;
}
(this.element as any)[$currentGLTF] = null;
(this.element as any)[$originalGltfJson] = null;
(this.element as any)[$model] = null;
}

get currentGLTF() {
return this._currentGLTF;
}
Expand Down
3 changes: 0 additions & 3 deletions packages/model-viewer/src/three-components/Renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,6 @@ export class Renderer extends EventDispatcher {
}

private copyPixels(scene: ModelScene, width: number, height: number) {
if (scene.context == null) {
scene.createContext();
}
const context2D = scene.context;
if (context2D == null) {
console.log('could not acquire 2d context');
Expand Down
18 changes: 17 additions & 1 deletion packages/model-viewer/src/three-components/Shadow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* limitations under the License.
*/

import {BackSide, Box3, Mesh, MeshBasicMaterial, MeshDepthMaterial, Object3D, OrthographicCamera, PlaneGeometry, RGBAFormat, Scene, ShaderMaterial, Vector3, WebGLRenderer, WebGLRenderTarget, WebGLRenderTargetOptions} from 'three';
import {BackSide, Box3, Material, Mesh, MeshBasicMaterial, MeshDepthMaterial, Object3D, OrthographicCamera, PlaneGeometry, RGBAFormat, Scene, ShaderMaterial, Vector3, WebGLRenderer, WebGLRenderTarget, WebGLRenderTargetOptions} from 'three';
import {HorizontalBlurShader} from 'three/examples/jsm/shaders/HorizontalBlurShader.js';
import {VerticalBlurShader} from 'three/examples/jsm/shaders/VerticalBlurShader.js';
import {lerp} from 'three/src/math/MathUtils.js';
Expand Down Expand Up @@ -330,4 +330,20 @@ export class Shadow extends Object3D {

blurPlane.visible = false;
}

dispose() {
if (this.renderTarget != null) {
this.renderTarget.dispose();
}
if (this.renderTargetBlur != null) {
this.renderTargetBlur.dispose();
}
this.depthMaterial.dispose();
this.horizontalBlurMaterial.dispose();
this.verticalBlurMaterial.dispose();
(this.floor.material as Material).dispose();
this.floor.geometry.dispose();
this.blurPlane.geometry.dispose();
this.removeFromParent();
}
}

0 comments on commit 61435b8

Please sign in to comment.