diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index c99621d35d403..3f43d429ad4b8 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -146,6 +146,7 @@ ../../../flutter/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents_unittests.cc ../../../flutter/impeller/entity/contents/filters/gaussian_blur_filter_contents_unittests.cc ../../../flutter/impeller/entity/contents/filters/inputs/filter_input_unittests.cc +../../../flutter/impeller/entity/contents/host_buffer_unittests.cc ../../../flutter/impeller/entity/contents/test ../../../flutter/impeller/entity/contents/tiled_texture_contents_unittests.cc ../../../flutter/impeller/entity/contents/vertices_contents_unittests.cc @@ -187,7 +188,6 @@ ../../../flutter/impeller/renderer/compute_subgroup_unittests.cc ../../../flutter/impeller/renderer/compute_unittests.cc ../../../flutter/impeller/renderer/device_buffer_unittests.cc -../../../flutter/impeller/renderer/host_buffer_unittests.cc ../../../flutter/impeller/renderer/pipeline_descriptor_unittests.cc ../../../flutter/impeller/renderer/pool_unittests.cc ../../../flutter/impeller/renderer/renderer_dart_unittests.cc diff --git a/impeller/aiks/aiks_context.cc b/impeller/aiks/aiks_context.cc index 86baab74d7953..d001c189e3b0d 100644 --- a/impeller/aiks/aiks_context.cc +++ b/impeller/aiks/aiks_context.cc @@ -4,6 +4,7 @@ #include "impeller/aiks/aiks_context.h" +#include "fml/closure.h" #include "impeller/aiks/picture.h" #include "impeller/typographer/typographer_context.h" @@ -40,11 +41,18 @@ ContentContext& AiksContext::GetContentContext() const { return *content_context_; } -bool AiksContext::Render(const Picture& picture, RenderTarget& render_target) { +bool AiksContext::Render(const Picture& picture, + RenderTarget& render_target, + bool reset_host_buffer) { if (!IsValid()) { return false; } + fml::ScopedCleanupClosure closure([&]() { + if (reset_host_buffer) { + content_context_->GetTransientsBuffer().Reset(); + } + }); if (picture.pass) { return picture.pass->Render(*content_context_, render_target); } diff --git a/impeller/aiks/aiks_context.h b/impeller/aiks/aiks_context.h index 650465d770dfc..ad8d6429c4d01 100644 --- a/impeller/aiks/aiks_context.h +++ b/impeller/aiks/aiks_context.h @@ -39,7 +39,9 @@ class AiksContext { ContentContext& GetContentContext() const; - bool Render(const Picture& picture, RenderTarget& render_target); + bool Render(const Picture& picture, + RenderTarget& render_target, + bool reset_host_buffer); private: std::shared_ptr context_; diff --git a/impeller/aiks/aiks_playground.cc b/impeller/aiks/aiks_playground.cc index b9ed2a828e7ae..8714b54697ac2 100644 --- a/impeller/aiks/aiks_playground.cc +++ b/impeller/aiks/aiks_playground.cc @@ -53,7 +53,7 @@ bool AiksPlayground::OpenPlaygroundHere(AiksPlaygroundCallback callback) { if (!picture.has_value()) { return false; } - return renderer.Render(*picture, render_target); + return renderer.Render(*picture, render_target, true); }); } diff --git a/impeller/aiks/picture.cc b/impeller/aiks/picture.cc index 907bbf6ca49ba..ea07dfd27a58c 100644 --- a/impeller/aiks/picture.cc +++ b/impeller/aiks/picture.cc @@ -84,7 +84,7 @@ std::shared_ptr Picture::RenderToTexture( return nullptr; } - if (!context.Render(*this, target)) { + if (!context.Render(*this, target, false)) { VALIDATION_LOG << "Could not render Picture to Texture."; return nullptr; } diff --git a/impeller/base/allocation.h b/impeller/base/allocation.h index dd1b06befa6fe..bd9b2370ef7fb 100644 --- a/impeller/base/allocation.h +++ b/impeller/base/allocation.h @@ -6,7 +6,6 @@ #define FLUTTER_IMPELLER_BASE_ALLOCATION_H_ #include -#include #include #include "flutter/fml/mapping.h" diff --git a/impeller/core/buffer.h b/impeller/core/buffer.h index 0664f1afc53b3..df58b56c0c62c 100644 --- a/impeller/core/buffer.h +++ b/impeller/core/buffer.h @@ -16,8 +16,7 @@ class Buffer { public: virtual ~Buffer(); - virtual std::shared_ptr GetDeviceBuffer( - Allocator& allocator) const = 0; + virtual std::shared_ptr GetDeviceBuffer() const = 0; }; } // namespace impeller diff --git a/impeller/core/device_buffer.cc b/impeller/core/device_buffer.cc index 741a4d7ee2386..5c6ecf4077ed3 100644 --- a/impeller/core/device_buffer.cc +++ b/impeller/core/device_buffer.cc @@ -11,11 +11,12 @@ DeviceBuffer::DeviceBuffer(DeviceBufferDescriptor desc) : desc_(desc) {} DeviceBuffer::~DeviceBuffer() = default; // |Buffer| -std::shared_ptr DeviceBuffer::GetDeviceBuffer( - Allocator& allocator) const { +std::shared_ptr DeviceBuffer::GetDeviceBuffer() const { return shared_from_this(); } +void DeviceBuffer::Flush(std::optional range) const {} + BufferView DeviceBuffer::AsBufferView() const { BufferView view; view.buffer = shared_from_this(); diff --git a/impeller/core/device_buffer.h b/impeller/core/device_buffer.h index c3ed289922d30..7f0cb99f3ba3f 100644 --- a/impeller/core/device_buffer.h +++ b/impeller/core/device_buffer.h @@ -38,13 +38,21 @@ class DeviceBuffer : public Buffer, uint16_t row_bytes) const; // |Buffer| - std::shared_ptr GetDeviceBuffer( - Allocator& allocator) const; + std::shared_ptr GetDeviceBuffer() const; const DeviceBufferDescriptor& GetDeviceBufferDescriptor() const; virtual uint8_t* OnGetContents() const = 0; + /// Make any pending writes visible to the GPU. + /// + /// This method must be called if the device pointer provided by + /// [OnGetContents] is written to without using [CopyHostBuffer]. On Devices + /// with coherent host memory, this method will not perform extra work. + /// + /// If the range is not provided, the entire buffer is flushed. + virtual void Flush(std::optional range = std::nullopt) const; + protected: const DeviceBufferDescriptor desc_; diff --git a/impeller/core/host_buffer.cc b/impeller/core/host_buffer.cc index 7e2eae85ac97f..1abc892116817 100644 --- a/impeller/core/host_buffer.cc +++ b/impeller/core/host_buffer.cc @@ -4,143 +4,196 @@ #include "impeller/core/host_buffer.h" -#include #include - -#include "flutter/fml/logging.h" +#include #include "impeller/core/allocator.h" #include "impeller/core/buffer_view.h" #include "impeller/core/device_buffer.h" +#include "impeller/core/device_buffer_descriptor.h" +#include "impeller/core/formats.h" namespace impeller { -std::shared_ptr HostBuffer::Create() { - return std::shared_ptr(new HostBuffer()); +constexpr size_t kAllocatorBlockSize = 1024000; // 1024 Kb. + +std::shared_ptr HostBuffer::Create( + const std::shared_ptr& allocator) { + return std::shared_ptr(new HostBuffer(allocator)); } -HostBuffer::HostBuffer() = default; +HostBuffer::HostBuffer(const std::shared_ptr& allocator) + : allocator_(allocator) { + DeviceBufferDescriptor desc; + desc.size = kAllocatorBlockSize; + desc.storage_mode = StorageMode::kHostVisible; + for (auto i = 0u; i < kHostBufferArenaSize; i++) { + device_buffers_[i].push_back(allocator->CreateBuffer(desc)); + } +} HostBuffer::~HostBuffer() = default; void HostBuffer::SetLabel(std::string label) { - state_->label = std::move(label); + label_ = std::move(label); } BufferView HostBuffer::Emplace(const void* buffer, size_t length, size_t align) { - auto [device_buffer, range] = state_->Emplace(buffer, length, align); + auto [data, range, device_buffer] = EmplaceInternal(buffer, length, align); if (!device_buffer) { return {}; } - return BufferView{state_, device_buffer, range}; + return BufferView{std::move(device_buffer), data, range}; } BufferView HostBuffer::Emplace(const void* buffer, size_t length) { - auto [device_buffer, range] = state_->Emplace(buffer, length); + auto [data, range, device_buffer] = EmplaceInternal(buffer, length); if (!device_buffer) { return {}; } - return BufferView{state_, device_buffer, range}; + return BufferView{std::move(device_buffer), data, range}; } BufferView HostBuffer::Emplace(size_t length, size_t align, const EmplaceProc& cb) { - auto [buffer, range] = state_->Emplace(length, align, cb); - if (!buffer) { + auto [data, range, device_buffer] = EmplaceInternal(length, align, cb); + if (!device_buffer) { return {}; } - return BufferView{state_, buffer, range}; -} - -std::shared_ptr HostBuffer::GetDeviceBuffer( - Allocator& allocator) const { - return state_->GetDeviceBuffer(allocator); + return BufferView{std::move(device_buffer), data, range}; } -void HostBuffer::Reset() { - state_->Reset(); +HostBuffer::TestStateQuery HostBuffer::GetStateForTest() { + return HostBuffer::TestStateQuery{ + .current_frame = frame_index_, + .current_buffer = current_buffer_, + .total_buffer_count = device_buffers_[frame_index_].size(), + }; } -size_t HostBuffer::GetSize() const { - return state_->GetReservedLength(); -} - -size_t HostBuffer::GetLength() const { - return state_->GetLength(); +void HostBuffer::MaybeCreateNewBuffer(size_t required_size) { + current_buffer_++; + if (current_buffer_ >= device_buffers_[frame_index_].size()) { + FML_DCHECK(required_size <= kAllocatorBlockSize); + DeviceBufferDescriptor desc; + desc.size = kAllocatorBlockSize; + desc.storage_mode = StorageMode::kHostVisible; + device_buffers_[frame_index_].push_back(allocator_->CreateBuffer(desc)); + } + offset_ = 0; } -std::pair HostBuffer::HostBufferState::Emplace( - size_t length, - size_t align, - const EmplaceProc& cb) { +std::tuple> +HostBuffer::EmplaceInternal(size_t length, + size_t align, + const EmplaceProc& cb) { if (!cb) { return {}; } + + // If the requested allocation is bigger than the block size, create a one-off + // device buffer and write to that. + if (length > kAllocatorBlockSize) { + DeviceBufferDescriptor desc; + desc.size = length; + desc.storage_mode = StorageMode::kHostVisible; + auto device_buffer = allocator_->CreateBuffer(desc); + if (!device_buffer) { + return {}; + } + if (cb) { + cb(device_buffer->OnGetContents()); + device_buffer->Flush(Range{0, length}); + } + return std::make_tuple(device_buffer->OnGetContents(), Range{0, length}, + device_buffer); + } + auto old_length = GetLength(); - if (!Truncate(old_length + length)) { - return {}; + if (old_length + length > kAllocatorBlockSize) { + MaybeCreateNewBuffer(length); } - generation++; - cb(GetBuffer() + old_length); + old_length = GetLength(); + + auto current_buffer = GetCurrentBuffer(); + cb(current_buffer->OnGetContents() + old_length); + current_buffer->Flush(Range{old_length, length}); - return std::make_pair(GetBuffer(), Range{old_length, length}); + offset_ += length; + auto contents = current_buffer->OnGetContents(); + return std::make_tuple(contents, Range{old_length, length}, + std::move(current_buffer)); } -std::shared_ptr -HostBuffer::HostBufferState::GetDeviceBuffer(Allocator& allocator) const { - if (generation == device_buffer_generation) { - return device_buffer; - } - auto new_buffer = allocator.CreateBufferWithCopy(GetBuffer(), GetLength()); - if (!new_buffer) { - return nullptr; +std::tuple> +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) { + DeviceBufferDescriptor desc; + desc.size = length; + desc.storage_mode = StorageMode::kHostVisible; + auto device_buffer = allocator_->CreateBuffer(desc); + if (!device_buffer) { + return {}; + } + if (buffer) { + if (!device_buffer->CopyHostBuffer(static_cast(buffer), + Range{0, length})) { + return {}; + } + } + return std::make_tuple(device_buffer->OnGetContents(), Range{0, length}, + device_buffer); } - new_buffer->SetLabel(label); - device_buffer_generation = generation; - device_buffer = std::move(new_buffer); - return device_buffer; -} -std::pair HostBuffer::HostBufferState::Emplace( - const void* buffer, - size_t length) { auto old_length = GetLength(); - if (!Truncate(old_length + length)) { - return {}; + if (old_length + length > kAllocatorBlockSize) { + MaybeCreateNewBuffer(length); } - generation++; + old_length = GetLength(); + + auto current_buffer = GetCurrentBuffer(); if (buffer) { - ::memmove(GetBuffer() + old_length, buffer, length); + ::memmove(current_buffer->OnGetContents() + old_length, buffer, length); + current_buffer->Flush(Range{old_length, length}); } - return std::make_pair(GetBuffer(), Range{old_length, length}); + offset_ += length; + auto contents = current_buffer->OnGetContents(); + return std::make_tuple(contents, Range{old_length, length}, + std::move(current_buffer)); } -std::pair HostBuffer::HostBufferState::Emplace( - const void* buffer, - size_t length, - size_t align) { +std::tuple> +HostBuffer::EmplaceInternal(const void* buffer, size_t length, size_t align) { if (align == 0 || (GetLength() % align) == 0) { - return Emplace(buffer, length); + return EmplaceInternal(buffer, length); } { - auto [buffer, range] = Emplace(nullptr, align - (GetLength() % align)); + auto [buffer, range, device_buffer] = + EmplaceInternal(nullptr, align - (GetLength() % align)); if (!buffer) { return {}; } } - return Emplace(buffer, length); + return EmplaceInternal(buffer, length); } -void HostBuffer::HostBufferState::Reset() { - generation += 1; - device_buffer = nullptr; - bool did_truncate = Truncate(0); - FML_CHECK(did_truncate); +void HostBuffer::Reset() { + // When resetting the host buffer state at the end of the frame, check if + // there are any unused buffers and remove them. + while (device_buffers_[frame_index_].size() > current_buffer_ + 1) { + device_buffers_[frame_index_].pop_back(); + } + + offset_ = 0u; + current_buffer_ = 0u; + frame_index_ = (frame_index_ + 1) % kHostBufferArenaSize; } } // namespace impeller diff --git a/impeller/core/host_buffer.h b/impeller/core/host_buffer.h index 5c3a69c75dcbf..16c118093c3a2 100644 --- a/impeller/core/host_buffer.h +++ b/impeller/core/host_buffer.h @@ -6,20 +6,29 @@ #define FLUTTER_IMPELLER_CORE_HOST_BUFFER_H_ #include +#include +#include #include #include #include -#include "impeller/base/allocation.h" #include "impeller/core/buffer.h" #include "impeller/core/buffer_view.h" #include "impeller/core/platform.h" namespace impeller { -class HostBuffer final : public Buffer { +/// Approximately the same size as the max frames in flight. +static const constexpr size_t kHostBufferArenaSize = 3u; + +/// The host buffer class manages one more 1024 Kb blocks of device buffer +/// allocations. +/// +/// These are reset per-frame. +class HostBuffer { public: - static std::shared_ptr Create(); + static std::shared_ptr Create( + const std::shared_ptr& allocator); // |Buffer| virtual ~HostBuffer(); @@ -114,52 +123,49 @@ class HostBuffer final : public Buffer { /// reused. void Reset(); - //---------------------------------------------------------------------------- - /// @brief Returns the capacity of the HostBuffer in memory in bytes. - size_t GetSize() const; + /// Test only internal state. + struct TestStateQuery { + size_t current_frame; + size_t current_buffer; + size_t total_buffer_count; + }; - //---------------------------------------------------------------------------- - /// @brief Returns the size of the currently allocated HostBuffer memory in - /// bytes. - size_t GetLength() const; + /// @brief Retrieve internal buffer state for test expectations. + TestStateQuery GetStateForTest(); private: - struct HostBufferState : public Buffer, public Allocation { - std::shared_ptr GetDeviceBuffer( - Allocator& allocator) const override; - - [[nodiscard]] std::pair Emplace(const void* buffer, - size_t length); + [[nodiscard]] std::tuple> + EmplaceInternal(const void* buffer, size_t length); - std::pair Emplace(size_t length, - size_t align, - const EmplaceProc& cb); + std::tuple> + EmplaceInternal(size_t length, size_t align, const EmplaceProc& cb); - std::pair Emplace(const void* buffer, - size_t length, - size_t align); + std::tuple> + EmplaceInternal(const void* buffer, size_t length, size_t align); - void Reset(); + size_t GetLength() const { return offset_; } - mutable std::shared_ptr device_buffer; - mutable size_t device_buffer_generation = 0u; - size_t generation = 1u; - std::string label; - }; - - std::shared_ptr state_ = std::make_shared(); + void MaybeCreateNewBuffer(size_t required_size); - // |Buffer| - std::shared_ptr GetDeviceBuffer( - Allocator& allocator) const override; + std::shared_ptr& GetCurrentBuffer() { + return device_buffers_[frame_index_][current_buffer_]; + } [[nodiscard]] BufferView Emplace(const void* buffer, size_t length); - HostBuffer(); + explicit HostBuffer(const std::shared_ptr& allocator); HostBuffer(const HostBuffer&) = delete; HostBuffer& operator=(const HostBuffer&) = delete; + + std::shared_ptr allocator_; + std::array>, kHostBufferArenaSize> + device_buffers_; + size_t current_buffer_ = 0u; + size_t offset_ = 0u; + size_t frame_index_ = 0u; + std::string label_; }; } // namespace impeller diff --git a/impeller/display_list/dl_playground.cc b/impeller/display_list/dl_playground.cc index ba94de2be370a..a9c510a076701 100644 --- a/impeller/display_list/dl_playground.cc +++ b/impeller/display_list/dl_playground.cc @@ -51,7 +51,7 @@ bool DlPlayground::OpenPlaygroundHere(DisplayListPlaygroundCallback callback) { list->Dispatch(dispatcher); auto picture = dispatcher.EndRecordingAsPicture(); - return context.Render(picture, render_target); + return context.Render(picture, render_target, true); }); } diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 4dd5d9fe19eb3..c3fc2a8dca355 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -269,6 +269,7 @@ impeller_component("entity_unittests") { "contents/filters/directional_gaussian_blur_filter_contents_unittests.cc", "contents/filters/gaussian_blur_filter_contents_unittests.cc", "contents/filters/inputs/filter_input_unittests.cc", + "contents/host_buffer_unittests.cc", "contents/tiled_texture_contents_unittests.cc", "contents/vertices_contents_unittests.cc", "entity_pass_target_unittests.cc", diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 380fa276ce212..206273d554765 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -217,7 +217,7 @@ bool AtlasContents::Render(const ContentContext& renderer, VertexBufferBuilder vtx_builder; vtx_builder.Reserve(texture_coords_.size() * 6); const auto texture_size = texture_->GetSize(); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); for (size_t i = 0; i < texture_coords_.size(); i++) { auto sample_rect = texture_coords_[i]; @@ -399,7 +399,7 @@ bool AtlasTextureContents::Render(const ContentContext& renderer, Command cmd; DEBUG_COMMAND_INFO(cmd, "AtlasTexture"); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); VS::FrameInfo frame_info; frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform(); @@ -486,7 +486,7 @@ bool AtlasColorContents::Render(const ContentContext& renderer, Command cmd; DEBUG_COMMAND_INFO(cmd, "AtlasColors"); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); VS::FrameInfo frame_info; frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform(); diff --git a/impeller/entity/contents/checkerboard_contents.cc b/impeller/entity/contents/checkerboard_contents.cc index f58bb38850891..91f6959bf6d6f 100644 --- a/impeller/entity/contents/checkerboard_contents.cc +++ b/impeller/entity/contents/checkerboard_contents.cc @@ -21,7 +21,7 @@ CheckerboardContents::~CheckerboardContents() = default; bool CheckerboardContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); using VS = CheckerboardPipeline::VertexShader; using FS = CheckerboardPipeline::FragmentShader; diff --git a/impeller/entity/contents/clip_contents.cc b/impeller/entity/contents/clip_contents.cc index a9eaf8a6be953..16f10b0603fc4 100644 --- a/impeller/entity/contents/clip_contents.cc +++ b/impeller/entity/contents/clip_contents.cc @@ -96,11 +96,12 @@ bool ClipContents::Render(const ContentContext& renderer, auto vertices = VertexBufferBuilder{} .AddVertices({{points[0]}, {points[1]}, {points[2]}, {points[3]}}) - .CreateVertexBuffer(pass.GetTransientsBuffer()); + .CreateVertexBuffer(renderer.GetTransientsBuffer()); cmd.BindVertices(std::move(vertices)); info.mvp = pass.GetOrthographicTransform(); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(info)); options.primitive_type = PrimitiveType::kTriangleStrip; cmd.pipeline = renderer.GetClipPipeline(options); @@ -128,7 +129,7 @@ bool ClipContents::Render(const ContentContext& renderer, cmd.BindVertices(std::move(geometry_result.vertex_buffer)); info.mvp = geometry_result.transform; - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(info)); + VS::BindFrameInfo(cmd, renderer.GetTransientsBuffer().EmplaceUniform(info)); pass.AddCommand(std::move(cmd)); return true; @@ -197,11 +198,12 @@ bool ClipRestoreContents::Render(const ContentContext& renderer, {Point(ltrb[0], ltrb[3])}, {Point(ltrb[2], ltrb[3])}, }); - cmd.BindVertices(vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer())); + cmd.BindVertices( + vtx_builder.CreateVertexBuffer(renderer.GetTransientsBuffer())); VS::FrameInfo info; info.mvp = pass.GetOrthographicTransform(); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(info)); + VS::BindFrameInfo(cmd, renderer.GetTransientsBuffer().EmplaceUniform(info)); pass.AddCommand(std::move(cmd)); return true; diff --git a/impeller/entity/contents/conical_gradient_contents.cc b/impeller/entity/contents/conical_gradient_contents.cc index c6d52fd78d768..28c738ec9b65a 100644 --- a/impeller/entity/contents/conical_gradient_contents.cc +++ b/impeller/entity/contents/conical_gradient_contents.cc @@ -78,7 +78,7 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer, frag_info.focus_radius = 0.0; } - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto colors = CreateGradientColors(colors_, stops_); frag_info.colors_length = colors.size(); @@ -105,9 +105,11 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer, cmd.pipeline = renderer.GetConicalGradientSSBOFillPipeline(options); cmd.BindVertices(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); FS::BindColorData(cmd, color_buffer); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; @@ -171,14 +173,16 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer, cmd.pipeline = renderer.GetConicalGradientFillPipeline(options); cmd.BindVertices(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); SamplerDescriptor sampler_desc; sampler_desc.min_filter = MinMagFilter::kLinear; sampler_desc.mag_filter = MinMagFilter::kLinear; FS::BindTextureSampler( cmd, gradient_texture, renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 606420b0ece98..17c194e64e022 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -184,10 +184,12 @@ ContentContext::ContentContext( render_target_cache_(render_target_allocator == nullptr ? std::make_shared( context_->GetResourceAllocator()) - : std::move(render_target_allocator)) { + : std::move(render_target_allocator)), + host_buffer_(HostBuffer::Create(context_->GetResourceAllocator())) { if (!context_ || !context_->IsValid()) { return; } + auto options = ContentContextOptions{ .sample_count = SampleCount::kCount4, .color_attachment_pixel_format = diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index d8217da6d5e35..c1b287e633dda 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -15,6 +15,7 @@ #include "flutter/fml/status_or.h" #include "impeller/base/validation.h" #include "impeller/core/formats.h" +#include "impeller/core/host_buffer.h" #include "impeller/entity/entity.h" #include "impeller/renderer/capabilities.h" #include "impeller/renderer/pipeline.h" @@ -729,6 +730,12 @@ class ContentContext { return render_target_cache_; } + /// @brief Retrieve the currnent host buffer for transient storage. + /// + /// This is only safe to use from the raster threads. Other threads should + /// allocate their own device buffers. + HostBuffer& GetTransientsBuffer() const { return *host_buffer_; } + private: std::shared_ptr context_; std::shared_ptr lazy_glyph_atlas_; @@ -940,6 +947,7 @@ class ContentContext { std::shared_ptr scene_context_; #endif // IMPELLER_ENABLE_3D std::shared_ptr render_target_cache_; + std::shared_ptr host_buffer_; bool wireframe_ = false; ContentContext(const ContentContext&) = delete; diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index 9b12d641a383c..6cec6f769b083 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -146,7 +146,7 @@ static std::optional AdvancedBlend( ContentContext::SubpassCallback callback = [&](const ContentContext& renderer, RenderPass& pass) { - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto size = pass.GetRenderTargetSize(); VertexBufferBuilder vtx_builder; @@ -264,7 +264,7 @@ std::optional BlendFilterContents::CreateForegroundAdvancedBlend( using VS = BlendScreenPipeline::VertexShader; using FS = BlendScreenPipeline::FragmentShader; - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto maybe_dst_uvs = dst_snapshot->GetCoverageUVs(coverage); if (!maybe_dst_uvs.has_value()) { @@ -433,7 +433,7 @@ std::optional BlendFilterContents::CreateForegroundPorterDuffBlend( using VS = PorterDuffBlendPipeline::VertexShader; using FS = PorterDuffBlendPipeline::FragmentShader; - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto maybe_dst_uvs = dst_snapshot->GetCoverageUVs(coverage); if (!maybe_dst_uvs.has_value()) { @@ -550,7 +550,7 @@ static std::optional PipelineBlend( ContentContext::SubpassCallback callback = [&](const ContentContext& renderer, RenderPass& pass) { - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); Command cmd; DEBUG_COMMAND_INFO(cmd, SPrintF("Pipeline Blend Filter (%s)", diff --git a/impeller/entity/contents/filters/border_mask_blur_filter_contents.cc b/impeller/entity/contents/filters/border_mask_blur_filter_contents.cc index c246b4ff24a76..fddd2c3b0bcde 100644 --- a/impeller/entity/contents/filters/border_mask_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/border_mask_blur_filter_contents.cc @@ -89,7 +89,7 @@ std::optional BorderMaskBlurFilterContents::RenderFilter( outer_blur_factor = outer_blur_factor_, sigma]( const ContentContext& renderer, const Entity& entity, RenderPass& pass) -> bool { - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); VertexBufferBuilder vtx_builder; auto origin = coverage.GetOrigin(); diff --git a/impeller/entity/contents/filters/color_matrix_filter_contents.cc b/impeller/entity/contents/filters/color_matrix_filter_contents.cc index 89fd478de4396..837416118210d 100644 --- a/impeller/entity/contents/filters/color_matrix_filter_contents.cc +++ b/impeller/entity/contents/filters/color_matrix_filter_contents.cc @@ -72,7 +72,7 @@ std::optional ColorMatrixFilterContents::RenderFilter( {Point(0, 1)}, {Point(1, 1)}, }); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); cmd.BindVertices(vtx_builder.CreateVertexBuffer(host_buffer)); VS::FrameInfo frame_info; diff --git a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.cc index 791a457e3ecef..3115d9624b48b 100644 --- a/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/directional_gaussian_blur_filter_contents.cc @@ -155,7 +155,7 @@ std::optional DirectionalGaussianBlurFilterContents::RenderFilter( ContentContext::SubpassCallback subpass_callback = [&](const ContentContext& renderer, RenderPass& pass) { - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); VertexBufferBuilder vtx_builder; vtx_builder.AddVertices({ diff --git a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc index e23f95c4cc192..835e254328274 100644 --- a/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc +++ b/impeller/entity/contents/filters/gaussian_blur_filter_contents.cc @@ -75,7 +75,7 @@ fml::StatusOr MakeDownsampleSubpass( Entity::TileMode tile_mode) { ContentContext::SubpassCallback subpass_callback = [&](const ContentContext& renderer, RenderPass& pass) { - HostBuffer& host_buffer = pass.GetTransientsBuffer(); + HostBuffer& host_buffer = renderer.GetTransientsBuffer(); Command cmd; DEBUG_COMMAND_INFO(cmd, "Gaussian blur downsample"); @@ -139,7 +139,7 @@ fml::StatusOr MakeBlurSubpass( .mvp = Matrix::MakeOrthographic(ISize(1, 1)), .texture_sampler_y_coord_scale = 1.0}; - HostBuffer& host_buffer = pass.GetTransientsBuffer(); + HostBuffer& host_buffer = renderer.GetTransientsBuffer(); Command cmd; ContentContextOptions options = OptionsFromPass(pass); diff --git a/impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc b/impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc index 7b768bc708af9..3c7d864b06dfa 100644 --- a/impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc +++ b/impeller/entity/contents/filters/linear_to_srgb_filter_contents.cc @@ -62,7 +62,7 @@ std::optional LinearToSrgbFilterContents::RenderFilter( {Point(1, 1)}, }); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); cmd.BindVertices(vtx_builder.CreateVertexBuffer(host_buffer)); VS::FrameInfo frame_info; diff --git a/impeller/entity/contents/filters/morphology_filter_contents.cc b/impeller/entity/contents/filters/morphology_filter_contents.cc index a90aa853b7a1c..9b7bb80e64d7b 100644 --- a/impeller/entity/contents/filters/morphology_filter_contents.cc +++ b/impeller/entity/contents/filters/morphology_filter_contents.cc @@ -75,7 +75,7 @@ std::optional DirectionalMorphologyFilterContents::RenderFilter( ContentContext::SubpassCallback callback = [&](const ContentContext& renderer, RenderPass& pass) { - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); VertexBufferBuilder vtx_builder; vtx_builder.AddVertices({ diff --git a/impeller/entity/contents/filters/srgb_to_linear_filter_contents.cc b/impeller/entity/contents/filters/srgb_to_linear_filter_contents.cc index a1a36abc154d6..567e6c204a983 100644 --- a/impeller/entity/contents/filters/srgb_to_linear_filter_contents.cc +++ b/impeller/entity/contents/filters/srgb_to_linear_filter_contents.cc @@ -62,7 +62,7 @@ std::optional SrgbToLinearFilterContents::RenderFilter( {Point(1, 1)}, }); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); cmd.BindVertices(vtx_builder.CreateVertexBuffer(host_buffer)); VS::FrameInfo frame_info; diff --git a/impeller/entity/contents/filters/yuv_to_rgb_filter_contents.cc b/impeller/entity/contents/filters/yuv_to_rgb_filter_contents.cc index 9d3c418bdb5af..78874b335ce4a 100644 --- a/impeller/entity/contents/filters/yuv_to_rgb_filter_contents.cc +++ b/impeller/entity/contents/filters/yuv_to_rgb_filter_contents.cc @@ -91,7 +91,7 @@ std::optional YUVToRGBFilterContents::RenderFilter( {Point(1, 1)}, }); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); cmd.BindVertices(vtx_builder.CreateVertexBuffer(host_buffer)); VS::FrameInfo frame_info; diff --git a/impeller/entity/contents/framebuffer_blend_contents.cc b/impeller/entity/contents/framebuffer_blend_contents.cc index d48b5d5ffe1bb..91445c39c7bcd 100644 --- a/impeller/entity/contents/framebuffer_blend_contents.cc +++ b/impeller/entity/contents/framebuffer_blend_contents.cc @@ -38,7 +38,7 @@ bool FramebufferBlendContents::Render(const ContentContext& renderer, using VS = FramebufferBlendScreenPipeline::VertexShader; using FS = FramebufferBlendScreenPipeline::FragmentShader; - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto src_snapshot = child_contents_->RenderToSnapshot( renderer, // renderer diff --git a/impeller/entity/contents/host_buffer_unittests.cc b/impeller/entity/contents/host_buffer_unittests.cc new file mode 100644 index 0000000000000..3ae3c285e07c0 --- /dev/null +++ b/impeller/entity/contents/host_buffer_unittests.cc @@ -0,0 +1,150 @@ +// 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/host_buffer.h" +#include "impeller/entity/entity_playground.h" + +namespace impeller { +namespace testing { + +using HostBufferTest = EntityPlayground; +INSTANTIATE_PLAYGROUND_SUITE(HostBufferTest); + +TEST_P(HostBufferTest, CanEmplace) { + struct Length2 { + uint8_t pad[2]; + }; + static_assert(sizeof(Length2) == 2u); + + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + + 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)); + } +} + +TEST_P(HostBufferTest, CanEmplaceWithAlignment) { + struct Length2 { + uint8_t pad[2]; + }; + static_assert(sizeof(Length2) == 2); + struct alignas(16) Align16 { + uint8_t pad[2]; + }; + static_assert(alignof(Align16) == 16); + static_assert(sizeof(Align16) == 16); + + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + ASSERT_TRUE(buffer); + + { + auto view = buffer->Emplace(Length2{}); + ASSERT_TRUE(view); + ASSERT_EQ(view.range, Range(0u, 2u)); + } + + { + auto view = buffer->Emplace(Align16{}); + ASSERT_TRUE(view); + ASSERT_EQ(view.range.offset, 16u); + ASSERT_EQ(view.range.length, 16u); + } + { + auto view = buffer->Emplace(Length2{}); + ASSERT_TRUE(view); + ASSERT_EQ(view.range, Range(32u, 2u)); + } + + { + auto view = buffer->Emplace(Align16{}); + ASSERT_TRUE(view); + ASSERT_EQ(view.range.offset, 48u); + ASSERT_EQ(view.range.length, 16u); + } +} + +TEST_P(HostBufferTest, HostBufferInitialState) { + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + + EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u); + EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); + EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u); +} + +TEST_P(HostBufferTest, ResetIncrementsFrameCounter) { + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + + EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); + + buffer->Reset(); + EXPECT_EQ(buffer->GetStateForTest().current_frame, 1u); + + buffer->Reset(); + EXPECT_EQ(buffer->GetStateForTest().current_frame, 2u); + + buffer->Reset(); + EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); +} + +TEST_P(HostBufferTest, + EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback) { + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + + // Emplace an amount larger than the block size, to verify that the host + // buffer does not create a buffer. + auto buffer_view = buffer->Emplace(1024000 + 10, 0, [](uint8_t* data) {}); + + EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u); + EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); + EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u); +} + +TEST_P(HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBuffer) { + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + + // Emplace an amount larger than the block size, to verify that the host + // buffer does not create a buffer. + auto buffer_view = buffer->Emplace(nullptr, 1024000 + 10, 0); + + EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u); + EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); + EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u); +} + +TEST_P(HostBufferTest, UnusedBuffersAreDiscardedWhenResetting) { + auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); + + // Emplace two large allocations to force the allocation of a second buffer. + auto buffer_view_a = buffer->Emplace(1020000, 0, [](uint8_t* data) {}); + auto buffer_view_b = buffer->Emplace(1020000, 0, [](uint8_t* data) {}); + + EXPECT_EQ(buffer->GetStateForTest().current_buffer, 1u); + EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u); + EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); + + // Reset until we get back to this frame. + for (auto i = 0; i < 3; i++) { + buffer->Reset(); + } + + EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u); + EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u); + EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); + + // Now when we reset, the buffer should get dropped. + // Reset until we get back to this frame. + for (auto i = 0; i < 3; i++) { + buffer->Reset(); + } + + EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u); + EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u); + EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u); +} + +} // namespace testing +} // namespace impeller diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index fbee0df907bb6..60e903c81fb98 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -106,14 +106,16 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer, cmd.pipeline = renderer.GetLinearGradientFillPipeline(options); cmd.BindVertices(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); SamplerDescriptor sampler_desc; sampler_desc.min_filter = MinMagFilter::kLinear; sampler_desc.mag_filter = MinMagFilter::kLinear; FS::BindTextureSampler( cmd, std::move(gradient_texture), renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; @@ -140,7 +142,7 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer, frag_info.decal_border_color = decal_border_color_; frag_info.alpha = GetOpacityFactor(); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto colors = CreateGradientColors(colors_, stops_); frag_info.colors_length = colors.size(); @@ -167,9 +169,11 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer, cmd.pipeline = renderer.GetLinearGradientSSBOFillPipeline(options); cmd.BindVertices(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); FS::BindColorData(cmd, color_buffer); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; diff --git a/impeller/entity/contents/radial_gradient_contents.cc b/impeller/entity/contents/radial_gradient_contents.cc index 37c5cdef2b3c3..3706ca224497a 100644 --- a/impeller/entity/contents/radial_gradient_contents.cc +++ b/impeller/entity/contents/radial_gradient_contents.cc @@ -77,7 +77,7 @@ bool RadialGradientContents::RenderSSBO(const ContentContext& renderer, frag_info.decal_border_color = decal_border_color_; frag_info.alpha = GetOpacityFactor(); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto colors = CreateGradientColors(colors_, stops_); frag_info.colors_length = colors.size(); @@ -104,9 +104,11 @@ bool RadialGradientContents::RenderSSBO(const ContentContext& renderer, cmd.pipeline = renderer.GetRadialGradientSSBOFillPipeline(options); cmd.BindVertices(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); FS::BindColorData(cmd, color_buffer); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; @@ -163,14 +165,16 @@ bool RadialGradientContents::RenderTexture(const ContentContext& renderer, cmd.pipeline = renderer.GetRadialGradientFillPipeline(options); cmd.BindVertices(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); SamplerDescriptor sampler_desc; sampler_desc.min_filter = MinMagFilter::kLinear; sampler_desc.mag_filter = MinMagFilter::kLinear; FS::BindTextureSampler( cmd, gradient_texture, renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; diff --git a/impeller/entity/contents/runtime_effect_contents.cc b/impeller/entity/contents/runtime_effect_contents.cc index 20f73299a49cd..7cf6e931986af 100644 --- a/impeller/entity/contents/runtime_effect_contents.cc +++ b/impeller/entity/contents/runtime_effect_contents.cc @@ -199,7 +199,8 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, VS::FrameInfo frame_info; frame_info.mvp = geometry_result.transform; - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); //-------------------------------------------------------------------------- /// Fragment stage uniforms. @@ -228,7 +229,7 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, case kFloat: { size_t alignment = std::max(uniform.bit_width / 8, DefaultUniformAlignment()); - auto buffer_view = pass.GetTransientsBuffer().Emplace( + auto buffer_view = renderer.GetTransientsBuffer().Emplace( uniform_data_->data() + buffer_offset, uniform.GetSize(), alignment); diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index 323da22797e7c..2683bf07e04bd 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -72,7 +72,8 @@ bool SolidColorContents::Render(const ContentContext& renderer, VS::FrameInfo frame_info; frame_info.mvp = capture.AddMatrix("Transform", geometry_result.transform); frame_info.color = capture.AddColor("Color", GetColor()).Premultiply(); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; diff --git a/impeller/entity/contents/solid_rrect_blur_contents.cc b/impeller/entity/contents/solid_rrect_blur_contents.cc index a05002b3d3709..4aa04d0fa63d0 100644 --- a/impeller/entity/contents/solid_rrect_blur_contents.cc +++ b/impeller/entity/contents/solid_rrect_blur_contents.cc @@ -106,12 +106,14 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer, cmd.pipeline = renderer.GetRRectBlurPipeline(opts); cmd.stencil_reference = entity.GetClipDepth(); - cmd.BindVertices(vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer())); + cmd.BindVertices( + vtx_builder.CreateVertexBuffer(renderer.GetTransientsBuffer())); VS::FrameInfo frame_info; frame_info.mvp = pass.GetOrthographicTransform() * entity.GetTransform() * Matrix::MakeTranslation(positive_rect.GetOrigin()); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); FS::FragInfo frag_info; frag_info.color = color; @@ -120,7 +122,8 @@ bool SolidRRectBlurContents::Render(const ContentContext& renderer, frag_info.corner_radius = std::min(corner_radius_, std::min(positive_rect.GetWidth() / 2.0f, positive_rect.GetHeight() / 2.0f)); - FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); if (!pass.AddCommand(std::move(cmd))) { return false; diff --git a/impeller/entity/contents/sweep_gradient_contents.cc b/impeller/entity/contents/sweep_gradient_contents.cc index 87f7774d0a3d9..eda81794695c8 100644 --- a/impeller/entity/contents/sweep_gradient_contents.cc +++ b/impeller/entity/contents/sweep_gradient_contents.cc @@ -84,7 +84,7 @@ bool SweepGradientContents::RenderSSBO(const ContentContext& renderer, frag_info.decal_border_color = decal_border_color_; frag_info.alpha = GetOpacityFactor(); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto colors = CreateGradientColors(colors_, stops_); frag_info.colors_length = colors.size(); @@ -111,9 +111,11 @@ bool SweepGradientContents::RenderSSBO(const ContentContext& renderer, cmd.pipeline = renderer.GetSweepGradientSSBOFillPipeline(options); cmd.BindVertices(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); FS::BindColorData(cmd, color_buffer); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; @@ -171,8 +173,10 @@ bool SweepGradientContents::RenderTexture(const ContentContext& renderer, cmd.pipeline = renderer.GetSweepGradientFillPipeline(options); cmd.BindVertices(std::move(geometry_result.vertex_buffer)); - FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + FS::BindFragInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); SamplerDescriptor sampler_desc; sampler_desc.min_filter = MinMagFilter::kLinear; sampler_desc.mag_filter = MinMagFilter::kLinear; diff --git a/impeller/entity/contents/text_contents.cc b/impeller/entity/contents/text_contents.cc index 8bfb68340d381..89438851afaf0 100644 --- a/impeller/entity/contents/text_contents.cc +++ b/impeller/entity/contents/text_contents.cc @@ -117,14 +117,15 @@ bool TextContents::Render(const ContentContext& renderer, frame_info.entity_transform = entity.GetTransform(); frame_info.text_color = ToVector(color.Premultiply()); - VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, + renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (type == GlyphAtlas::Type::kColorBitmap) { using FSS = GlyphAtlasColorPipeline::FragmentShader; FSS::FragInfo frag_info; frag_info.use_text_color = force_text_color_ ? 1.0 : 0.0; FSS::BindFragInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + renderer.GetTransientsBuffer().EmplaceUniform(frag_info)); } SamplerDescriptor sampler_desc; @@ -160,7 +161,7 @@ bool TextContents::Render(const ContentContext& renderer, Point{0, 1}, Point{1, 0}, Point{0, 1}, Point{1, 1}}; - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); size_t vertex_count = 0; for (const auto& run : frame_->GetRuns()) { vertex_count += run.GetGlyphPositions().size(); diff --git a/impeller/entity/contents/texture_contents.cc b/impeller/entity/contents/texture_contents.cc index e109d1e575334..dddbf879d360b 100644 --- a/impeller/entity/contents/texture_contents.cc +++ b/impeller/entity/contents/texture_contents.cc @@ -138,7 +138,7 @@ bool TextureContents::Render(const ContentContext& renderer, {destination_rect.GetRightBottom(), texture_coords.GetRightBottom()}, }); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); VS::FrameInfo frame_info; frame_info.mvp = pass.GetOrthographicTransform() * diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc index a71c3ca50c39d..28d5af604b168 100644 --- a/impeller/entity/contents/tiled_texture_contents.cc +++ b/impeller/entity/contents/tiled_texture_contents.cc @@ -128,7 +128,7 @@ bool TiledTextureContents::Render(const ContentContext& renderer, bool is_external_texture = texture_->GetTextureDescriptor().type == TextureType::kTextureExternalOES; - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto geometry_result = GetGeometry()->GetPositionUVBuffer( Rect::MakeSize(texture_size), GetInverseEffectTransform(), renderer, diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 37885ac371fe1..46ff686220c1b 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -121,7 +121,7 @@ bool VerticesUVContents::Render(const ContentContext& renderer, Command cmd; DEBUG_COMMAND_INFO(cmd, "VerticesUV"); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto geometry = parent_.GetGeometry(); auto coverage = src_contents->GetCoverage(Entity{}); @@ -175,7 +175,7 @@ bool VerticesColorContents::Render(const ContentContext& renderer, Command cmd; DEBUG_COMMAND_INFO(cmd, "VerticesColors"); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto geometry = parent_.GetGeometry(); auto geometry_result = diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index 495b038273b68..67e343de8a6d5 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -304,6 +304,10 @@ bool EntityPass::Render(ContentContext& renderer, renderer.GetContext()->capture.GetDocument(kCaptureDocumentName); renderer.GetRenderTargetCache()->Start(); + fml::ScopedCleanupClosure reset_state([&renderer]() { + renderer.GetLazyGlyphAtlas()->ResetTextFrames(); + renderer.GetRenderTargetCache()->End(); + }); auto root_render_target = render_target; @@ -317,11 +321,6 @@ bool EntityPass::Render(ContentContext& renderer, Rect::MakeSize(root_render_target.GetRenderTargetSize()), {.readonly = true}); - fml::ScopedCleanupClosure reset_state([&renderer]() { - renderer.GetLazyGlyphAtlas()->ResetTextFrames(); - renderer.GetRenderTargetCache()->End(); - }); - IterateAllEntities([lazy_glyph_atlas = renderer.GetLazyGlyphAtlas()](const Entity& entity) { if (const auto& contents = entity.GetContents()) { diff --git a/impeller/entity/entity_playground.cc b/impeller/entity/entity_playground.cc index 3763cac125780..d74e177e2e382 100644 --- a/impeller/entity/entity_playground.cc +++ b/impeller/entity/entity_playground.cc @@ -53,6 +53,7 @@ bool EntityPlayground::OpenPlaygroundHere(Entity entity) { content_context->GetRenderTargetCache()->Start(); bool result = entity.Render(*content_context, pass); content_context->GetRenderTargetCache()->End(); + content_context->GetTransientsBuffer().Reset(); return result; }; return Playground::OpenPlaygroundHere(callback); @@ -76,6 +77,7 @@ bool EntityPlayground::OpenPlaygroundHere(EntityPlaygroundCallback callback) { content_context.GetRenderTargetCache()->Start(); bool result = callback(content_context, pass); content_context.GetRenderTargetCache()->End(); + content_context.GetTransientsBuffer().Reset(); return result; }; return Playground::OpenPlaygroundHere(pass_callback); diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 4cfc06fbb7987..452cf7ba38ebb 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -881,13 +881,13 @@ TEST_P(EntityTest, BlendingModeOptions) { options.primitive_type = PrimitiveType::kTriangle; cmd.pipeline = context.GetSolidFillPipeline(options); cmd.BindVertices( - vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer())); + vtx_builder.CreateVertexBuffer(context.GetTransientsBuffer())); VS::FrameInfo frame_info; frame_info.mvp = pass.GetOrthographicTransform() * world_matrix; frame_info.color = color.Premultiply(); - VS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo( + cmd, context.GetTransientsBuffer().EmplaceUniform(frame_info)); return pass.AddCommand(std::move(cmd)); }; diff --git a/impeller/entity/geometry/circle_geometry.cc b/impeller/entity/geometry/circle_geometry.cc index 908485a811924..bd9aa8c796378 100644 --- a/impeller/entity/geometry/circle_geometry.cc +++ b/impeller/entity/geometry/circle_geometry.cc @@ -41,7 +41,7 @@ GeometryResult CircleGeometry::GetPositionBuffer(const ContentContext& renderer, auto generator = tessellator->StrokedCircle(transform, center_, radius_, half_width); - return ComputePositionGeometry(generator, entity, pass); + return ComputePositionGeometry(renderer, generator, entity, pass); } // |Geometry| @@ -65,7 +65,8 @@ GeometryResult CircleGeometry::GetPositionUVBuffer( auto generator = tessellator->StrokedCircle(transform, center_, radius_, half_width); - return ComputePositionUVGeometry(generator, uv_transform, entity, pass); + return ComputePositionUVGeometry(renderer, generator, uv_transform, entity, + pass); } GeometryVertexType CircleGeometry::GetVertexType() const { diff --git a/impeller/entity/geometry/cover_geometry.cc b/impeller/entity/geometry/cover_geometry.cc index bae1b8d034b81..29518da1efbfc 100644 --- a/impeller/entity/geometry/cover_geometry.cc +++ b/impeller/entity/geometry/cover_geometry.cc @@ -15,7 +15,7 @@ GeometryResult CoverGeometry::GetPositionBuffer(const ContentContext& renderer, RenderPass& pass) const { auto rect = Rect::MakeSize(pass.GetRenderTargetSize()); constexpr uint16_t kRectIndicies[4] = {0, 1, 2, 3}; - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); return GeometryResult{ .type = PrimitiveType::kTriangleStrip, .vertex_buffer = diff --git a/impeller/entity/geometry/ellipse_geometry.cc b/impeller/entity/geometry/ellipse_geometry.cc index ef4438e6ede67..b0d21324b437e 100644 --- a/impeller/entity/geometry/ellipse_geometry.cc +++ b/impeller/entity/geometry/ellipse_geometry.cc @@ -17,6 +17,7 @@ GeometryResult EllipseGeometry::GetPositionBuffer( const Entity& entity, RenderPass& pass) const { return ComputePositionGeometry( + renderer, renderer.GetTessellator()->FilledEllipse(entity.GetTransform(), bounds_), entity, pass); } @@ -29,6 +30,7 @@ GeometryResult EllipseGeometry::GetPositionUVBuffer( const Entity& entity, RenderPass& pass) const { return ComputePositionUVGeometry( + renderer, renderer.GetTessellator()->FilledEllipse(entity.GetTransform(), bounds_), texture_coverage.GetNormalizingTransform() * effect_transform, entity, pass); diff --git a/impeller/entity/geometry/fill_path_geometry.cc b/impeller/entity/geometry/fill_path_geometry.cc index 6365f4123903a..a906a661636de 100644 --- a/impeller/entity/geometry/fill_path_geometry.cc +++ b/impeller/entity/geometry/fill_path_geometry.cc @@ -14,7 +14,7 @@ GeometryResult FillPathGeometry::GetPositionBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); VertexBuffer vertex_buffer; if (path_.GetFillType() == FillType::kNonZero && // @@ -94,7 +94,7 @@ GeometryResult FillPathGeometry::GetPositionUVBuffer( return GeometryResult{ .type = PrimitiveType::kTriangleStrip, .vertex_buffer = - vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer()), + vertex_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()), .transform = pass.GetOrthographicTransform() * entity.GetTransform(), .prevent_overdraw = false, }; @@ -127,7 +127,7 @@ GeometryResult FillPathGeometry::GetPositionUVBuffer( return GeometryResult{ .type = PrimitiveType::kTriangle, .vertex_buffer = - vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer()), + vertex_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()), .transform = pass.GetOrthographicTransform() * entity.GetTransform(), .prevent_overdraw = false, }; diff --git a/impeller/entity/geometry/geometry.cc b/impeller/entity/geometry/geometry.cc index 9d32e883e0c65..c29ceb13c31b1 100644 --- a/impeller/entity/geometry/geometry.cc +++ b/impeller/entity/geometry/geometry.cc @@ -7,6 +7,7 @@ #include #include +#include "impeller/entity/contents/content_context.h" #include "impeller/entity/geometry/circle_geometry.h" #include "impeller/entity/geometry/cover_geometry.h" #include "impeller/entity/geometry/ellipse_geometry.h" @@ -21,6 +22,7 @@ namespace impeller { GeometryResult Geometry::ComputePositionGeometry( + const ContentContext& renderer, const Tessellator::VertexGenerator& generator, const Entity& entity, RenderPass& pass) { @@ -32,7 +34,7 @@ GeometryResult Geometry::ComputePositionGeometry( .type = generator.GetTriangleType(), .vertex_buffer = { - .vertex_buffer = pass.GetTransientsBuffer().Emplace( + .vertex_buffer = renderer.GetTransientsBuffer().Emplace( count * sizeof(VT), alignof(VT), [&generator](uint8_t* buffer) { auto vertices = reinterpret_cast(buffer); @@ -53,6 +55,7 @@ GeometryResult Geometry::ComputePositionGeometry( } GeometryResult Geometry::ComputePositionUVGeometry( + const ContentContext& renderer, const Tessellator::VertexGenerator& generator, const Matrix& uv_transform, const Entity& entity, @@ -65,7 +68,7 @@ GeometryResult Geometry::ComputePositionUVGeometry( .type = generator.GetTriangleType(), .vertex_buffer = { - .vertex_buffer = pass.GetTransientsBuffer().Emplace( + .vertex_buffer = renderer.GetTransientsBuffer().Emplace( count * sizeof(VT), alignof(VT), [&generator, &uv_transform](uint8_t* buffer) { auto vertices = reinterpret_cast(buffer); @@ -114,7 +117,7 @@ GeometryResult ComputeUVGeometryForRect(Rect source_rect, const ContentContext& renderer, const Entity& entity, RenderPass& pass) { - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto uv_transform = texture_coverage.GetNormalizingTransform() * effect_transform; diff --git a/impeller/entity/geometry/geometry.h b/impeller/entity/geometry/geometry.h index a958f8e5aacaa..685820fe9ed6b 100644 --- a/impeller/entity/geometry/geometry.h +++ b/impeller/entity/geometry/geometry.h @@ -123,11 +123,13 @@ class Geometry { protected: static GeometryResult ComputePositionGeometry( + const ContentContext& renderer, const Tessellator::VertexGenerator& generator, const Entity& entity, RenderPass& pass); static GeometryResult ComputePositionUVGeometry( + const ContentContext& renderer, const Tessellator::VertexGenerator& generator, const Matrix& uv_transform, const Entity& entity, diff --git a/impeller/entity/geometry/line_geometry.cc b/impeller/entity/geometry/line_geometry.cc index 0036278f765db..80b166bd3d056 100644 --- a/impeller/entity/geometry/line_geometry.cc +++ b/impeller/entity/geometry/line_geometry.cc @@ -75,7 +75,7 @@ GeometryResult LineGeometry::GetPositionBuffer(const ContentContext& renderer, if (cap_ == Cap::kRound) { std::shared_ptr tessellator = renderer.GetTessellator(); auto generator = tessellator->RoundCapLine(transform, p0_, p1_, radius); - return ComputePositionGeometry(generator, entity, pass); + return ComputePositionGeometry(renderer, generator, entity, pass); } Point corners[4]; @@ -83,7 +83,7 @@ GeometryResult LineGeometry::GetPositionBuffer(const ContentContext& renderer, return kEmptyResult; } - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); size_t count = 4; BufferView vertex_buffer = host_buffer.Emplace( @@ -115,7 +115,7 @@ GeometryResult LineGeometry::GetPositionUVBuffer(Rect texture_coverage, const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); using VT = TextureFillVertexShader::PerVertexData; auto& transform = entity.GetTransform(); @@ -127,7 +127,8 @@ GeometryResult LineGeometry::GetPositionUVBuffer(Rect texture_coverage, if (cap_ == Cap::kRound) { std::shared_ptr tessellator = renderer.GetTessellator(); auto generator = tessellator->RoundCapLine(transform, p0_, p1_, radius); - return ComputePositionUVGeometry(generator, uv_transform, entity, pass); + return ComputePositionUVGeometry(renderer, generator, uv_transform, entity, + pass); } Point corners[4]; diff --git a/impeller/entity/geometry/point_field_geometry.cc b/impeller/entity/geometry/point_field_geometry.cc index fcd986de8e522..2b7a1af87bf2f 100644 --- a/impeller/entity/geometry/point_field_geometry.cc +++ b/impeller/entity/geometry/point_field_geometry.cc @@ -26,7 +26,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer( return {}; } - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); return { .type = PrimitiveType::kTriangleStrip, .vertex_buffer = vtx_builder->CreateVertexBuffer(host_buffer), @@ -54,7 +54,7 @@ GeometryResult PointFieldGeometry::GetPositionUVBuffer( ComputeUVGeometryCPU(vtx_builder.value(), {0, 0}, texture_coverage.GetSize(), effect_transform); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); return { .type = PrimitiveType::kTriangleStrip, .vertex_buffer = uv_vtx_builder.CreateVertexBuffer(host_buffer), @@ -152,7 +152,7 @@ GeometryResult PointFieldGeometry::GetPositionBufferGPU( auto cmd_buffer = renderer.GetContext()->CreateCommandBuffer(); auto compute_pass = cmd_buffer->CreateComputePass(); - auto& host_buffer = compute_pass->GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto points_data = host_buffer.Emplace(points_.data(), points_.size() * sizeof(Point), diff --git a/impeller/entity/geometry/rect_geometry.cc b/impeller/entity/geometry/rect_geometry.cc index 1f9336ec50030..000e834bb4018 100644 --- a/impeller/entity/geometry/rect_geometry.cc +++ b/impeller/entity/geometry/rect_geometry.cc @@ -11,7 +11,7 @@ RectGeometry::RectGeometry(Rect rect) : rect_(rect) {} GeometryResult RectGeometry::GetPositionBuffer(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); return GeometryResult{ .type = PrimitiveType::kTriangleStrip, .vertex_buffer = diff --git a/impeller/entity/geometry/round_rect_geometry.cc b/impeller/entity/geometry/round_rect_geometry.cc index b8f3883033049..28cf77d9798ec 100644 --- a/impeller/entity/geometry/round_rect_geometry.cc +++ b/impeller/entity/geometry/round_rect_geometry.cc @@ -17,7 +17,8 @@ GeometryResult RoundRectGeometry::GetPositionBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - return ComputePositionGeometry(renderer.GetTessellator()->FilledRoundRect( + return ComputePositionGeometry(renderer, + renderer.GetTessellator()->FilledRoundRect( entity.GetTransform(), bounds_, radii_), entity, pass); } @@ -30,6 +31,7 @@ GeometryResult RoundRectGeometry::GetPositionUVBuffer( const Entity& entity, RenderPass& pass) const { return ComputePositionUVGeometry( + renderer, renderer.GetTessellator()->FilledRoundRect(entity.GetTransform(), bounds_, radii_), texture_coverage.GetNormalizingTransform() * effect_transform, entity, diff --git a/impeller/entity/geometry/stroke_path_geometry.cc b/impeller/entity/geometry/stroke_path_geometry.cc index 4b0b5258308b3..87eca5da815bf 100644 --- a/impeller/entity/geometry/stroke_path_geometry.cc +++ b/impeller/entity/geometry/stroke_path_geometry.cc @@ -451,7 +451,7 @@ GeometryResult StrokePathGeometry::GetPositionBuffer( Scalar min_size = 1.0f / sqrt(std::abs(determinant)); Scalar stroke_width = std::max(stroke_width_, min_size); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto vertex_builder = CreateSolidStrokeVertices( path_, stroke_width, miter_limit_ * stroke_width_ * 0.5, GetJoinProc(stroke_join_), GetCapProc(stroke_cap_), @@ -482,7 +482,7 @@ GeometryResult StrokePathGeometry::GetPositionUVBuffer( Scalar min_size = 1.0f / sqrt(std::abs(determinant)); Scalar stroke_width = std::max(stroke_width_, min_size); - auto& host_buffer = pass.GetTransientsBuffer(); + auto& host_buffer = renderer.GetTransientsBuffer(); auto stroke_builder = CreateSolidStrokeVertices( path_, stroke_width, miter_limit_ * stroke_width_ * 0.5, GetJoinProc(stroke_join_), GetCapProc(stroke_cap_), diff --git a/impeller/entity/inline_pass_context.cc b/impeller/entity/inline_pass_context.cc index a1904b743bce8..b8295c2cb444a 100644 --- a/impeller/entity/inline_pass_context.cc +++ b/impeller/entity/inline_pass_context.cc @@ -6,9 +6,9 @@ #include +#include "impeller/base/allocation.h" #include "impeller/base/validation.h" #include "impeller/core/formats.h" -#include "impeller/core/texture_descriptor.h" #include "impeller/entity/entity_pass_target.h" #include "impeller/renderer/command_buffer.h" diff --git a/impeller/fixtures/dart_tests.dart b/impeller/fixtures/dart_tests.dart index 19596fed70375..8105f04b2e5ce 100644 --- a/impeller/fixtures/dart_tests.dart +++ b/impeller/fixtures/dart_tests.dart @@ -21,7 +21,7 @@ void instantiateDefaultContext() { @pragma('vm:entry-point') void canEmplaceHostBuffer() { - final gpu.HostBuffer hostBuffer = gpu.HostBuffer(); + final gpu.HostBuffer hostBuffer = gpu.HostBuffer(gpu.gpuContext); final gpu.BufferView view0 = hostBuffer .emplace(Int8List.fromList([0, 1, 2, 3]).buffer.asByteData()); @@ -216,7 +216,7 @@ void uniformBindFailsForInvalidHostBufferOffset() { final gpu.RenderPipeline pipeline = createUnlitRenderPipeline(); encoder.bindPipeline(pipeline); - final gpu.HostBuffer transients = gpu.HostBuffer(); + final gpu.HostBuffer transients = gpu.HostBuffer(gpu.gpuContext); final gpu.BufferView vertInfoData = transients.emplace(float32([ 1, 0, 0, 0, // mvp 0, 1, 0, 0, // mvp @@ -262,7 +262,7 @@ void canCreateRenderPassAndSubmit() { encoder.setColorBlendEnable(true); encoder.setColorBlendEquation(gpu.ColorBlendEquation()); - final gpu.HostBuffer transients = gpu.HostBuffer(); + final gpu.HostBuffer transients = gpu.HostBuffer(gpu.gpuContext); final gpu.BufferView vertices = transients.emplace(float32([ -0.5, -0.5, // 0.5, 0.5, // diff --git a/impeller/playground/imgui/imgui_impl_impeller.cc b/impeller/playground/imgui/imgui_impl_impeller.cc index 990f2c6b102c6..6d61f369f197e 100644 --- a/impeller/playground/imgui/imgui_impl_impeller.cc +++ b/impeller/playground/imgui/imgui_impl_impeller.cc @@ -9,6 +9,8 @@ #include #include +#include "impeller/core/host_buffer.h" +#include "impeller/core/platform.h" #include "impeller/geometry/scalar.h" #include "impeller/geometry/vector.h" #include "impeller/playground/imgui/imgui_raster.frag.h" @@ -123,6 +125,8 @@ void ImGui_ImplImpeller_RenderDrawData(ImDrawData* draw_data, if (draw_data->CmdListsCount == 0) { return; // Nothing to render. } + auto host_buffer = impeller::HostBuffer::Create( + render_pass.GetContext().lock()->GetResourceAllocator()); using VS = impeller::ImguiRasterVertexShader; using FS = impeller::ImguiRasterFragmentShader; @@ -156,8 +160,7 @@ void ImGui_ImplImpeller_RenderDrawData(ImDrawData* draw_data, VS::UniformBuffer uniforms; uniforms.mvp = impeller::Matrix::MakeOrthographic(display_rect.GetSize()) .Translate(-display_rect.GetOrigin()); - auto vtx_uniforms = - render_pass.GetTransientsBuffer().EmplaceUniform(uniforms); + auto vtx_uniforms = host_buffer->EmplaceUniform(uniforms); size_t vertex_buffer_offset = 0; size_t index_buffer_offset = total_vtx_bytes; @@ -269,4 +272,5 @@ void ImGui_ImplImpeller_RenderDrawData(ImDrawData* draw_data, vertex_buffer_offset += draw_list_vtx_bytes; index_buffer_offset += draw_list_idx_bytes; } + host_buffer->Reset(); } diff --git a/impeller/renderer/BUILD.gn b/impeller/renderer/BUILD.gn index 8d6a2061f9e59..6b17817b849f3 100644 --- a/impeller/renderer/BUILD.gn +++ b/impeller/renderer/BUILD.gn @@ -125,7 +125,6 @@ impeller_component("renderer_unittests") { "blit_pass_unittests.cc", "capabilities_unittests.cc", "device_buffer_unittests.cc", - "host_buffer_unittests.cc", "pipeline_descriptor_unittests.cc", "pool_unittests.cc", "renderer_unittests.cc", diff --git a/impeller/renderer/backend/gles/buffer_bindings_gles.cc b/impeller/renderer/backend/gles/buffer_bindings_gles.cc index 899cbbb5b7224..168053efdbdd9 100644 --- a/impeller/renderer/backend/gles/buffer_bindings_gles.cc +++ b/impeller/renderer/backend/gles/buffer_bindings_gles.cc @@ -232,8 +232,7 @@ bool BufferBindingsGLES::BindUniformBuffer(const ProcTableGLES& gl, Allocator& transients_allocator, const BufferResource& buffer) { const auto* metadata = buffer.GetMetadata(); - auto device_buffer = - buffer.resource.buffer->GetDeviceBuffer(transients_allocator); + auto device_buffer = buffer.resource.buffer->GetDeviceBuffer(); if (!device_buffer) { VALIDATION_LOG << "Device buffer not found."; return false; diff --git a/impeller/renderer/backend/gles/context_gles.h b/impeller/renderer/backend/gles/context_gles.h index a81b10ec75fb3..3b1d19870263d 100644 --- a/impeller/renderer/backend/gles/context_gles.h +++ b/impeller/renderer/backend/gles/context_gles.h @@ -5,9 +5,6 @@ #ifndef FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_CONTEXT_GLES_H_ #define FLUTTER_IMPELLER_RENDERER_BACKEND_GLES_CONTEXT_GLES_H_ -#include -#include -#include "flutter/fml/macros.h" #include "impeller/base/backend_cast.h" #include "impeller/renderer/backend/gles/allocator_gles.h" #include "impeller/renderer/backend/gles/capabilities_gles.h" diff --git a/impeller/renderer/backend/gles/device_buffer_gles.cc b/impeller/renderer/backend/gles/device_buffer_gles.cc index 0ba29c1b67e31..3cbc9ea5139d9 100644 --- a/impeller/renderer/backend/gles/device_buffer_gles.cc +++ b/impeller/renderer/backend/gles/device_buffer_gles.cc @@ -57,6 +57,10 @@ bool DeviceBufferGLES::OnCopyHostBuffer(const uint8_t* source, return true; } +void DeviceBufferGLES::Flush(std::optional range) const { + generation_++; +} + static GLenum ToTarget(DeviceBufferGLES::BindingType type) { switch (type) { case DeviceBufferGLES::BindingType::kArrayBuffer: diff --git a/impeller/renderer/backend/gles/device_buffer_gles.h b/impeller/renderer/backend/gles/device_buffer_gles.h index 8aee746127fea..932a2df69bef0 100644 --- a/impeller/renderer/backend/gles/device_buffer_gles.h +++ b/impeller/renderer/backend/gles/device_buffer_gles.h @@ -8,7 +8,6 @@ #include #include -#include "flutter/fml/macros.h" #include "impeller/base/allocation.h" #include "impeller/base/backend_cast.h" #include "impeller/core/device_buffer.h" @@ -39,6 +38,8 @@ class DeviceBufferGLES final [[nodiscard]] bool BindAndUploadDataIfNecessary(BindingType type) const; + void Flush(std::optional range = std::nullopt) const override; + private: ReactorGLES::Ref reactor_; HandleGLES handle_; diff --git a/impeller/renderer/backend/gles/render_pass_gles.cc b/impeller/renderer/backend/gles/render_pass_gles.cc index 7209050f64b2b..c13dbb196f627 100644 --- a/impeller/renderer/backend/gles/render_pass_gles.cc +++ b/impeller/renderer/backend/gles/render_pass_gles.cc @@ -386,8 +386,7 @@ struct RenderPassData { return false; } - auto vertex_buffer = - vertex_buffer_view.buffer->GetDeviceBuffer(*transients_allocator); + auto vertex_buffer = vertex_buffer_view.buffer->GetDeviceBuffer(); if (!vertex_buffer) { return false; @@ -446,8 +445,7 @@ struct RenderPassData { } else { // Bind the index buffer if necessary. auto index_buffer_view = command.vertex_buffer.index_buffer; - auto index_buffer = - index_buffer_view.buffer->GetDeviceBuffer(*transients_allocator); + auto index_buffer = index_buffer_view.buffer->GetDeviceBuffer(); const auto& index_buffer_gles = DeviceBufferGLES::Cast(*index_buffer); if (!index_buffer_gles.BindAndUploadDataIfNecessary( DeviceBufferGLES::BindingType::kElementArrayBuffer)) { diff --git a/impeller/renderer/backend/metal/compute_pass_mtl.mm b/impeller/renderer/backend/metal/compute_pass_mtl.mm index 0cbce56c48c31..3f3f7c3fd18e7 100644 --- a/impeller/renderer/backend/metal/compute_pass_mtl.mm +++ b/impeller/renderer/backend/metal/compute_pass_mtl.mm @@ -171,7 +171,7 @@ static bool Bind(ComputePassBindingsCache& pass, return false; } - auto device_buffer = view.buffer->GetDeviceBuffer(allocator); + auto device_buffer = view.buffer->GetDeviceBuffer(); if (!device_buffer) { return false; } diff --git a/impeller/renderer/backend/metal/device_buffer_mtl.h b/impeller/renderer/backend/metal/device_buffer_mtl.h index 93e548895ef8c..936bc449e0a9c 100644 --- a/impeller/renderer/backend/metal/device_buffer_mtl.h +++ b/impeller/renderer/backend/metal/device_buffer_mtl.h @@ -52,6 +52,9 @@ class DeviceBufferMTL final : public DeviceBuffer, // |DeviceBuffer| bool SetLabel(const std::string& label, Range range) override; + // |DeviceBuffer| + void Flush(std::optional range) const override; + DeviceBufferMTL(const DeviceBufferMTL&) = delete; DeviceBufferMTL& operator=(const DeviceBufferMTL&) = delete; diff --git a/impeller/renderer/backend/metal/device_buffer_mtl.mm b/impeller/renderer/backend/metal/device_buffer_mtl.mm index 860e216264975..c2ea8d89ef731 100644 --- a/impeller/renderer/backend/metal/device_buffer_mtl.mm +++ b/impeller/renderer/backend/metal/device_buffer_mtl.mm @@ -78,6 +78,16 @@ return true; } +void DeviceBufferMTL::Flush(std::optional range) const { +#if !FML_OS_IOS + auto flush_range = range.value_or(Range{0, GetDeviceBufferDescriptor().size}); + if (storage_mode_ == MTLStorageModeManaged) { + [buffer_ + didModifyRange:NSMakeRange(flush_range.offset, flush_range.length)]; + } +#endif +} + bool DeviceBufferMTL::SetLabel(const std::string& label) { if (label.empty()) { return false; diff --git a/impeller/renderer/backend/metal/render_pass_mtl.mm b/impeller/renderer/backend/metal/render_pass_mtl.mm index 3f414ad2a6ced..8b22881000def 100644 --- a/impeller/renderer/backend/metal/render_pass_mtl.mm +++ b/impeller/renderer/backend/metal/render_pass_mtl.mm @@ -364,7 +364,7 @@ static bool Bind(PassBindingsCache& pass, return false; } - auto device_buffer = view.buffer->GetDeviceBuffer(allocator); + auto device_buffer = view.buffer->GetDeviceBuffer(); if (!device_buffer) { return false; } @@ -508,7 +508,7 @@ static bool Bind(PassBindingsCache& pass, if (!index_buffer) { return false; } - auto device_buffer = index_buffer->GetDeviceBuffer(*allocator); + auto device_buffer = index_buffer->GetDeviceBuffer(); if (!device_buffer) { return false; } diff --git a/impeller/renderer/backend/vulkan/binding_helpers_vk.cc b/impeller/renderer/backend/vulkan/binding_helpers_vk.cc index 676980689ce65..6a96d0119c059 100644 --- a/impeller/renderer/backend/vulkan/binding_helpers_vk.cc +++ b/impeller/renderer/backend/vulkan/binding_helpers_vk.cc @@ -70,7 +70,7 @@ static bool BindBuffers(const Bindings& bindings, for (const BufferAndUniformSlot& data : bindings.buffers) { const auto& buffer_view = data.view.resource.buffer; - auto device_buffer = buffer_view->GetDeviceBuffer(allocator); + auto device_buffer = buffer_view->GetDeviceBuffer(); if (!device_buffer) { VALIDATION_LOG << "Failed to get device buffer for vertex binding"; return false; diff --git a/impeller/renderer/backend/vulkan/command_encoder_vk.h b/impeller/renderer/backend/vulkan/command_encoder_vk.h index 612c63f213034..4c682e8284884 100644 --- a/impeller/renderer/backend/vulkan/command_encoder_vk.h +++ b/impeller/renderer/backend/vulkan/command_encoder_vk.h @@ -95,6 +95,7 @@ class CommandEncoderVK { std::shared_ptr tracked_objects_; std::shared_ptr queue_; const std::shared_ptr fence_waiter_; + std::shared_ptr host_buffer_; bool is_valid_ = true; void Reset(); diff --git a/impeller/renderer/backend/vulkan/command_pool_vk.cc b/impeller/renderer/backend/vulkan/command_pool_vk.cc index 018a2199882c2..1c5d0dec6c843 100644 --- a/impeller/renderer/backend/vulkan/command_pool_vk.cc +++ b/impeller/renderer/backend/vulkan/command_pool_vk.cc @@ -9,8 +9,9 @@ #include #include "fml/thread_local.h" -#include "fml/trace_event.h" +#include "impeller/renderer/backend/vulkan/context_vk.h" #include "impeller/renderer/backend/vulkan/resource_manager_vk.h" + #include "impeller/renderer/backend/vulkan/vk.h" // IWYU pragma: keep. #include "vulkan/vulkan_structs.hpp" @@ -134,9 +135,10 @@ FML_THREAD_LOCAL fml::ThreadLocalUniquePtr tls_command_pool_map; // Map each context to a list of all thread-local command pools associated // with that context. static Mutex g_all_pools_map_mutex; -static std::unordered_map>> - g_all_pools_map IPLR_GUARDED_BY(g_all_pools_map_mutex); +static std::unordered_map< + const ContextVK*, + std::vector>> g_all_pools_map + IPLR_GUARDED_BY(g_all_pools_map_mutex); // TODO(matanlurey): Return a status_or<> instead of nullptr when we have one. std::shared_ptr CommandPoolRecyclerVK::Get() { diff --git a/impeller/renderer/backend/vulkan/command_pool_vk.h b/impeller/renderer/backend/vulkan/command_pool_vk.h index 6fb1bcadcd3e2..4db6c098c98ae 100644 --- a/impeller/renderer/backend/vulkan/command_pool_vk.h +++ b/impeller/renderer/backend/vulkan/command_pool_vk.h @@ -8,9 +8,8 @@ #include #include #include -#include "fml/macros.h" + #include "impeller/base/thread.h" -#include "impeller/renderer/backend/vulkan/context_vk.h" #include "impeller/renderer/backend/vulkan/vk.h" // IWYU pragma: keep. namespace impeller { @@ -67,8 +66,8 @@ class CommandPoolVK final { std::weak_ptr& context_; // Used to retain a reference on these until the pool is reset. - std::vector collected_buffers_ - IPLR_GUARDED_BY(pool_mutex_); + std::vector collected_buffers_ IPLR_GUARDED_BY( + pool_mutex_); }; //------------------------------------------------------------------------------ diff --git a/impeller/renderer/backend/vulkan/context_vk.h b/impeller/renderer/backend/vulkan/context_vk.h index 2bb9927dca65d..ac059ebed237c 100644 --- a/impeller/renderer/backend/vulkan/context_vk.h +++ b/impeller/renderer/backend/vulkan/context_vk.h @@ -8,7 +8,6 @@ #include #include "flutter/fml/concurrent_message_loop.h" -#include "flutter/fml/macros.h" #include "flutter/fml/mapping.h" #include "flutter/fml/unique_fd.h" #include "fml/thread.h" diff --git a/impeller/renderer/backend/vulkan/device_buffer_vk.cc b/impeller/renderer/backend/vulkan/device_buffer_vk.cc index 483bfab7c2f7f..9aec90beb3038 100644 --- a/impeller/renderer/backend/vulkan/device_buffer_vk.cc +++ b/impeller/renderer/backend/vulkan/device_buffer_vk.cc @@ -5,6 +5,8 @@ #include "impeller/renderer/backend/vulkan/device_buffer_vk.h" #include "flutter/fml/trace_event.h" +#include "impeller/renderer/backend/vulkan/context_vk.h" +#include "vulkan/vulkan_core.h" namespace impeller { @@ -62,6 +64,13 @@ bool DeviceBufferVK::SetLabel(const std::string& label) { label); } +void DeviceBufferVK::Flush(std::optional range) const { + auto flush_range = range.value_or(Range{0, GetDeviceBufferDescriptor().size}); + ::vmaFlushAllocation(resource_->buffer.get().allocator, + resource_->buffer.get().allocation, flush_range.offset, + flush_range.length); +} + bool DeviceBufferVK::SetLabel(const std::string& label, Range range) { // We do not have the ability to name ranges. Just name the whole thing. return SetLabel(label); diff --git a/impeller/renderer/backend/vulkan/device_buffer_vk.h b/impeller/renderer/backend/vulkan/device_buffer_vk.h index c2e617dff3b8f..33182c52f31af 100644 --- a/impeller/renderer/backend/vulkan/device_buffer_vk.h +++ b/impeller/renderer/backend/vulkan/device_buffer_vk.h @@ -7,11 +7,8 @@ #include -#include "flutter/fml/macros.h" -#include "flutter/fml/trace_event.h" #include "impeller/base/backend_cast.h" #include "impeller/core/device_buffer.h" -#include "impeller/renderer/backend/vulkan/context_vk.h" #include "impeller/renderer/backend/vulkan/resource_manager_vk.h" #include "impeller/renderer/backend/vulkan/vma.h" @@ -69,6 +66,9 @@ class DeviceBufferVK final : public DeviceBuffer, // |DeviceBuffer| bool SetLabel(const std::string& label, Range range) override; + // |DeviceBuffer| + void Flush(std::optional range) const override; + DeviceBufferVK(const DeviceBufferVK&) = delete; DeviceBufferVK& operator=(const DeviceBufferVK&) = delete; diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.cc b/impeller/renderer/backend/vulkan/render_pass_vk.cc index bf0a54e9cefa3..67066c0878d0c 100644 --- a/impeller/renderer/backend/vulkan/render_pass_vk.cc +++ b/impeller/renderer/backend/vulkan/render_pass_vk.cc @@ -410,7 +410,7 @@ static bool EncodeCommand(const Context& context, } auto& allocator = *context.GetResourceAllocator(); - auto vertex_buffer = vertex_buffer_view.buffer->GetDeviceBuffer(allocator); + auto vertex_buffer = vertex_buffer_view.buffer->GetDeviceBuffer(); if (!vertex_buffer) { VALIDATION_LOG << "Failed to acquire device buffer" @@ -435,7 +435,7 @@ static bool EncodeCommand(const Context& context, return false; } - auto index_buffer = index_buffer_view.buffer->GetDeviceBuffer(allocator); + auto index_buffer = index_buffer_view.buffer->GetDeviceBuffer(); if (!index_buffer) { VALIDATION_LOG << "Failed to acquire device buffer" << " for index buffer view"; diff --git a/impeller/renderer/backend/vulkan/surface_context_vk.h b/impeller/renderer/backend/vulkan/surface_context_vk.h index 5c8a327685dba..0394d45c9650f 100644 --- a/impeller/renderer/backend/vulkan/surface_context_vk.h +++ b/impeller/renderer/backend/vulkan/surface_context_vk.h @@ -8,6 +8,7 @@ #include #include "impeller/base/backend_cast.h" +#include "impeller/core/host_buffer.h" #include "impeller/renderer/backend/vulkan/vk.h" #include "impeller/renderer/context.h" diff --git a/impeller/renderer/blit_pass.cc b/impeller/renderer/blit_pass.cc index e521a6a6543ca..81c4e500b0494 100644 --- a/impeller/renderer/blit_pass.cc +++ b/impeller/renderer/blit_pass.cc @@ -9,24 +9,17 @@ #include "impeller/base/strings.h" #include "impeller/base/validation.h" #include "impeller/core/formats.h" -#include "impeller/core/host_buffer.h" -#include "impeller/renderer/blit_command.h" namespace impeller { -BlitPass::BlitPass() : transients_buffer_(HostBuffer::Create()) {} +BlitPass::BlitPass() {} BlitPass::~BlitPass() = default; -HostBuffer& BlitPass::GetTransientsBuffer() { - return *transients_buffer_; -} - void BlitPass::SetLabel(std::string label) { if (label.empty()) { return; } - transients_buffer_->SetLabel(SPrintF("%s Transients", label.c_str())); OnSetLabel(std::move(label)); } diff --git a/impeller/renderer/blit_pass.h b/impeller/renderer/blit_pass.h index 61f53b49dc5f1..64ab734c1035b 100644 --- a/impeller/renderer/blit_pass.h +++ b/impeller/renderer/blit_pass.h @@ -6,11 +6,9 @@ #define FLUTTER_IMPELLER_RENDERER_BLIT_PASS_H_ #include -#include #include "impeller/core/device_buffer.h" #include "impeller/core/texture.h" -#include "impeller/renderer/blit_command.h" namespace impeller { @@ -33,8 +31,6 @@ class BlitPass { void SetLabel(std::string label); - HostBuffer& GetTransientsBuffer(); - //---------------------------------------------------------------------------- /// @brief Record a command to copy the contents of one texture to /// another texture. The blit area is limited by the intersection @@ -128,8 +124,6 @@ class BlitPass { const std::shared_ptr& transients_allocator) const = 0; protected: - std::shared_ptr transients_buffer_; - explicit BlitPass(); virtual void OnSetLabel(std::string label) = 0; diff --git a/impeller/renderer/compute_pass.cc b/impeller/renderer/compute_pass.cc index 95478f964acf9..8446fffdc53a2 100644 --- a/impeller/renderer/compute_pass.cc +++ b/impeller/renderer/compute_pass.cc @@ -5,26 +5,20 @@ #include "impeller/renderer/compute_pass.h" #include -#include "impeller/base/strings.h" +#include "fml/logging.h" #include "impeller/base/validation.h" -#include "impeller/core/host_buffer.h" namespace impeller { ComputePass::ComputePass(std::weak_ptr context) - : context_(std::move(context)), transients_buffer_(HostBuffer::Create()) {} + : context_(std::move(context)) {} ComputePass::~ComputePass() = default; -HostBuffer& ComputePass::GetTransientsBuffer() { - return *transients_buffer_; -} - void ComputePass::SetLabel(const std::string& label) { if (label.empty()) { return; } - transients_buffer_->SetLabel(SPrintF("%s Transients", label.c_str())); OnSetLabel(label); } diff --git a/impeller/renderer/compute_pass.h b/impeller/renderer/compute_pass.h index bd32e6f4713af..4ba6e802c3275 100644 --- a/impeller/renderer/compute_pass.h +++ b/impeller/renderer/compute_pass.h @@ -32,8 +32,6 @@ class ComputePass { void SetThreadGroupSize(const ISize& size); - HostBuffer& GetTransientsBuffer(); - //---------------------------------------------------------------------------- /// @brief Record a command for subsequent encoding to the underlying /// command buffer. No work is encoded into the command buffer at diff --git a/impeller/renderer/compute_subgroup_unittests.cc b/impeller/renderer/compute_subgroup_unittests.cc index 3d2f5798967a7..e93bec3b28f0f 100644 --- a/impeller/renderer/compute_subgroup_unittests.cc +++ b/impeller/renderer/compute_subgroup_unittests.cc @@ -12,6 +12,7 @@ #include "gmock/gmock.h" #include "impeller/base/strings.h" #include "impeller/core/formats.h" +#include "impeller/core/host_buffer.h" #include "impeller/display_list/skia_conversions.h" #include "impeller/entity/contents/content_context.h" #include "impeller/fixtures/golden_paths.h" @@ -88,11 +89,12 @@ TEST_P(ComputeSubgroupTest, PathPlayground) { auto future = promise.get_future(); auto path = skia_conversions::ToPath(sk_path); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); auto status = ComputeTessellator{} .SetStrokeWidth(stroke_width) .Tessellate( - path, context, vertex_buffer->AsBufferView(), + path, *host_buffer, context, vertex_buffer->AsBufferView(), vertex_buffer_count->AsBufferView(), [vertex_buffer_count, &vertex_count, &promise](CommandBuffer::Status status) { @@ -162,8 +164,8 @@ TEST_P(ComputeSubgroupTest, PathPlayground) { auto world_matrix = Matrix::MakeScale(GetContentScale()); frame_info.mvp = pass.GetOrthographicTransform() * world_matrix; frame_info.color = Color::Red().Premultiply(); - VS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo( + cmd, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; @@ -316,22 +318,22 @@ TEST_P(ComputeSubgroupTest, LargePath) { ::memset(vertex_buffer->AsBufferView().contents, 0, sizeof(SS::VertexBuffer<2048>)); + ContentContext renderer(context, nullptr); + if (!renderer.IsValid()) { + return false; + } + ComputeTessellator{} .SetStrokeWidth(stroke_width) .Tessellate( - complex_path, context, vertex_buffer->AsBufferView(), - vertex_buffer_count->AsBufferView(), + complex_path, renderer.GetTransientsBuffer(), context, + vertex_buffer->AsBufferView(), vertex_buffer_count->AsBufferView(), [vertex_buffer_count, &vertex_count](CommandBuffer::Status status) { vertex_count = reinterpret_cast( vertex_buffer_count->AsBufferView().contents) ->count; }); - ContentContext renderer(context, nullptr); - if (!renderer.IsValid()) { - return false; - } - using VS = SolidFillPipeline::VertexShader; Command cmd; @@ -364,8 +366,8 @@ TEST_P(ComputeSubgroupTest, LargePath) { auto world_matrix = Matrix::MakeScale(GetContentScale()); frame_info.mvp = pass.GetOrthographicTransform() * world_matrix; frame_info.color = Color::Red().Premultiply(); - VS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo( + cmd, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; @@ -398,8 +400,9 @@ TEST_P(ComputeSubgroupTest, QuadAndCubicInOnePath) { fml::AutoResetWaitableEvent latch; + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); auto status = tessellator.Tessellate( - path, context, vertex_buffer->AsBufferView(), + path, *host_buffer, context, vertex_buffer->AsBufferView(), vertex_buffer_count->AsBufferView(), [&latch](CommandBuffer::Status status) { EXPECT_EQ(status, CommandBuffer::Status::kCompleted); @@ -446,8 +449,8 @@ TEST_P(ComputeSubgroupTest, QuadAndCubicInOnePath) { auto world_matrix = Matrix::MakeScale(GetContentScale()); frame_info.mvp = pass.GetOrthographicTransform() * world_matrix; frame_info.color = Color::Red().Premultiply(); - VS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo( + cmd, renderer.GetTransientsBuffer().EmplaceUniform(frame_info)); if (!pass.AddCommand(std::move(cmd))) { return false; diff --git a/impeller/renderer/compute_tessellator.cc b/impeller/renderer/compute_tessellator.cc index 87f27fc88f31b..1c6a22f2d77da 100644 --- a/impeller/renderer/compute_tessellator.cc +++ b/impeller/renderer/compute_tessellator.cc @@ -62,6 +62,7 @@ ComputeTessellator& ComputeTessellator::SetQuadraticTolerance(Scalar value) { ComputeTessellator::Status ComputeTessellator::Tessellate( const Path& path, + HostBuffer& host_buffer, const std::shared_ptr& context, BufferView vertex_buffer, BufferView vertex_buffer_count, @@ -127,13 +128,11 @@ ComputeTessellator::Status ComputeTessellator::Tessellate( DEBUG_COMMAND_INFO(cmd, "Generate Polyline"); cmd.pipeline = compute_pipeline; - PS::BindConfig(cmd, pass->GetTransientsBuffer().EmplaceUniform(config)); - PS::BindCubics(cmd, - pass->GetTransientsBuffer().EmplaceStorageBuffer(cubics)); - PS::BindQuads(cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(quads)); - PS::BindLines(cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(lines)); - PS::BindComponents( - cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(components)); + PS::BindConfig(cmd, host_buffer.EmplaceUniform(config)); + PS::BindCubics(cmd, host_buffer.EmplaceStorageBuffer(cubics)); + PS::BindQuads(cmd, host_buffer.EmplaceStorageBuffer(quads)); + PS::BindLines(cmd, host_buffer.EmplaceStorageBuffer(lines)); + PS::BindComponents(cmd, host_buffer.EmplaceStorageBuffer(components)); PS::BindPolyline(cmd, polyline_buffer->AsBufferView()); if (!pass->AddCommand(std::move(cmd))) { @@ -163,7 +162,7 @@ ComputeTessellator::Status ComputeTessellator::Tessellate( .join = static_cast(stroke_join_), .miter_limit = miter_limit_, }; - SS::BindConfig(cmd, pass->GetTransientsBuffer().EmplaceUniform(config)); + SS::BindConfig(cmd, host_buffer.EmplaceUniform(config)); SS::BindPolyline(cmd, polyline_buffer->AsBufferView()); SS::BindVertexBufferCount(cmd, std::move(vertex_buffer_count)); diff --git a/impeller/renderer/compute_tessellator.h b/impeller/renderer/compute_tessellator.h index f8ccd0d8dfe2a..0dc6b56bc1e76 100644 --- a/impeller/renderer/compute_tessellator.h +++ b/impeller/renderer/compute_tessellator.h @@ -65,6 +65,7 @@ class ComputeTessellator { // and heap allocated buffers on Metal. Status Tessellate( const Path& path, + HostBuffer& host_buffer, const std::shared_ptr& context, BufferView vertex_buffer, BufferView vertex_buffer_count, diff --git a/impeller/renderer/compute_unittests.cc b/impeller/renderer/compute_unittests.cc index bcaeff41bb924..03eb2686806d5 100644 --- a/impeller/renderer/compute_unittests.cc +++ b/impeller/renderer/compute_unittests.cc @@ -8,6 +8,7 @@ #include "gmock/gmock.h" #include "impeller/base/strings.h" #include "impeller/core/formats.h" +#include "impeller/core/host_buffer.h" #include "impeller/fixtures/sample.comp.h" #include "impeller/fixtures/stage1.comp.h" #include "impeller/fixtures/stage2.comp.h" @@ -35,6 +36,7 @@ TEST_P(ComputeTest, CapabilitiesReportSupport) { TEST_P(ComputeTest, CanCreateComputePass) { using CS = SampleComputeShader; auto context = GetContext(); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -74,11 +76,9 @@ TEST_P(ComputeTest, CanCreateComputePass) { auto output_buffer = CreateHostVisibleDeviceBuffer>( context, "Output Buffer"); - CS::BindInfo(cmd, pass->GetTransientsBuffer().EmplaceUniform(info)); - CS::BindInput0(cmd, - pass->GetTransientsBuffer().EmplaceStorageBuffer(input_0)); - CS::BindInput1(cmd, - pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1)); + CS::BindInfo(cmd, host_buffer->EmplaceUniform(info)); + CS::BindInput0(cmd, host_buffer->EmplaceStorageBuffer(input_0)); + CS::BindInput1(cmd, host_buffer->EmplaceStorageBuffer(input_1)); CS::BindOutput(cmd, output_buffer->AsBufferView()); ASSERT_TRUE(pass->AddCommand(std::move(cmd))); @@ -113,6 +113,7 @@ TEST_P(ComputeTest, CanCreateComputePass) { TEST_P(ComputeTest, CanComputePrefixSum) { using CS = PrefixSumTestComputeShader; auto context = GetContext(); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -145,8 +146,7 @@ TEST_P(ComputeTest, CanComputePrefixSum) { auto output_buffer = CreateHostVisibleDeviceBuffer>( context, "Output Buffer"); - CS::BindInputData( - cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(input_data)); + CS::BindInputData(cmd, host_buffer->EmplaceStorageBuffer(input_data)); CS::BindOutputData(cmd, output_buffer->AsBufferView()); ASSERT_TRUE(pass->AddCommand(std::move(cmd))); @@ -231,6 +231,8 @@ TEST_P(ComputeTest, CanComputePrefixSumLargeInteractive) { using CS = PrefixSumTestComputeShader; auto context = GetContext(); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); + ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -260,12 +262,12 @@ TEST_P(ComputeTest, CanComputePrefixSumLargeInteractive) { auto output_buffer = CreateHostVisibleDeviceBuffer>( context, "Output Buffer"); - CS::BindInputData( - cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(input_data)); + CS::BindInputData(cmd, host_buffer->EmplaceStorageBuffer(input_data)); CS::BindOutputData(cmd, output_buffer->AsBufferView()); pass->AddCommand(std::move(cmd)); pass->EncodeCommands(); + host_buffer->Reset(); return cmd_buffer->SubmitCommands(); }; ASSERT_TRUE(OpenPlaygroundHere(callback)); @@ -278,6 +280,7 @@ TEST_P(ComputeTest, MultiStageInputAndOutput) { using Stage2PipelineBuilder = ComputePipelineBuilder; auto context = GetContext(); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -326,8 +329,7 @@ TEST_P(ComputeTest, MultiStageInputAndOutput) { ComputeCommand cmd; cmd.pipeline = compute_pipeline_1; - CS1::BindInput(cmd, - pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1)); + CS1::BindInput(cmd, host_buffer->EmplaceStorageBuffer(input_1)); CS1::BindOutput(cmd, output_buffer_1->AsBufferView()); ASSERT_TRUE(pass->AddCommand(std::move(cmd))); @@ -373,6 +375,7 @@ TEST_P(ComputeTest, MultiStageInputAndOutput) { TEST_P(ComputeTest, CanCompute1DimensionalData) { using CS = SampleComputeShader; auto context = GetContext(); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -411,11 +414,9 @@ TEST_P(ComputeTest, CanCompute1DimensionalData) { auto output_buffer = CreateHostVisibleDeviceBuffer>( context, "Output Buffer"); - CS::BindInfo(cmd, pass->GetTransientsBuffer().EmplaceUniform(info)); - CS::BindInput0(cmd, - pass->GetTransientsBuffer().EmplaceStorageBuffer(input_0)); - CS::BindInput1(cmd, - pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1)); + CS::BindInfo(cmd, host_buffer->EmplaceUniform(info)); + CS::BindInput0(cmd, host_buffer->EmplaceStorageBuffer(input_0)); + CS::BindInput1(cmd, host_buffer->EmplaceStorageBuffer(input_1)); CS::BindOutput(cmd, output_buffer->AsBufferView()); ASSERT_TRUE(pass->AddCommand(std::move(cmd))); @@ -450,6 +451,7 @@ TEST_P(ComputeTest, CanCompute1DimensionalData) { TEST_P(ComputeTest, ReturnsEarlyWhenAnyGridDimensionIsZero) { using CS = SampleComputeShader; auto context = GetContext(); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); ASSERT_TRUE(context); ASSERT_TRUE(context->GetCapabilities()->SupportsCompute()); @@ -491,11 +493,9 @@ TEST_P(ComputeTest, ReturnsEarlyWhenAnyGridDimensionIsZero) { auto output_buffer = CreateHostVisibleDeviceBuffer>( context, "Output Buffer"); - CS::BindInfo(cmd, pass->GetTransientsBuffer().EmplaceUniform(info)); - CS::BindInput0(cmd, - pass->GetTransientsBuffer().EmplaceStorageBuffer(input_0)); - CS::BindInput1(cmd, - pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1)); + CS::BindInfo(cmd, host_buffer->EmplaceUniform(info)); + CS::BindInput0(cmd, host_buffer->EmplaceStorageBuffer(input_0)); + CS::BindInput1(cmd, host_buffer->EmplaceStorageBuffer(input_1)); CS::BindOutput(cmd, output_buffer->AsBufferView()); ASSERT_TRUE(pass->AddCommand(std::move(cmd))); diff --git a/impeller/renderer/context.h b/impeller/renderer/context.h index 2b76e8f3bfa93..1f80c296e8fc4 100644 --- a/impeller/renderer/context.h +++ b/impeller/renderer/context.h @@ -180,10 +180,6 @@ class Context { /// pending work. virtual void SetSyncPresentation(bool value) {} - //---------------------------------------------------------------------------- - /// @brief Accessor for a pool of HostBuffers. - Pool& GetHostBufferPool() const { return host_buffer_pool_; } - CaptureContext capture; /// Stores a task on the `ContextMTL` that is awaiting access for the GPU. @@ -202,9 +198,9 @@ class Context { protected: Context(); - private: - mutable Pool host_buffer_pool_ = Pool(1'000'000); + std::vector> per_frame_task_; + private: Context(const Context&) = delete; Context& operator=(const Context&) = delete; diff --git a/impeller/renderer/host_buffer_unittests.cc b/impeller/renderer/host_buffer_unittests.cc deleted file mode 100644 index 3046e801b24c0..0000000000000 --- a/impeller/renderer/host_buffer_unittests.cc +++ /dev/null @@ -1,79 +0,0 @@ -// 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/host_buffer.h" - -namespace impeller { -namespace testing { - -TEST(HostBufferTest, TestInitialization) { - ASSERT_TRUE(HostBuffer::Create()); - // Newly allocated buffers don't touch the heap till they have to. - ASSERT_EQ(HostBuffer::Create()->GetLength(), 0u); - ASSERT_EQ(HostBuffer::Create()->GetSize(), 0u); -} - -TEST(HostBufferTest, CanEmplace) { - struct Length2 { - uint8_t pad[2]; - }; - static_assert(sizeof(Length2) == 2u); - - auto buffer = HostBuffer::Create(); - - for (size_t i = 0; i < 12500; i++) { - auto view = buffer->Emplace(Length2{}); - ASSERT_TRUE(view); - ASSERT_EQ(buffer->GetLength(), (i + 1) * sizeof(Length2)); - ASSERT_EQ(view.range, Range(i * sizeof(Length2), 2u)); - } -} - -TEST(HostBufferTest, CanEmplaceWithAlignment) { - struct Length2 { - uint8_t pad[2]; - }; - static_assert(sizeof(Length2) == 2); - struct alignas(16) Align16 { - uint8_t pad[2]; - }; - static_assert(alignof(Align16) == 16); - static_assert(sizeof(Align16) == 16); - - auto buffer = HostBuffer::Create(); - ASSERT_TRUE(buffer); - - { - auto view = buffer->Emplace(Length2{}); - ASSERT_TRUE(view); - ASSERT_EQ(buffer->GetLength(), 2u); - ASSERT_EQ(view.range, 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(buffer->GetLength(), 32u); - } - { - auto view = buffer->Emplace(Length2{}); - ASSERT_TRUE(view); - ASSERT_EQ(buffer->GetLength(), 34u); - ASSERT_EQ(view.range, 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(buffer->GetLength(), 64u); - } -} - -} // namespace testing -} // namespace impeller diff --git a/impeller/renderer/render_pass.cc b/impeller/renderer/render_pass.cc index 8710a397a4320..e8dd476d45134 100644 --- a/impeller/renderer/render_pass.cc +++ b/impeller/renderer/render_pass.cc @@ -14,19 +14,9 @@ RenderPass::RenderPass(std::weak_ptr context, has_stencil_attachment_(target.GetStencilAttachment().has_value()), render_target_size_(target.GetRenderTargetSize()), render_target_(target), - transients_buffer_(), - orthographic_(Matrix::MakeOrthographic(render_target_size_)) { - auto strong_context = context_.lock(); - FML_DCHECK(strong_context); - transients_buffer_ = strong_context->GetHostBufferPool().Grab(); -} + orthographic_(Matrix::MakeOrthographic(render_target_size_)) {} -RenderPass::~RenderPass() { - auto strong_context = context_.lock(); - if (strong_context) { - strong_context->GetHostBufferPool().Recycle(transients_buffer_); - } -} +RenderPass::~RenderPass() {} SampleCount RenderPass::GetSampleCount() const { return sample_count_; @@ -52,15 +42,10 @@ const Matrix& RenderPass::GetOrthographicTransform() const { return orthographic_; } -HostBuffer& RenderPass::GetTransientsBuffer() { - return *transients_buffer_; -} - void RenderPass::SetLabel(std::string label) { if (label.empty()) { return; } - transients_buffer_->SetLabel(SPrintF("%s Transients", label.c_str())); OnSetLabel(std::move(label)); } diff --git a/impeller/renderer/render_pass.h b/impeller/renderer/render_pass.h index 33bb8abd0ddba..3dc4ab943f45d 100644 --- a/impeller/renderer/render_pass.h +++ b/impeller/renderer/render_pass.h @@ -49,8 +49,6 @@ class RenderPass { commands_.reserve(command_count); } - HostBuffer& GetTransientsBuffer(); - //---------------------------------------------------------------------------- /// @brief Record a command for subsequent encoding to the underlying /// command buffer. No work is encoded into the command buffer at @@ -101,7 +99,6 @@ class RenderPass { const bool has_stencil_attachment_; const ISize render_target_size_; const RenderTarget render_target_; - std::shared_ptr transients_buffer_; std::vector commands_; const Matrix orthographic_; diff --git a/impeller/renderer/renderer_unittests.cc b/impeller/renderer/renderer_unittests.cc index c54e213f10caa..f63ee2a263615 100644 --- a/impeller/renderer/renderer_unittests.cc +++ b/impeller/renderer/renderer_unittests.cc @@ -6,6 +6,7 @@ #include "impeller/core/device_buffer_descriptor.h" #include "impeller/core/formats.h" +#include "impeller/core/host_buffer.h" #include "impeller/core/sampler_descriptor.h" #include "impeller/fixtures/array.frag.h" #include "impeller/fixtures/array.vert.h" @@ -70,6 +71,8 @@ TEST_P(RendererTest, CanCreateBoxPrimitive) { ASSERT_TRUE(bridge && boston); auto sampler = context->GetSamplerLibrary()->GetSampler({}); ASSERT_TRUE(sampler); + + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); SinglePassCallback callback = [&](RenderPass& pass) { ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize); static bool wireframe; @@ -93,8 +96,7 @@ TEST_P(RendererTest, CanCreateBoxPrimitive) { Matrix::MakeOrthographic(pass.GetRenderTargetSize())); uniforms.mvp = pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale()); - VS::BindUniformBuffer(cmd, - pass.GetTransientsBuffer().EmplaceUniform(uniforms)); + VS::BindUniformBuffer(cmd, host_buffer->EmplaceUniform(uniforms)); FS::FrameInfo frame_info; frame_info.current_time = GetSecondsElapsed(); @@ -102,10 +104,11 @@ TEST_P(RendererTest, CanCreateBoxPrimitive) { frame_info.window_size.x = GetWindowSize().width; frame_info.window_size.y = GetWindowSize().height; - FS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + FS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); FS::BindContents1(cmd, boston, sampler); FS::BindContents2(cmd, bridge, sampler); + + host_buffer->Reset(); if (!pass.AddCommand(std::move(cmd))) { return false; } @@ -170,6 +173,7 @@ TEST_P(RendererTest, CanRenderPerspectiveCube) { ASSERT_TRUE(sampler); Vector3 euler_angles; + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); SinglePassCallback callback = [&](RenderPass& pass) { static Degrees fov_y(60); static Scalar distance = 10; @@ -195,8 +199,9 @@ TEST_P(RendererTest, CanRenderPerspectiveCube) { Matrix::MakeRotationX(Radians(euler_angles.x)) * Matrix::MakeRotationY(Radians(euler_angles.y)) * Matrix::MakeRotationZ(Radians(euler_angles.z)); - VS::BindUniformBuffer(cmd, - pass.GetTransientsBuffer().EmplaceUniform(uniforms)); + VS::BindUniformBuffer(cmd, host_buffer->EmplaceUniform(uniforms)); + + host_buffer->Reset(); if (!pass.AddCommand(std::move(cmd))) { return false; } @@ -240,6 +245,7 @@ TEST_P(RendererTest, CanRenderMultiplePrimitives) { auto sampler = context->GetSamplerLibrary()->GetSampler({}); ASSERT_TRUE(sampler); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); SinglePassCallback callback = [&](RenderPass& pass) { Command cmd; DEBUG_COMMAND_INFO(cmd, "Box"); @@ -253,8 +259,7 @@ TEST_P(RendererTest, CanRenderMultiplePrimitives) { frame_info.window_size.x = GetWindowSize().width; frame_info.window_size.y = GetWindowSize().height; - FS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + FS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); FS::BindContents1(cmd, boston, sampler); FS::BindContents2(cmd, bridge, sampler); @@ -266,14 +271,14 @@ TEST_P(RendererTest, CanRenderMultiplePrimitives) { uniforms.mvp = pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale()) * Matrix::MakeTranslation({i * 50.0f, j * 50.0f, 0.0f}); - VS::BindUniformBuffer( - cmd, pass.GetTransientsBuffer().EmplaceUniform(uniforms)); + VS::BindUniformBuffer(cmd, host_buffer->EmplaceUniform(uniforms)); if (!pass.AddCommand(std::move(cmd))) { return false; } } } + host_buffer->Reset(); return true; }; OpenPlaygroundHere(callback); @@ -293,6 +298,7 @@ TEST_P(RendererTest, CanRenderToTexture) { auto box_pipeline = context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get(); ASSERT_TRUE(box_pipeline); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); VertexBufferBuilder vertex_builder; vertex_builder.SetLabel("Box"); @@ -369,16 +375,14 @@ TEST_P(RendererTest, CanRenderToTexture) { frame_info.window_size.x = GetWindowSize().width; frame_info.window_size.y = GetWindowSize().height; - FS::BindFrameInfo(cmd, - r2t_pass->GetTransientsBuffer().EmplaceUniform(frame_info)); + FS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); FS::BindContents1(cmd, boston, sampler); FS::BindContents2(cmd, bridge, sampler); VS::UniformBuffer uniforms; uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) * Matrix::MakeTranslation({50.0f, 50.0f, 0.0f}); - VS::BindUniformBuffer( - cmd, r2t_pass->GetTransientsBuffer().EmplaceUniform(uniforms)); + VS::BindUniformBuffer(cmd, host_buffer->EmplaceUniform(uniforms)); ASSERT_TRUE(r2t_pass->AddCommand(std::move(cmd))); ASSERT_TRUE(r2t_pass->EncodeCommands()); } @@ -433,20 +437,21 @@ TEST_P(RendererTest, CanRenderInstanced) { instances.colors[i] = Color::Random(); } + auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator()); ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool { VS::FrameInfo frame_info; EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(pass.GetRenderTargetSize())); frame_info.mvp = pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale()); - VS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frame_info)); - VS::BindInstanceInfo( - cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(instances)); - cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer())); + VS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); + VS::BindInstanceInfo(cmd, host_buffer->EmplaceStorageBuffer(instances)); + cmd.BindVertices(builder.CreateVertexBuffer(*host_buffer)); cmd.instance_count = kInstancesCount; pass.AddCommand(std::move(cmd)); + + host_buffer->Reset(); return true; })); } @@ -498,6 +503,7 @@ TEST_P(RendererTest, CanBlitTextureToTexture) { vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()); ASSERT_TRUE(vertex_buffer); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); Renderer::RenderCallback callback = [&](RenderTarget& render_target) { auto buffer = context->CreateCommandBuffer(); if (!buffer) { @@ -542,13 +548,11 @@ TEST_P(RendererTest, CanBlitTextureToTexture) { Matrix::MakeOrthographic(pass->GetRenderTargetSize())); frame_info.mvp = pass->GetOrthographicTransform() * Matrix::MakeScale(GetContentScale()); - VS::BindFrameInfo( - cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); FS::FragInfo frag_info; frag_info.lod = 0; - FS::BindFragInfo(cmd, - pass->GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, host_buffer->EmplaceUniform(frag_info)); auto sampler = context->GetSamplerLibrary()->GetSampler({}); FS::BindTex(cmd, texture, sampler); @@ -561,6 +565,7 @@ TEST_P(RendererTest, CanBlitTextureToTexture) { if (!buffer->SubmitCommands()) { return false; } + host_buffer->Reset(); return true; }; OpenPlaygroundHere(callback); @@ -618,6 +623,7 @@ TEST_P(RendererTest, CanBlitTextureToBuffer) { vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()); ASSERT_TRUE(vertex_buffer); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); Renderer::RenderCallback callback = [&](RenderTarget& render_target) { { auto buffer = context->CreateCommandBuffer(); @@ -669,13 +675,11 @@ TEST_P(RendererTest, CanBlitTextureToBuffer) { Matrix::MakeOrthographic(pass->GetRenderTargetSize())); frame_info.mvp = pass->GetOrthographicTransform() * Matrix::MakeScale(GetContentScale()); - VS::BindFrameInfo( - cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); FS::FragInfo frag_info; frag_info.lod = 0; - FS::BindFragInfo(cmd, - pass->GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, host_buffer->EmplaceUniform(frag_info)); auto sampler = context->GetSamplerLibrary()->GetSampler({}); auto buffer_view = device_buffer->AsBufferView(); @@ -695,6 +699,7 @@ TEST_P(RendererTest, CanBlitTextureToBuffer) { return false; } } + host_buffer->Reset(); return true; }; OpenPlaygroundHere(callback); @@ -734,6 +739,7 @@ TEST_P(RendererTest, CanGenerateMipmaps) { ASSERT_TRUE(vertex_buffer); bool first_frame = true; + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); Renderer::RenderCallback callback = [&](RenderTarget& render_target) { const char* mip_filter_names[] = {"Nearest", "Linear"}; const MipFilter mip_filters[] = {MipFilter::kNearest, MipFilter::kLinear}; @@ -792,13 +798,11 @@ TEST_P(RendererTest, CanGenerateMipmaps) { Matrix::MakeOrthographic(pass->GetRenderTargetSize())); frame_info.mvp = pass->GetOrthographicTransform() * Matrix::MakeScale(GetContentScale()); - VS::BindFrameInfo( - cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); FS::FragInfo frag_info; frag_info.lod = lod; - FS::BindFragInfo(cmd, - pass->GetTransientsBuffer().EmplaceUniform(frag_info)); + FS::BindFragInfo(cmd, host_buffer->EmplaceUniform(frag_info)); SamplerDescriptor sampler_desc; sampler_desc.mip_filter = mip_filters[selected_mip_filter]; @@ -814,6 +818,7 @@ TEST_P(RendererTest, CanGenerateMipmaps) { if (!buffer->SubmitCommands()) { return false; } + host_buffer->Reset(); return true; }; OpenPlaygroundHere(callback); @@ -845,6 +850,7 @@ TEST_P(RendererTest, TheImpeller) { "table_mountain_py.png", "table_mountain_ny.png", "table_mountain_pz.png", "table_mountain_nz.png"}); auto cube_map_sampler = context->GetSamplerLibrary()->GetSampler({}); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); SinglePassCallback callback = [&](RenderPass& pass) { auto size = pass.GetRenderTargetSize(); @@ -859,23 +865,22 @@ TEST_P(RendererTest, TheImpeller) { {Point(size.width, 0)}, {Point(0, size.height)}, {Point(size.width, size.height)}}); - cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer())); + cmd.BindVertices(builder.CreateVertexBuffer(*host_buffer)); VS::FrameInfo frame_info; EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size)); frame_info.mvp = pass.GetOrthographicTransform(); - VS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); FS::FragInfo fs_uniform; fs_uniform.texture_size = Point(size); fs_uniform.time = GetSecondsElapsed(); - FS::BindFragInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(fs_uniform)); + FS::BindFragInfo(cmd, host_buffer->EmplaceUniform(fs_uniform)); FS::BindBlueNoise(cmd, blue_noise, noise_sampler); FS::BindCubeMap(cmd, cube_map, cube_map_sampler); pass.AddCommand(std::move(cmd)); + host_buffer->Reset(); return true; }; OpenPlaygroundHere(callback); @@ -895,6 +900,7 @@ TEST_P(RendererTest, ArrayUniforms) { context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get(); ASSERT_TRUE(pipeline && pipeline->IsValid()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); SinglePassCallback callback = [&](RenderPass& pass) { auto size = pass.GetRenderTargetSize(); @@ -908,14 +914,13 @@ TEST_P(RendererTest, ArrayUniforms) { {Point(size.width, 0)}, {Point(0, size.height)}, {Point(size.width, size.height)}}); - cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer())); + cmd.BindVertices(builder.CreateVertexBuffer(*host_buffer)); VS::FrameInfo frame_info; EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size)); frame_info.mvp = pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale()); - VS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); auto time = GetSecondsElapsed(); auto y_pos = [&time](float x) { @@ -930,10 +935,10 @@ TEST_P(RendererTest, ArrayUniforms) { Color::MakeRGBA8(244, 180, 0, 255), Color::MakeRGBA8(15, 157, 88, 255)}, }; - FS::BindFragInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(fs_uniform)); + FS::BindFragInfo(cmd, host_buffer->EmplaceUniform(fs_uniform)); pass.AddCommand(std::move(cmd)); + host_buffer->Reset(); return true; }; OpenPlaygroundHere(callback); @@ -953,6 +958,7 @@ TEST_P(RendererTest, InactiveUniforms) { context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get(); ASSERT_TRUE(pipeline && pipeline->IsValid()); + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); SinglePassCallback callback = [&](RenderPass& pass) { auto size = pass.GetRenderTargetSize(); @@ -966,21 +972,20 @@ TEST_P(RendererTest, InactiveUniforms) { {Point(size.width, 0)}, {Point(0, size.height)}, {Point(size.width, size.height)}}); - cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer())); + cmd.BindVertices(builder.CreateVertexBuffer(*host_buffer)); VS::FrameInfo frame_info; EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size)); frame_info.mvp = pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale()); - VS::BindFrameInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + VS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); FS::FragInfo fs_uniform = {.unused_color = Color::Red(), .color = Color::Green()}; - FS::BindFragInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(fs_uniform)); + FS::BindFragInfo(cmd, host_buffer->EmplaceUniform(fs_uniform)); pass.AddCommand(std::move(cmd)); + host_buffer->Reset(); return true; }; OpenPlaygroundHere(callback); @@ -1153,6 +1158,8 @@ TEST_P(RendererTest, StencilMask) { CompareFunctionUI().IndexOf(CompareFunction::kLessEqual); static int current_back_compare = CompareFunctionUI().IndexOf(CompareFunction::kLessEqual); + + auto host_buffer = HostBuffer::Create(context->GetResourceAllocator()); Renderer::RenderCallback callback = [&](RenderTarget& render_target) { auto buffer = context->CreateCommandBuffer(); if (!buffer) { @@ -1238,8 +1245,7 @@ TEST_P(RendererTest, StencilMask) { if (mirror) { uniforms.mvp = Matrix::MakeScale(Vector2(-1, 1)) * uniforms.mvp; } - VS::BindUniformBuffer( - cmd, pass->GetTransientsBuffer().EmplaceUniform(uniforms)); + VS::BindUniformBuffer(cmd, host_buffer->EmplaceUniform(uniforms)); FS::FrameInfo frame_info; frame_info.current_time = GetSecondsElapsed(); @@ -1247,8 +1253,7 @@ TEST_P(RendererTest, StencilMask) { frame_info.window_size.x = GetWindowSize().width; frame_info.window_size.y = GetWindowSize().height; - FS::BindFrameInfo(cmd, - pass->GetTransientsBuffer().EmplaceUniform(frame_info)); + FS::BindFrameInfo(cmd, host_buffer->EmplaceUniform(frame_info)); FS::BindContents1(cmd, boston, sampler); FS::BindContents2(cmd, bridge, sampler); if (!pass->AddCommand(std::move(cmd))) { @@ -1260,6 +1265,7 @@ TEST_P(RendererTest, StencilMask) { if (!buffer->SubmitCommands()) { return false; } + host_buffer->Reset(); return true; }; OpenPlaygroundHere(callback); diff --git a/impeller/scene/scene.cc b/impeller/scene/scene.cc index ca7202afb04b4..172e1c1e4a067 100644 --- a/impeller/scene/scene.cc +++ b/impeller/scene/scene.cc @@ -8,6 +8,7 @@ #include #include "flutter/fml/logging.h" +#include "fml/closure.h" #include "impeller/renderer/render_target.h" #include "impeller/scene/scene_context.h" #include "impeller/scene/scene_encoder.h" @@ -32,6 +33,9 @@ Node& Scene::GetRoot() { bool Scene::Render(const RenderTarget& render_target, const Matrix& camera_transform) { + fml::ScopedCleanupClosure reset_state( + [context = scene_context_]() { context->GetTransientsBuffer().Reset(); }); + // Collect the render commands from the scene. SceneEncoder encoder; if (!root_.Render(encoder, diff --git a/impeller/scene/scene_context.cc b/impeller/scene/scene_context.cc index baece932832a2..c4637837b3644 100644 --- a/impeller/scene/scene_context.cc +++ b/impeller/scene/scene_context.cc @@ -4,6 +4,7 @@ #include "impeller/scene/scene_context.h" #include "impeller/core/formats.h" +#include "impeller/core/host_buffer.h" #include "impeller/scene/material.h" #include "impeller/scene/shaders/skinned.vert.h" #include "impeller/scene/shaders/unlit.frag.h" @@ -80,7 +81,7 @@ SceneContext::SceneContext(std::shared_ptr context) return; } } - + host_buffer_ = HostBuffer::Create(GetContext()->GetResourceAllocator()); is_valid_ = true; } diff --git a/impeller/scene/scene_context.h b/impeller/scene/scene_context.h index 24d49249f7ac0..4c99e99867213 100644 --- a/impeller/scene/scene_context.h +++ b/impeller/scene/scene_context.h @@ -7,6 +7,7 @@ #include +#include "impeller/core/host_buffer.h" #include "impeller/renderer/context.h" #include "impeller/renderer/pipeline.h" #include "impeller/renderer/pipeline_descriptor.h" @@ -53,6 +54,8 @@ class SceneContext { std::shared_ptr GetPlaceholderTexture() const; + HostBuffer& GetTransientsBuffer() const { return *host_buffer_; } + private: class PipelineVariants { public: @@ -144,6 +147,7 @@ class SceneContext { // A 1x1 opaque white texture that can be used as a placeholder binding. // Available for the lifetime of the scene context std::shared_ptr placeholder_texture_; + std::shared_ptr host_buffer_; SceneContext(const SceneContext&) = delete; diff --git a/impeller/scene/scene_encoder.cc b/impeller/scene/scene_encoder.cc index e0572ffdb6971..43c9c85af8caa 100644 --- a/impeller/scene/scene_encoder.cc +++ b/impeller/scene/scene_encoder.cc @@ -24,7 +24,7 @@ static void EncodeCommand(const SceneContext& scene_context, const Matrix& view_transform, RenderPass& render_pass, const SceneCommand& scene_command) { - auto& host_buffer = render_pass.GetTransientsBuffer(); + auto& host_buffer = scene_context.GetTransientsBuffer(); Command cmd; DEBUG_COMMAND_INFO(cmd, scene_command.label); diff --git a/impeller/scene/skin.cc b/impeller/scene/skin.cc index b3ea96993a6e7..ffabd8253b243 100644 --- a/impeller/scene/skin.cc +++ b/impeller/scene/skin.cc @@ -6,10 +6,10 @@ #include #include -#include #include #include "flutter/fml/logging.h" +#include "impeller/base/allocation.h" #include "impeller/core/allocator.h" #include "impeller/scene/importer/conversions.h" diff --git a/lib/gpu/device_buffer.h b/lib/gpu/device_buffer.h index 707d01f150ba4..a2b262b3795c9 100644 --- a/lib/gpu/device_buffer.h +++ b/lib/gpu/device_buffer.h @@ -8,7 +8,7 @@ #include "flutter/lib/gpu/context.h" #include "flutter/lib/gpu/export.h" #include "flutter/lib/ui/dart_wrapper.h" -#include "impeller/core/device_buffer_descriptor.h" + #include "third_party/tonic/typed_data/dart_byte_data.h" namespace flutter { diff --git a/lib/gpu/host_buffer.cc b/lib/gpu/host_buffer.cc index e7600e8d98592..6d76464c6c787 100644 --- a/lib/gpu/host_buffer.cc +++ b/lib/gpu/host_buffer.cc @@ -4,6 +4,9 @@ #include "flutter/lib/gpu/host_buffer.h" +#include + +#include "dart_api.h" #include "impeller/core/host_buffer.h" #include "impeller/core/platform.h" #include "third_party/tonic/typed_data/dart_byte_data.h" @@ -13,7 +16,9 @@ namespace gpu { IMPLEMENT_WRAPPERTYPEINFO(flutter_gpu, HostBuffer); -HostBuffer::HostBuffer() : host_buffer_(impeller::HostBuffer::Create()) {} +HostBuffer::HostBuffer(Context* context) + : host_buffer_(impeller::HostBuffer::Create( + context->GetContext()->GetResourceAllocator())) {} HostBuffer::~HostBuffer() = default; @@ -42,8 +47,9 @@ std::optional HostBuffer::GetBufferViewForOffset( /// Exports /// -void InternalFlutterGpu_HostBuffer_Initialize(Dart_Handle wrapper) { - auto res = fml::MakeRefCounted(); +void InternalFlutterGpu_HostBuffer_Initialize(Dart_Handle wrapper, + flutter::gpu::Context* context) { + auto res = fml::MakeRefCounted(context); res->AssociateWithDartWrapper(wrapper); } diff --git a/lib/gpu/host_buffer.h b/lib/gpu/host_buffer.h index 7b25f5182c721..75d33c739ac39 100644 --- a/lib/gpu/host_buffer.h +++ b/lib/gpu/host_buffer.h @@ -9,6 +9,7 @@ #include "flutter/lib/ui/dart_wrapper.h" #include "impeller/core/buffer_view.h" #include "impeller/core/host_buffer.h" +#include "lib/gpu/context.h" #include "third_party/tonic/typed_data/dart_byte_data.h" namespace flutter { @@ -19,7 +20,7 @@ class HostBuffer : public RefCountedDartWrappable { FML_FRIEND_MAKE_REF_COUNTED(HostBuffer); public: - explicit HostBuffer(); + explicit HostBuffer(Context* context); ~HostBuffer() override; diff --git a/lib/gpu/lib/src/buffer.dart b/lib/gpu/lib/src/buffer.dart index 0e0edd7b50132..abed1a7a04949 100644 --- a/lib/gpu/lib/src/buffer.dart +++ b/lib/gpu/lib/src/buffer.dart @@ -135,8 +135,8 @@ base class DeviceBuffer extends NativeFieldWrapperClass1 with Buffer { /// and automatically inserts padding between emplaced data if necessary. base class HostBuffer extends NativeFieldWrapperClass1 with Buffer { /// Creates a new HostBuffer. - HostBuffer() { - _initialize(); + HostBuffer(GpuContext gpuContext) { + _initialize(gpuContext); } @override @@ -161,9 +161,9 @@ base class HostBuffer extends NativeFieldWrapperClass1 with Buffer { } /// Wrap with native counterpart. - @Native( + @Native( symbol: 'InternalFlutterGpu_HostBuffer_Initialize') - external void _initialize(); + external void _initialize(GpuContext gpuContext); /// Append byte data to the end of the [HostBuffer] and produce a [BufferView] /// that references the new data in the buffer. diff --git a/shell/gpu/gpu_surface_gl_impeller.cc b/shell/gpu/gpu_surface_gl_impeller.cc index 19e2669c997a2..53c457bdda6a4 100644 --- a/shell/gpu/gpu_surface_gl_impeller.cc +++ b/shell/gpu/gpu_surface_gl_impeller.cc @@ -122,7 +122,8 @@ std::unique_ptr GPUSurfaceGLImpeller::AcquireFrame( fml::MakeCopyable( [aiks_context, picture = std::move(picture)]( impeller::RenderTarget& render_target) -> bool { - return aiks_context->Render(picture, render_target); + return aiks_context->Render(picture, render_target, + /*reset_host_buffer=*/true); })); }); diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index 94302399c8481..e08587ef64461 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -163,7 +163,7 @@ std::move(surface), fml::MakeCopyable([aiks_context, picture = std::move(picture)]( impeller::RenderTarget& render_target) -> bool { - return aiks_context->Render(picture, render_target); + return aiks_context->Render(picture, render_target, /*reset_host_buffer=*/true); })); }); @@ -257,12 +257,12 @@ display_list->Dispatch(impeller_dispatcher, sk_cull_rect); auto picture = impeller_dispatcher.EndRecordingAsPicture(); - bool render_result = - renderer->Render(std::move(surface), - fml::MakeCopyable([aiks_context, picture = std::move(picture)]( - impeller::RenderTarget& render_target) -> bool { - return aiks_context->Render(picture, render_target); - })); + bool render_result = renderer->Render( + std::move(surface), + fml::MakeCopyable([aiks_context, picture = std::move(picture)]( + impeller::RenderTarget& render_target) -> bool { + return aiks_context->Render(picture, render_target, /*reset_host_buffer=*/true); + })); if (!render_result) { FML_LOG(ERROR) << "Failed to render Impeller frame"; return false; diff --git a/shell/gpu/gpu_surface_vulkan_impeller.cc b/shell/gpu/gpu_surface_vulkan_impeller.cc index 917b5f0e6e11d..cf2733baab5ea 100644 --- a/shell/gpu/gpu_surface_vulkan_impeller.cc +++ b/shell/gpu/gpu_surface_vulkan_impeller.cc @@ -94,7 +94,8 @@ std::unique_ptr GPUSurfaceVulkanImpeller::AcquireFrame( fml::MakeCopyable( [aiks_context, picture = std::move(picture)]( impeller::RenderTarget& render_target) -> bool { - return aiks_context->Render(picture, render_target); + return aiks_context->Render(picture, render_target, + /*reset_host_buffer=*/true); })); }); diff --git a/shell/platform/embedder/embedder_external_view.cc b/shell/platform/embedder/embedder_external_view.cc index 23ecd22415424..592b89f9fdba2 100644 --- a/shell/platform/embedder/embedder_external_view.cc +++ b/shell/platform/embedder/embedder_external_view.cc @@ -107,7 +107,7 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target, auto dispatcher = impeller::DlDispatcher(); dispatcher.drawDisplayList(dl_builder.Build(), 1); return aiks_context->Render(dispatcher.EndRecordingAsPicture(), - *impeller_target); + *impeller_target, /*reset_host_buffer=*/true); } #endif // IMPELLER_SUPPORTS_RENDERING