-
Notifications
You must be signed in to change notification settings - Fork 6k
Flatten LayerTree on raster thread to include texture registry and GrDirectContext #34624
Conversation
This comment was marked as off-topic.
This comment was marked as off-topic.
|
or maybe it will, need to actually build on Android and test |
flow/layers/layer_tree.cc
Outdated
|
|
||
| sk_sp<DisplayList> LayerTree::FlattenWithContext( | ||
| const SkRect& bounds, | ||
| TextureRegistry* texture_registry) { |
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.
I think you can probably just add this as an optional parameter on Flatten
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.
Yeah, that makes sense!
lib/ui/compositing/scene.cc
Outdated
| auto picture = layer_tree_->Flatten(SkRect::MakeWH(width, height)); | ||
| auto picture = layer_tree_->FlattenWithContext( | ||
| SkRect::MakeWH(width, height), | ||
| snapshot_delegate.get()->GetTextureRegistry()); |
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.
You can drop .get() here, but you should null check this. I think if the snapshot delegate is nullptr we can just proceed without the texture registry.
lib/ui/compositing/scene.cc
Outdated
| Dart_Handle raw_image_handle) { | ||
| TRACE_EVENT0("flutter", "Scene::toImageSync"); | ||
| auto* dart_state = UIDartState::Current(); | ||
| auto snapshot_delegate = dart_state->GetSnapshotDelegate(); |
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.
nullcheck on dart_state.
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.
These can be deleted now
|
I got this almost working (as in, it works but eventually crashes), the problem is that the texture registry needs to be accessed on the raster thread, so the flatten call needs to go in the posted task |
lib/ui/compositing/scene.cc
Outdated
| fml::TaskRunner::RunNowOrPostTask( | ||
| raster_task_runner, | ||
| [snapshot_delegate, unref_queue, dl_image = std::move(dl_image), | ||
| layer_tree = std::move(layer_tree.get()), width, height]() { |
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.
What I'm doing to layer_tree doesn't seem right, but it did compile....
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.
I don't think we can safely call takeLayerTree here. That makes the scene unusable in the future.
That said, I think we'll have to make the layer_tree_ a shared_ptr for this to work to share it across threads.
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.
Also you don't need to move a raw pointer.
You'll want something like layer_tree = layer_tree_, and make the ivar a std::shared_ptr.
flow/layers/layer_tree.h
Outdated
| sk_sp<DisplayList> FlattenWithContext(const SkRect& bounds, | ||
| TextureRegistry* texture_registry); |
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.
just remove this now
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.
oop, why did this compile lol
…ne into hack_for_texture_view
lib/ui/compositing/scene.cc
Outdated
|
|
||
| std::unique_ptr<flutter::LayerTree> Scene::takeLayerTree() { | ||
| return std::move(layer_tree_); | ||
| return nullptr; |
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.
Changing to shared_ptr almost works, except that everything that uses this API expects a unique_ptr.
Maybe I can hold onto the parts used to construct the LayerTree and then build either a shared_ptr or unique_ptr on the fly?
The root layer used to construct the layer tree is itself a shared_ptr...
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.
What's it look like to just convert all those callsites to shared?
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.
its a lot, let me dig in some more.
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.
I updated the PR with all the changes needed to compile this
lib/ui/compositing/scene.cc
Outdated
| layer_tree = layer_tree_, width, height]() { | ||
| auto display_list = | ||
| layer_tree->Flatten(SkRect::MakeWH(width, height), | ||
| snapshot_delegate.get()->GetTextureRegistry()); |
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.
need a to check snapshot_delegate. It might have been collected by now.
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.
Doneish. Do I need to set anything on the dl_image, or could we assume we're shutting down now?
dnfield
left a comment
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.
Will need a test.
lib/ui/compositing/scene.cc
Outdated
|
|
||
| fml::TaskRunner::RunNowOrPostTask( | ||
| raster_task_runner, | ||
| [snapshot_delegate, unref_queue, dl_image = std::move(dl_image), |
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.
std::move snapshot_delegate and unref_queue.
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.
Done
| uint32_t height, | ||
| Dart_Handle raw_image_handle); | ||
|
|
||
| std::shared_ptr<flutter::LayerTree> layer_tree_; |
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.
Consider documenting why this is a shared pointer - and that it's no longer valid after takeLayerTree.
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.
Done
| void Scene::RasterizeToImageSync(uint32_t width, | ||
| uint32_t height, | ||
| Dart_Handle raw_image_handle) { | ||
| auto* dart_state = UIDartState::Current(); |
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.
I know this is a private method, but we should probably at least FML_DCHECK(layer_tree_) here.
Also, you'll need to do a null check on dart_state and just bail out early if it's nullptr (I think that might be extra defensive but there ends up being weirdness around isolate teardown and when these objects get destroyed).
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.
Done
|
I added a test that Scene.toImageSync works with a texture layer, but since actual texture creation is platform specific the only way I could test it further would be to mock the texture out like the unit tests do. Any other ideas @dnfield ? |
|
Testing this more today, I ran into some issues I hadn't seen before with the texture registry. I'll need to step back through the code and see where I made a mistake. This doesn't block the page transition PR though, since that can use a fallback for both TextureLayer and PlatformLayer until this is fixed (we'd retain the fallback for PlatformLayer) |
|
Ahh I'm missing the grcontext! |
|
Updated and works correctly now, we also need a GrContext to paint the texture |
|
|
||
| sk_sp<DisplayList> LayerTree::Flatten(const SkRect& bounds) { | ||
| sk_sp<DisplayList> LayerTree::Flatten(const SkRect& bounds, | ||
| TextureRegistry* texture_registry, |
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.
In #35073 I'm making this a shared_ptr everywhere. Could you rebase on top of that? I'd rather do that than have bare pointers floating around.
|
|
||
| sk_sp<DisplayList> Flatten(const SkRect& bounds); | ||
| sk_sp<DisplayList> Flatten(const SkRect& bounds, | ||
| TextureRegistry* texture_registry = nullptr, |
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.
Ditto here - let's just make these smart pointer objects.
| } | ||
| return _futurize((_Callback<Image?> callback) => _toImage(width, height, (_Image? image) { | ||
| final _Image image = _Image._(); | ||
| return _futurize((_Callback<Image?> callback) => _toImage(width, height, image, (_Image? image) { |
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 should just make this a voidcallback, right?
We're passing in an image and then passing the same handle back it seems.
|
Will update this after I can rebase on the toPictureSync change |
|
I think we should probably icebox this until we figure out toImageSync for Image shaders/paints. Otherwise we'll end up with different coverage on the sync and async paths, with the former able to access textures easily and the latter able to be used in image shaders |
ToImage/toImageSync doesn't currently include the output of textures, due to LayerTree::Flatten using a no-op texture registry. We should provide one so texture backed platform views work.
(This implementation is just a hack so i can test it out.) Also unsure if there were other reasons why this wouldn't work
FYI @dnfield @zanderso