mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Make device resident vertex buffers easier to use.
This commit is contained in:
parent
703a269481
commit
167150a45f
@ -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",
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
namespace impeller {
|
||||
|
||||
struct BufferView {
|
||||
std::shared_ptr<Buffer> buffer;
|
||||
std::shared_ptr<const Buffer> buffer;
|
||||
Range range;
|
||||
|
||||
constexpr operator bool() const { return static_cast<bool>(buffer); }
|
||||
|
||||
@ -25,6 +25,16 @@ class Context {
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @return An allocator suitable for allocations that persist between
|
||||
/// frames.
|
||||
///
|
||||
std::shared_ptr<Allocator> GetPermanentsAllocator() const;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @return An allocator suitable for allocations that used only for one
|
||||
/// frame or render pass.
|
||||
///
|
||||
std::shared_ptr<Allocator> GetTransientsAllocator() const;
|
||||
|
||||
std::shared_ptr<ShaderLibrary> GetShaderLibrary() const;
|
||||
@ -39,6 +49,7 @@ class Context {
|
||||
id<MTLCommandQueue> transfer_queue_ = nullptr;
|
||||
std::shared_ptr<ShaderLibrary> shader_library_;
|
||||
std::shared_ptr<PipelineLibrary> pipeline_library_;
|
||||
std::shared_ptr<Allocator> permanents_allocator_;
|
||||
std::shared_ptr<Allocator> transients_allocator_;
|
||||
bool is_valid_ = false;
|
||||
|
||||
|
||||
@ -61,6 +61,12 @@ Context::Context(std::string shaders_directory)
|
||||
if (!transients_allocator_) {
|
||||
return;
|
||||
}
|
||||
|
||||
permanents_allocator_ = std::shared_ptr<Allocator>(
|
||||
new Allocator(device_, "Impeller Permanents Allocator"));
|
||||
if (!permanents_allocator_) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
is_valid_ = true;
|
||||
@ -93,6 +99,10 @@ std::shared_ptr<CommandBuffer> Context::CreateRenderCommandBuffer() const {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::shared_ptr<Allocator> Context::GetPermanentsAllocator() const {
|
||||
return permanents_allocator_;
|
||||
}
|
||||
|
||||
std::shared_ptr<Allocator> Context::GetTransientsAllocator() const {
|
||||
return transients_allocator_;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
21
engine/src/flutter/impeller/compositor/vertex_buffer.h
Normal file
21
engine/src/flutter/impeller/compositor/vertex_buffer.h
Normal file
@ -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<bool>(vertex_buffer) && static_cast<bool>(index_buffer);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
11
engine/src/flutter/impeller/compositor/vertex_buffer.mm
Normal file
11
engine/src/flutter/impeller/compositor/vertex_buffer.mm
Normal file
@ -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
|
||||
@ -9,7 +9,11 @@
|
||||
#include <vector>
|
||||
|
||||
#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<VertexType> 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<const uint8_t*>(vertices_.data()),
|
||||
vertices_.size() * sizeof(VertexType));
|
||||
return buffer ? buffer->AsBufferView() : BufferView{};
|
||||
}
|
||||
|
||||
std::vector<IndexType> 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<IndexType> 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<const uint8_t*>(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<VertexType> vertices_;
|
||||
size_t GetIndexCount() const { return vertices_.size(); }
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
@ -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<Entity> root_;
|
||||
std::shared_ptr<BoxPrimitive> box_primitive_;
|
||||
VertexBuffer vertex_buffer_;
|
||||
bool is_valid_ = false;
|
||||
|
||||
// |Renderer|
|
||||
|
||||
@ -29,6 +29,20 @@ EntityRenderer::EntityRenderer(std::string shaders_directory)
|
||||
return;
|
||||
}
|
||||
|
||||
VertexBufferBuilder<shader::BoxVertexInfo::PerVertexData> 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<shader::BoxVertexInfo::PerVertexData> 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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user