Skip to content

Commit e31934f

Browse files
committed
update Skin textures with ImageData
When possible pass ImageData to texture creation and updating to help remove chance of references that keep canvas and underlying data from being garbage collected.
1 parent be5ab2e commit e31934f

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

src/BitmapSkin.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,20 +79,31 @@ class BitmapSkin extends Skin {
7979
setBitmap (bitmapData, costumeResolution, rotationCenter) {
8080
const gl = this._renderer.gl;
8181

82+
// Preferably bitmapData is ImageData. ImageData speeds up updating
83+
// Silhouette and is better handled by more browsers in regards to
84+
// memory.
85+
let textureData = bitmapData;
86+
if (bitmapData instanceof HTMLCanvasElement) {
87+
// Given a HTMLCanvasElement get the image data to pass to webgl and
88+
// Silhouette.
89+
const context = bitmapData.getContext('2d');
90+
textureData = context.getImageData(0, 0, bitmapData.width, bitmapData.height);
91+
}
92+
8293
if (this._texture) {
8394
gl.bindTexture(gl.TEXTURE_2D, this._texture);
84-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmapData);
85-
this._silhouette.update(bitmapData);
95+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureData);
96+
this._silhouette.update(textureData);
8697
} else {
8798
// TODO: mipmaps?
8899
const textureOptions = {
89100
auto: true,
90101
wrap: gl.CLAMP_TO_EDGE,
91-
src: bitmapData
102+
src: textureData
92103
};
93104

94105
this._texture = twgl.createTexture(gl, textureOptions);
95-
this._silhouette.update(bitmapData);
106+
this._silhouette.update(textureData);
96107
}
97108

98109
// Do these last in case any of the above throws an exception

src/SVGSkin.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,14 @@ class SVGSkin extends Skin {
7777
this._textureScale = newScale;
7878
this._svgRenderer._draw(this._textureScale, () => {
7979
if (this._textureScale === newScale) {
80+
const canvas = this._svgRenderer.canvas;
81+
const context = canvas.getContext('2d');
82+
const textureData = context.getImageData(0, 0, canvas.width, canvas.height);
83+
8084
const gl = this._renderer.gl;
8185
gl.bindTexture(gl.TEXTURE_2D, this._texture);
82-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._svgRenderer.canvas);
83-
this._silhouette.update(this._svgRenderer.canvas);
86+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureData);
87+
this._silhouette.update(textureData);
8488
}
8589
});
8690
}
@@ -99,20 +103,28 @@ class SVGSkin extends Skin {
99103
this._svgRenderer.fromString(svgData, 1, () => {
100104
const gl = this._renderer.gl;
101105
this._textureScale = this._maxTextureScale = 1;
106+
107+
// Pull out the ImageData from the canvas. ImageData speeds up
108+
// updating Silhouette and is better handled by more browsers in
109+
// regards to memory.
110+
const canvas = this._svgRenderer.canvas;
111+
const context = canvas.getContext('2d');
112+
const textureData = context.getImageData(0, 0, canvas.width, canvas.height);
113+
102114
if (this._texture) {
103115
gl.bindTexture(gl.TEXTURE_2D, this._texture);
104-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this._svgRenderer.canvas);
105-
this._silhouette.update(this._svgRenderer.canvas);
116+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureData);
117+
this._silhouette.update(textureData);
106118
} else {
107119
// TODO: mipmaps?
108120
const textureOptions = {
109121
auto: true,
110122
wrap: gl.CLAMP_TO_EDGE,
111-
src: this._svgRenderer.canvas
123+
src: textureData
112124
};
113125

114126
this._texture = twgl.createTexture(gl, textureOptions);
115-
this._silhouette.update(this._svgRenderer.canvas);
127+
this._silhouette.update(textureData);
116128
}
117129

118130
const maxDimension = Math.max(this._svgRenderer.canvas.width, this._svgRenderer.canvas.height);

0 commit comments

Comments
 (0)