From 167150a45f235e342085bbd33feea16969a0753c Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Tue, 29 Jun 2021 14:02:06 -0700 Subject: [PATCH] Make device resident vertex buffers easier to use. --- .../src/flutter/impeller/compositor/BUILD.gn | 2 + .../flutter/impeller/compositor/buffer_view.h | 2 +- .../src/flutter/impeller/compositor/context.h | 11 ++++ .../flutter/impeller/compositor/context.mm | 10 ++++ .../impeller/compositor/device_buffer.h | 3 + .../impeller/compositor/device_buffer.mm | 7 +++ .../impeller/compositor/vertex_buffer.h | 21 +++++++ .../impeller/compositor/vertex_buffer.mm | 11 ++++ .../compositor/vertex_buffer_builder.h | 55 ++++++++++++++++--- .../flutter/impeller/entity/entity_renderer.h | 2 + .../impeller/entity/entity_renderer.mm | 29 ++++++---- 11 files changed, 133 insertions(+), 20 deletions(-) create mode 100644 engine/src/flutter/impeller/compositor/vertex_buffer.h create mode 100644 engine/src/flutter/impeller/compositor/vertex_buffer.mm diff --git a/engine/src/flutter/impeller/compositor/BUILD.gn b/engine/src/flutter/impeller/compositor/BUILD.gn index 5fa6a67aa16..ebb93652f2c 100644 --- a/engine/src/flutter/impeller/compositor/BUILD.gn +++ b/engine/src/flutter/impeller/compositor/BUILD.gn @@ -52,6 +52,8 @@ impeller_component("compositor") { "surface.mm", "texture.h", "texture.mm", + "vertex_buffer.h", + "vertex_buffer.mm", "vertex_buffer_builder.h", "vertex_buffer_builder.mm", "vertex_descriptor.h", diff --git a/engine/src/flutter/impeller/compositor/buffer_view.h b/engine/src/flutter/impeller/compositor/buffer_view.h index aa07cf30cef..835d8e134ff 100644 --- a/engine/src/flutter/impeller/compositor/buffer_view.h +++ b/engine/src/flutter/impeller/compositor/buffer_view.h @@ -11,7 +11,7 @@ namespace impeller { struct BufferView { - std::shared_ptr buffer; + std::shared_ptr buffer; Range range; constexpr operator bool() const { return static_cast(buffer); } diff --git a/engine/src/flutter/impeller/compositor/context.h b/engine/src/flutter/impeller/compositor/context.h index 77dd15a8260..5d40a251b46 100644 --- a/engine/src/flutter/impeller/compositor/context.h +++ b/engine/src/flutter/impeller/compositor/context.h @@ -25,6 +25,16 @@ class Context { bool IsValid() const; + //---------------------------------------------------------------------------- + /// @return An allocator suitable for allocations that persist between + /// frames. + /// + std::shared_ptr GetPermanentsAllocator() const; + + //---------------------------------------------------------------------------- + /// @return An allocator suitable for allocations that used only for one + /// frame or render pass. + /// std::shared_ptr GetTransientsAllocator() const; std::shared_ptr GetShaderLibrary() const; @@ -39,6 +49,7 @@ class Context { id transfer_queue_ = nullptr; std::shared_ptr shader_library_; std::shared_ptr pipeline_library_; + std::shared_ptr permanents_allocator_; std::shared_ptr transients_allocator_; bool is_valid_ = false; diff --git a/engine/src/flutter/impeller/compositor/context.mm b/engine/src/flutter/impeller/compositor/context.mm index 2ec6cb2fbe6..4b222b013a5 100644 --- a/engine/src/flutter/impeller/compositor/context.mm +++ b/engine/src/flutter/impeller/compositor/context.mm @@ -61,6 +61,12 @@ Context::Context(std::string shaders_directory) if (!transients_allocator_) { return; } + + permanents_allocator_ = std::shared_ptr( + new Allocator(device_, "Impeller Permanents Allocator")); + if (!permanents_allocator_) { + return; + } } is_valid_ = true; @@ -93,6 +99,10 @@ std::shared_ptr Context::CreateRenderCommandBuffer() const { return buffer; } +std::shared_ptr Context::GetPermanentsAllocator() const { + return permanents_allocator_; +} + std::shared_ptr Context::GetTransientsAllocator() const { return transients_allocator_; } diff --git a/engine/src/flutter/impeller/compositor/device_buffer.h b/engine/src/flutter/impeller/compositor/device_buffer.h index b49684a58c6..cb0f9491995 100644 --- a/engine/src/flutter/impeller/compositor/device_buffer.h +++ b/engine/src/flutter/impeller/compositor/device_buffer.h @@ -12,6 +12,7 @@ #include "flutter/fml/macros.h" #include "impeller/compositor/allocator.h" #include "impeller/compositor/buffer.h" +#include "impeller/compositor/buffer_view.h" #include "impeller/compositor/range.h" namespace impeller { @@ -31,6 +32,8 @@ class DeviceBuffer final : public Buffer, bool SetLabel(const std::string& label, Range range); + BufferView AsBufferView() const; + private: friend class Allocator; diff --git a/engine/src/flutter/impeller/compositor/device_buffer.mm b/engine/src/flutter/impeller/compositor/device_buffer.mm index ed089d53472..ff4a1a30888 100644 --- a/engine/src/flutter/impeller/compositor/device_buffer.mm +++ b/engine/src/flutter/impeller/compositor/device_buffer.mm @@ -62,4 +62,11 @@ bool DeviceBuffer::SetLabel(const std::string& label, Range range) { return true; } +BufferView DeviceBuffer::AsBufferView() const { + BufferView view; + view.buffer = shared_from_this(); + view.range = {0u, size_}; + return view; +} + } // namespace impeller diff --git a/engine/src/flutter/impeller/compositor/vertex_buffer.h b/engine/src/flutter/impeller/compositor/vertex_buffer.h new file mode 100644 index 00000000000..be29c5f3d19 --- /dev/null +++ b/engine/src/flutter/impeller/compositor/vertex_buffer.h @@ -0,0 +1,21 @@ +// 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. + +#pragma once + +#include "impeller/compositor/buffer_view.h" + +namespace impeller { + +struct VertexBuffer { + BufferView vertex_buffer; + BufferView index_buffer; + size_t index_count = 0u; + + constexpr operator bool() const { + return static_cast(vertex_buffer) && static_cast(index_buffer); + } +}; + +} // namespace impeller diff --git a/engine/src/flutter/impeller/compositor/vertex_buffer.mm b/engine/src/flutter/impeller/compositor/vertex_buffer.mm new file mode 100644 index 00000000000..62568a5e197 --- /dev/null +++ b/engine/src/flutter/impeller/compositor/vertex_buffer.mm @@ -0,0 +1,11 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/compositor/vertex_buffer.h" + +namespace impeller { + +// + +} // namespace impeller diff --git a/engine/src/flutter/impeller/compositor/vertex_buffer_builder.h b/engine/src/flutter/impeller/compositor/vertex_buffer_builder.h index c809a7758c0..ab490612911 100644 --- a/engine/src/flutter/impeller/compositor/vertex_buffer_builder.h +++ b/engine/src/flutter/impeller/compositor/vertex_buffer_builder.h @@ -9,7 +9,11 @@ #include #include "flutter/fml/macros.h" +#include "impeller/compositor/allocator.h" +#include "impeller/compositor/device_buffer.h" +#include "impeller/compositor/formats.h" #include "impeller/compositor/host_buffer.h" +#include "impeller/compositor/vertex_buffer.h" #include "impeller/geometry/vector.h" namespace impeller { @@ -32,30 +36,67 @@ class VertexBufferBuilder { return *this; } - BufferView CreateVertexBuffer(HostBuffer& buffer) const { + VertexBuffer CreateVertexBuffer(HostBuffer& host) const { + VertexBuffer buffer; + buffer.vertex_buffer = CreateVertexBufferView(host); + buffer.index_buffer = CreateIndexBufferView(host); + buffer.index_count = GetIndexCount(); + return buffer; + }; + + VertexBuffer CreateVertexBuffer(Allocator& device_allocator) const { + VertexBuffer buffer; + // This can be merged into a single allocation. + buffer.vertex_buffer = CreateVertexBufferView(device_allocator); + buffer.index_buffer = CreateIndexBufferView(device_allocator); + buffer.index_count = GetIndexCount(); + return buffer; + }; + + private: + // This is a placeholder till vertex de-duplication can be implemented. The + // current implementation is a very dumb placeholder. + std::vector vertices_; + + BufferView CreateVertexBufferView(HostBuffer& buffer) const { return buffer.Emplace(vertices_.data(), vertices_.size() * sizeof(VertexType), alignof(VertexType)); } - BufferView CreateIndexBuffer(HostBuffer& buffer) const { + BufferView CreateVertexBufferView(Allocator& allocator) const { + auto buffer = allocator.CreateBufferWithCopy( + reinterpret_cast(vertices_.data()), + vertices_.size() * sizeof(VertexType)); + return buffer ? buffer->AsBufferView() : BufferView{}; + } + + std::vector CreateIndexBuffer() const { // So dumb! We don't actually need an index buffer right now. But we will // once de-duplication is done. So assume this is always done. std::vector index_buffer; for (size_t i = 0; i < vertices_.size(); i++) { index_buffer.push_back(i); } + return index_buffer; + } + + BufferView CreateIndexBufferView(HostBuffer& buffer) const { + const auto index_buffer = CreateIndexBuffer(); return buffer.Emplace(index_buffer.data(), index_buffer.size() * sizeof(IndexType), alignof(IndexType)); } - size_t GetIndexCount() const { return vertices_.size(); } + BufferView CreateIndexBufferView(Allocator& allocator) const { + const auto index_buffer = CreateIndexBuffer(); + auto buffer = allocator.CreateBufferWithCopy( + reinterpret_cast(index_buffer.data()), + index_buffer.size() * sizeof(IndexType)); + return buffer ? buffer->AsBufferView() : BufferView{}; + } - private: - // This is a placeholder till vertex de-duplication can be implemented. The - // current implementation is a very dumb placeholder. - std::vector vertices_; + size_t GetIndexCount() const { return vertices_.size(); } }; } // namespace impeller diff --git a/engine/src/flutter/impeller/entity/entity_renderer.h b/engine/src/flutter/impeller/entity/entity_renderer.h index 0d00e6ffe91..bd91dcb6780 100644 --- a/engine/src/flutter/impeller/entity/entity_renderer.h +++ b/engine/src/flutter/impeller/entity/entity_renderer.h @@ -6,6 +6,7 @@ #include "flutter/fml/macros.h" #include "impeller/compositor/renderer.h" +#include "impeller/compositor/vertex_buffer.h" #include "impeller/entity/entity.h" #include "impeller/primitives/box_primitive.h" @@ -20,6 +21,7 @@ class EntityRenderer final : public Renderer { private: std::shared_ptr root_; std::shared_ptr box_primitive_; + VertexBuffer vertex_buffer_; bool is_valid_ = false; // |Renderer| diff --git a/engine/src/flutter/impeller/entity/entity_renderer.mm b/engine/src/flutter/impeller/entity/entity_renderer.mm index 030a790c29f..eb4cbcd3c74 100644 --- a/engine/src/flutter/impeller/entity/entity_renderer.mm +++ b/engine/src/flutter/impeller/entity/entity_renderer.mm @@ -29,6 +29,20 @@ EntityRenderer::EntityRenderer(std::string shaders_directory) return; } + VertexBufferBuilder vertex_builder; + + vertex_builder.AddVertices({ + {{0, 0, 0.0}, {Color::Red()}}, // + {{800, 0.0, 0.0}, {Color::Green()}}, // + {{0.0, 600, 0.0}, {Color::Blue()}}, // + }); + + vertex_buffer_ = + vertex_builder.CreateVertexBuffer(*context->GetPermanentsAllocator()); + if (!vertex_buffer_) { + return; + } + is_valid_ = true; } @@ -45,25 +59,16 @@ bool EntityRenderer::OnRender(const Surface& surface, RenderPass& pass) { uniforms.mvp = Matrix::MakeOrthographic(surface.GetSize()); - VertexBufferBuilder vertex_builder; - - vertex_builder.AddVertices({ - {{0, 0, 0.0}, {Color::Red()}}, // - {{800, 0.0, 0.0}, {Color::Green()}}, // - {{0.0, 600, 0.0}, {Color::Blue()}}, // - }); - Command cmd; cmd.label = "Box"; cmd.pipeline = box_primitive_->GetPipeline(); cmd.vertex_bindings.buffers[box_primitive_->GetVertexBufferIndex()] = - vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer()); + vertex_buffer_.vertex_buffer; cmd.vertex_bindings .buffers[shader::BoxVertexInfo::kUniformUniformBuffer.binding] = pass.GetTransientsBuffer().EmplaceUniform(uniforms); - cmd.index_buffer = - vertex_builder.CreateIndexBuffer(pass.GetTransientsBuffer()); - cmd.index_count = vertex_builder.GetIndexCount(); + cmd.index_buffer = vertex_buffer_.index_buffer; + cmd.index_count = vertex_buffer_.index_count; cmd.primitive_type = PrimitiveType::kTriange; if (!pass.RecordCommand(std::move(cmd))) { return false;