[canvaskit] Use transferToImageBitmap
instead of createImageBitmap
(#163175)
Use `transferToImageBitmap` instead of `createImageBitmap` if we have an `OffscreenCanvas`. Now that we are sizing the `OffscreenCanvas` exactly to the frame size, we can use `transferToImageBitmap`, which should be zero-copy and therefore faster than `createImageBitmap`. In testing, this speeds things up a little bit but we still drop frames compared to multi-Surface rasterization. Helps with https://github.com/flutter/flutter/issues/162618 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
7d22606cda
commit
934af97328
@ -149,17 +149,18 @@ class Surface extends DisplayCanvas {
|
||||
|
||||
if (browserSupportsCreateImageBitmap) {
|
||||
JSObject bitmapSource;
|
||||
DomImageBitmap bitmap;
|
||||
if (useOffscreenCanvas) {
|
||||
bitmapSource = _offscreenCanvas! as JSObject;
|
||||
bitmap = _offscreenCanvas!.transferToImageBitmap();
|
||||
} else {
|
||||
bitmapSource = _canvasElement! as JSObject;
|
||||
bitmap = await createImageBitmap(bitmapSource, (
|
||||
x: 0,
|
||||
y: _pixelHeight - bitmapSize.height,
|
||||
width: bitmapSize.width,
|
||||
height: bitmapSize.height,
|
||||
));
|
||||
}
|
||||
final DomImageBitmap bitmap = await createImageBitmap(bitmapSource, (
|
||||
x: 0,
|
||||
y: _pixelHeight - bitmapSize.height,
|
||||
width: bitmapSize.width,
|
||||
height: bitmapSize.height,
|
||||
));
|
||||
canvas.render(bitmap);
|
||||
} else {
|
||||
// If the browser doesn't support `createImageBitmap` (e.g. Safari 14)
|
||||
|
@ -287,6 +287,41 @@ void testMain() {
|
||||
skip: !Surface.offscreenCanvasSupported,
|
||||
);
|
||||
|
||||
test('uses transferToImageBitmap for bitmap creation', () async {
|
||||
final Surface surface = Surface();
|
||||
surface.ensureSurface(const BitmapSize(10, 10));
|
||||
final DomOffscreenCanvas offscreenCanvas = surface.debugGetOffscreenCanvas()!;
|
||||
final Object originalTransferToImageBitmap = js_util.getProperty(
|
||||
offscreenCanvas,
|
||||
'transferToImageBitmap',
|
||||
);
|
||||
js_util.setProperty(
|
||||
offscreenCanvas,
|
||||
'originalTransferToImageBitmap',
|
||||
originalTransferToImageBitmap,
|
||||
);
|
||||
int transferToImageBitmapCalls = 0;
|
||||
js_util.setProperty(
|
||||
offscreenCanvas,
|
||||
'transferToImageBitmap',
|
||||
js_util.allowInterop(() {
|
||||
transferToImageBitmapCalls++;
|
||||
return js_util.callMethod<Object>(offscreenCanvas, 'originalTransferToImageBitmap', []);
|
||||
}),
|
||||
);
|
||||
final RenderCanvas renderCanvas = RenderCanvas();
|
||||
final CkPictureRecorder recorder = CkPictureRecorder();
|
||||
final CkCanvas canvas = recorder.beginRecording(const ui.Rect.fromLTRB(0, 0, 10, 10));
|
||||
canvas.drawCircle(
|
||||
const ui.Offset(5, 5),
|
||||
3,
|
||||
CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
|
||||
);
|
||||
final CkPicture picture = recorder.endRecording();
|
||||
await surface.rasterizeToCanvas(const BitmapSize(10, 10), renderCanvas, <CkPicture>[picture]);
|
||||
expect(transferToImageBitmapCalls, 1);
|
||||
}, skip: !Surface.offscreenCanvasSupported);
|
||||
|
||||
test('can recover from MakeSWCanvasSurface failure', () async {
|
||||
debugOverrideJsConfiguration(
|
||||
<String, Object?>{'canvasKitForceCpuOnly': true}.jsify() as JsFlutterConfiguration?,
|
||||
|
Loading…
x
Reference in New Issue
Block a user