Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions src/PenSkin.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ class PenSkin extends Skin {
/** @type {boolean} */
this._silhouetteDirty = false;

/** @type {Uint8Array} */
this._silhouettePixels = null;

/** @type {ImageData} */
this._silhouetteImageData = null;

/** @type {object} */
this._lineOnBufferDrawRegionId = {
enter: () => this._enterDrawLineOnBuffer(),
Expand Down Expand Up @@ -597,6 +603,9 @@ class PenSkin extends Skin {
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);

this._silhouettePixels = new Uint8Array(Math.floor(width * height * 4));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the math.floor isn't necessary here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be used in every other place in the codebase that constructs a Uint8Array, specifically to prevent issues with Edge.

If I removed it here, I don't think it would cause any trouble (width and height should be integers), and newer versions of Edge (I tested it on Microsoft Edge 44.18362.449.0, Microsoft EdgeHTML 18.18363) have no trouble with floating-point values in typed array constructors, but it'd break the convention that the rest of the codebase is using. Is that okay?

(P.S. it may be worth revisiting this in the future by either testing whether Edge 15, the minimum version Scratch officially supports, supports floating-point values in TypedArray constructors, or by bumping the minimum supported Edge version in the FAQ to something newer.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops - thanks for the reminder! I had completely forgotten about that.

this._silhouetteImageData = this._canvas.getContext('2d').createImageData(width, height);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. We should definitely reuse these.


this._silhouetteDirty = true;
}

Expand Down Expand Up @@ -634,24 +643,17 @@ class PenSkin extends Skin {
// Render export texture to another framebuffer
const gl = this._renderer.gl;

const bounds = this._bounds;

this._renderer.enterDrawRegion(this._toBufferDrawRegionId);

// Sample the framebuffer's pixels into the silhouette instance
const skinPixels = new Uint8Array(Math.floor(this._canvas.width * this._canvas.height * 4));
gl.readPixels(0, 0, this._canvas.width, this._canvas.height, gl.RGBA, gl.UNSIGNED_BYTE, skinPixels);

const skinCanvas = this._canvas;
skinCanvas.width = bounds.width;
skinCanvas.height = bounds.height;

const skinContext = skinCanvas.getContext('2d');
const skinImageData = skinContext.createImageData(bounds.width, bounds.height);
skinImageData.data.set(skinPixels);
skinContext.putImageData(skinImageData, 0, 0);

this._silhouette.update(this._canvas, true /* isPremultiplied */);
gl.readPixels(
0, 0,
this._canvas.width, this._canvas.height,
gl.RGBA, gl.UNSIGNED_BYTE, this._silhouettePixels
);

this._silhouetteImageData.data.set(this._silhouettePixels);
this._silhouette.update(this._silhouetteImageData, true /* isPremultiplied */);

this._silhouetteDirty = false;
}
Expand Down