Revert "[Impeller] Use fast path for CPU generated textures where possible" (flutter/engine#36622)

This commit is contained in:
Dan Field 2022-10-05 12:29:23 -07:00 committed by GitHub
parent e4d709de85
commit c075bdbd9c
2 changed files with 66 additions and 50 deletions

View File

@ -26,7 +26,6 @@ uint8_t* DeviceBufferMTL::OnGetContents() const {
if (storage_mode_ != MTLStorageModeShared) {
return nullptr;
}
return reinterpret_cast<uint8_t*>(buffer_.contents);
}

View File

@ -4,14 +4,12 @@
#include "impeller/typographer/backends/skia/text_render_context_skia.h"
#include <stdlib.h>
#include <utility>
#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<Texture> CreateAtlasTexture(
const std::shared_ptr<Allocator>& allocator,
const GlyphAtlas& atlas,
const ISize& atlas_size) {
static std::shared_ptr<SkBitmap> CreateAtlasBitmap(const GlyphAtlas& atlas,
const ISize& atlas_size) {
TRACE_EVENT0("impeller", __FUNCTION__);
auto bitmap = std::make_shared<SkBitmap>();
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<uint16_t>(image_info.minRowBytes()),
static_cast<uint16_t>(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<void*>(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<Texture> CreateAtlasTexture(
return true;
});
if (atlas.GetType() == GlyphAtlas::Type::kSignedDistanceField) {
ConvertBitmapToSignedDistanceField(
reinterpret_cast<uint8_t*>(bitmap->getPixels()), atlas_size.width,
atlas_size.height);
return bitmap;
}
static std::shared_ptr<Texture> UploadGlyphTextureAtlas(
const std::shared_ptr<Allocator>& allocator,
std::shared_ptr<SkBitmap> 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<fml::NonOwnedMapping>(
reinterpret_cast<const uint8_t*>(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<GlyphAtlas> TextRenderContextSkia::CreateGlyphAtlas(
@ -387,19 +386,37 @@ std::shared_ptr<GlyphAtlas> 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<uint8_t*>(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));