Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 58198e8

Browse files
committed
[web] Make Canvaskit's malloc more useful
1 parent 8f6036e commit 58198e8

File tree

4 files changed

+49
-17
lines changed

4 files changed

+49
-17
lines changed

lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart

+46-14
Original file line numberDiff line numberDiff line change
@@ -1273,34 +1273,46 @@ Float32List toSkColorStops(List<double>? colorStops) {
12731273
return skColorStops;
12741274
}
12751275

1276-
@JS('Float32Array')
1277-
external _NativeFloat32ArrayType get _nativeFloat32ArrayType;
1278-
12791276
@JS()
12801277
@staticInterop
1281-
class _NativeFloat32ArrayType {}
1278+
abstract class _ArrayType {}
1279+
1280+
@JS('Float32Array')
1281+
external _ArrayType get _nativeFloat32ArrayType;
1282+
1283+
@JS('Uint32Array')
1284+
external _ArrayType get _nativeUint32ArrayType;
12821285

12831286
@JS('window.flutterCanvasKit.Malloc')
1284-
external SkFloat32List _mallocFloat32List(
1285-
_NativeFloat32ArrayType float32ListType,
1286-
int size,
1287-
);
1287+
external Object _mallocList(_ArrayType arrayType, int size);
12881288

12891289
/// Allocates a [Float32List] backed by WASM memory, managed by
12901290
/// a [SkFloat32List].
12911291
///
1292-
/// To free the allocated array use [freeFloat32List].
1292+
/// To free the allocated array use [freeList].
12931293
SkFloat32List mallocFloat32List(int size) {
1294-
return _mallocFloat32List(_nativeFloat32ArrayType, size);
1294+
return _mallocList(_nativeFloat32ArrayType, size) as SkFloat32List;
1295+
}
1296+
1297+
/// Allocates a [Uint32List] backed by WASM memory, managed by
1298+
/// a [SkUint32List].
1299+
///
1300+
/// To free the allocated array use [freeList].
1301+
SkUint32List mallocUint32List(int size) {
1302+
return _mallocList(_nativeUint32ArrayType, size) as SkUint32List;
12951303
}
12961304

1297-
/// Frees the WASM memory occupied by a [SkFloat32List].
1305+
/// Frees the WASM memory occupied by a [SkFloat32List] or [SkUint32List].
12981306
///
12991307
/// The [list] is no longer usable after calling this function.
13001308
///
13011309
/// Use this function to free lists owned by the engine.
13021310
@JS('window.flutterCanvasKit.Free')
1303-
external void freeFloat32List(SkFloat32List list);
1311+
external void freeList(_SkList list);
1312+
1313+
@JS()
1314+
@staticInterop
1315+
abstract class _SkList {}
13041316

13051317
/// Wraps a [Float32List] backed by WASM memory.
13061318
///
@@ -1309,7 +1321,7 @@ external void freeFloat32List(SkFloat32List list);
13091321
/// that's attached to the current WASM memory block.
13101322
@JS()
13111323
@staticInterop
1312-
class SkFloat32List {}
1324+
class SkFloat32List extends _SkList {}
13131325

13141326
extension SkFloat32ListExtension on SkFloat32List {
13151327
/// Returns the [Float32List] object backed by WASM memory.
@@ -1322,6 +1334,26 @@ extension SkFloat32ListExtension on SkFloat32List {
13221334
external Float32List toTypedArray();
13231335
}
13241336

1337+
/// Wraps a [Uint32List] backed by WASM memory.
1338+
///
1339+
/// This wrapper is necessary because the raw [Uint32List] will get detached
1340+
/// when WASM grows its memory. Call [toTypedArray] to get a new instance
1341+
/// that's attached to the current WASM memory block.
1342+
@JS()
1343+
@staticInterop
1344+
class SkUint32List extends _SkList {}
1345+
1346+
extension SkUint32ListExtension on SkUint32List {
1347+
/// Returns the [Uint32List] object backed by WASM memory.
1348+
///
1349+
/// Do not reuse the returned list across multiple WASM function/method
1350+
/// invocations that may lead to WASM memory to grow. When WASM memory
1351+
/// grows the [Uint32List] object becomes "detached" and is no longer
1352+
/// usable. Instead, call this method every time you need to read from
1353+
/// or write to the list.
1354+
external Uint32List toTypedArray();
1355+
}
1356+
13251357
/// Writes [color] information into the given [skColor] buffer.
13261358
Float32List _populateSkColor(SkFloat32List skColor, ui.Color color) {
13271359
final Float32List array = skColor.toTypedArray();
@@ -1590,7 +1622,7 @@ Float32List toOuterSkRect(ui.RRect rrect) {
15901622
/// Uses `CanvasKit.Malloc` to allocate storage for the points in the WASM
15911623
/// memory to avoid unnecessary copying. Unless CanvasKit takes ownership of
15921624
/// the list the returned list must be explicitly freed using
1593-
/// [freeMallocedFloat32List].
1625+
/// [freeList].
15941626
SkFloat32List toMallocedSkPoints(List<ui.Offset> points) {
15951627
final int len = points.length;
15961628
final SkFloat32List skPoints = mallocFloat32List(len * 2);

lib/web_ui/lib/src/engine/canvaskit/canvaskit_canvas.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ class CanvasKitCanvas implements ui.Canvas {
326326
pointMode,
327327
skPoints.toTypedArray(),
328328
);
329-
freeFloat32List(skPoints);
329+
freeList(skPoints);
330330
}
331331

332332
@override

lib/web_ui/lib/src/engine/canvaskit/path.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class CkPath extends ManagedSkiaObject<SkPath> implements ui.Path {
8989
assert(points != null);
9090
final SkFloat32List encodedPoints = toMallocedSkPoints(points);
9191
skiaObject.addPoly(encodedPoints.toTypedArray(), close);
92-
freeFloat32List(encodedPoints);
92+
freeList(encodedPoints);
9393
}
9494

9595
@override

lib/web_ui/test/canvaskit/canvaskit_api_test.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ void _pathTests() {
812812
ui.Offset(10, 10),
813813
]);
814814
path.addPoly(encodedPoints.toTypedArray(), true);
815-
freeFloat32List(encodedPoints);
815+
freeList(encodedPoints);
816816
});
817817

818818
test('addRRect', () {

0 commit comments

Comments
 (0)