| Flutter Impeller |

geometry.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "impeller/scene/geometry.h"
6
7 #include <memory>
8 #include <ostream>
9
10 #include "impeller/core/device_buffer_descriptor.h"
11 #include "impeller/core/formats.h"
12 #include "impeller/core/sampler_descriptor.h"
13 #include "impeller/core/vertex_buffer.h"
14 #include "impeller/geometry/point.h"
15 #include "impeller/geometry/vector.h"
16 #include "impeller/renderer/vertex_buffer_builder.h"
17 #include "impeller/scene/importer/scene_flatbuffers.h"
18 #include "impeller/scene/shaders/skinned.vert.h"
19 #include "impeller/scene/shaders/unskinned.vert.h"
20
21 namespace impeller {
22 namespace scene {
23
24 //------------------------------------------------------------------------------
25 /// Geometry
26 ///
27
28 Geometry::~Geometry() = default;
29
30 std::shared_ptr<CuboidGeometry> Geometry::MakeCuboid(Vector3 size) {
31 auto result = std::make_shared<CuboidGeometry>();
32 result->SetSize(size);
33 return result;
34 }
35
36 std::shared_ptr<Geometry> Geometry::MakeVertexBuffer(VertexBuffer vertex_buffer,
37 bool is_skinned) {
38 if (is_skinned) {
39 auto result = std::make_shared<SkinnedVertexBufferGeometry>();
40 result->SetVertexBuffer(std::move(vertex_buffer));
41 return result;
42 } else {
43 auto result = std::make_shared<UnskinnedVertexBufferGeometry>();
44 result->SetVertexBuffer(std::move(vertex_buffer));
45 return result;
46 }
47 }
48
49 std::shared_ptr<Geometry> Geometry::MakeFromFlatbuffer(
50 const fb::MeshPrimitive& mesh,
51 Allocator& allocator) {
52 IndexType index_type;
53 switch (mesh.indices()->type()) {
54 case fb::IndexType::k16Bit:
55 index_type = IndexType::k16bit;
56 break;
57 case fb::IndexType::k32Bit:
58 index_type = IndexType::k32bit;
59 break;
60 }
61
62 const uint8_t* vertices_start;
63 size_t vertices_bytes;
64 bool is_skinned;
65
66 switch (mesh.vertices_type()) {
67 case fb::VertexBuffer::UnskinnedVertexBuffer: {
68 const auto* vertices =
69 mesh.vertices_as_UnskinnedVertexBuffer()->vertices();
70 vertices_start = reinterpret_cast<const uint8_t*>(vertices->Get(0));
71 vertices_bytes = vertices->size() * sizeof(fb::Vertex);
72 is_skinned = false;
73 break;
74 }
75 case fb::VertexBuffer::SkinnedVertexBuffer: {
76 const auto* vertices = mesh.vertices_as_SkinnedVertexBuffer()->vertices();
77 vertices_start = reinterpret_cast<const uint8_t*>(vertices->Get(0));
78 vertices_bytes = vertices->size() * sizeof(fb::SkinnedVertex);
79 is_skinned = true;
80 break;
81 }
82 case fb::VertexBuffer::NONE:
83 VALIDATION_LOG << "Invalid vertex buffer type.";
84 return nullptr;
85 }
86
87 const uint8_t* indices_start =
88 reinterpret_cast<const uint8_t*>(mesh.indices()->data()->Data());
89
90 const size_t indices_bytes = mesh.indices()->data()->size();
91 if (vertices_bytes == 0 || indices_bytes == 0) {
92 return nullptr;
93 }
94
95 DeviceBufferDescriptor buffer_desc;
96 buffer_desc.size = vertices_bytes + indices_bytes;
97 buffer_desc.storage_mode = StorageMode::kHostVisible;
98
99 auto buffer = allocator.CreateBuffer(buffer_desc);
100 buffer->SetLabel("Mesh vertices+indices");
101
102 if (!buffer->CopyHostBuffer(vertices_start, Range(0, vertices_bytes))) {
103 return nullptr;
104 }
105 if (!buffer->CopyHostBuffer(indices_start, Range(0, indices_bytes),
106 vertices_bytes)) {
107 return nullptr;
108 }
109
110 VertexBuffer vertex_buffer = {
111 .vertex_buffer = {.buffer = buffer, .range = Range(0, vertices_bytes)},
112 .index_buffer = {.buffer = buffer,
113 .range = Range(vertices_bytes, indices_bytes)},
114 .vertex_count = mesh.indices()->count(),
115 .index_type = index_type,
116 };
117 return MakeVertexBuffer(std::move(vertex_buffer), is_skinned);
118 }
119
120 void Geometry::SetJointsTexture(const std::shared_ptr<Texture>& texture) {}
121
122 //------------------------------------------------------------------------------
123 /// CuboidGeometry
124 ///
125
126 CuboidGeometry::CuboidGeometry() = default;
127
128 CuboidGeometry::~CuboidGeometry() = default;
129
130 void CuboidGeometry::SetSize(Vector3 size) {
131 size_ = size;
132 }
133
134 // |Geometry|
135 GeometryType CuboidGeometry::GetGeometryType() const {
136 return GeometryType::kUnskinned;
137 }
138
139 // |Geometry|
140 VertexBuffer CuboidGeometry::GetVertexBuffer(Allocator& allocator) const {
141 VertexBufferBuilder<UnskinnedVertexShader::PerVertexData, uint16_t> builder;
142 // Layout: position, normal, tangent, uv
143 builder.AddVertices({
144 // Front.
145 {Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 0),
146 Color::White()},
147 {Vector3(1, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 0),
148 Color::White()},
149 {Vector3(1, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 1),
150 Color::White()},
151 {Vector3(1, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(1, 1),
152 Color::White()},
153 {Vector3(0, 1, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 1),
154 Color::White()},
155 {Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(1, 0, 0), Point(0, 0),
156 Color::White()},
157 });
158 return builder.CreateVertexBuffer(allocator);
159 }
160
161 // |Geometry|
162 void CuboidGeometry::BindToCommand(const SceneContext& scene_context,
163 HostBuffer& buffer,
164 const Matrix& transform,
165 Command& command) const {
166 command.BindVertices(
167 GetVertexBuffer(*scene_context.GetContext()->GetResourceAllocator()));
168
169 UnskinnedVertexShader::FrameInfo info;
170 info.mvp = transform;
171 UnskinnedVertexShader::BindFrameInfo(command, buffer.EmplaceUniform(info));
172 }
173
174 //------------------------------------------------------------------------------
175 /// UnskinnedVertexBufferGeometry
176 ///
177
178 UnskinnedVertexBufferGeometry::UnskinnedVertexBufferGeometry() = default;
179
180 UnskinnedVertexBufferGeometry::~UnskinnedVertexBufferGeometry() = default;
181
182 void UnskinnedVertexBufferGeometry::SetVertexBuffer(
183 VertexBuffer vertex_buffer) {
184 vertex_buffer_ = std::move(vertex_buffer);
185 }
186
187 // |Geometry|
188 GeometryType UnskinnedVertexBufferGeometry::GetGeometryType() const {
189 return GeometryType::kUnskinned;
190 }
191
192 // |Geometry|
193 VertexBuffer UnskinnedVertexBufferGeometry::GetVertexBuffer(
194 Allocator& allocator) const {
195 return vertex_buffer_;
196 }
197
198 // |Geometry|
199 void UnskinnedVertexBufferGeometry::BindToCommand(
200 const SceneContext& scene_context,
201 HostBuffer& buffer,
202 const Matrix& transform,
203 Command& command) const {
204 command.BindVertices(
205 GetVertexBuffer(*scene_context.GetContext()->GetResourceAllocator()));
206
207 UnskinnedVertexShader::FrameInfo info;
208 info.mvp = transform;
209 UnskinnedVertexShader::BindFrameInfo(command, buffer.EmplaceUniform(info));
210 }
211
212 //------------------------------------------------------------------------------
213 /// SkinnedVertexBufferGeometry
214 ///
215
216 SkinnedVertexBufferGeometry::SkinnedVertexBufferGeometry() = default;
217
218 SkinnedVertexBufferGeometry::~SkinnedVertexBufferGeometry() = default;
219
220 void SkinnedVertexBufferGeometry::SetVertexBuffer(VertexBuffer vertex_buffer) {
221 vertex_buffer_ = std::move(vertex_buffer);
222 }
223
224 // |Geometry|
225 GeometryType SkinnedVertexBufferGeometry::GetGeometryType() const {
226 return GeometryType::kSkinned;
227 }
228
229 // |Geometry|
230 VertexBuffer SkinnedVertexBufferGeometry::GetVertexBuffer(
231 Allocator& allocator) const {
232 return vertex_buffer_;
233 }
234
235 // |Geometry|
236 void SkinnedVertexBufferGeometry::BindToCommand(
237 const SceneContext& scene_context,
238 HostBuffer& buffer,
239 const Matrix& transform,
240 Command& command) const {
241 command.BindVertices(
242 GetVertexBuffer(*scene_context.GetContext()->GetResourceAllocator()));
243
244 SamplerDescriptor sampler_desc;
245 sampler_desc.min_filter = MinMagFilter::kNearest;
246 sampler_desc.mag_filter = MinMagFilter::kNearest;
247 sampler_desc.mip_filter = MipFilter::kNearest;
248 sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
249 sampler_desc.label = "NN Repeat";
250
251 SkinnedVertexShader::BindJointsTexture(
252 command,
253 joints_texture_ ? joints_texture_ : scene_context.GetPlaceholderTexture(),
254 scene_context.GetContext()->GetSamplerLibrary()->GetSampler(
255 sampler_desc));
256
257 SkinnedVertexShader::FrameInfo info;
258 info.mvp = transform;
259 info.enable_skinning = joints_texture_ ? 1 : 0;
260 info.joint_texture_size =
261 joints_texture_ ? joints_texture_->GetSize().width : 1;
262 SkinnedVertexShader::BindFrameInfo(command, buffer.EmplaceUniform(info));
263 }
264
265 // |Geometry|
266 void SkinnedVertexBufferGeometry::SetJointsTexture(
267 const std::shared_ptr<Texture>& texture) {
268 joints_texture_ = texture;
269 }
270 } // namespace scene
271 } // namespace impeller
impeller::scene::SkinnedVertexBufferGeometry::~SkinnedVertexBufferGeometry
~SkinnedVertexBufferGeometry() override
impeller::scene::Geometry::SetJointsTexture
virtual void SetJointsTexture(const std::shared_ptr< Texture > &texture)
Definition: geometry.cc:120
impeller::Command
An object used to specify work to the GPU along with references to resources the GPU will used when d...
Definition: command.h:92
point.h
impeller::IndexType::k16bit
@ k16bit
impeller::scene::Geometry::MakeCuboid
static std::shared_ptr< CuboidGeometry > MakeCuboid(Vector3 size)
Definition: geometry.cc:30
vertex_buffer.h
impeller::scene::GeometryType::kUnskinned
@ kUnskinned
impeller::DeviceBufferDescriptor
Definition: device_buffer_descriptor.h:14
impeller::scene::CuboidGeometry::BindToCommand
void BindToCommand(const SceneContext &scene_context, HostBuffer &buffer, const Matrix &transform, Command &command) const override
Definition: geometry.cc:162
impeller::HostBuffer
Definition: host_buffer.h:20
impeller::VertexBuffer
Definition: vertex_buffer.h:13
impeller::scene::UnskinnedVertexBufferGeometry::UnskinnedVertexBufferGeometry
UnskinnedVertexBufferGeometry()
impeller::scene::SkinnedVertexBufferGeometry::SkinnedVertexBufferGeometry
SkinnedVertexBufferGeometry()
impeller::scene::UnskinnedVertexBufferGeometry::GetGeometryType
GeometryType GetGeometryType() const override
Definition: geometry.cc:188
formats.h
impeller::scene::CuboidGeometry::~CuboidGeometry
~CuboidGeometry() override
impeller::scene::SceneContext::GetPlaceholderTexture
std::shared_ptr< Texture > GetPlaceholderTexture() const
Definition: scene_context.cc:109
impeller::scene::CuboidGeometry::GetGeometryType
GeometryType GetGeometryType() const override
Definition: geometry.cc:135
impeller::scene::UnskinnedVertexBufferGeometry::GetVertexBuffer
VertexBuffer GetVertexBuffer(Allocator &allocator) const override
Definition: geometry.cc:193
impeller::DeviceBufferDescriptor::size
size_t size
Definition: device_buffer_descriptor.h:16
impeller::VertexBufferBuilder::AddVertices
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
Definition: vertex_buffer_builder.h:70
impeller::scene::SceneContext
Definition: scene_context.h:40
impeller::IndexType::k32bit
@ k32bit
impeller::VertexBuffer::vertex_buffer
BufferView vertex_buffer
Definition: vertex_buffer.h:14
impeller::StorageMode::kHostVisible
@ kHostVisible
impeller::MinMagFilter::kNearest
@ kNearest
Select nearest to the sample point. Most widely supported.
impeller::SamplerDescriptor::mag_filter
MinMagFilter mag_filter
Definition: sampler_descriptor.h:17
impeller::SamplerDescriptor
Definition: sampler_descriptor.h:15
impeller::MipFilter::kNearest
@ kNearest
Sample from the nearest mip level.
impeller::SamplerDescriptor::min_filter
MinMagFilter min_filter
Definition: sampler_descriptor.h:16
impeller::scene::SkinnedVertexBufferGeometry::GetGeometryType
GeometryType GetGeometryType() const override
Definition: geometry.cc:225
impeller::scene::SkinnedVertexBufferGeometry::GetVertexBuffer
VertexBuffer GetVertexBuffer(Allocator &allocator) const override
Definition: geometry.cc:230
impeller::Point
TPoint< Scalar > Point
Definition: point.h:308
impeller::Allocator::CreateBuffer
std::shared_ptr< DeviceBuffer > CreateBuffer(const DeviceBufferDescriptor &desc)
Definition: allocator.cc:44
impeller::scene::SkinnedVertexBufferGeometry::BindToCommand
void BindToCommand(const SceneContext &scene_context, HostBuffer &buffer, const Matrix &transform, Command &command) const override
Definition: geometry.cc:236
impeller::VertexBufferBuilder
Definition: vertex_buffer_builder.h:24
impeller::scene::UnskinnedVertexBufferGeometry::BindToCommand
void BindToCommand(const SceneContext &scene_context, HostBuffer &buffer, const Matrix &transform, Command &command) const override
Definition: geometry.cc:199
impeller::scene::UnskinnedVertexBufferGeometry::SetVertexBuffer
void SetVertexBuffer(VertexBuffer vertex_buffer)
Definition: geometry.cc:182
impeller::BufferView::buffer
std::shared_ptr< const Buffer > buffer
Definition: buffer_view.h:14
impeller::IndexType
IndexType
Definition: formats.h:341
impeller::DeviceBufferDescriptor::storage_mode
StorageMode storage_mode
Definition: device_buffer_descriptor.h:15
impeller::Command::BindVertices
bool BindVertices(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
Definition: command.cc:15
impeller::scene::Geometry::~Geometry
virtual ~Geometry()
impeller::SamplerDescriptor::width_address_mode
SamplerAddressMode width_address_mode
Definition: sampler_descriptor.h:20
impeller::Color::White
static constexpr Color White()
Definition: color.h:256
impeller::Allocator
An object that allocates device memory.
Definition: allocator.h:22
impeller::scene::Geometry::MakeFromFlatbuffer
static std::shared_ptr< Geometry > MakeFromFlatbuffer(const fb::MeshPrimitive &mesh, Allocator &allocator)
Definition: geometry.cc:49
impeller::scene::Geometry::MakeVertexBuffer
static std::shared_ptr< Geometry > MakeVertexBuffer(VertexBuffer vertex_buffer, bool is_skinned)
Definition: geometry.cc:36
impeller::scene::UnskinnedVertexBufferGeometry::~UnskinnedVertexBufferGeometry
~UnskinnedVertexBufferGeometry() override
impeller::SamplerDescriptor::mip_filter
MipFilter mip_filter
Definition: sampler_descriptor.h:18
impeller::VertexBufferBuilder::CreateVertexBuffer
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
Definition: vertex_buffer_builder.h:84
sampler_descriptor.h
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:67
impeller::scene::GeometryType
GeometryType
Definition: pipeline_key.h:13
impeller::scene::CuboidGeometry::CuboidGeometry
CuboidGeometry()
impeller::scene::GeometryType::kSkinned
@ kSkinned
impeller::Range
Definition: range.h:14
vector.h
impeller::scene::SkinnedVertexBufferGeometry::SetVertexBuffer
void SetVertexBuffer(VertexBuffer vertex_buffer)
Definition: geometry.cc:220
impeller::scene::SceneContext::GetContext
std::shared_ptr< Context > GetContext() const
Definition: scene_context.cc:105
impeller::HostBuffer::EmplaceUniform
BufferView EmplaceUniform(const UniformType &uniform)
Emplace uniform data onto the host buffer. Ensure that backend specific uniform alignment requirement...
Definition: host_buffer.h:41
impeller::SamplerDescriptor::label
std::string label
Definition: sampler_descriptor.h:24
geometry.h
device_buffer_descriptor.h
impeller::scene::CuboidGeometry::GetVertexBuffer
VertexBuffer GetVertexBuffer(Allocator &allocator) const override
Definition: geometry.cc:140
impeller::scene::SkinnedVertexBufferGeometry::SetJointsTexture
void SetJointsTexture(const std::shared_ptr< Texture > &texture) override
Definition: geometry.cc:266
impeller
Definition: aiks_context.cc:10
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::Vector3
Definition: vector.h:20
vertex_buffer_builder.h
impeller::scene::CuboidGeometry::SetSize
void SetSize(Vector3 size)
Definition: geometry.cc:130
impeller::SamplerAddressMode::kRepeat
@ kRepeat