-
Notifications
You must be signed in to change notification settings - Fork 6k
[web] Support external textures for CanvasKit renderer #37890
Changes from all commits
1114e62
98104b1
d3fe247
c130534
2169028
dba4dfb
897be9d
de8ce4e
b43bf48
6cd871e
4fb05e5
fbb0aec
c726e29
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| import 'package:ui/ui.dart' as ui; | ||
|
|
||
| import '../texture.dart'; | ||
| import 'canvaskit_api.dart'; | ||
| import 'image.dart'; | ||
| import 'layer.dart'; | ||
| import 'painting.dart'; | ||
|
|
||
| class CkTexture { | ||
| CkTexture(this.source); | ||
|
|
||
| final Object source; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm wondering if accepting all possible texture sources is future-proof enough. In particular, Skwasm will move to a multi-threaded rendering model where GPU work will be done through an
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The issue you bring up is something that I'm going to have to work out regardless of this change, and I haven't gotten to the point with the multi-threaded rendering where I have to decide how I'm going to solve it, but I think this should be fine. A |
||
|
|
||
| CkImage? _ckImage; | ||
|
|
||
| bool _newFrameReady = false; | ||
|
|
||
| final CkPaint _paint = CkPaint(); | ||
|
|
||
| void markNewFrameAvailable() { | ||
| _newFrameReady = true; | ||
| } | ||
|
|
||
| void paint( | ||
| PaintContext context, | ||
| ui.Offset offset, | ||
| double width, | ||
| double height, | ||
| bool freeze, | ||
| ui.FilterQuality filterQuality, | ||
| ) { | ||
| if (_ckImage == null || _newFrameReady && !freeze) { | ||
| final SkImage? skImage = | ||
| canvasKit.MakeLazyImageFromTextureSource(source, null); | ||
|
|
||
| if (skImage == null) { | ||
| return; | ||
| } | ||
|
|
||
| _ckImage?.dispose(); | ||
| _ckImage = CkImage(skImage); | ||
| } | ||
|
|
||
| context.leafNodesCanvas?.drawImageRect( | ||
| _ckImage!, | ||
| ui.Rect.fromLTWH( | ||
| 0, | ||
| 0, | ||
| _ckImage!.width.toDouble(), | ||
| _ckImage!.height.toDouble(), | ||
| ), | ||
| ui.Rect.fromLTWH(offset.dx, offset.dy, width, height), | ||
| _paint..filterQuality = filterQuality, | ||
| ); | ||
| } | ||
|
|
||
| void dispose() { | ||
| _ckImage?.dispose(); | ||
| } | ||
| } | ||
|
|
||
| class CkTextureRegistry implements TextureRegistry { | ||
| CkTextureRegistry._(); | ||
|
|
||
| static final CkTextureRegistry instance = CkTextureRegistry._(); | ||
|
|
||
| final Map<int, CkTexture> _textures = <int, CkTexture>{}; | ||
|
|
||
| int _nextTextureId = 0; | ||
|
|
||
| @override | ||
| int registerTexture(Object source) { | ||
| final int id = _nextTextureId++; | ||
| _textures[id] = CkTexture(source); | ||
| return id; | ||
| } | ||
|
|
||
| @override | ||
| void unregisterTexture(int id) { | ||
| final CkTexture? texture = _textures.remove(id); | ||
| texture?.dispose(); | ||
| } | ||
|
|
||
| CkTexture? getTexture(int id) { | ||
| return _textures[id]; | ||
| } | ||
|
|
||
| @override | ||
| void textureFrameAvailable(int id) { | ||
| final CkTexture? texture = _textures[id]; | ||
| if (texture != null) { | ||
| texture.markNewFrameAvailable(); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are working on removing web-specific API from
dart:uibecause it confuses compilers and code analyzers. Instead, we expose API through JS-interop. Let's consult with @ditman on how best to do this for textures. We might want to do it in a way that's easy to expose throughflutter.jsAPI.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Realistically we don't have a good place to put this in a way that is ergonomic for users to use (and a workaround for the analyzer to freak out less when using these web-only APIs).
In practice, the API surface of dart:ui has barely changed in the last couple of years, and adding one more object to the mix is not too bad.
@yjbanov I think this can land in
dart:ui, and whenever we come up with a better location for all these extra methods (dart:web_ui?), move them there. WDYT?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ditman Is there any way we could have two separate, clearly named libraries in the future, something like
dart:native_uianddart:web_ui? I feel likedart:uiin and of itself has been a point of confusion for too long for those working with the web platform as a target. I would assume that for backwards compatibility (if necessary)dart:uicould just re-export (certain members of) one or both - much like Rust'sstdre-exports (almost?) all of thecorepackage members.Personally, I would love for these to be named in a way that clearly shows they're building blocks for Flutter, and not really useful on their own when using pure Dart, but that might be too big a deviation from the norm at this point. I don't know, for example, if it would be possible technically to implement packages prefixed with
flutter, likeflutter:nativeandflutter:web.Long story short, I would appreciate a clear separation between Dart and Flutter, where one ends and the other begins, and the same for native and web targets. But I'm sure this isn't the place to discuss this in detail, so I'll be looking out for issues related to this in the future, if any.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@skreborn you're not alone, and this is such a big change that you'll know when it's coming for sure! The decision of making the flutter engine (
dart:ui) a dart library predates me, by years! I guess it's because the engine needs some extra help from the Dart compilers, but I haven't dug too deep.(I'd be happy if we could get to a point where
dart:uidoes not have anything web-specific, anddart:web_ui(or whatever its final name is) has only web-specific things, so it's clear from your imports if you're calling web-only APIs. Not sure what needs to be done for that to happen, haven't looked into the structural bits of the code yet!)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PS: We now have a
dart:ui_webpackage for things like this 😅Thank @eyebrowsoffire and @mdebbar!