-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] Create a drawable backed TextureMTL. #48049
[Impeller] Create a drawable backed TextureMTL. #48049
Conversation
| TextureMTL::TextureMTL(TextureDescriptor p_desc, | ||
| /// @brief an implementation of TextureMTL that is backed by a real Metal | ||
| /// texture. | ||
| class BetterNameTextureMTL final : public TextureMTL { |
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.
Help me come up with a better name.
chinmaygarde
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.
The std::async feedback is the crux of the review. Everything else is nits.
On a related note, I thought we discussed making pass attachments taking texture descriptors instead of textures and have the texture be lazily evaluation. This would move the lazy acquisition of the on-screen drawable above the HAL which should be more desirable. But that we can do that separately.
| return; | ||
| } | ||
|
|
||
| if (desc.size != GetSize()) { |
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.
Do we not have a utility to just construct an impeller::TextureDescriptor from an MTLTextureDescriptor? Seems like one can be inferred from the other and we won't have to check if they disagree. Impeller texture descriptors are comparable.
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.
This was an existing check 🤷
Also we need to relax this in order to make the texture cache more effective, but that is for another day.
| }; | ||
|
|
||
| /// @brief A class that holds the mutable state of the DrawableTextureMTL. | ||
| class DrawableHolder { |
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'd move these to their own TU. Generally prefer classes in their own TUs. Even for ones that are ostensibly "internal" to others for ease of code navigation IMO.
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.
Moved this to lazy_drawable_holder.h
| /// the next drawable of the provided metal layer. This class is intended to be | ||
| /// used to allow referencing the onscreen Metal drawable without blocking on | ||
| /// drawable acquisition. | ||
| class DrawableTextureMTL final : public TextureMTL { |
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.
LazilyAcquiredFromLayerTextureMTL? Is it bad if the only argument is that its silly-ly long?
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.
Removed, only have one class now
|
|
||
| ~DrawableHolder() = default; | ||
|
|
||
| bool AcquireNextDrawable(CAMetalLayer* layer) { |
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.
This seems to be a couple of levels of overkill. All we need is a lambda that is lazily evaluated and its results cached. std::async with std::launch::deferred will defer calling the lambda on the calling thread when the future is awaited upon. And, the future itself will hold the value around till you discard it.
So the DrawableHolder can just be std::future<std::shared_ptr<impeller::Texture>> (typedef it maybe). That can be obtained using a call to std::async(std::launch::deferred, [layer](){return WrapIntoAtexture([layer nextDrawable]);})
For style points, TextureMTL itself can take only a single argument which is a lambda that returns a texture. A lambda that will always be evaluated lazily. And in case you already have a texture, the lambda becomes [texture](){return texture};. Create a factory that creates the lambda if need be to keep the interface the same.
That way, you don't have to create a subclass hierarchy to LayerMTL. More importantly, you also don't have to think about naming the subclasses.
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.
Unfortunately I need access to both the texture and its drawable, the former to add to the MTL attachment, the later to present in SurfaceMTL.
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 can definitely compress this into a subclass, but I can't think of a way to do so without adding new API to query the drawable 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.
Unfortunately I need access to both the texture and its drawable, the former to add to the MTL attachment, the later to present in SurfaceMTL.
Thats just a future to a std::pair or struct.
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.
But the usage of the drawable isn't internal to the texture or to the callback, its done by the surface MTL. So roughly:
- surface_mtl has access to CAMetalLayer.
- Create TextureMTL from CAMetalLayer.
3a. Worker thread begins encoding root pass and waits on next drawable.
3b. surface_mtl waits on same drawable (without requesting it twice) and presents.
But thinking about it, I could probably have an object captured by that callback manage this state (essentially the state holder object I created)?
So I'll give that a shot. We do stil need an additional bit for whether or not the texture is lazy
| } | ||
|
|
||
| } // namespace testing | ||
| } // namespace impeller No newline at end of file |
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.
Newline at EOF.
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 don't recall discussing this, or even how we would do it. Can you elaborate a bit? |
|
As I recall (this was during a tail end of one of the weekly syncs), the observation was that the presence of full blown textures on As you said, not sure this is possible. But we were wondering if |
|
Still need to do some refactoring to make this use std::async and std::launch::deferred |
|
Updated to use std::shared_future and std::async. The idea is that the surface_mtl will wrap the CAMetalLayer with this callback, then pass a copy to the TextureMTL used in the root pass resolve. Then to present the surface_mtl should be able to block on getting the drawable and it should be cached. |
…138568) flutter/engine@22baa83...094a338 2023-11-16 [email protected] Roll Skia from 297049bbfc0d to 4c099aaa259f (5 revisions) (flutter/engine#48138) 2023-11-16 [email protected] Roll Dart SDK from b512191e9612 to 906f23c1cb20 (1 revision) (flutter/engine#48136) 2023-11-16 [email protected] Disable the `runIfNot` clauses in `.ci.yaml`, as they are unsafe. (flutter/engine#48132) 2023-11-16 [email protected] Fix race condition in Unobstructed Platform View Scenario tests (flutter/engine#48096) 2023-11-16 [email protected] [Impeller] store all path point data in single buffer. (flutter/engine#47896) 2023-11-16 [email protected] Roll Skia from b9ead4140f84 to 297049bbfc0d (2 revisions) (flutter/engine#48133) 2023-11-16 [email protected] [macOS] Replace pasteboard mock with fake (flutter/engine#48110) 2023-11-16 [email protected] [Impeller] Fix issue where the lock was not re-acquired when the wait exits on CV. (flutter/engine#48104) 2023-11-16 [email protected] [Impeller] Create a drawable backed TextureMTL. (flutter/engine#48049) 2023-11-16 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Make `flow/embedded_views.h` compatible with `.clang_tidy`." (flutter/engine#48130) 2023-11-16 [email protected] [macOS] Replace fixture subclasses with usings (flutter/engine#48111) 2023-11-16 [email protected] Make `flow/embedded_views.h` compatible with `.clang_tidy`. (flutter/engine#47994) 2023-11-16 [email protected] Make `flow/...` compatible with `.clang_tidy`. (flutter/engine#47995) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Allow creating a TextureMTL instance that is backend by a CAMetalLayer, which only acquires the drawable (and texture) lazily.
I split TextureMTL into two subclasses, one that has the standard wrapping behavior of a MTLTexture, and the other that holds a drawable. This is part of the foundational work for "removing drawable acquisition latency", as we need to delay aquisition of the drawable texture to a worker thread.
The drawable backed texture is only used in tests for now.
Part of flutter/flutter#138490