diff --git a/impeller/typographer/backends/skia/typographer_context_skia.cc b/impeller/typographer/backends/skia/typographer_context_skia.cc index 52616ed85d454..96027ea9906d4 100644 --- a/impeller/typographer/backends/skia/typographer_context_skia.cc +++ b/impeller/typographer/backends/skia/typographer_context_skia.cc @@ -46,56 +46,6 @@ namespace impeller { // https://github.com/flutter/flutter/issues/114563 constexpr auto kPadding = 2; -namespace { - -class HostBufferAllocator : public SkBitmap::Allocator { - public: - explicit HostBufferAllocator(HostBuffer& host_buffer) - : host_buffer_(host_buffer) {} - - [[nodiscard]] BufferView TakeBufferView() { - buffer_view_.buffer->Flush(); - return std::move(buffer_view_); - } - - // |SkBitmap::Allocator| - bool allocPixelRef(SkBitmap* bitmap) override { - if (!bitmap) { - return false; - } - const SkImageInfo& info = bitmap->info(); - if (kUnknown_SkColorType == info.colorType() || info.width() < 0 || - info.height() < 0 || !info.validRowBytes(bitmap->rowBytes())) { - return false; - } - - size_t required_bytes = bitmap->rowBytes() * bitmap->height(); - BufferView buffer_view = host_buffer_.Emplace(nullptr, required_bytes, - DefaultUniformAlignment()); - - // The impeller host buffer is not cleared between frames and may contain - // stale data. The Skia software canvas does not write to pixels without - // any contents, which causes this data to leak through. - ::memset(buffer_view.buffer->OnGetContents() + buffer_view.range.offset, 0, - required_bytes); - - auto pixel_ref = sk_sp(new SkPixelRef( - info.width(), info.height(), - buffer_view.buffer->OnGetContents() + buffer_view.range.offset, - bitmap->rowBytes())); - - bitmap->setPixelRef(std::move(pixel_ref), 0, 0); - buffer_view_ = std::move(buffer_view); - return true; - } - - private: - BufferView buffer_view_; - HostBuffer& host_buffer_; -}; - -} // namespace - std::shared_ptr TypographerContextSkia::Make() { return std::make_shared(); } @@ -282,9 +232,8 @@ static bool UpdateAtlasBitmap(const GlyphAtlas& atlas, } SkBitmap bitmap; - HostBufferAllocator allocator(host_buffer); bitmap.setInfo(GetImageInfo(atlas, size)); - if (!bitmap.tryAllocPixels(&allocator)) { + if (!bitmap.tryAllocPixels()) { return false; } auto surface = SkSurfaces::WrapPixels(bitmap.pixmap()); @@ -298,11 +247,19 @@ static bool UpdateAtlasBitmap(const GlyphAtlas& atlas, DrawGlyph(canvas, pair.scaled_font, pair.glyph, has_color); + // Writing to a malloc'd buffer and then copying to the staging buffers + // benchmarks as substantially faster on a number of Android devices. + BufferView buffer_view = host_buffer.Emplace( + bitmap.getAddr(0, 0), + size.Area() * BytesPerPixelForPixelFormat( + atlas.GetTexture()->GetTextureDescriptor().format), + DefaultUniformAlignment()); + // convert_to_read is set to false so that the texture remains in a transfer // dst layout until we finish writing to it below. This only has an impact // on Vulkan where we are responsible for managing image layouts. - if (!blit_pass->AddCopy(allocator.TakeBufferView(), // - texture, // + if (!blit_pass->AddCopy(std::move(buffer_view), // + texture, // IRect::MakeXYWH(pos->GetLeft(), pos->GetTop(), size.width, size.height), // /*label=*/"", //