From c075bdbd9ca27d7d87da94ea707588a013c7da3d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 5 Oct 2022 12:29:23 -0700 Subject: [PATCH] Revert "[Impeller] Use fast path for CPU generated textures where possible" (flutter/engine#36622) --- .../backend/metal/device_buffer_mtl.mm | 1 - .../backends/skia/text_render_context_skia.cc | 115 ++++++++++-------- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/engine/src/flutter/impeller/renderer/backend/metal/device_buffer_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/device_buffer_mtl.mm index 81aa2387c6c..67525dde4de 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/device_buffer_mtl.mm +++ b/engine/src/flutter/impeller/renderer/backend/metal/device_buffer_mtl.mm @@ -26,7 +26,6 @@ uint8_t* DeviceBufferMTL::OnGetContents() const { if (storage_mode_ != MTLStorageModeShared) { return nullptr; } - return reinterpret_cast(buffer_.contents); } diff --git a/engine/src/flutter/impeller/typographer/backends/skia/text_render_context_skia.cc b/engine/src/flutter/impeller/typographer/backends/skia/text_render_context_skia.cc index 9002452427e..96ef3f68518 100644 --- a/engine/src/flutter/impeller/typographer/backends/skia/text_render_context_skia.cc +++ b/engine/src/flutter/impeller/typographer/backends/skia/text_render_context_skia.cc @@ -4,14 +4,12 @@ #include "impeller/typographer/backends/skia/text_render_context_skia.h" -#include #include #include "flutter/fml/logging.h" #include "flutter/fml/trace_event.h" #include "impeller/base/allocation.h" #include "impeller/renderer/allocator.h" -#include "impeller/renderer/device_buffer.h" #include "impeller/typographer/backends/skia/typeface_skia.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -240,59 +238,32 @@ static void ConvertBitmapToSignedDistanceField(uint8_t* pixels, #undef nearestpt } -static std::shared_ptr CreateAtlasTexture( - const std::shared_ptr& allocator, - const GlyphAtlas& atlas, - const ISize& atlas_size) { +static std::shared_ptr CreateAtlasBitmap(const GlyphAtlas& atlas, + const ISize& atlas_size) { TRACE_EVENT0("impeller", __FUNCTION__); auto bitmap = std::make_shared(); SkImageInfo image_info; - PixelFormat format; switch (atlas.GetType()) { case GlyphAtlas::Type::kSignedDistanceField: case GlyphAtlas::Type::kAlphaBitmap: - format = PixelFormat::kA8UNormInt; image_info = SkImageInfo::MakeA8(atlas_size.width, atlas_size.height); break; case GlyphAtlas::Type::kColorBitmap: - format = PixelFormat::kR8G8B8A8UNormInt; image_info = SkImageInfo::MakeN32Premul(atlas_size.width, atlas_size.height); break; } - auto row_bytes = - std::max(static_cast(image_info.minRowBytes()), - static_cast(allocator->MinimumBytesPerRow(format))); - - DeviceBufferDescriptor buffer_descriptor; - buffer_descriptor.storage_mode = StorageMode::kHostVisible; - buffer_descriptor.size = image_info.computeByteSize(row_bytes); - - auto buffer = allocator->CreateBuffer(buffer_descriptor); - if (!buffer) { - return nullptr; - } - - auto pixels = reinterpret_cast(buffer->AsBufferView().contents); - if (!pixels) { - FML_LOG(ERROR) << "No pixels"; - return nullptr; - } - - if (!bitmap->installPixels(image_info, pixels, row_bytes)) { - FML_LOG(ERROR) << "No install pixels"; + if (!bitmap->tryAllocPixels(image_info)) { return nullptr; } auto surface = SkSurface::MakeRasterDirect(bitmap->pixmap()); if (!surface) { - FML_LOG(ERROR) << "No surf"; return nullptr; } auto canvas = surface->getCanvas(); if (!canvas) { - FML_LOG(ERROR) << "No canv"; return nullptr; } @@ -323,20 +294,48 @@ static std::shared_ptr CreateAtlasTexture( return true; }); - if (atlas.GetType() == GlyphAtlas::Type::kSignedDistanceField) { - ConvertBitmapToSignedDistanceField( - reinterpret_cast(bitmap->getPixels()), atlas_size.width, - atlas_size.height); + return bitmap; +} + +static std::shared_ptr UploadGlyphTextureAtlas( + const std::shared_ptr& allocator, + std::shared_ptr bitmap, + const ISize& atlas_size, + PixelFormat format) { + TRACE_EVENT0("impeller", __FUNCTION__); + if (!allocator) { + return nullptr; } - { - TRACE_EVENT0("impeller", "Texture Creation/Upload"); - TextureDescriptor texture_descriptor; - texture_descriptor.storage_mode = StorageMode::kHostVisible; - texture_descriptor.format = format; - texture_descriptor.size = atlas_size; - return buffer->AsTexture(*allocator, texture_descriptor, row_bytes); + FML_DCHECK(bitmap != nullptr); + const auto& pixmap = bitmap->pixmap(); + + TextureDescriptor texture_descriptor; + texture_descriptor.storage_mode = StorageMode::kHostVisible; + texture_descriptor.format = format; + texture_descriptor.size = atlas_size; + + if (pixmap.rowBytes() * pixmap.height() != + texture_descriptor.GetByteSizeOfBaseMipLevel()) { + return nullptr; } + + auto texture = allocator->CreateTexture(texture_descriptor); + if (!texture || !texture->IsValid()) { + return nullptr; + } + texture->SetLabel("GlyphAtlas"); + + auto mapping = std::make_shared( + reinterpret_cast(bitmap->getAddr(0, 0)), // data + texture_descriptor.GetByteSizeOfBaseMipLevel(), // size + [bitmap](auto, auto) mutable { bitmap.reset(); } // proc + ); + + if (!texture->SetContents(mapping)) { + return nullptr; + } + return texture; } std::shared_ptr TextRenderContextSkia::CreateGlyphAtlas( @@ -387,19 +386,37 @@ std::shared_ptr TextRenderContextSkia::CreateGlyphAtlas( } // --------------------------------------------------------------------------- - // Step 5: Create a texture and draw font-glyph pairs in the correct spot in - // the atlas. + // Step 5: Draw font-glyph pairs in the correct spot in the atlas. // --------------------------------------------------------------------------- + auto bitmap = CreateAtlasBitmap(*glyph_atlas, atlas_size); + if (!bitmap) { + return nullptr; + } - auto texture = CreateAtlasTexture(GetContext()->GetResourceAllocator(), - *glyph_atlas, atlas_size); - + // --------------------------------------------------------------------------- + // Step 6: Upload the atlas as a texture. + // --------------------------------------------------------------------------- + PixelFormat format; + switch (type) { + case GlyphAtlas::Type::kSignedDistanceField: + ConvertBitmapToSignedDistanceField( + reinterpret_cast(bitmap->getPixels()), atlas_size.width, + atlas_size.height); + case GlyphAtlas::Type::kAlphaBitmap: + format = PixelFormat::kA8UNormInt; + break; + case GlyphAtlas::Type::kColorBitmap: + format = PixelFormat::kR8G8B8A8UNormInt; + break; + } + auto texture = UploadGlyphTextureAtlas(GetContext()->GetResourceAllocator(), + bitmap, atlas_size, format); if (!texture) { return nullptr; } // --------------------------------------------------------------------------- - // Step 6: Record the texture in the glyph atlas. + // Step 7: Record the texture in the glyph atlas. // --------------------------------------------------------------------------- glyph_atlas->SetTexture(std::move(texture));