Skip to content
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

Merged
merged 22 commits into from
Apr 26, 2023

Conversation

jonahwilliams
Copy link
Member

@jonahwilliams jonahwilliams commented Apr 20, 2023

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.

Comment on lines +16 to +32
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_;
};

Copy link
Member Author

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.

Copy link
Member Author

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.

Copy link
Member Author

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?

Copy link
Contributor

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.

@jonahwilliams
Copy link
Member Author

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.

@jonahwilliams jonahwilliams changed the title [Impeller] use a device buffer for SkBitmap allocation, avoid upload on metal [Impeller] use a device buffer for SkBitmap allocation, use LinearTexture on metal backend Apr 21, 2023
@jonahwilliams jonahwilliams changed the title [Impeller] use a device buffer for SkBitmap allocation, use LinearTexture on metal backend [Impeller] use a device buffer for SkBitmap allocation, use Linear texture on metal backend Apr 21, 2023
@jonahwilliams jonahwilliams marked this pull request as ready for review April 21, 2023 16:51
@chinmaygarde chinmaygarde changed the title [Impeller] use a device buffer for SkBitmap allocation, use Linear texture on metal backend [Impeller] Use a device buffer for SkBitmap allocation, use Linear texture on Metal backend. Apr 21, 2023
bool CapabilitiesVK::SupportsDecalTileMode() const {
return true;
}

// |Capabilities|
bool CapabilitiesVK::SupportsSharedDeviceBufferTextureMemory() const {
return false;
Copy link
Member

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.

Copy link
Member Author

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));
Copy link
Member

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?

Copy link
Member Author

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;
Copy link
Member

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 {
Copy link
Member

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.

Copy link
Member Author

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.

Copy link
Member Author

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() &&
Copy link
Member

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.

Copy link
Member Author

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

Copy link
Member

@gaaclarke gaaclarke left a 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(
Copy link
Member

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?

Copy link
Member Author

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

Comment on lines +441 to +442
auto texture = device_buffer->AsTexture(allocator, texture_descriptor,
texture_descriptor.GetBytesPerRow());
Copy link
Contributor

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?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup!

Comment on lines +21 to +22
/// image_decode_impeller.cc due to the lack of a reasonable library
/// that could be shared.
Copy link
Contributor

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.

Copy link
Contributor

@dnfield dnfield left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with nits

@jonahwilliams jonahwilliams added the autosubmit Merge PR when tree becomes green via auto submit App label Apr 26, 2023
@auto-submit auto-submit bot merged commit fddd5ad into flutter:main Apr 26, 2023
@jonahwilliams jonahwilliams deleted the upload_with_shared_texture branch April 26, 2023 19:47
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 26, 2023
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Apr 26, 2023
…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
jonahwilliams added a commit that referenced this pull request Apr 26, 2023
…inear texture on Metal backend. (#41374)"

This reverts commit fddd5ad.
auto-submit bot pushed a commit that referenced this pull request Apr 26, 2023
…inear texture on Metal backend." (#41533)

Reverts #41374

Breaks on Simulators!
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 26, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Apr 27, 2023
jonahwilliams pushed a commit to flutter/flutter that referenced this pull request Apr 27, 2023
…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
auto-submit bot pushed a commit that referenced this pull request Apr 27, 2023
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autosubmit Merge PR when tree becomes green via auto submit App e: impeller
Projects
No open projects
Archived in project
4 participants