diff --git a/engine/src/flutter/ci/licenses_golden/excluded_files b/engine/src/flutter/ci/licenses_golden/excluded_files index ffbff44e4a..0392730b99 100644 --- a/engine/src/flutter/ci/licenses_golden/excluded_files +++ b/engine/src/flutter/ci/licenses_golden/excluded_files @@ -136,6 +136,7 @@ ../../../flutter/impeller/compiler/shader_bundle_unittests.cc ../../../flutter/impeller/compiler/switches_unittests.cc ../../../flutter/impeller/core/allocator_unittests.cc +../../../flutter/impeller/core/buffer_view_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_atlas_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_basic_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_blend_unittests.cc diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 3206a9a083..3f2f1e42f9 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -42900,6 +42900,7 @@ ORIGIN: ../../../flutter/impeller/core/formats.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/core/formats.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/core/host_buffer.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/core/host_buffer.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/core/idle_waiter.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/core/platform.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/core/platform.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/core/range.cc + ../../../flutter/LICENSE @@ -45761,6 +45762,7 @@ FILE: ../../../flutter/impeller/core/formats.cc FILE: ../../../flutter/impeller/core/formats.h FILE: ../../../flutter/impeller/core/host_buffer.cc FILE: ../../../flutter/impeller/core/host_buffer.h +FILE: ../../../flutter/impeller/core/idle_waiter.h FILE: ../../../flutter/impeller/core/platform.cc FILE: ../../../flutter/impeller/core/platform.h FILE: ../../../flutter/impeller/core/range.cc diff --git a/engine/src/flutter/impeller/core/BUILD.gn b/engine/src/flutter/impeller/core/BUILD.gn index e526c46115..bb7ef28cf1 100644 --- a/engine/src/flutter/impeller/core/BUILD.gn +++ b/engine/src/flutter/impeller/core/BUILD.gn @@ -18,6 +18,7 @@ impeller_component("core") { "formats.h", "host_buffer.cc", "host_buffer.h", + "idle_waiter.h", "platform.cc", "platform.h", "range.cc", @@ -50,7 +51,10 @@ impeller_component("core") { impeller_component("allocator_unittests") { testonly = true - sources = [ "allocator_unittests.cc" ] + sources = [ + "allocator_unittests.cc", + "buffer_view_unittests.cc", + ] deps = [ ":core", diff --git a/engine/src/flutter/impeller/core/allocator.h b/engine/src/flutter/impeller/core/allocator.h index a4b3509884..50da86fe10 100644 --- a/engine/src/flutter/impeller/core/allocator.h +++ b/engine/src/flutter/impeller/core/allocator.h @@ -8,6 +8,7 @@ #include "flutter/fml/mapping.h" #include "impeller/base/allocation_size.h" #include "impeller/core/device_buffer_descriptor.h" +#include "impeller/core/idle_waiter.h" #include "impeller/core/texture.h" #include "impeller/core/texture_descriptor.h" #include "impeller/geometry/size.h" diff --git a/engine/src/flutter/impeller/core/buffer_view.cc b/engine/src/flutter/impeller/core/buffer_view.cc index 8d0887a3b5..5ab3ee01fc 100644 --- a/engine/src/flutter/impeller/core/buffer_view.cc +++ b/engine/src/flutter/impeller/core/buffer_view.cc @@ -6,6 +6,29 @@ namespace impeller { -// +BufferView::BufferView() : buffer_(nullptr), raw_buffer_(nullptr), range_({}) {} + +BufferView::BufferView(DeviceBuffer* buffer, Range range) + : buffer_(), raw_buffer_(buffer), range_(range) {} + +BufferView::BufferView(std::shared_ptr buffer, Range range) + : buffer_(std::move(buffer)), raw_buffer_(nullptr), range_(range) {} + +const DeviceBuffer* BufferView::GetBuffer() const { + return raw_buffer_ ? raw_buffer_ : buffer_.get(); +} + +std::shared_ptr BufferView::TakeBuffer() { + if (buffer_) { + raw_buffer_ = buffer_.get(); + return std::move(buffer_); + } else { + return nullptr; + } +} + +BufferView::operator bool() const { + return buffer_ || raw_buffer_; +} } // namespace impeller diff --git a/engine/src/flutter/impeller/core/buffer_view.h b/engine/src/flutter/impeller/core/buffer_view.h index e319f44f28..f5a3cf1420 100644 --- a/engine/src/flutter/impeller/core/buffer_view.h +++ b/engine/src/flutter/impeller/core/buffer_view.h @@ -12,11 +12,34 @@ namespace impeller { class DeviceBuffer; +/// A specific range in a DeviceBuffer. +/// +/// BufferView can maintain ownership over the DeviceBuffer or not depending on +/// if it is created with a std::shared_ptr or a raw pointer. struct BufferView { - std::shared_ptr buffer; - Range range; + public: + BufferView(); - constexpr explicit operator bool() const { return static_cast(buffer); } + BufferView(DeviceBuffer* buffer, Range range); + + BufferView(std::shared_ptr buffer, Range range); + + Range GetRange() const { return range_; } + + const DeviceBuffer* GetBuffer() const; + + std::shared_ptr TakeBuffer(); + + explicit operator bool() const; + + private: + std::shared_ptr buffer_; + /// This is a non-owned DeviceBuffer. Steps should be taken to make sure this + /// lives for the duration of the BufferView's life. Usually this is done + /// automatically by the graphics API or in the case of Vulkan the HostBuffer + /// or TrackedObjectsVK keeps it alive. + const DeviceBuffer* raw_buffer_; + Range range_; }; } // namespace impeller diff --git a/engine/src/flutter/impeller/core/buffer_view_unittests.cc b/engine/src/flutter/impeller/core/buffer_view_unittests.cc new file mode 100644 index 0000000000..27c80247a9 --- /dev/null +++ b/engine/src/flutter/impeller/core/buffer_view_unittests.cc @@ -0,0 +1,26 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/testing/testing.h" +#include "impeller/core/buffer_view.h" + +namespace impeller { +namespace testing { + +TEST(BufferViewTest, Empty) { + BufferView buffer_view; + EXPECT_FALSE(buffer_view); +} + +TEST(BufferViewTest, TakeRaw) { + DeviceBuffer* buffer = reinterpret_cast(0xcafebabe); + BufferView buffer_view(buffer, {0, 123}); + EXPECT_TRUE(buffer_view); + std::shared_ptr taken = buffer_view.TakeBuffer(); + EXPECT_FALSE(taken); + EXPECT_EQ(buffer_view.GetBuffer(), buffer); +} + +} // namespace testing +} // namespace impeller diff --git a/engine/src/flutter/impeller/core/device_buffer.cc b/engine/src/flutter/impeller/core/device_buffer.cc index 1df3c03b36..0d3f01afff 100644 --- a/engine/src/flutter/impeller/core/device_buffer.cc +++ b/engine/src/flutter/impeller/core/device_buffer.cc @@ -16,10 +16,8 @@ void DeviceBuffer::Invalidate(std::optional range) const {} // static BufferView DeviceBuffer::AsBufferView(std::shared_ptr buffer) { - BufferView view; - view.buffer = std::move(buffer); - view.range = {0u, view.buffer->desc_.size}; - return view; + Range range = {0u, buffer->desc_.size}; + return BufferView(std::move(buffer), range); } const DeviceBufferDescriptor& DeviceBuffer::GetDeviceBufferDescriptor() const { diff --git a/engine/src/flutter/impeller/core/host_buffer.cc b/engine/src/flutter/impeller/core/host_buffer.cc index 1bee37599a..1fef5df595 100644 --- a/engine/src/flutter/impeller/core/host_buffer.cc +++ b/engine/src/flutter/impeller/core/host_buffer.cc @@ -19,12 +19,14 @@ namespace impeller { constexpr size_t kAllocatorBlockSize = 1024000; // 1024 Kb. std::shared_ptr HostBuffer::Create( - const std::shared_ptr& allocator) { - return std::shared_ptr(new HostBuffer(allocator)); + const std::shared_ptr& allocator, + const std::shared_ptr& idle_waiter) { + return std::shared_ptr(new HostBuffer(allocator, idle_waiter)); } -HostBuffer::HostBuffer(const std::shared_ptr& allocator) - : allocator_(allocator) { +HostBuffer::HostBuffer(const std::shared_ptr& allocator, + const std::shared_ptr& idle_waiter) + : allocator_(allocator), idle_waiter_(idle_waiter) { DeviceBufferDescriptor desc; desc.size = kAllocatorBlockSize; desc.storage_mode = StorageMode::kHostVisible; @@ -35,34 +37,52 @@ HostBuffer::HostBuffer(const std::shared_ptr& allocator) } } -HostBuffer::~HostBuffer() = default; +HostBuffer::~HostBuffer() { + if (idle_waiter_) { + // Since we hold on to DeviceBuffers we should make sure they aren't being + // used while we are deleting the HostBuffer. + idle_waiter_->WaitIdle(); + } +}; BufferView HostBuffer::Emplace(const void* buffer, size_t length, size_t align) { - auto [range, device_buffer] = EmplaceInternal(buffer, length, align); - if (!device_buffer) { + auto [range, device_buffer, raw_device_buffer] = + EmplaceInternal(buffer, length, align); + if (device_buffer) { + return BufferView(std::move(device_buffer), range); + } else if (raw_device_buffer) { + return BufferView(raw_device_buffer, range); + } else { return {}; } - return BufferView{std::move(device_buffer), range}; } BufferView HostBuffer::Emplace(const void* buffer, size_t length) { - auto [range, device_buffer] = EmplaceInternal(buffer, length); - if (!device_buffer) { + auto [range, device_buffer, raw_device_buffer] = + EmplaceInternal(buffer, length); + if (device_buffer) { + return BufferView(std::move(device_buffer), range); + } else if (raw_device_buffer) { + return BufferView(raw_device_buffer, range); + } else { return {}; } - return BufferView{std::move(device_buffer), range}; } BufferView HostBuffer::Emplace(size_t length, size_t align, const EmplaceProc& cb) { - auto [range, device_buffer] = EmplaceInternal(length, align, cb); - if (!device_buffer) { + auto [range, device_buffer, raw_device_buffer] = + EmplaceInternal(length, align, cb); + if (device_buffer) { + return BufferView(std::move(device_buffer), range); + } else if (raw_device_buffer) { + return BufferView(raw_device_buffer, range); + } else { return {}; } - return BufferView{std::move(device_buffer), range}; } HostBuffer::TestStateQuery HostBuffer::GetStateForTest() { @@ -90,10 +110,10 @@ bool HostBuffer::MaybeCreateNewBuffer() { return true; } -std::tuple> HostBuffer::EmplaceInternal( - size_t length, - size_t align, - const EmplaceProc& cb) { +std::tuple, DeviceBuffer*> +HostBuffer::EmplaceInternal(size_t length, + size_t align, + const EmplaceProc& cb) { if (!cb) { return {}; } @@ -113,7 +133,7 @@ std::tuple> HostBuffer::EmplaceInternal( cb(device_buffer->OnGetContents()); device_buffer->Flush(Range{0, length}); } - return std::make_tuple(Range{0, length}, std::move(device_buffer)); + return std::make_tuple(Range{0, length}, std::move(device_buffer), nullptr); } size_t padding = 0; @@ -135,12 +155,11 @@ std::tuple> HostBuffer::EmplaceInternal( current_buffer->Flush(output_range); offset_ += length; - return std::make_tuple(output_range, current_buffer); + return std::make_tuple(output_range, nullptr, current_buffer.get()); } -std::tuple> HostBuffer::EmplaceInternal( - const void* buffer, - size_t length) { +std::tuple, DeviceBuffer*> +HostBuffer::EmplaceInternal(const void* buffer, size_t length) { // If the requested allocation is bigger than the block size, create a one-off // device buffer and write to that. if (length > kAllocatorBlockSize) { @@ -158,7 +177,7 @@ std::tuple> HostBuffer::EmplaceInternal( return {}; } } - return std::make_tuple(Range{0, length}, std::move(device_buffer)); + return std::make_tuple(Range{0, length}, std::move(device_buffer), nullptr); } auto old_length = GetLength(); @@ -176,10 +195,11 @@ std::tuple> HostBuffer::EmplaceInternal( current_buffer->Flush(Range{old_length, length}); } offset_ += length; - return std::make_tuple(Range{old_length, length}, current_buffer); + return std::make_tuple(Range{old_length, length}, nullptr, + current_buffer.get()); } -std::tuple> +std::tuple, DeviceBuffer*> HostBuffer::EmplaceInternal(const void* buffer, size_t length, size_t align) { if (align == 0 || (GetLength() % align) == 0) { return EmplaceInternal(buffer, length); diff --git a/engine/src/flutter/impeller/core/host_buffer.h b/engine/src/flutter/impeller/core/host_buffer.h index 43c03c3a20..d0c5dbf3f3 100644 --- a/engine/src/flutter/impeller/core/host_buffer.h +++ b/engine/src/flutter/impeller/core/host_buffer.h @@ -28,7 +28,8 @@ static const constexpr size_t kHostBufferArenaSize = 4u; class HostBuffer { public: static std::shared_ptr Create( - const std::shared_ptr& allocator); + const std::shared_ptr& allocator, + const std::shared_ptr& idle_waiter); ~HostBuffer(); @@ -133,13 +134,13 @@ class HostBuffer { TestStateQuery GetStateForTest(); private: - [[nodiscard]] std::tuple> + [[nodiscard]] std::tuple, DeviceBuffer*> EmplaceInternal(const void* buffer, size_t length); - std::tuple> + std::tuple, DeviceBuffer*> EmplaceInternal(size_t length, size_t align, const EmplaceProc& cb); - std::tuple> + std::tuple, DeviceBuffer*> EmplaceInternal(const void* buffer, size_t length, size_t align); size_t GetLength() const { return offset_; } @@ -154,13 +155,15 @@ class HostBuffer { [[nodiscard]] BufferView Emplace(const void* buffer, size_t length); - explicit HostBuffer(const std::shared_ptr& allocator); + explicit HostBuffer(const std::shared_ptr& allocator, + const std::shared_ptr& idle_waiter); HostBuffer(const HostBuffer&) = delete; HostBuffer& operator=(const HostBuffer&) = delete; std::shared_ptr allocator_; + std::shared_ptr idle_waiter_; std::array>, kHostBufferArenaSize> device_buffers_; size_t current_buffer_ = 0u; diff --git a/engine/src/flutter/impeller/core/idle_waiter.h b/engine/src/flutter/impeller/core/idle_waiter.h new file mode 100644 index 0000000000..f346375b2b --- /dev/null +++ b/engine/src/flutter/impeller/core/idle_waiter.h @@ -0,0 +1,25 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_IMPELLER_CORE_IDLE_WAITER_H_ +#define FLUTTER_IMPELLER_CORE_IDLE_WAITER_H_ + +namespace impeller { + +/// Abstraction over waiting for the GPU to be idle. +/// +/// This is important for platforms like Vulkan where we need to make sure +/// we aren't deleting resources while the GPU is using them. +class IdleWaiter { + public: + virtual ~IdleWaiter() = default; + + /// Wait for the GPU tasks to finish. + /// This is a noop on some platforms, it's important for Vulkan. + virtual void WaitIdle() const = 0; +}; + +} // namespace impeller + +#endif // FLUTTER_IMPELLER_CORE_IDLE_WAITER_H_ diff --git a/engine/src/flutter/impeller/entity/contents/content_context.cc b/engine/src/flutter/impeller/entity/contents/content_context.cc index 6748058270..92c854f41d 100644 --- a/engine/src/flutter/impeller/entity/contents/content_context.cc +++ b/engine/src/flutter/impeller/entity/contents/content_context.cc @@ -250,7 +250,8 @@ ContentContext::ContentContext( ? std::make_shared( context_->GetResourceAllocator()) : std::move(render_target_allocator)), - host_buffer_(HostBuffer::Create(context_->GetResourceAllocator())) { + host_buffer_(HostBuffer::Create(context_->GetResourceAllocator(), + context_->GetIdleWaiter())) { if (!context_ || !context_->IsValid()) { return; } diff --git a/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents_unittests.cc b/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents_unittests.cc index 977eae47a2..cc8176679e 100644 --- a/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents_unittests.cc +++ b/engine/src/flutter/impeller/entity/contents/filters/blend_filter_contents_unittests.cc @@ -54,8 +54,8 @@ TEST_P(BlendFilterContentsTest, AdvancedBlendColorAlignsColorTo4) { uint8_t byte = 0xff; BufferView buffer_view = renderer->GetTransientsBuffer().Emplace(&byte, /*length=*/1, /*align=*/1); - EXPECT_EQ(buffer_view.range.offset, 4u); - EXPECT_EQ(buffer_view.range.length, 1u); + EXPECT_EQ(buffer_view.GetRange().offset, 4u); + EXPECT_EQ(buffer_view.GetRange().length, 1u); Entity entity; std::optional result = filter_contents.GetEntity( 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 77f425bf7e..ffac9c806a 100644 --- a/engine/src/flutter/impeller/entity/contents/host_buffer_unittests.cc +++ b/engine/src/flutter/impeller/entity/contents/host_buffer_unittests.cc @@ -4,30 +4,48 @@ #include #include + #include "flutter/testing/testing.h" +#include "gmock/gmock.h" #include "impeller/base/validation.h" #include "impeller/core/allocator.h" #include "impeller/core/host_buffer.h" +#include "impeller/core/idle_waiter.h" #include "impeller/entity/entity_playground.h" namespace impeller { namespace testing { +class MockIdleWaiter : public IdleWaiter { + public: + MOCK_METHOD(void, WaitIdle, (), (const, override)); +}; + using HostBufferTest = EntityPlayground; INSTANTIATE_PLAYGROUND_SUITE(HostBufferTest); +TEST_P(HostBufferTest, IdleWaiter) { + auto mock_idle_waiter = std::make_shared(); + { + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + mock_idle_waiter); + EXPECT_CALL(*mock_idle_waiter, WaitIdle()); + } +} + TEST_P(HostBufferTest, CanEmplace) { struct Length2 { uint8_t pad[2]; }; static_assert(sizeof(Length2) == 2u); - auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); for (size_t i = 0; i < 12500; i++) { auto view = buffer->Emplace(Length2{}); ASSERT_TRUE(view); - ASSERT_EQ(view.range, Range(i * sizeof(Length2), 2u)); + ASSERT_EQ(view.GetRange(), Range(i * sizeof(Length2), 2u)); } } @@ -42,37 +60,39 @@ TEST_P(HostBufferTest, CanEmplaceWithAlignment) { static_assert(alignof(Align16) == 16); static_assert(sizeof(Align16) == 16); - auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); ASSERT_TRUE(buffer); { auto view = buffer->Emplace(Length2{}); ASSERT_TRUE(view); - ASSERT_EQ(view.range, Range(0u, 2u)); + ASSERT_EQ(view.GetRange(), Range(0u, 2u)); } { auto view = buffer->Emplace(Align16{}); ASSERT_TRUE(view); - ASSERT_EQ(view.range.offset, 16u); - ASSERT_EQ(view.range.length, 16u); + ASSERT_EQ(view.GetRange().offset, 16u); + ASSERT_EQ(view.GetRange().length, 16u); } { auto view = buffer->Emplace(Length2{}); ASSERT_TRUE(view); - ASSERT_EQ(view.range, Range(32u, 2u)); + ASSERT_EQ(view.GetRange(), Range(32u, 2u)); } { auto view = buffer->Emplace(Align16{}); ASSERT_TRUE(view); - ASSERT_EQ(view.range.offset, 48u); - ASSERT_EQ(view.range.length, 16u); + ASSERT_EQ(view.GetRange().offset, 48u); + ASSERT_EQ(view.GetRange().length, 16u); } } TEST_P(HostBufferTest, HostBufferInitialState) { - auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u); EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); @@ -80,7 +100,8 @@ TEST_P(HostBufferTest, HostBufferInitialState) { } TEST_P(HostBufferTest, ResetIncrementsFrameCounter) { - auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); @@ -99,7 +120,8 @@ TEST_P(HostBufferTest, ResetIncrementsFrameCounter) { TEST_P(HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback) { - auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); // Emplace an amount larger than the block size, to verify that the host // buffer does not create a buffer. @@ -111,7 +133,8 @@ TEST_P(HostBufferTest, } TEST_P(HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBuffer) { - auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); // Emplace an amount larger than the block size, to verify that the host // buffer does not create a buffer. @@ -123,7 +146,8 @@ TEST_P(HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBuffer) { } TEST_P(HostBufferTest, UnusedBuffersAreDiscardedWhenResetting) { - auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); // Emplace two large allocations to force the allocation of a second buffer. auto buffer_view_a = buffer->Emplace(1020000, 0, [](uint8_t* data) {}); @@ -154,13 +178,14 @@ TEST_P(HostBufferTest, UnusedBuffersAreDiscardedWhenResetting) { } TEST_P(HostBufferTest, EmplaceWithProcIsAligned) { - auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); BufferView view = buffer->Emplace(std::array()); - EXPECT_EQ(view.range, Range(0, 21)); + EXPECT_EQ(view.GetRange(), Range(0, 21)); view = buffer->Emplace(64, 16, [](uint8_t*) {}); - EXPECT_EQ(view.range, Range(32, 64)); + EXPECT_EQ(view.GetRange(), Range(32, 64)); } static constexpr const size_t kMagicFailingAllocation = 1024000 * 2; @@ -197,13 +222,13 @@ TEST_P(HostBufferTest, EmplaceWithFailingAllocationDoesntCrash) { ScopedValidationDisable disable; std::shared_ptr allocator = std::make_shared(GetContext()->GetResourceAllocator()); - auto buffer = HostBuffer::Create(allocator); + auto buffer = HostBuffer::Create(allocator, GetContext()->GetIdleWaiter()); auto view = buffer->Emplace(nullptr, kMagicFailingAllocation, 0); - EXPECT_EQ(view.buffer, nullptr); - EXPECT_EQ(view.range.offset, 0u); - EXPECT_EQ(view.range.length, 0u); + EXPECT_EQ(view.GetBuffer(), nullptr); + EXPECT_EQ(view.GetRange().offset, 0u); + EXPECT_EQ(view.GetRange().length, 0u); } } // namespace testing diff --git a/engine/src/flutter/impeller/entity/entity_unittests.cc b/engine/src/flutter/impeller/entity/entity_unittests.cc index c8b4bb722e..816427f12b 100644 --- a/engine/src/flutter/impeller/entity/entity_unittests.cc +++ b/engine/src/flutter/impeller/entity/entity_unittests.cc @@ -1863,8 +1863,9 @@ TEST_P(EntityTest, RuntimeEffectSetsRightSizeWhenUniformIsStruct) { // 8 bytes for iResolution // 4 bytes for iTime // 4 bytes padding - EXPECT_EQ(command.fragment_bindings.buffers[0].view.resource.range.length, - 16u); + EXPECT_EQ( + command.fragment_bindings.buffers[0].view.resource.GetRange().length, + 16u); } TEST_P(EntityTest, ColorFilterWithForegroundColorAdvancedBlend) { diff --git a/engine/src/flutter/impeller/playground/imgui/imgui_impl_impeller.cc b/engine/src/flutter/impeller/playground/imgui/imgui_impl_impeller.cc index 44af6fddbd..ff8ebaeec8 100644 --- a/engine/src/flutter/impeller/playground/imgui/imgui_impl_impeller.cc +++ b/engine/src/flutter/impeller/playground/imgui/imgui_impl_impeller.cc @@ -143,7 +143,8 @@ void ImGui_ImplImpeller_RenderDrawData(ImDrawData* draw_data, return; // Nothing to render. } auto host_buffer = impeller::HostBuffer::Create( - render_pass.GetContext()->GetResourceAllocator()); + render_pass.GetContext()->GetResourceAllocator(), + render_pass.GetContext()->GetIdleWaiter()); using VS = impeller::ImguiRasterVertexShader; using FS = impeller::ImguiRasterFragmentShader; @@ -265,14 +266,12 @@ void ImGui_ImplImpeller_RenderDrawData(ImDrawData* draw_data, vertex_buffer_offset + pcmd->VtxOffset * sizeof(ImDrawVert); impeller::VertexBuffer vertex_buffer; - vertex_buffer.vertex_buffer = impeller::BufferView{ - .buffer = buffer, - .range = impeller::Range(vb_start, draw_list_vtx_bytes - vb_start)}; - vertex_buffer.index_buffer = { - .buffer = buffer, - .range = impeller::Range( - index_buffer_offset + pcmd->IdxOffset * sizeof(ImDrawIdx), - pcmd->ElemCount * sizeof(ImDrawIdx))}; + vertex_buffer.vertex_buffer = impeller::BufferView( + buffer, impeller::Range(vb_start, draw_list_vtx_bytes - vb_start)); + vertex_buffer.index_buffer = impeller::BufferView( + buffer, impeller::Range(index_buffer_offset + + pcmd->IdxOffset * sizeof(ImDrawIdx), + pcmd->ElemCount * sizeof(ImDrawIdx))); vertex_buffer.vertex_count = pcmd->ElemCount; vertex_buffer.index_type = impeller::IndexType::k16bit; render_pass.SetVertexBuffer(std::move(vertex_buffer)); diff --git a/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc index 04f6c4acce..c9dd0f5d7a 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/blit_command_gles.cc @@ -220,7 +220,7 @@ bool BlitCopyBufferToTextureCommandGLES::Encode( } if (!tex_descriptor.IsValid() || - source.range.length != + source.GetRange().length != BytesPerPixelForPixelFormat(tex_descriptor.format) * destination_region.Area()) { return false; @@ -263,8 +263,8 @@ bool BlitCopyBufferToTextureCommandGLES::Encode( } const auto& gl = reactor.GetProcTable(); gl.BindTexture(texture_type, gl_handle.value()); - const GLvoid* tex_data = - data.buffer_view.buffer->OnGetContents() + data.buffer_view.range.offset; + const GLvoid* tex_data = data.buffer_view.GetBuffer()->OnGetContents() + + data.buffer_view.GetRange().offset; // GL_INVALID_OPERATION if the texture array has not been // defined by a previous glTexImage2D operation. diff --git a/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc index 2b12ecd25d..e4adb99a9b 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/buffer_bindings_gles.cc @@ -276,14 +276,14 @@ bool BufferBindingsGLES::BindUniformBuffer(const ProcTableGLES& gl, Allocator& transients_allocator, const BufferResource& buffer) { const auto* metadata = buffer.GetMetadata(); - auto device_buffer = buffer.resource.buffer; + auto device_buffer = buffer.resource.GetBuffer(); if (!device_buffer) { VALIDATION_LOG << "Device buffer not found."; return false; } const auto& device_buffer_gles = DeviceBufferGLES::Cast(*device_buffer); const uint8_t* buffer_ptr = - device_buffer_gles.GetBufferData() + buffer.resource.range.offset; + device_buffer_gles.GetBufferData() + buffer.resource.GetRange().offset; if (metadata->members.empty()) { VALIDATION_LOG << "Uniform buffer had no members. This is currently " diff --git a/engine/src/flutter/impeller/renderer/backend/gles/render_pass_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/render_pass_gles.cc index d9e7191d7e..b0359c1640 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/render_pass_gles.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/render_pass_gles.cc @@ -149,7 +149,7 @@ static bool BindVertexBuffer(const ProcTableGLES& gl, return false; } - auto vertex_buffer = vertex_buffer_view.buffer; + const DeviceBuffer* vertex_buffer = vertex_buffer_view.GetBuffer(); if (!vertex_buffer) { return false; @@ -165,7 +165,7 @@ static bool BindVertexBuffer(const ProcTableGLES& gl, /// Bind the vertex attributes associated with vertex buffer. /// if (!vertex_desc_gles->BindVertexAttributes( - gl, buffer_index, vertex_buffer_view.range.offset)) { + gl, buffer_index, vertex_buffer_view.GetRange().offset)) { return false; } @@ -459,7 +459,7 @@ static bool BindVertexBuffer(const ProcTableGLES& gl, } else { // Bind the index buffer if necessary. auto index_buffer_view = command.index_buffer; - auto index_buffer = index_buffer_view.buffer; + const DeviceBuffer* index_buffer = index_buffer_view.GetBuffer(); const auto& index_buffer_gles = DeviceBufferGLES::Cast(*index_buffer); if (!index_buffer_gles.BindAndUploadDataIfNecessary( DeviceBufferGLES::BindingType::kElementArrayBuffer)) { @@ -469,7 +469,7 @@ static bool BindVertexBuffer(const ProcTableGLES& gl, command.element_count, // count ToIndexType(command.index_type), // type reinterpret_cast(static_cast( - index_buffer_view.range.offset)) // indices + index_buffer_view.GetRange().offset)) // indices ); } diff --git a/engine/src/flutter/impeller/renderer/backend/metal/blit_pass_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/blit_pass_mtl.mm index 09f381f5bf..e41e24f05e 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/blit_pass_mtl.mm +++ b/engine/src/flutter/impeller/renderer/backend/metal/blit_pass_mtl.mm @@ -194,7 +194,7 @@ bool BlitPassMTL::OnCopyBufferToTextureCommand( uint32_t mip_level, uint32_t slice, bool convert_to_read) { - auto source_mtl = DeviceBufferMTL::Cast(*source.buffer).GetMTLBuffer(); + auto source_mtl = DeviceBufferMTL::Cast(*source.GetBuffer()).GetMTLBuffer(); if (!source_mtl) { return false; } @@ -221,7 +221,7 @@ bool BlitPassMTL::OnCopyBufferToTextureCommand( #endif // IMPELLER_DEBUG [encoder_ copyFromBuffer:source_mtl - sourceOffset:source.range.offset + sourceOffset:source.GetRange().offset sourceBytesPerRow:source_bytes_per_row sourceBytesPerImage: 0 // 0 for 2D textures according to diff --git a/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.mm index b5d29b3770..ee667fccaa 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.mm +++ b/engine/src/flutter/impeller/renderer/backend/metal/compute_pass_mtl.mm @@ -84,11 +84,11 @@ bool ComputePassMTL::BindResource(ShaderStage stage, const ShaderUniformSlot& slot, const ShaderMetadata& metadata, BufferView view) { - if (!view.buffer) { + if (!view.GetBuffer()) { return false; } - const std::shared_ptr& device_buffer = view.buffer; + const DeviceBuffer* device_buffer = view.GetBuffer(); if (!device_buffer) { return false; } @@ -99,7 +99,8 @@ bool ComputePassMTL::BindResource(ShaderStage stage, return false; } - pass_bindings_cache_.SetBuffer(slot.ext_res_0, view.range.offset, buffer); + pass_bindings_cache_.SetBuffer(slot.ext_res_0, view.GetRange().offset, + buffer); return true; } diff --git a/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm b/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm index 6047fbea0a..4463fa2837 100644 --- a/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm +++ b/engine/src/flutter/impeller/renderer/backend/metal/render_pass_mtl.mm @@ -189,11 +189,11 @@ static bool Bind(PassBindingsCacheMTL& pass, ShaderStage stage, size_t bind_index, const BufferView& view) { - if (!view.buffer) { + if (!view.GetBuffer()) { return false; } - auto device_buffer = view.buffer; + const DeviceBuffer* device_buffer = view.GetBuffer(); if (!device_buffer) { return false; } @@ -204,7 +204,7 @@ static bool Bind(PassBindingsCacheMTL& pass, return false; } - return pass.SetBuffer(stage, bind_index, view.range.offset, buffer); + return pass.SetBuffer(stage, bind_index, view.GetRange().offset, buffer); } static bool Bind(PassBindingsCacheMTL& pass, @@ -346,13 +346,13 @@ fml::Status RenderPassMTL::Draw() { } } else { id mtl_index_buffer = - DeviceBufferMTL::Cast(*index_buffer_.buffer).GetMTLBuffer(); + DeviceBufferMTL::Cast(*index_buffer_.GetBuffer()).GetMTLBuffer(); if (instance_count_ != 1u) { [encoder_ drawIndexedPrimitives:ToMTLPrimitiveType(primitive_type_) indexCount:vertex_count_ indexType:index_type_ indexBuffer:mtl_index_buffer - indexBufferOffset:index_buffer_.range.offset + indexBufferOffset:index_buffer_.GetRange().offset instanceCount:instance_count_ baseVertex:base_vertex_ baseInstance:0u]; @@ -361,7 +361,7 @@ fml::Status RenderPassMTL::Draw() { indexCount:vertex_count_ indexType:index_type_ indexBuffer:mtl_index_buffer - indexBufferOffset:index_buffer_.range.offset]; + indexBufferOffset:index_buffer_.GetRange().offset]; } } diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc index 5a3b2ef25d..02ca972655 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/blit_pass_vk.cc @@ -248,9 +248,10 @@ bool BlitPassVK::OnCopyBufferToTextureCommand( // cast destination to TextureVK const auto& dst = TextureVK::Cast(*destination); - const auto& src = DeviceBufferVK::Cast(*source.buffer); + const auto& src = DeviceBufferVK::Cast(*source.GetBuffer()); - if (!command_buffer_->Track(source.buffer) || + std::shared_ptr source_buffer = source.TakeBuffer(); + if ((source_buffer && !command_buffer_->Track(source_buffer)) || !command_buffer_->Track(destination)) { return false; } @@ -266,7 +267,7 @@ bool BlitPassVK::OnCopyBufferToTextureCommand( vk::PipelineStageFlagBits::eTransfer; vk::BufferImageCopy image_copy; - image_copy.setBufferOffset(source.range.offset); + image_copy.setBufferOffset(source.GetRange().offset); image_copy.setBufferRowLength(0); image_copy.setBufferImageHeight(0); image_copy.setImageSubresource(vk::ImageSubresourceLayers( diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.cc index 309710b785..402d4bd24a 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.cc @@ -178,27 +178,27 @@ bool ComputePassVK::BindResource( bool ComputePassVK::BindResource(size_t binding, DescriptorType type, - const BufferView& view) { + BufferView view) { if (bound_buffer_offset_ >= kMaxBindings) { return false; } - const std::shared_ptr& device_buffer = view.buffer; - auto buffer = DeviceBufferVK::Cast(*device_buffer).GetBuffer(); + auto buffer = DeviceBufferVK::Cast(*view.GetBuffer()).GetBuffer(); if (!buffer) { return false; } - if (!command_buffer_->Track(device_buffer)) { + std::shared_ptr device_buffer = view.TakeBuffer(); + if (device_buffer && !command_buffer_->Track(device_buffer)) { return false; } - uint32_t offset = view.range.offset; + uint32_t offset = view.GetRange().offset; vk::DescriptorBufferInfo buffer_info; buffer_info.buffer = buffer; buffer_info.offset = offset; - buffer_info.range = view.range.length; + buffer_info.range = view.GetRange().length; buffer_workspace_[bound_buffer_offset_++] = buffer_info; vk::WriteDescriptorSet write_set; diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.h index 968542fc97..b281775259 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/compute_pass_vk.h @@ -82,9 +82,7 @@ class ComputePassVK final : public ComputePass { std::shared_ptr texture, const std::unique_ptr& sampler) override; - bool BindResource(size_t binding, - DescriptorType type, - const BufferView& view); + bool BindResource(size_t binding, DescriptorType type, BufferView view); }; } // namespace impeller diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc index 95fd1793e4..d793b3e9c6 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc @@ -456,6 +456,7 @@ void ContextVK::Setup(Settings settings) { /// All done! /// device_holder_ = std::move(device_holder); + idle_waiter_vk_ = std::make_shared(device_holder_); driver_info_ = std::make_unique(device_holder_->physical_device); debug_report_ = std::move(debug_report); diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.h index aa587bb003..40bddc494d 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.h @@ -41,6 +41,24 @@ class DescriptorPoolRecyclerVK; class CommandQueueVK; class DescriptorPoolVK; +class IdleWaiterVK : public IdleWaiter { + public: + explicit IdleWaiterVK(std::weak_ptr device_holder) + : device_holder_(std::move(device_holder)) {} + + void WaitIdle() const override { + std::shared_ptr strong_device_holder_ = + device_holder_.lock(); + if (strong_device_holder_ && strong_device_holder_->GetDevice()) { + [[maybe_unused]] auto result = + strong_device_holder_->GetDevice().waitIdle(); + } + } + + private: + std::weak_ptr device_holder_; +}; + class ContextVK final : public Context, public BackendCast, public std::enable_shared_from_this { @@ -211,6 +229,10 @@ class ContextVK final : public Context, // | Context | bool FlushCommandBuffers() override; + std::shared_ptr GetIdleWaiter() const override { + return idle_waiter_vk_; + } + private: struct DeviceHolderImpl : public DeviceHolderVK { // |DeviceHolder| @@ -251,6 +273,7 @@ class ContextVK final : public Context, std::shared_ptr raster_message_loop_; std::shared_ptr gpu_tracer_; std::shared_ptr command_queue_vk_; + std::shared_ptr idle_waiter_vk_; using DescriptorPoolMap = std::unordered_map>; diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.cc index ffb3f05fb6..d971bf7142 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.cc @@ -377,9 +377,14 @@ bool RenderPassVK::SetVertexBuffer(BufferView vertex_buffers[], vk::Buffer buffers[kMaxVertexBuffers]; vk::DeviceSize vertex_buffer_offsets[kMaxVertexBuffers]; for (size_t i = 0; i < vertex_buffer_count; i++) { - buffers[i] = DeviceBufferVK::Cast(*vertex_buffers[i].buffer).GetBuffer(); - vertex_buffer_offsets[i] = vertex_buffers[i].range.offset; - command_buffer_->Track(vertex_buffers[i].buffer); + buffers[i] = + DeviceBufferVK::Cast(*vertex_buffers[i].GetBuffer()).GetBuffer(); + vertex_buffer_offsets[i] = vertex_buffers[i].GetRange().offset; + std::shared_ptr device_buffer = + vertex_buffers[i].TakeBuffer(); + if (device_buffer) { + command_buffer_->Track(device_buffer); + } } // Bind the vertex buffers. @@ -399,27 +404,27 @@ bool RenderPassVK::SetIndexBuffer(BufferView index_buffer, if (index_type != IndexType::kNone) { has_index_buffer_ = true; - const BufferView& index_buffer_view = index_buffer; + BufferView index_buffer_view = std::move(index_buffer); if (!index_buffer_view) { return false; } - const std::shared_ptr& index_buffer = - index_buffer_view.buffer; - if (!index_buffer) { + if (!index_buffer_view.GetBuffer()) { VALIDATION_LOG << "Failed to acquire device buffer" << " for index buffer view"; return false; } - if (!command_buffer_->Track(index_buffer)) { + std::shared_ptr index_buffer = + index_buffer_view.TakeBuffer(); + if (index_buffer && !command_buffer_->Track(index_buffer)) { return false; } vk::Buffer index_buffer_handle = - DeviceBufferVK::Cast(*index_buffer).GetBuffer(); + DeviceBufferVK::Cast(*index_buffer_view.GetBuffer()).GetBuffer(); command_buffer_vk_.bindIndexBuffer(index_buffer_handle, - index_buffer_view.range.offset, + index_buffer_view.GetRange().offset, ToVKIndexType(index_type)); } else { has_index_buffer_ = false; @@ -555,27 +560,27 @@ bool RenderPassVK::BindResource( bool RenderPassVK::BindResource(size_t binding, DescriptorType type, - const BufferView& view) { + BufferView view) { if (bound_buffer_offset_ >= kMaxBindings) { return false; } - const std::shared_ptr& device_buffer = view.buffer; - auto buffer = DeviceBufferVK::Cast(*device_buffer).GetBuffer(); + auto buffer = DeviceBufferVK::Cast(*view.GetBuffer()).GetBuffer(); if (!buffer) { return false; } - if (!command_buffer_->Track(device_buffer)) { + std::shared_ptr device_buffer = view.TakeBuffer(); + if (device_buffer && !command_buffer_->Track(device_buffer)) { return false; } - uint32_t offset = view.range.offset; + uint32_t offset = view.GetRange().offset; vk::DescriptorBufferInfo buffer_info; buffer_info.buffer = buffer; buffer_info.offset = offset; - buffer_info.range = view.range.length; + buffer_info.range = view.GetRange().length; buffer_workspace_[bound_buffer_offset_++] = buffer_info; vk::WriteDescriptorSet write_set; diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.h index 9f3c3ea299..61ca7533b0 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/render_pass_vk.h @@ -117,9 +117,7 @@ class RenderPassVK final : public RenderPass { std::shared_ptr texture, const std::unique_ptr& sampler) override; - bool BindResource(size_t binding, - DescriptorType type, - const BufferView& view); + bool BindResource(size_t binding, DescriptorType type, BufferView view); // |RenderPass| bool IsValid() const override; diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc b/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc index 3b6d77150d..faaf748df9 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.cc @@ -58,6 +58,10 @@ const std::shared_ptr& SurfaceContextVK::GetCapabilities() return parent_->GetCapabilities(); } +std::shared_ptr SurfaceContextVK::GetIdleWaiter() const { + return parent_->GetIdleWaiter(); +} + void SurfaceContextVK::Shutdown() { parent_->Shutdown(); } diff --git a/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.h b/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.h index 22663f0fb4..f439ff927a 100644 --- a/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.h +++ b/engine/src/flutter/impeller/renderer/backend/vulkan/surface_context_vk.h @@ -66,6 +66,8 @@ class SurfaceContextVK : public Context, // |Context| std::shared_ptr GetCommandQueue() const override; + std::shared_ptr GetIdleWaiter() const override; + // |Context| void Shutdown() override; diff --git a/engine/src/flutter/impeller/renderer/blit_pass.cc b/engine/src/flutter/impeller/renderer/blit_pass.cc index 7d199d38ae..bc5c603eee 100644 --- a/engine/src/flutter/impeller/renderer/blit_pass.cc +++ b/engine/src/flutter/impeller/renderer/blit_pass.cc @@ -146,7 +146,7 @@ bool BlitPass::AddCopy(BufferView source, BytesPerPixelForPixelFormat(destination->GetTextureDescriptor().format); auto bytes_per_region = destination_region_value.Area() * bytes_per_pixel; - if (source.range.length != bytes_per_region) { + if (source.GetRange().length != bytes_per_region) { VALIDATION_LOG << "Attempted to add a texture blit with out of bounds access."; return false; diff --git a/engine/src/flutter/impeller/renderer/compute_unittests.cc b/engine/src/flutter/impeller/renderer/compute_unittests.cc index 39e14a0a99..0d2ae2194e 100644 --- a/engine/src/flutter/impeller/renderer/compute_unittests.cc +++ b/engine/src/flutter/impeller/renderer/compute_unittests.cc @@ -30,7 +30,8 @@ TEST_P(ComputeTest, CapabilitiesReportSupport) { TEST_P(ComputeTest, CanCreateComputePass) { using CS = SampleComputeShader; auto context = GetContext(); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -84,7 +85,7 @@ TEST_P(ComputeTest, CanCreateComputePass) { EXPECT_EQ(status, CommandBuffer::Status::kCompleted); auto view = DeviceBuffer::AsBufferView(output_buffer); - EXPECT_EQ(view.range.length, sizeof(CS::Output)); + EXPECT_EQ(view.GetRange().length, sizeof(CS::Output)); CS::Output* output = reinterpret_cast*>( @@ -109,7 +110,8 @@ TEST_P(ComputeTest, CanCreateComputePass) { TEST_P(ComputeTest, CanComputePrefixSum) { using CS = PrefixSumTestComputeShader; auto context = GetContext(); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -152,7 +154,7 @@ TEST_P(ComputeTest, CanComputePrefixSum) { EXPECT_EQ(status, CommandBuffer::Status::kCompleted); auto view = DeviceBuffer::AsBufferView(output_buffer); - EXPECT_EQ(view.range.length, + EXPECT_EQ(view.GetRange().length, sizeof(CS::OutputData)); CS::OutputData* output = @@ -210,7 +212,7 @@ TEST_P(ComputeTest, 1DThreadgroupSizingIsCorrect) { EXPECT_EQ(status, CommandBuffer::Status::kCompleted); auto view = DeviceBuffer::AsBufferView(output_buffer); - EXPECT_EQ(view.range.length, + EXPECT_EQ(view.GetRange().length, sizeof(CS::OutputData)); CS::OutputData* output = @@ -229,7 +231,8 @@ TEST_P(ComputeTest, CanComputePrefixSumLargeInteractive) { using CS = PrefixSumTestComputeShader; auto context = GetContext(); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -275,7 +278,8 @@ TEST_P(ComputeTest, MultiStageInputAndOutput) { using Stage2PipelineBuilder = ComputePipelineBuilder; auto context = GetContext(); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -373,7 +377,8 @@ TEST_P(ComputeTest, MultiStageInputAndOutput) { TEST_P(ComputeTest, CanCompute1DimensionalData) { using CS = SampleComputeShader; auto context = GetContext(); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -427,7 +432,7 @@ TEST_P(ComputeTest, CanCompute1DimensionalData) { EXPECT_EQ(status, CommandBuffer::Status::kCompleted); auto view = DeviceBuffer::AsBufferView(output_buffer); - EXPECT_EQ(view.range.length, sizeof(CS::Output)); + EXPECT_EQ(view.GetRange().length, sizeof(CS::Output)); CS::Output* output = reinterpret_cast*>( @@ -452,7 +457,8 @@ TEST_P(ComputeTest, CanCompute1DimensionalData) { TEST_P(ComputeTest, ReturnsEarlyWhenAnyGridDimensionIsZero) { using CS = SampleComputeShader; auto context = GetContext(); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); diff --git a/engine/src/flutter/impeller/renderer/context.h b/engine/src/flutter/impeller/renderer/context.h index 91c5ee7a77..657083c04b 100644 --- a/engine/src/flutter/impeller/renderer/context.h +++ b/engine/src/flutter/impeller/renderer/context.h @@ -222,6 +222,10 @@ class Context { /// rendering a 2D workload. [[nodiscard]] virtual bool FlushCommandBuffers(); + virtual std::shared_ptr GetIdleWaiter() const { + return nullptr; + } + protected: Context(); diff --git a/engine/src/flutter/impeller/renderer/renderer_dart_unittests.cc b/engine/src/flutter/impeller/renderer/renderer_dart_unittests.cc index 1c847955a0..3368ae759e 100644 --- a/engine/src/flutter/impeller/renderer/renderer_dart_unittests.cc +++ b/engine/src/flutter/impeller/renderer/renderer_dart_unittests.cc @@ -224,7 +224,8 @@ class RendererDartTest : public PlaygroundTest, return false; } - auto buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer( *context->GetResourceAllocator())); diff --git a/engine/src/flutter/impeller/renderer/renderer_unittests.cc b/engine/src/flutter/impeller/renderer/renderer_unittests.cc index ab4520ed63..39cb1a7f19 100644 --- a/engine/src/flutter/impeller/renderer/renderer_unittests.cc +++ b/engine/src/flutter/impeller/renderer/renderer_unittests.cc @@ -80,7 +80,8 @@ TEST_P(RendererTest, CanCreateBoxPrimitive) { context->GetSamplerLibrary()->GetSampler({}); ASSERT_TRUE(sampler); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); SinglePassCallback callback = [&](RenderPass& pass) { ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize); static bool wireframe; @@ -145,7 +146,8 @@ TEST_P(RendererTest, BabysFirstTriangle) { auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get(); // Create a host side buffer to build the vertex and uniform information. - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); // Specify the vertex buffer information. VertexBufferBuilder vertex_buffer_builder; @@ -165,7 +167,8 @@ TEST_P(RendererTest, BabysFirstTriangle) { FS::FragInfo frag_info; frag_info.time = fml::TimePoint::Now().ToEpochDelta().ToSecondsF(); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); FS::BindFragInfo(pass, host_buffer->EmplaceUniform(frag_info)); return pass.Draw().ok(); @@ -241,7 +244,8 @@ TEST_P(RendererTest, CanRenderPerspectiveCube) { ASSERT_TRUE(sampler); Vector3 euler_angles; - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); SinglePassCallback callback = [&](RenderPass& pass) { static Degrees fov_y(60); static Scalar distance = 10; @@ -255,17 +259,14 @@ TEST_P(RendererTest, CanRenderPerspectiveCube) { pass.SetPipeline(pipeline); std::array vertex_buffers = { - BufferView{ - .buffer = device_buffer, - .range = Range(offsetof(Cube, positions), sizeof(Cube::positions))}, - BufferView{ - .buffer = device_buffer, - .range = Range(offsetof(Cube, colors), sizeof(Cube::colors))}, + BufferView(device_buffer, + Range(offsetof(Cube, positions), sizeof(Cube::positions))), + BufferView(device_buffer, + Range(offsetof(Cube, colors), sizeof(Cube::colors))), }; - BufferView index_buffer = { - .buffer = device_buffer, - .range = Range(offsetof(Cube, indices), sizeof(Cube::indices))}; + BufferView index_buffer( + device_buffer, Range(offsetof(Cube, indices), sizeof(Cube::indices))); pass.SetVertexBuffer(vertex_buffers.data(), vertex_buffers.size()); pass.SetElementCount(36); pass.SetIndexBuffer(index_buffer, IndexType::k16bit); @@ -324,7 +325,8 @@ TEST_P(RendererTest, CanRenderMultiplePrimitives) { context->GetSamplerLibrary()->GetSampler({}); ASSERT_TRUE(sampler); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); SinglePassCallback callback = [&](RenderPass& pass) { for (size_t i = 0; i < 1; i++) { for (size_t j = 0; j < 1; j++) { @@ -377,7 +379,8 @@ TEST_P(RendererTest, CanRenderToTexture) { auto box_pipeline = context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get(); ASSERT_TRUE(box_pipeline); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); VertexBufferBuilder vertex_builder; vertex_builder.SetLabel("Box"); @@ -499,7 +502,8 @@ TEST_P(RendererTest, CanRenderInstanced) { instances.colors[i] = Color::Random(); } - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool { pass.SetPipeline(pipeline); pass.SetCommandLabel("InstancedDraw"); @@ -570,7 +574,8 @@ TEST_P(RendererTest, CanBlitTextureToTexture) { vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()); ASSERT_TRUE(vertex_buffer); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); Playground::RenderCallback callback = [&](RenderTarget& render_target) { auto buffer = context->CreateCommandBuffer(); if (!buffer) { @@ -690,7 +695,8 @@ TEST_P(RendererTest, CanBlitTextureToBuffer) { vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()); ASSERT_TRUE(vertex_buffer); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); Playground::RenderCallback callback = [&](RenderTarget& render_target) { { auto buffer = context->CreateCommandBuffer(); @@ -751,7 +757,7 @@ TEST_P(RendererTest, CanBlitTextureToBuffer) { auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc); if (!texture->SetContents(device_buffer->OnGetContents(), - buffer_view.range.length)) { + buffer_view.GetRange().length)) { VALIDATION_LOG << "Could not upload texture to device memory"; return false; } @@ -807,7 +813,8 @@ TEST_P(RendererTest, CanGenerateMipmaps) { ASSERT_TRUE(vertex_buffer); bool first_frame = true; - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); Playground::RenderCallback callback = [&](RenderTarget& render_target) { const char* mip_filter_names[] = {"Base", "Nearest", "Linear"}; const MipFilter mip_filters[] = {MipFilter::kBase, MipFilter::kNearest, @@ -919,7 +926,8 @@ TEST_P(RendererTest, TheImpeller) { "table_mountain_pz.png", "table_mountain_nz.png"}); const std::unique_ptr& cube_map_sampler = context->GetSamplerLibrary()->GetSampler({}); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); SinglePassCallback callback = [&](RenderPass& pass) { auto size = pass.GetRenderTargetSize(); @@ -968,7 +976,8 @@ TEST_P(RendererTest, Planet) { context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get(); ASSERT_TRUE(pipeline && pipeline->IsValid()); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); SinglePassCallback callback = [&](RenderPass& pass) { static Scalar speed = 0.1; @@ -1034,7 +1043,8 @@ TEST_P(RendererTest, ArrayUniforms) { context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get(); ASSERT_TRUE(pipeline && pipeline->IsValid()); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); SinglePassCallback callback = [&](RenderPass& pass) { auto size = pass.GetRenderTargetSize(); @@ -1091,7 +1101,8 @@ TEST_P(RendererTest, InactiveUniforms) { context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get(); ASSERT_TRUE(pipeline && pipeline->IsValid()); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); SinglePassCallback callback = [&](RenderPass& pass) { auto size = pass.GetRenderTargetSize(); @@ -1256,7 +1267,8 @@ TEST_P(RendererTest, StencilMask) { static int current_back_compare = CompareFunctionUI().IndexOf(CompareFunction::kLessEqual); - auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); Playground::RenderCallback callback = [&](RenderTarget& render_target) { auto buffer = context->CreateCommandBuffer(); if (!buffer) { @@ -1469,7 +1481,8 @@ TEST_P(RendererTest, CanSepiaToneWithSubpasses) { ASSERT_TRUE(sampler); SinglePassCallback callback = [&](RenderPass& pass) { - auto buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); // Draw the texture. { @@ -1562,7 +1575,8 @@ TEST_P(RendererTest, CanSepiaToneThenSwizzleWithSubpasses) { ASSERT_TRUE(sampler); SinglePassCallback callback = [&](RenderPass& pass) { - auto buffer = HostBuffer::Create(context->GetResourceAllocator()); + auto buffer = HostBuffer::Create(context->GetResourceAllocator(), + context->GetIdleWaiter()); // Draw the texture. { diff --git a/engine/src/flutter/impeller/renderer/vertex_buffer_builder.h b/engine/src/flutter/impeller/renderer/vertex_buffer_builder.h index bcbde03daa..974268caab 100644 --- a/engine/src/flutter/impeller/renderer/vertex_buffer_builder.h +++ b/engine/src/flutter/impeller/renderer/vertex_buffer_builder.h @@ -138,7 +138,7 @@ class VertexBufferBuilder { if (!label_.empty()) { buffer->SetLabel(SPrintF("%s Vertices", label_.c_str())); } - return DeviceBuffer::AsBufferView(buffer); + return DeviceBuffer::AsBufferView(std::move(buffer)); } std::vector CreateIndexBuffer() const { return indices_; } @@ -167,7 +167,7 @@ class VertexBufferBuilder { if (!label_.empty()) { buffer->SetLabel(SPrintF("%s Indices", label_.c_str())); } - return DeviceBuffer::AsBufferView(buffer); + return DeviceBuffer::AsBufferView(std::move(buffer)); } }; diff --git a/engine/src/flutter/impeller/tessellator/tessellator.cc b/engine/src/flutter/impeller/tessellator/tessellator.cc index bf07e45429..6a2fc8260b 100644 --- a/engine/src/flutter/impeller/tessellator/tessellator.cc +++ b/engine/src/flutter/impeller/tessellator/tessellator.cc @@ -47,10 +47,11 @@ VertexBuffer Tessellator::TessellateConvex(const Path& path, if (supports_triangle_fan) { FanVertexWriter writer( - reinterpret_cast(point_buffer.buffer->OnGetContents() + - point_buffer.range.offset), - reinterpret_cast(index_buffer.buffer->OnGetContents() + - index_buffer.range.offset)); + reinterpret_cast(point_buffer.GetBuffer()->OnGetContents() + + point_buffer.GetRange().offset), + reinterpret_cast( + index_buffer.GetBuffer()->OnGetContents() + + index_buffer.GetRange().offset)); path.WritePolyline(tolerance, writer); return VertexBuffer{ @@ -61,10 +62,11 @@ VertexBuffer Tessellator::TessellateConvex(const Path& path, }; } else { StripVertexWriter writer( - reinterpret_cast(point_buffer.buffer->OnGetContents() + - point_buffer.range.offset), - reinterpret_cast(index_buffer.buffer->OnGetContents() + - index_buffer.range.offset)); + reinterpret_cast(point_buffer.GetBuffer()->OnGetContents() + + point_buffer.GetRange().offset), + reinterpret_cast( + index_buffer.GetBuffer()->OnGetContents() + + index_buffer.GetRange().offset)); path.WritePolyline(tolerance, writer); return VertexBuffer{ diff --git a/engine/src/flutter/impeller/typographer/typographer_unittests.cc b/engine/src/flutter/impeller/typographer/typographer_unittests.cc index 751977d502..6367314d9b 100644 --- a/engine/src/flutter/impeller/typographer/typographer_unittests.cc +++ b/engine/src/flutter/impeller/typographer/typographer_unittests.cc @@ -81,7 +81,8 @@ TEST_P(TypographerTest, CanCreateGlyphAtlas) { auto context = TypographerContextSkia::Make(); auto atlas_context = context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap); - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); ASSERT_TRUE(context && context->IsValid()); SkFont sk_font = flutter::testing::CreateTestFontOfSize(12); auto blob = SkTextBlob::MakeFromString("hello", sk_font); @@ -116,7 +117,8 @@ TEST_P(TypographerTest, CanCreateGlyphAtlas) { } TEST_P(TypographerTest, LazyAtlasTracksColor) { - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); #if FML_OS_MACOSX auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc"); #else @@ -158,7 +160,8 @@ TEST_P(TypographerTest, GlyphAtlasWithOddUniqueGlyphSize) { auto context = TypographerContextSkia::Make(); auto atlas_context = context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap); - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); ASSERT_TRUE(context && context->IsValid()); SkFont sk_font = flutter::testing::CreateTestFontOfSize(12); auto blob = SkTextBlob::MakeFromString("AGH", sk_font); @@ -178,7 +181,8 @@ TEST_P(TypographerTest, GlyphAtlasIsRecycledIfUnchanged) { auto context = TypographerContextSkia::Make(); auto atlas_context = context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap); - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); ASSERT_TRUE(context && context->IsValid()); SkFont sk_font = flutter::testing::CreateTestFontOfSize(12); auto blob = SkTextBlob::MakeFromString("spooky skellingtons", sk_font); @@ -202,7 +206,8 @@ TEST_P(TypographerTest, GlyphAtlasIsRecycledIfUnchanged) { } TEST_P(TypographerTest, GlyphAtlasWithLotsOfdUniqueGlyphSize) { - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); auto context = TypographerContextSkia::Make(); auto atlas_context = context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap); @@ -249,7 +254,8 @@ TEST_P(TypographerTest, GlyphAtlasWithLotsOfdUniqueGlyphSize) { } TEST_P(TypographerTest, GlyphAtlasTextureIsRecycledIfUnchanged) { - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); auto context = TypographerContextSkia::Make(); auto atlas_context = context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap); @@ -286,7 +292,8 @@ TEST_P(TypographerTest, GlyphAtlasTextureIsRecycledIfUnchanged) { } TEST_P(TypographerTest, GlyphColorIsPartOfCacheKey) { - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); #if FML_OS_MACOSX auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc"); #else @@ -320,7 +327,8 @@ TEST_P(TypographerTest, GlyphColorIsPartOfCacheKey) { } TEST_P(TypographerTest, GlyphColorIsIgnoredForNonEmojiFonts) { - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); sk_sp font_mgr = txt::GetDefaultFontManager(); sk_sp typeface = font_mgr->matchFamilyStyle("Arial", SkFontStyle::Normal()); @@ -419,7 +427,8 @@ TEST_P(TypographerTest, GlyphAtlasTextureWillGrowTilMaxTextureSize) { GTEST_SKIP() << "Atlas growth isn't supported for OpenGLES currently."; } - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); auto context = TypographerContextSkia::Make(); auto atlas_context = context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap); @@ -495,7 +504,8 @@ TEST_P(TypographerTest, TextFrameInitialBoundsArePlaceholder) { auto context = TypographerContextSkia::Make(); auto atlas_context = context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap); - auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(), + GetContext()->GetIdleWaiter()); auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer, GlyphAtlas::Type::kAlphaBitmap, 1.0f, diff --git a/engine/src/flutter/lib/gpu/render_pass.cc b/engine/src/flutter/lib/gpu/render_pass.cc index a9dc310ffc..637f7446e5 100644 --- a/engine/src/flutter/lib/gpu/render_pass.cc +++ b/engine/src/flutter/lib/gpu/render_pass.cc @@ -312,10 +312,8 @@ static void BindVertexBuffer( int offset_in_bytes, int length_in_bytes, int vertex_count) { - wrapper->vertex_buffer = impeller::BufferView{ - .buffer = buffer, - .range = impeller::Range(offset_in_bytes, length_in_bytes), - }; + wrapper->vertex_buffer = impeller::BufferView( + buffer, impeller::Range(offset_in_bytes, length_in_bytes)); // If the index type is set, then the `vertex_count` becomes the index // count... So don't overwrite the count if it's already been set when binding @@ -348,10 +346,8 @@ static void BindIndexBuffer( int index_type, int index_count) { impeller::IndexType type = flutter::gpu::ToImpellerIndexType(index_type); - wrapper->index_buffer = impeller::BufferView{ - .buffer = buffer, - .range = impeller::Range(offset_in_bytes, length_in_bytes), - }; + wrapper->index_buffer = impeller::BufferView( + buffer, impeller::Range(offset_in_bytes, length_in_bytes)); wrapper->index_buffer_type = type; bool setting_index_buffer = type != impeller::IndexType::kNone; @@ -412,10 +408,8 @@ static bool BindUniform( .slot = uniform_struct->slot, .view = impeller::BufferResource{ &uniform_struct->metadata, - impeller::BufferView{ - .buffer = buffer, - .range = impeller::Range(offset_in_bytes, length_in_bytes), - }, + impeller::BufferView( + buffer, impeller::Range(offset_in_bytes, length_in_bytes)), }}); return true; } diff --git a/engine/src/flutter/testing/run_tests.py b/engine/src/flutter/testing/run_tests.py index 8ecbb673b3..de576890ef 100755 --- a/engine/src/flutter/testing/run_tests.py +++ b/engine/src/flutter/testing/run_tests.py @@ -130,8 +130,9 @@ def run_cmd( # pylint: disable=too-many-arguments for forbidden_string in forbidden_output: if forbidden_string in output: + matches = [x.group(0) for x in re.findall(f'^.*{forbidden_string}.*$', output)] raise RuntimeError( - 'command "%s" contained forbidden string "%s"' % (command_string, forbidden_string) + f'command "{command_string}" contained forbidden string "{forbidden_string}": {matches}' ) print_divider('<')