[canvaskit] Fix freeing of memory in computeTonalColors
Change-Id: I82317cf762362a4fb74933d7d7145555d397c850
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/294700
Reviewed-by: Nathaniel Nifong <nifong@google.com>
diff --git a/modules/canvaskit/CHANGELOG.md b/modules/canvaskit/CHANGELOG.md
index 9b3e1ed..17da546 100644
--- a/modules/canvaskit/CHANGELOG.md
+++ b/modules/canvaskit/CHANGELOG.md
@@ -9,7 +9,8 @@
### Fixed
- A bug where loading fonts (and other memory intensive calls) would cause CanvasKit
to infrequently crash with
- `TypeError: Cannot perform %TypedArray%.prototype.set on a neutered ArrayBuffer`
+ `TypeError: Cannot perform %TypedArray%.prototype.set on a neutered ArrayBuffer`.
+ - Incorrectly freeing Malloced colors passed into computeTonalColors.
## [0.16.1] - 2020-06-04
diff --git a/modules/canvaskit/helper.js b/modules/canvaskit/helper.js
index 5c50316..7123c10 100644
--- a/modules/canvaskit/helper.js
+++ b/modules/canvaskit/helper.js
@@ -739,7 +739,7 @@
// This helper will free the given pointer unless the provided array is one
// that was returned by CanvasKit.Malloc.
function freeArraysThatAreNotMallocedByUsers(ptr, arr) {
- if (!arr || !arr['_ck']) {
+ if (!arr['_ck']) {
CanvasKit._free(ptr);
}
}
diff --git a/modules/canvaskit/interface.js b/modules/canvaskit/interface.js
index ad3547f..23a4c4a 100644
--- a/modules/canvaskit/interface.js
+++ b/modules/canvaskit/interface.js
@@ -1201,7 +1201,7 @@
colors.length, mode, flags, localMatrixPtr, colorSpace);
CanvasKit._free(colorPtr);
- freeArraysThatAreNotMallocedByUsers(posPtr, pos);
+ pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
return lgs;
}
@@ -1216,7 +1216,7 @@
colors.length, mode, flags, localMatrixPtr, colorSpace);
CanvasKit._free(colorPtr);
- freeArraysThatAreNotMallocedByUsers(posPtr, pos);
+ pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
return rgs;
}
@@ -1235,7 +1235,7 @@
localMatrixPtr, colorSpace);
CanvasKit._free(colorPtr);
- freeArraysThatAreNotMallocedByUsers(posPtr, pos);
+ pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
return sgs;
}
@@ -1252,7 +1252,7 @@
colorPtr, posPtr, colors.length, mode, flags, localMatrixPtr, colorSpace);
CanvasKit._free(colorPtr);
- freeArraysThatAreNotMallocedByUsers(posPtr, pos);
+ pos && freeArraysThatAreNotMallocedByUsers(posPtr, pos);
return rgs;
}
@@ -1275,17 +1275,23 @@
// ambient: {r, g, b, a},
// spot: {r, g, b, a},
// }
-// Returns the same format
+// Returns the same format. Note, if malloced colors are passed in, the memory
+// housing the passed in colors passed in will be overwritten with the computed
+// tonal colors.
CanvasKit.computeTonalColors = function(tonalColors) {
+ // copy the colors into WASM
var cPtrAmbi = copyColorToWasmNoScratch(tonalColors['ambient']);
var cPtrSpot = copyColorToWasmNoScratch(tonalColors['spot']);
+ // The output of this function will be the same pointers we passed in.
this._computeTonalColors(cPtrAmbi, cPtrSpot);
+ // Read the results out.
var result = {
'ambient': copyColorFromWasm(cPtrAmbi),
'spot': copyColorFromWasm(cPtrSpot),
}
- freeArraysThatAreNotMallocedByUsers(cPtrAmbi);
- freeArraysThatAreNotMallocedByUsers(cPtrSpot);
+ // If the user passed us malloced colors in here, we don't want to clean them up.
+ freeArraysThatAreNotMallocedByUsers(cPtrAmbi, tonalColors['ambient']);
+ freeArraysThatAreNotMallocedByUsers(cPtrSpot, tonalColors['spot']);
return result;
}
diff --git a/modules/canvaskit/tests/core.spec.js b/modules/canvaskit/tests/core.spec.js
index 428ff9f..c6346ac 100644
--- a/modules/canvaskit/tests/core.spec.js
+++ b/modules/canvaskit/tests/core.spec.js
@@ -66,6 +66,25 @@
expect(out.spot[3]).toBeCloseTo(expectedSpot[3], 3);
});
+ it('can compute tonal colors with malloced values', () => {
+ const ambientColor = CanvasKit.Malloc(Float32Array, 4);
+ ambientColor.toTypedArray().set(CanvasKit.BLUE);
+ const spotColor = CanvasKit.Malloc(Float32Array, 4);
+ spotColor.toTypedArray().set(CanvasKit.RED);
+ const input = {
+ ambient: ambientColor,
+ spot: spotColor,
+ };
+ const out = CanvasKit.computeTonalColors(input);
+ expect(new Float32Array(out.ambient)).toEqual(CanvasKit.BLACK);
+ const expectedSpot = [0.173, 0, 0, 0.969];
+ expect(out.spot.length).toEqual(4);
+ expect(out.spot[0]).toBeCloseTo(expectedSpot[0], 3);
+ expect(out.spot[1]).toBeCloseTo(expectedSpot[1], 3);
+ expect(out.spot[2]).toBeCloseTo(expectedSpot[2], 3);
+ expect(out.spot[3]).toBeCloseTo(expectedSpot[3], 3);
+ });
+
// This helper is used for all the MakeImageFromEncoded tests.
// TODO(kjlubick): rewrite this and callers to use gm
function decodeAndDrawSingleFrameImage(imgName, goldName, done) {