diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index ac3662a46a485..5554cac371ec0 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -133,6 +133,7 @@ ../../../flutter/impeller/aiks/canvas_unittests.cc ../../../flutter/impeller/aiks/testing ../../../flutter/impeller/base/README.md +../../../flutter/impeller/base/allocation_size_unittests.cc ../../../flutter/impeller/base/base_unittests.cc ../../../flutter/impeller/compiler/README.md ../../../flutter/impeller/compiler/compiler_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index aa5e92a36b8b4..312b14e585b8a 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -41853,6 +41853,8 @@ ORIGIN: ../../../flutter/impeller/aiks/picture_recorder.cc + ../../../flutter/LI ORIGIN: ../../../flutter/impeller/aiks/picture_recorder.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/base/allocation.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/base/allocation.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/base/allocation_size.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/base/allocation_size.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/base/backend_cast.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/base/comparable.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/base/comparable.h + ../../../flutter/LICENSE @@ -44717,6 +44719,8 @@ FILE: ../../../flutter/impeller/aiks/picture_recorder.cc FILE: ../../../flutter/impeller/aiks/picture_recorder.h FILE: ../../../flutter/impeller/base/allocation.cc FILE: ../../../flutter/impeller/base/allocation.h +FILE: ../../../flutter/impeller/base/allocation_size.cc +FILE: ../../../flutter/impeller/base/allocation_size.h FILE: ../../../flutter/impeller/base/backend_cast.h FILE: ../../../flutter/impeller/base/comparable.cc FILE: ../../../flutter/impeller/base/comparable.h diff --git a/impeller/base/BUILD.gn b/impeller/base/BUILD.gn index 03ee14f645658..aa99334f465b7 100644 --- a/impeller/base/BUILD.gn +++ b/impeller/base/BUILD.gn @@ -8,6 +8,8 @@ impeller_component("base") { sources = [ "allocation.cc", "allocation.h", + "allocation_size.cc", + "allocation_size.h", "backend_cast.h", "comparable.cc", "comparable.h", @@ -33,7 +35,10 @@ impeller_component("base") { impeller_component("base_unittests") { testonly = true - sources = [ "base_unittests.cc" ] + sources = [ + "allocation_size_unittests.cc", + "base_unittests.cc", + ] deps = [ ":base", "//flutter/testing", diff --git a/impeller/base/allocation.h b/impeller/base/allocation.h index bd9b2370ef7fb..784c6efa33220 100644 --- a/impeller/base/allocation.h +++ b/impeller/base/allocation.h @@ -9,6 +9,7 @@ #include #include "flutter/fml/mapping.h" +#include "impeller/base/allocation_size.h" namespace impeller { diff --git a/impeller/base/allocation_size.cc b/impeller/base/allocation_size.cc new file mode 100644 index 0000000000000..f79ae819a12d6 --- /dev/null +++ b/impeller/base/allocation_size.cc @@ -0,0 +1,11 @@ +// 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 "impeller/base/allocation_size.h" + +namespace impeller { + +// + +} // namespace impeller diff --git a/impeller/base/allocation_size.h b/impeller/base/allocation_size.h new file mode 100644 index 0000000000000..fd0717bb9a421 --- /dev/null +++ b/impeller/base/allocation_size.h @@ -0,0 +1,198 @@ +// 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_BASE_ALLOCATION_SIZE_H_ +#define FLUTTER_IMPELLER_BASE_ALLOCATION_SIZE_H_ + +#include +#include + +namespace impeller { + +enum class FromBytesTag { kFromBytes }; + +//------------------------------------------------------------------------------ +/// @brief Represents the size of an allocation in different units. +/// +/// Refer to the typedefs for Bytes, KiloBytes, MegaBytes, +/// Gigabytes, KibiBytes, MebiBytes, and GibiBytes below when using. +/// +/// Storage and all operations are always on unsigned units of +/// bytes. +/// +/// @tparam Period The number of bytes in 1 unit of the allocation size. +/// +template +class AllocationSize { + public: + //---------------------------------------------------------------------------- + /// @brief Create a zero allocation size. + /// + constexpr AllocationSize() = default; + + //---------------------------------------------------------------------------- + /// @brief Create an allocation size with the amount in the `Period` + /// number of bytes. + /// + /// @param[in] size The size in `Period` number of bytes. + /// + explicit constexpr AllocationSize(double size) : bytes_(size * Period) {} + + //---------------------------------------------------------------------------- + /// @brief Create an allocation size from another instance with a + /// different period. + /// + /// @param[in] other The other allocation size. + /// + /// @tparam OtherPeriod The period of the other allocation. + /// + template + explicit constexpr AllocationSize(const AllocationSize& other) + : bytes_(other.GetByteSize()) {} + + //---------------------------------------------------------------------------- + /// @brief Create an allocation size with the amount directly specified + /// in bytes. + /// + /// @param[in] byte_size The byte size. + /// @param[in] tag A tag for this constructor. + /// + constexpr AllocationSize(uint64_t byte_size, FromBytesTag) + : bytes_(byte_size) {} + + //---------------------------------------------------------------------------- + /// @return The byte size. + /// + constexpr uint64_t GetByteSize() const { return bytes_; } + + //---------------------------------------------------------------------------- + /// @return The number of `Periods` of bytes. + /// + constexpr double GetSize() const { + return GetByteSize() / static_cast(Period); + } + + //---------------------------------------------------------------------------- + /// @brief Convert the allocation size from one unit to another. + /// + /// Conversions are non-truncating. + /// + /// @tparam AllocationSize The allocation size to convert to. + /// + /// @return The new allocation size. + /// + template + constexpr AllocationSize ConvertTo() { + return AllocationSize{GetByteSize(), FromBytesTag::kFromBytes}; + } + + // The following relational operators can be replaced with a defaulted + // spaceship operator post C++20. + + constexpr bool operator<(const AllocationSize& other) const { + return bytes_ < other.bytes_; + } + + constexpr bool operator>(const AllocationSize& other) const { + return bytes_ > other.bytes_; + } + + constexpr bool operator>=(const AllocationSize& other) const { + return bytes_ >= other.bytes_; + } + + constexpr bool operator<=(const AllocationSize& other) const { + return bytes_ <= other.bytes_; + } + + constexpr bool operator==(const AllocationSize& other) const { + return bytes_ == other.bytes_; + } + + constexpr bool operator!=(const AllocationSize& other) const { + return bytes_ != other.bytes_; + } + + // Explicit casts. + + explicit constexpr operator bool() const { return bytes_ != 0u; } + + // Arithmetic operators (overflows are caller error). + + constexpr AllocationSize operator+(const AllocationSize& other) const { + return AllocationSize(bytes_ + other.GetByteSize(), + FromBytesTag::kFromBytes); + } + + constexpr AllocationSize operator-(const AllocationSize& other) const { + return AllocationSize(bytes_ - other.GetByteSize(), + FromBytesTag::kFromBytes); + } + + constexpr AllocationSize& operator+=(const AllocationSize& other) { + bytes_ += other.GetByteSize(); + return *this; + } + + constexpr AllocationSize& operator-=(const AllocationSize& other) { + bytes_ -= other.GetByteSize(); + return *this; + } + + private: + uint64_t bytes_ = {}; +}; + +using Bytes = AllocationSize<1u>; + +using KiloBytes = AllocationSize<1'000u>; +using MegaBytes = AllocationSize<1'000u * 1'000u>; +using GigaBytes = AllocationSize<1'000u * 1'000u * 1'000u>; + +using KibiBytes = AllocationSize<1'024u>; +using MebiBytes = AllocationSize<1'024u * 1'024u>; +using GibiBytes = AllocationSize<1'024u * 1'024u * 1'024u>; + +inline namespace allocation_size_literals { + +// NOLINTNEXTLINE +constexpr Bytes operator"" _bytes(unsigned long long int size) { + return Bytes{static_cast(size)}; +} + +// NOLINTNEXTLINE +constexpr KiloBytes operator"" _kb(unsigned long long int size) { + return KiloBytes{static_cast(size)}; +} + +// NOLINTNEXTLINE +constexpr MegaBytes operator"" _mb(unsigned long long int size) { + return MegaBytes{static_cast(size)}; +} + +// NOLINTNEXTLINE +constexpr GigaBytes operator"" _gb(unsigned long long int size) { + return GigaBytes{static_cast(size)}; +} + +// NOLINTNEXTLINE +constexpr KibiBytes operator"" _kib(unsigned long long int size) { + return KibiBytes{static_cast(size)}; +} + +// NOLINTNEXTLINE +constexpr MebiBytes operator"" _mib(unsigned long long int size) { + return MebiBytes{static_cast(size)}; +} + +// NOLINTNEXTLINE +constexpr GibiBytes operator"" _gib(unsigned long long int size) { + return GibiBytes{static_cast(size)}; +} + +} // namespace allocation_size_literals + +} // namespace impeller + +#endif // FLUTTER_IMPELLER_BASE_ALLOCATION_SIZE_H_ diff --git a/impeller/base/allocation_size_unittests.cc b/impeller/base/allocation_size_unittests.cc new file mode 100644 index 0000000000000..370b6450485e9 --- /dev/null +++ b/impeller/base/allocation_size_unittests.cc @@ -0,0 +1,110 @@ +// 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/base/allocation_size.h" + +namespace impeller::testing { + +TEST(AllocationSizeTest, CanCreateTypedAllocations) { + auto bytes = Bytes{1024}; + ASSERT_EQ(bytes.GetByteSize(), 1024u); + + auto kilobytes = KiloBytes{5}; + ASSERT_EQ(kilobytes.GetByteSize(), 5u * 1e3); + + auto megabytes = MegaBytes{5}; + ASSERT_EQ(megabytes.GetByteSize(), 5u * 1e6); + + auto gigabytes = GigaBytes{5}; + ASSERT_EQ(gigabytes.GetByteSize(), 5u * 1e9); + + auto kibibytes = KibiBytes{1}; + ASSERT_EQ(kibibytes.GetByteSize(), 1024u); + + auto mebibytes = MebiBytes{1}; + ASSERT_EQ(mebibytes.GetByteSize(), 1048576u); + + auto gigibytes = GibiBytes{1}; + ASSERT_EQ(gigibytes.GetByteSize(), 1073741824u); +} + +TEST(AllocationSizeTest, CanCreateTypedAllocationsWithLiterals) { + using namespace allocation_size_literals; + ASSERT_EQ((1024_bytes).GetByteSize(), 1024u); + ASSERT_EQ((5_kb).GetByteSize(), 5u * 1e3); + ASSERT_EQ((5_mb).GetByteSize(), 5u * 1e6); + ASSERT_EQ((5_gb).GetByteSize(), 5u * 1e9); + ASSERT_EQ((1_kib).GetByteSize(), 1024u); + ASSERT_EQ((1_mib).GetByteSize(), 1048576u); + ASSERT_EQ((1_gib).GetByteSize(), 1073741824u); +} + +TEST(AllocationSizeTest, CanConvert) { + using namespace allocation_size_literals; + ASSERT_EQ((5_gb).ConvertTo().GetSize(), 5000u); +} + +TEST(AllocationSizeTest, ConversionsAreNonTruncating) { + using namespace allocation_size_literals; + ASSERT_DOUBLE_EQ((1500_bytes).ConvertTo().GetSize(), 1.5); + ASSERT_EQ((1500_bytes).ConvertTo().GetByteSize(), 1500u); +} + +TEST(AllocationSizeTest, CanGetFloatValues) { + using namespace allocation_size_literals; + ASSERT_DOUBLE_EQ((1500_bytes).ConvertTo().GetSize(), 1.5); +} + +TEST(AllocationSizeTest, RelationalOperatorsAreFunctional) { + using namespace allocation_size_literals; + + auto a = 1500_bytes; + auto b = 2500_bytes; + auto c = 0_bytes; + + ASSERT_TRUE(a != b); + ASSERT_FALSE(a == b); + ASSERT_TRUE(b > a); + ASSERT_TRUE(b >= a); + ASSERT_TRUE(a < b); + ASSERT_TRUE(a <= b); + ASSERT_TRUE(a); + ASSERT_FALSE(c); +} + +TEST(AllocationSizeTest, CanCast) { + using namespace allocation_size_literals; + { + auto a = KiloBytes{1500_bytes}; + ASSERT_DOUBLE_EQ(a.GetSize(), 1.5); + } + { + auto a = KiloBytes{Bytes{1500}}; + ASSERT_DOUBLE_EQ(a.GetSize(), 1.5); + } + + ASSERT_DOUBLE_EQ(MebiBytes{Bytes{4194304}}.GetSize(), 4); +} + +TEST(AllocationSizeTest, CanPerformSimpleArithmetic) { + using namespace allocation_size_literals; + { + auto a = 100_bytes; + auto b = 200_bytes; + ASSERT_EQ((a + b).GetByteSize(), 300u); + } + { + auto a = 100_bytes; + a += 200_bytes; + ASSERT_EQ(a.GetByteSize(), 300u); + } + { + auto a = 100_bytes; + a -= 50_bytes; + ASSERT_EQ(a.GetByteSize(), 50u); + } +} + +} // namespace impeller::testing diff --git a/impeller/core/allocator.h b/impeller/core/allocator.h index 921fb64a9edda..a4b3509884ca5 100644 --- a/impeller/core/allocator.h +++ b/impeller/core/allocator.h @@ -6,6 +6,7 @@ #define FLUTTER_IMPELLER_CORE_ALLOCATOR_H_ #include "flutter/fml/mapping.h" +#include "impeller/base/allocation_size.h" #include "impeller/core/device_buffer_descriptor.h" #include "impeller/core/texture.h" #include "impeller/core/texture_descriptor.h" @@ -51,7 +52,7 @@ class Allocator { virtual void DebugTraceMemoryStatistics() const {}; // Visible for testing. - virtual size_t DebugGetHeapUsage() const { return 0; } + virtual Bytes DebugGetHeapUsage() const { return Bytes{0}; } protected: Allocator(); diff --git a/impeller/renderer/backend/metal/allocator_mtl.h b/impeller/renderer/backend/metal/allocator_mtl.h index 82fd870190a0f..4111172c382cf 100644 --- a/impeller/renderer/backend/metal/allocator_mtl.h +++ b/impeller/renderer/backend/metal/allocator_mtl.h @@ -25,8 +25,8 @@ class DebugAllocatorStats { /// Decrement the tracked allocation size in bytes. void Decrement(size_t size); - /// Get the current tracked allocation size in MB. - size_t GetAllocationSizeMB(); + /// Get the current tracked allocation size. + Bytes GetAllocationSize(); private: std::atomic size_ = 0; @@ -40,7 +40,7 @@ class AllocatorMTL final : public Allocator { ~AllocatorMTL() override; // |Allocator| - size_t DebugGetHeapUsage() const override; + Bytes DebugGetHeapUsage() const override; private: friend class ContextMTL; diff --git a/impeller/renderer/backend/metal/allocator_mtl.mm b/impeller/renderer/backend/metal/allocator_mtl.mm index 6a9e4437f4bb5..834a52992ceee 100644 --- a/impeller/renderer/backend/metal/allocator_mtl.mm +++ b/impeller/renderer/backend/metal/allocator_mtl.mm @@ -7,6 +7,7 @@ #include "flutter/fml/build_config.h" #include "flutter/fml/logging.h" #include "fml/trace_event.h" +#include "impeller/base/allocation_size.h" #include "impeller/base/validation.h" #include "impeller/core/formats.h" #include "impeller/renderer/backend/metal/device_buffer_mtl.h" @@ -98,10 +99,9 @@ static bool SupportsLossyTextureCompression(id device) { size_.fetch_sub(size, std::memory_order_relaxed); } -size_t DebugAllocatorStats::GetAllocationSizeMB() { +Bytes DebugAllocatorStats::GetAllocationSize() { // RAM is measured in MiB, thus a divisor of 2^20 instead of 1,000,000. - size_t new_value = size_ / (1024 * 1024); - return new_value; + return Bytes{static_cast(size_)}; } AllocatorMTL::AllocatorMTL(id device, std::string label) @@ -256,20 +256,20 @@ static MTLStorageMode ToMTLStorageMode(StorageMode mode, return max_texture_supported_; } -size_t AllocatorMTL::DebugGetHeapUsage() const { +Bytes AllocatorMTL::DebugGetHeapUsage() const { #ifdef IMPELLER_DEBUG - return debug_allocater_->GetAllocationSizeMB(); + return debug_allocater_->GetAllocationSize(); #else - return 0u; + return {}; #endif // IMPELLER_DEBUG } void AllocatorMTL::DebugTraceMemoryStatistics() const { #ifdef IMPELLER_DEBUG - size_t allocated_size = DebugGetHeapUsage(); FML_TRACE_COUNTER("flutter", "AllocatorMTL", reinterpret_cast(this), // Trace Counter ID - "MemoryBudgetUsageMB", allocated_size); + "MemoryBudgetUsageMB", + DebugGetHeapUsage().ConvertTo().GetSize()); #endif // IMPELLER_DEBUG } diff --git a/impeller/renderer/backend/metal/allocator_mtl_unittests.mm b/impeller/renderer/backend/metal/allocator_mtl_unittests.mm index ea1bac5421b67..fe351f5f693ca 100644 --- a/impeller/renderer/backend/metal/allocator_mtl_unittests.mm +++ b/impeller/renderer/backend/metal/allocator_mtl_unittests.mm @@ -29,7 +29,8 @@ auto& context_mtl = ContextMTL::Cast(*GetContext()); const auto& allocator = context_mtl.GetResourceAllocator(); - EXPECT_EQ(allocator->DebugGetHeapUsage(), 0u); + EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo().GetSize(), + 0u); // Memoryless texture does not increase allocated size. { @@ -39,16 +40,16 @@ desc.size = {1024, 1024}; auto texture_1 = allocator->CreateTexture(desc); - EXPECT_EQ(allocator->DebugGetHeapUsage(), 0u); - // Private storage texture increases allocated size. desc.storage_mode = StorageMode::kDevicePrivate; auto texture_2 = allocator->CreateTexture(desc); #ifdef IMPELLER_DEBUG - EXPECT_EQ(allocator->DebugGetHeapUsage(), 4u); + EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo().GetSize(), + 4u); #else - EXPECT_EQ(allocator->DebugGetHeapUsage(), 0u); + EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo().GetSize(), + 0u); #endif // IMPELLER_DEBUG // Host storage texture increases allocated size. @@ -56,14 +57,17 @@ auto texture_3 = allocator->CreateTexture(desc); #ifdef IMPELLER_DEBUG - EXPECT_EQ(allocator->DebugGetHeapUsage(), 8u); + EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo().GetSize(), + 8u); #else - EXPECT_EQ(allocator->DebugGetHeapUsage(), 0u); + EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo().GetSize(), + 0u); #endif // IMPELLER_DEBUG } // After all textures are out of scope, memory has been decremented. - EXPECT_EQ(allocator->DebugGetHeapUsage(), 0u); + EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo().GetSize(), + 0u); } } // namespace testing diff --git a/impeller/renderer/backend/vulkan/allocator_vk.cc b/impeller/renderer/backend/vulkan/allocator_vk.cc index 032f9d7e7d51b..ddbedc2df928f 100644 --- a/impeller/renderer/backend/vulkan/allocator_vk.cc +++ b/impeller/renderer/backend/vulkan/allocator_vk.cc @@ -8,6 +8,7 @@ #include "flutter/fml/memory/ref_ptr.h" #include "flutter/fml/trace_event.h" +#include "impeller/base/allocation_size.h" #include "impeller/core/formats.h" #include "impeller/renderer/backend/vulkan/device_buffer_vk.h" #include "impeller/renderer/backend/vulkan/formats_vk.h" @@ -509,7 +510,7 @@ std::shared_ptr AllocatorVK::OnCreateBuffer( ); } -size_t AllocatorVK::DebugGetHeapUsage() const { +Bytes AllocatorVK::DebugGetHeapUsage() const { auto count = memory_properties_.memoryHeapCount; std::vector budgets(count); vmaGetHeapBudgets(allocator_.get(), budgets.data()); @@ -518,16 +519,15 @@ size_t AllocatorVK::DebugGetHeapUsage() const { const VmaBudget& budget = budgets[i]; total_usage += budget.usage; } - // Convert bytes to MB. - total_usage /= (1024 * 1024); - return total_usage; + return Bytes{static_cast(total_usage)}; } void AllocatorVK::DebugTraceMemoryStatistics() const { #ifdef IMPELLER_DEBUG FML_TRACE_COUNTER("flutter", "AllocatorVK", reinterpret_cast(this), // Trace Counter ID - "MemoryBudgetUsageMB", DebugGetHeapUsage()); + "MemoryBudgetUsageMB", + DebugGetHeapUsage().ConvertTo().GetSize()); #endif // IMPELLER_DEBUG } diff --git a/impeller/renderer/backend/vulkan/allocator_vk.h b/impeller/renderer/backend/vulkan/allocator_vk.h index f1a3201e8f676..53e2772e740a6 100644 --- a/impeller/renderer/backend/vulkan/allocator_vk.h +++ b/impeller/renderer/backend/vulkan/allocator_vk.h @@ -22,7 +22,7 @@ class AllocatorVK final : public Allocator { ~AllocatorVK() override; // |Allocator| - size_t DebugGetHeapUsage() const override; + Bytes DebugGetHeapUsage() const override; /// @brief Select a matching memory type for the given /// [memory_type_bits_requirement], or -1 if none is found. diff --git a/impeller/renderer/backend/vulkan/allocator_vk_unittests.cc b/impeller/renderer/backend/vulkan/allocator_vk_unittests.cc index f8326c983345c..cc00ec119079d 100644 --- a/impeller/renderer/backend/vulkan/allocator_vk_unittests.cc +++ b/impeller/renderer/backend/vulkan/allocator_vk_unittests.cc @@ -4,6 +4,7 @@ #include "flutter/testing/testing.h" // IWYU pragma: keep #include "gtest/gtest.h" +#include "impeller/base/allocation_size.h" #include "impeller/core/device_buffer_descriptor.h" #include "impeller/core/formats.h" #include "impeller/renderer/backend/vulkan/allocator_vk.h" @@ -76,8 +77,10 @@ TEST(AllocatorVKTest, RecreateSwapchainWhenSizeChanges) { auto const context = MockVulkanContextBuilder().Build(); auto allocator = context->GetResourceAllocator(); - EXPECT_EQ( - reinterpret_cast(allocator.get())->DebugGetHeapUsage(), 0u); + EXPECT_EQ(reinterpret_cast(allocator.get()) + ->DebugGetHeapUsage() + .GetByteSize(), + 0u); allocator->CreateBuffer(DeviceBufferDescriptor{ .storage_mode = StorageMode::kDevicePrivate, @@ -87,9 +90,11 @@ TEST(AllocatorVKTest, RecreateSwapchainWhenSizeChanges) { // Usage increases beyond the size of the allocated buffer since VMA will // first allocate large blocks of memory and then suballocate small memory // allocations. - EXPECT_EQ( - reinterpret_cast(allocator.get())->DebugGetHeapUsage(), - 16u); + EXPECT_EQ(reinterpret_cast(allocator.get()) + ->DebugGetHeapUsage() + .ConvertTo() + .GetSize(), + 16u); } #endif // IMPELLER_DEBUG