From a72fddf9545da98c450583cd1f70d5d6c8b3ffe8 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Wed, 6 Mar 2024 10:58:46 -0800 Subject: [PATCH] [Impeller] Apply padding for alignment when doing HostBuffer::Emplace with a callback (flutter/engine#51221) --- .../src/flutter/impeller/core/host_buffer.cc | 19 ++++++++++++------- .../entity/contents/host_buffer_unittests.cc | 10 ++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/engine/src/flutter/impeller/core/host_buffer.cc b/engine/src/flutter/impeller/core/host_buffer.cc index 07528182560..67d3ca260af 100644 --- a/engine/src/flutter/impeller/core/host_buffer.cc +++ b/engine/src/flutter/impeller/core/host_buffer.cc @@ -110,19 +110,24 @@ std::tuple> HostBuffer::EmplaceInternal( return std::make_tuple(Range{0, length}, device_buffer); } - auto old_length = GetLength(); - if (old_length + length > kAllocatorBlockSize) { - MaybeCreateNewBuffer(); + size_t padding = 0; + if (align > 0 && offset_ % align) { + padding = align - (offset_ % align); + } + if (offset_ + padding + length > kAllocatorBlockSize) { + MaybeCreateNewBuffer(); + } else { + offset_ += padding; } - old_length = GetLength(); auto current_buffer = GetCurrentBuffer(); auto contents = current_buffer->OnGetContents(); - cb(contents + old_length); - current_buffer->Flush(Range{old_length, length}); + cb(contents + offset_); + Range output_range(offset_, length); + current_buffer->Flush(output_range); offset_ += length; - return std::make_tuple(Range{old_length, length}, std::move(current_buffer)); + return std::make_tuple(output_range, std::move(current_buffer)); } std::tuple> HostBuffer::EmplaceInternal( diff --git a/engine/src/flutter/impeller/entity/contents/host_buffer_unittests.cc b/engine/src/flutter/impeller/entity/contents/host_buffer_unittests.cc index 3ae3c285e07..28ac62dccea 100644 --- a/engine/src/flutter/impeller/entity/contents/host_buffer_unittests.cc +++ b/engine/src/flutter/impeller/entity/contents/host_buffer_unittests.cc @@ -146,5 +146,15 @@ TEST_P(HostBufferTest, UnusedBuffersAreDiscardedWhenResetting) { EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); } +TEST_P(HostBufferTest, EmplaceWithProcIsAligned) { + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + + BufferView view = buffer->Emplace(std::array()); + EXPECT_EQ(view.range, Range(0, 21)); + + view = buffer->Emplace(64, 16, [](uint8_t*) {}); + EXPECT_EQ(view.range, Range(32, 64)); +} + } // namespace testing } // namespace impeller