瀏覽代碼

[ts][canvaskit] Fix memory access error with clipping.

Davide Tantillo 1 周之前
父節點
當前提交
0b42677299
共有 1 個文件被更改,包括 24 次插入15 次删除
  1. 24 15
      spine-ts/spine-canvaskit/src/index.ts

+ 24 - 15
spine-ts/spine-canvaskit/src/index.ts

@@ -53,12 +53,10 @@ import {
 } from "@esotericsoftware/spine-core";
 import {
 	Canvas,
-	Surface,
 	CanvasKit,
 	Image,
 	Paint,
 	Shader,
-	BlendMode as CanvasKitBlendMode,
 } from "canvaskit-wasm";
 
 Skeleton.yDown = true;
@@ -275,7 +273,7 @@ export class SkeletonRenderer {
 			let numVertices = 0;
 			if (attachment instanceof RegionAttachment) {
 				let region = attachment as RegionAttachment;
-				positions = positions.length < 8 ? Utils.newFloatArray(8) : positions;
+				if (positions.length < 8) this.scratchPositions = positions = Utils.newFloatArray(8);
 				numVertices = 4;
 				region.computeWorldVertices(slot, positions, 0, 2);
 				triangles = SkeletonRenderer.QUAD_TRIANGLES;
@@ -284,10 +282,8 @@ export class SkeletonRenderer {
 				attachmentColor = region.color;
 			} else if (attachment instanceof MeshAttachment) {
 				let mesh = attachment as MeshAttachment;
-				positions =
-					positions.length < mesh.worldVerticesLength
-						? Utils.newFloatArray(mesh.worldVerticesLength)
-						: positions;
+				if (positions.length < mesh.worldVerticesLength)
+					this.scratchPositions = positions = Utils.newFloatArray(mesh.worldVerticesLength);
 				numVertices = mesh.worldVerticesLength >> 1;
 				mesh.computeWorldVertices(
 					slot,
@@ -318,9 +314,23 @@ export class SkeletonRenderer {
 						triangles.length,
 						uvs
 					);
-					positions = clipper.clippedVertices;
-					uvs = clipper.clippedUVs;
-					triangles = clipper.clippedTriangles;
+
+					if (clipper.clippedVertices.length > 0) {
+						// clipping eventually "erases" clippedVertices array (set length to 0 at next clip)
+						// it's necessary to keep the array alive until canvaskit paints,
+						// otherwise a memory access occurs
+						if (positions.length < clipper.clippedVertices.length)
+							this.scratchPositions = positions = Utils.newFloatArray(clipper.clippedVertices.length);
+						numVertices = clipper.clippedVertices.length / 2;
+						for (let i = 0; i < clipper.clippedVertices.length; i++)
+							positions[i] = clipper.clippedVertices[i];
+
+						uvs = clipper.clippedUVs;
+						triangles = clipper.clippedTriangles;
+					} else {
+						clipper.clipEndWithSlot(slot);
+						continue;
+					}
 				}
 
 				let slotColor = slot.color;
@@ -331,7 +341,7 @@ export class SkeletonRenderer {
 				finalColor.a = skeletonColor.a * slotColor.a * attachmentColor.a;
 
 				if (colors.length / 4 < numVertices)
-					colors = Utils.newFloatArray(numVertices * 4);
+					this.scratchColors = colors = Utils.newFloatArray(numVertices * 4);
 				for (let i = 0, n = numVertices * 4; i < n; i += 4) {
 					colors[i] = finalColor.r;
 					colors[i + 1] = finalColor.g;
@@ -339,10 +349,9 @@ export class SkeletonRenderer {
 					colors[i + 3] = finalColor.a;
 				}
 
-				const scaledUvs =
-					this.scratchUVs.length < uvs.length
-						? Utils.newFloatArray(uvs.length)
-						: this.scratchUVs;
+				const scaledUvs = this.scratchUVs.length < uvs.length
+					? (this.scratchUVs = Utils.newFloatArray(uvs.length))
+					: this.scratchUVs;
 				const width = texture.getImage().image.width();
 				const height = texture.getImage().image.height();
 				for (let i = 0; i < uvs.length; i += 2) {