Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
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
17 changes: 15 additions & 2 deletions lib/web_ui/lib/src/engine/canvaskit/image_web_codecs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'dart:js_interop';
import 'dart:math' as math;
import 'dart:typed_data';

import 'package:js/js.dart';
import 'package:meta/meta.dart';
import 'package:ui/ui.dart' as ui;

Expand Down Expand Up @@ -439,12 +440,24 @@ bool _shouldReadPixelsUnmodified(VideoFrame videoFrame, ui.ImageByteFormat forma
return format == ui.ImageByteFormat.rawRgba && isRgbFrame;
}

@JS('Uint8Array')
@staticInterop
class _JSUint8Array {
external factory _JSUint8Array(JSNumber length);
}

Future<ByteBuffer> readVideoFramePixelsUnmodified(VideoFrame videoFrame) async {
final int size = videoFrame.allocationSize().toInt();
final Uint8List destination = Uint8List(size);

// In dart2wasm, Uint8List is not the same as a JS Uint8Array. So we
// explicitly construct the JS object here.
final JSUint8Array destination = _JSUint8Array(size.toJS) as JSUint8Array;
final JsPromise copyPromise = videoFrame.copyTo(destination);
await promiseToFuture<void>(copyPromise);
return destination.buffer;

// In dart2wasm, `toDart` incurs a copy here. On JS backends, this is a
// no-op.
return destination.toDart.buffer;
}

Future<Uint8List> encodeVideoFrameAsPng(VideoFrame videoFrame) async {
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/test/canvaskit/canvas_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ void testMain() {

test('emoji text with skin tone', () async {
await testSampleText('emoji_with_skin_tone', '👋🏿 👋🏾 👋🏽 👋🏼 👋🏻');
}, skip: isWasm || isSafari || isFirefox); // https://github.com/flutter/flutter/issues/124068
}, timeout: const Timeout.factor(2));

// Make sure we clear the canvas in between frames.
test('empty frame after contentful frame', () async {
Expand Down
8 changes: 2 additions & 6 deletions lib/web_ui/test/canvaskit/image_golden_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -887,9 +887,7 @@ void _testCkBrowserImageDecoder() {
expect(rgba!.buffer.asUint8List(), expectedColors[i]);
}
testCollector.collectNow();
// TODO(jacksongardner): enable on wasm
// see https://github.com/flutter/flutter/issues/118334
}, skip: isWasm);
});

test('ImageDecoder expires after inactivity', () async {
const Duration testExpireDuration = Duration(milliseconds: 100);
Expand Down Expand Up @@ -934,9 +932,7 @@ void _testCkBrowserImageDecoder() {

testCollector.collectNow();
debugRestoreWebDecoderExpireDuration();
// TODO(jacksongardner): enable on wasm
// see https://github.com/flutter/flutter/issues/118334
}, skip: isWasm);
});
}

Future<void> expectFrameData(ui.FrameInfo frame, List<int> data) async {
Expand Down
4 changes: 2 additions & 2 deletions lib/web_ui/test/engine/channel_buffers_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ void testMain() {
'b: seven',
'-9',
]);
}, skip: isWasm); // https://github.com/dart-lang/sdk/issues/50778
});

test('ChannelBuffers.clearListener', () async {
final List<String> log = <String>[];
Expand Down Expand Up @@ -365,7 +365,7 @@ void testMain() {
'callback1: true',
'callback2: true',
]);
}, skip: isWasm); // https://github.com/dart-lang/sdk/issues/50778
});
}

class _TestChannelBuffers extends ui.ChannelBuffers {
Expand Down