-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Impeller] Use a device buffer for SkBitmap allocation, use Linear texture on Metal backend. #41374
[Impeller] Use a device buffer for SkBitmap allocation, use Linear texture on Metal backend. #41374
Conversation
class FontImpellerAllocator : public SkBitmap::Allocator { | ||
public: | ||
explicit FontImpellerAllocator( | ||
std::shared_ptr<impeller::Allocator> allocator); | ||
|
||
~FontImpellerAllocator() = default; | ||
|
||
// |Allocator| | ||
bool allocPixelRef(SkBitmap* bitmap) override; | ||
|
||
std::optional<std::shared_ptr<DeviceBuffer>> GetDeviceBuffer() const; | ||
|
||
private: | ||
std::shared_ptr<impeller::Allocator> allocator_; | ||
std::optional<std::shared_ptr<DeviceBuffer>> buffer_; | ||
}; | ||
|
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 is an exact copy of the implementation used in image decoding.
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 like to put it somewhere shared but I'm not quite sure where that would be.
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.
ignoring the skia dependency, it would just go in core. But with the skia dep I have no idea. I could create a new impeller-skia interop target?
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 should add a dependency on skia to core but we could. I think impeller/image
is probably the right spot for this.
For non metal platforms this may still be faster as it will use the device allocator instead of malloc, but IIRC it should have the same number of copies and uploads. |
…/engine into upload_with_shared_texture
bool CapabilitiesVK::SupportsDecalTileMode() const { | ||
return true; | ||
} | ||
|
||
// |Capabilities| | ||
bool CapabilitiesVK::SupportsSharedDeviceBufferTextureMemory() const { | ||
return false; |
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 should support it eventually, right? Probably worth adding a TODO.
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 did some research but I think is metal only
TextFrameFromTextBlob(blob)); | ||
auto atlas = context->CreateGlyphAtlas( | ||
GlyphAtlas::Type::kAlphaBitmap, atlas_context, | ||
CapabilitiesBuilder().Build(), TextFrameFromTextBlob(blob)); |
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.
Shouldn't we have a test where SupportsSharedDeviceBufferTextureMemory() == true
? We should get test coverage from our metal playground tests?
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.
Added a test that only runs if the backend supports this feature and validates the texture is valid for a single character atlas.
@@ -153,7 +154,8 @@ class GlyphAtlasContext { | |||
|
|||
//---------------------------------------------------------------------------- | |||
/// @brief Retrieve the previous (if any) SkBitmap instance. | |||
std::shared_ptr<SkBitmap> GetBitmap() const; | |||
std::pair<std::shared_ptr<SkBitmap>, std::shared_ptr<DeviceBuffer>> | |||
GetBitmap() const; |
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.
Looks like people want one or the other, right? Not both. Might be worth just keeping this the same and adding a device buffer accessor when/if we need it.
class DeviceBuffer; | ||
class Allocator; | ||
|
||
class FontImpellerAllocator : public SkBitmap::Allocator { |
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.
Please add docstring. The important thing to note is having access to the DeviceBuffer.
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.
still working on this, want to combine it with the identical class in image_decode_impeller but haven't thought of the right target 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.
Added a doc comment here. Haven't found a home yet but I think this can still be landed
// --------------------------------------------------------------------------- | ||
if (!UpdateGlyphTextureAtlas(bitmap, last_atlas->GetTexture())) { | ||
if (!capabilities->SupportsSharedDeviceBufferTextureMemory() && |
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.
Here's the payoff, right? LGTM.
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.
Technically this and below where we construct a texture from the device buffer, that required a second copy before but now its "free" on iOS/macOS
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.
lgtm
@@ -552,11 +559,12 @@ std::shared_ptr<GlyphAtlas> TextRenderContextSkia::CreateGlyphAtlas( | |||
// --------------------------------------------------------------------------- | |||
// Step 7: Draw font-glyph pairs in the correct spot in the atlas. | |||
// --------------------------------------------------------------------------- | |||
auto bitmap = CreateAtlasBitmap(*glyph_atlas, atlas_size); | |||
auto [bitmap, device_buffer] = CreateAtlasBitmap( |
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 are shadowing the declarations in 509, right?
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.
No, those are in a different block
auto texture = device_buffer->AsTexture(allocator, texture_descriptor, | ||
texture_descriptor.GetBytesPerRow()); |
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.
Does this punish non-metal implementations right now?
I think it doesn't because before we did the copy explicitly in this code, and now it gets done implicitly if needed there, right?
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.
Yup!
/// image_decode_impeller.cc due to the lack of a reasonable library | ||
/// that could be 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.
Right now we have display_list:skia_conversions
, aiks
, and image
and this that know about Skia.
It seems like this could probably go into image
, and we could add a dep to impeller/image
to both lib/ui
and impeller/typographer
. Doesn't have to be done in this patch but would be good as a follow up if not done here.
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.
LGTM with nits
Co-authored-by: Dan Field <dfield@gmail.com>
… Linear texture on Metal backend. (flutter/engine#41374)
…125583) flutter/engine@cf97541...fddd5ad 2023-04-26 jonahwilliams@google.com [Impeller] Use a device buffer for SkBitmap allocation, use Linear texture on Metal backend. (flutter/engine#41374) 2023-04-26 zanderso@users.noreply.github.com Manual clang roll to 5344d8e10bb7d8672d4bfae8adb010465470d51b (flutter/engine#41520) 2023-04-26 zanderso@users.noreply.github.com Download and use the goma client from cipd (flutter/engine#41488) 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 jsimmons@google.com,rmistry@google.com,zra@google.com 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://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
… Linear texture on Metal backend. (flutter/engine#41374)
… Linear texture on Metal backend. (flutter/engine#41374)
…125593) flutter/engine@cf97541...d4ca524 2023-04-27 skia-flutter-autoroll@skia.org Roll Skia from 20a1c61c5597 to d315ab065af3 (5 revisions) (flutter/engine#41535) 2023-04-26 jonahwilliams@google.com Revert "[Impeller] Use a device buffer for SkBitmap allocation, use Linear texture on Metal backend." (flutter/engine#41533) 2023-04-26 xilaizhang@google.com [codesign] Add pinned xcode version as property to mac android aot engine (flutter/engine#41518) 2023-04-26 bdero@google.com [Impeller] Coerce opaque ColorSourceContents to Source (flutter/engine#41525) 2023-04-26 skia-flutter-autoroll@skia.org Roll Skia from 3fea88565a83 to 20a1c61c5597 (3 revisions) (flutter/engine#41530) 2023-04-26 jonahwilliams@google.com [Impeller] partial repaint for Impeller/iOS. (flutter/engine#40959) 2023-04-26 30870216+gaaclarke@users.noreply.github.com Updated todo with github issue link (flutter/engine#41517) 2023-04-26 skia-flutter-autoroll@skia.org Roll Clang from 20d06c833d83 to 5344d8e10bb7 (flutter/engine#41524) 2023-04-26 jonahwilliams@google.com [Impeller] Use a device buffer for SkBitmap allocation, use Linear texture on Metal backend. (flutter/engine#41374) 2023-04-26 zanderso@users.noreply.github.com Manual clang roll to 5344d8e10bb7d8672d4bfae8adb010465470d51b (flutter/engine#41520) 2023-04-26 zanderso@users.noreply.github.com Download and use the goma client from cipd (flutter/engine#41488) 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 jsimmons@google.com,rmistry@google.com,zra@google.com 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://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…inear texture on Metal backend. (#41538) Original PR: #41374 This was reverted because it broke on simulators as they do not support linear textures. To fix this, I've ifdef'd out the DeviceBufferMTL implementation of AsTexture so that it falls back to the slow path copy. Also updated the capabilities check so that the glyph atlas updates the texture contents when it changes.
This reduces the cost of uploading the glyph atlas, as we can exploit metal's capabilies to create a texture from a device buffer and share the underlying memory with a linear texture. This also means that subsequent updates don't require uploads or copies either.
From scrolling through wonderous, this shaves off about 0.2 ms (0.6 ms -> 0.4 ms) of fresh atlas construction.