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