chrono_batch_render/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
196 / 228
86.0%
Branches:
238 / 412
57.8%
Functions:
26 / 28
92.9%

stage/views/view.cpp
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 #include "chrono_batch_render/stage/views/view.h"
3 #include "chrono_batch_render/stage/views/view_state.h"
4
5 #include <set>
6 #include <utility>
7
8 #include "chrono_batch_render/device/device.h"
9 #include "chrono_batch_render/stage/views/attribute.h"
10 #include "chrono_batch_render/stage/views/poses.h"
11 #include "chrono_batch_render/util/error.h"
12 #include "chrono_batch_render/util/span.h"
13
14 namespace chrono::batch_render {
15
16 58821 ViewState::ViewState(Structure& structure, SchemaId schema, std::vector<uint32_t> prims,
17 58821 uint32_t instance)
18
1/1
✓ Branch 1 taken 58821 times.
58821 : m_structure(structure), m_schema(schema), m_instance(instance), m_prims(std::move(prims)) {
19
1/1
✓ Branch 1 taken 58821 times.
58821 const chrono::batch_render::Prims& records = structure.GetPrims();
20
1/1
✓ Branch 1 taken 58821 times.
58821 m_generations.reserve(m_prims.size());
21
2/2
✓ Branch 0 taken 63051 times.
✓ Branch 1 taken 58820 times.
121871 for (const uint32_t prim : m_prims) {
22
1/1
✓ Branch 1 taken 63051 times.
63051 const PrimRecord& record = records.Record(prim);
23
7/7
✓ Branch 0 taken 61421 times.
✓ Branch 1 taken 1630 times.
✓ Branch 3 taken 61421 times.
✓ Branch 5 taken 40 times.
✓ Branch 6 taken 61381 times.
✓ Branch 7 taken 1 time.
✓ Branch 8 taken 39 times.
63091 if (schema != SchemaId::None && !IsA(record.schema, schema) &&
24
1/1
✓ Branch 1 taken 40 times.
40 !HasApi(record.apis, schema)) {
25 3 throw Error("Prim {}, a {}, isn't a {}", prim, Info(record.schema).name,
26
3/5
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 time.
✓ Branch 6 taken 1 time.
3 Info(schema).name);
27 }
28
2/2
✓ Branch 1 taken 63050 times.
✓ Branch 4 taken 63050 times.
63050 m_generations.push_back(records.Generation(prim));
29 }
30 58822 }
31
32 62718 bool ViewState::Live(uint32_t index) const {
33 62718 const chrono::batch_render::Prims& records = m_structure.GetPrims();
34
4/4
✓ Branch 1 taken 62715 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 time.
✓ Branch 4 taken 62714 times.
125433 return records.Alive(m_prims[index]) &&
35
2/2
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 62714 times.
62715 records.Generation(m_prims[index]) == m_generations[index];
36 }
37
38 256175 const ViewRows& ViewState::Rows(SchemaId table) {
39 256175 ViewRows& rows = m_rows[table];
40
2/2
✓ Branch 0 taken 59155 times.
✓ Branch 1 taken 197020 times.
256175 if (rows.epoch == m_structure.Epoch()) {
41 return rows;
42 }
43 59155 const chrono::batch_render::Prims& records = m_structure.GetPrims();
44 59155 rows = {};
45 59155 rows.epoch = m_structure.Epoch();
46 59155 rows.rows.reserve(m_prims.size());
47 59155 std::set<uint32_t> worlds;
48
2/2
✓ Branch 0 taken 62681 times.
✓ Branch 1 taken 59155 times.
121836 for (uint32_t index = 0; index < m_prims.size(); ++index) {
49
3/3
✓ Branch 1 taken 62681 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 62677 times.
62681 if (!Live(index)) {
50
1/1
✓ Branch 1 taken 4 times.
4 rows.rows.push_back(kNoRow);
51 4 continue;
52 }
53 62677 uint32_t row = kNoRow;
54
3/3
✓ Branch 1 taken 62677 times.
✓ Branch 3 taken 62670 times.
✓ Branch 4 taken 7 times.
62677 if (!IsMultipleApi(table)) {
55
1/1
✓ Branch 1 taken 62670 times.
62670 row = records.Row(m_prims[index], table);
56
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 } else if (m_instance == kNoInstance) {
57 ✗ throw Error("{} is applied many times, so a view reaches it through an instance name",
58
0/3
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Info(table).name);
59 } else {
60
1/1
✓ Branch 1 taken 7 times.
7 row = records.InstanceRow(m_prims[index], table, m_instance);
61
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (row == kNoRow) {
62 ✗ throw Error("{} has no {} {}", m_structure.GetPaths().Path(m_prims[index]),
63
0/5
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✗ Branch 10 not taken.
✗ Info(table).name, m_structure.GetTokens().Text(Token{m_instance}));
64 }
65 }
66
1/1
✓ Branch 1 taken 62677 times.
62677 const uint32_t world = records.Record(m_prims[index]).world;
67
1/1
✓ Branch 1 taken 62677 times.
62677 rows.rows.push_back(row);
68 62677 ++rows.live;
69
1/1
✓ Branch 1 taken 62677 times.
62677 worlds.insert(world);
70
2/2
✓ Branch 0 taken 3522 times.
✓ Branch 1 taken 59155 times.
62677 ViewBlock* last = rows.blocks.empty() ? nullptr : &rows.blocks.back();
71
4/6
✓ Branch 0 taken 3522 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3522 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1972 times.
✓ Branch 5 taken 1550 times.
3522 if (last && last->first + last->count == index && last->firstRow + last->count == row) {
72 1972 ++last->count;
73 } else {
74
1/1
✓ Branch 1 taken 60705 times.
60705 rows.blocks.push_back({index, row, 1});
75 }
76 }
77
1/1
✓ Branch 1 taken 59155 times.
59155 rows.worlds.assign(worlds.begin(), worlds.end());
78 59155 return rows;
79 59155 }
80
81 122 const Ref<device::Buffer>& ViewState::DeviceRows(SchemaId table) {
82 122 Rows(table);
83 122 ViewRows& rows = m_rows.at(table);
84
3/4
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 107 times.
✗ Branch 3 not taken.
122 if (!rows.device && !rows.rows.empty()) {
85
1/1
✓ Branch 2 taken 107 times.
214 rows.device = GetColumnStore().GetDevice().CreateBuffer(
86
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 107 times.
214 {.label = "view rows"}, std::span<const uint32_t>(rows.rows));
87 }
88 122 return rows.device;
89 214 }
90
91 7 const Ref<device::Buffer>& ViewState::XformParents() {
92
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7 if (m_xformParents && m_xformParentsEpoch == m_structure.Epoch()) {
93 ✗ return m_xformParents;
94 }
95
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 const chrono::batch_render::Prims& prims = m_structure.GetPrims();
96 7 std::vector<uint32_t> parents;
97
2/3
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✓ Branch 3 taken 7 times.
7 parents.reserve(std::max<size_t>(m_prims.size(), 1));
98
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 7 times.
16 for (uint32_t index = 0; index < m_prims.size(); ++index) {
99
3/4
✓ Branch 1 taken 9 times.
✓ Branch 3 taken 9 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 9 times.
9 uint32_t up = Live(index) ? prims.Record(m_prims[index]).parent : kNoPrim;
100
5/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 time.
✓ Branch 3 taken 8 times.
✓ Branch 6 taken 8 times.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
9 while (up != kNoPrim && !IsA(prims.Record(up).schema, SchemaId::Xformable)) {
101
0/1
✗ Branch 1 not taken.
✗ up = prims.Record(up).parent;
102 }
103
4/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 time.
✓ Branch 3 taken 8 times.
✓ Branch 6 taken 9 times.
9 parents.push_back(up == kNoPrim ? kNoRow : prims.Row(up, SchemaId::Xformable));
104 }
105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (parents.empty()) {
106
0/1
✗ Branch 1 not taken.
✗ parents.push_back(kNoRow);
107 }
108
2/2
✓ Branch 1 taken 7 times.
✓ Branch 4 taken 7 times.
14 m_xformParents = GetColumnStore().GetDevice().CreateBuffer({.label = "view parents"},
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 std::span<const uint32_t>(parents));
110 7 m_xformParentsEpoch = m_structure.Epoch();
111 7 return m_xformParents;
112 14 }
113
114 35529 RowSource ViewState::Source(SchemaId table) {
115 35529 const ViewRows& rows = Rows(table);
116
2/2
✓ Branch 0 taken 35416 times.
✓ Branch 1 taken 113 times.
35529 if (rows.Dense()) {
117 35416 return {0, rows.blocks.front().firstRow};
118 }
119 113 const Ref<device::Buffer>& device = DeviceRows(table);
120
1/2
✓ Branch 0 taken 113 times.
✗ Branch 1 not taken.
113 return {device ? device->Address() : 0, 0};
121 }
122
123 58779 View::View(Structure& structure, SchemaId schema, std::vector<uint32_t> prims)
124 58778 : m_state(std::make_shared<ViewState>(structure, schema, std::move(prims))) {}
125
126 7 View::View(Structure& structure, SchemaId schema, std::vector<uint32_t> prims,
127 7 std::string_view instance)
128 7 : m_state(std::make_shared<ViewState>(structure, schema, std::move(prims),
129 7 structure.GetTokens().Intern(instance).id)) {}
130
131
1/1
✓ Branch 1 taken 33 times.
33 View::View(Structure& structure, SchemaId schema, const PrimBlock& block, uint32_t index) {
132 33 std::vector<uint32_t> prims;
133
1/1
✓ Branch 1 taken 33 times.
33 prims.reserve(block.copies);
134
2/2
✓ Branch 0 taken 1419 times.
✓ Branch 1 taken 33 times.
1452 for (uint32_t copy = 0; copy < block.copies; ++copy) {
135
1/1
✓ Branch 1 taken 1419 times.
1419 prims.push_back(block.Prim(copy, index));
136 }
137
2/3
✓ Branch 1 taken 33 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 33 times.
33 m_state = std::make_shared<ViewState>(structure, schema, std::move(prims));
138 33 }
139
140 12 uint32_t View::PrimCount() const {
141
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
142
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 return m_state ? m_state->Size() : 0;
143 12 }
144
145 ✗ SchemaId View::Schema() const {
146
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
147
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ return m_state ? m_state->Schema() : SchemaId::None;
148 ✗ }
149
150 4 bool View::Dense(SchemaId table) const {
151
3/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 3 times.
4 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
152
4/5
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 5 taken 1 time.
✓ Branch 6 taken 3 times.
8 return m_state && m_state->Rows(table).Dense();
153 4 }
154
155 108 Span<const uint32_t> View::Prims() const {
156
2/4
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
✗ Branch 3 not taken.
108 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
157
1/2
✓ Branch 0 taken 108 times.
✗ Branch 1 not taken.
108 return m_state ? m_state->Prims() : std::span<const uint32_t>{};
158 108 }
159
160 2 View View::World(uint32_t world) const {
161
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
162 2 std::vector<uint32_t> prims;
163
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (m_state) {
164 2 const chrono::batch_render::Prims& records = m_state->GetStructure().GetPrims();
165
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 for (uint32_t index = 0; index < m_state->Size(); ++index) {
166
5/6
✓ Branch 1 taken 6 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 6 times.
✓ Branch 8 taken 4 times.
✓ Branch 9 taken 2 times.
6 if (m_state->Live(index) && records.Record(m_state->Prims()[index]).world == world) {
167
1/1
✓ Branch 1 taken 2 times.
2 prims.push_back(m_state->Prims()[index]);
168 }
169 }
170 }
171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!m_state) {
172 ✗ return View();
173 }
174 2 View narrowed;
175 2 narrowed.m_state = std::make_shared<ViewState>(m_state->GetStructure(), m_state->Schema(),
176
2/5
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 std::move(prims), m_state->Instance());
177
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 return narrowed;
178 2 }
179
180 1146 device::Operation View::WritePoses(const DLTensor& source, Stream producer, QuaternionOrder order,
181 const DLTensor* rows, const DLTensor* mask) const {
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1146 times.
1146 if (!m_state) {
183
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no poses");
184 }
185
4/6
✓ Branch 0 taken 1146 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 1146 times.
✓ Branch 6 taken 1145 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1145 times.
2292 return Poses(m_state).Write(source, producer, order, rows, mask);
186 }
187
188 33965 device::Operation View::WritePoses(const DLTensor& translation, const DLTensor& rotation,
189 Stream producer, QuaternionOrder order, const DLTensor* rows,
190 const DLTensor* mask) const {
191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33965 times.
33965 if (!m_state) {
192
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no poses");
193 }
194
4/6
✓ Branch 0 taken 33965 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 33965 times.
✓ Branch 6 taken 33965 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 33965 times.
67930 return Poses(m_state).Write(translation, rotation, producer, order, rows, mask);
195 }
196
197 1 device::Operation View::WritePoses(const device::Tensor& source, Stream producer,
198 QuaternionOrder order, const device::Tensor& rows,
199 const device::Tensor& mask) const {
200
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (!m_state) {
202
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no poses");
203 }
204
4/7
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 time.
4 return Poses(m_state).Write(source, producer, order, rows, mask);
205 1 }
206
207 1 device::Operation View::WritePoses(const device::Tensor& translation,
208 const device::Tensor& rotation, Stream producer,
209 QuaternionOrder order, const device::Tensor& rows,
210 const device::Tensor& mask) const {
211
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 time.
1 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
212
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (!m_state) {
213
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no poses");
214 }
215
2/6
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 time.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
3 return Poses(m_state).Write(translation, rotation, producer, order, rows, mask);
216 1 }
217
218 115 device::Tensor View::ReadPoses(device::DType type, Stream consumer, QuaternionOrder order) const {
219
3/4
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 108 times.
✓ Branch 3 taken 7 times.
115 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
220
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115 times.
115 if (!m_state) {
221
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no poses");
222 }
223
4/6
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 115 times.
✓ Branch 6 taken 115 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 115 times.
345 return Poses(m_state).Read(type, consumer, order);
224 115 }
225
226 5 device::Operation View::WriteWorldPoses(const DLTensor& source, Stream producer,
227 QuaternionOrder order, const DLTensor* rows,
228 const DLTensor* mask) const {
229
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!m_state) {
231
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no poses");
232 }
233
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 device::Device& device = m_state->GetColumnStore().GetDevice();
234
4/6
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 6 taken 5 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 5 times.
20 return Poses(m_state).WriteWorld(
235
2/2
✓ Branch 1 taken 5 times.
✓ Branch 4 taken 5 times.
10 device.Import(source, producer, "world pose staging"), nullptr, producer, order,
236
3/9
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✓ Branch 9 taken 5 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 5 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
10 rows ? device.Import(*rows, producer, "pose rows") : device::Tensor(),
237
3/9
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✓ Branch 9 taken 5 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 5 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
15 mask ? device.Import(*mask, producer, "pose mask") : device::Tensor());
238 5 }
239
240 1 device::Operation View::WriteWorldPoses(const DLTensor& translation, const DLTensor& rotation,
241 Stream producer, QuaternionOrder order,
242 const DLTensor* rows, const DLTensor* mask) const {
243
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
1 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (!m_state) {
245
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no poses");
246 }
247
1/1
✓ Branch 1 taken 1 time.
1 device::Device& device = m_state->GetColumnStore().GetDevice();
248
2/2
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
1 const device::Tensor rotations = device.Import(rotation, producer, "world rotation staging");
249
4/6
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
4 return Poses(m_state).WriteWorld(
250
2/2
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
2 device.Import(translation, producer, "world translation staging"), &rotations, producer,
251
4/9
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 12 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
3 order, rows ? device.Import(*rows, producer, "pose rows") : device::Tensor(),
252
4/9
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 12 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
4 mask ? device.Import(*mask, producer, "pose mask") : device::Tensor());
253 1 }
254
255 1 device::Operation View::WriteWorldPoses(const device::Tensor& source, Stream producer,
256 QuaternionOrder order, const device::Tensor& rows,
257 const device::Tensor& mask) const {
258
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
1 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (!m_state) {
260
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no poses");
261 }
262
4/6
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
3 return Poses(m_state).WriteWorld(source, nullptr, producer, order, rows, mask);
263 1 }
264
265 ✗ device::Operation View::WriteWorldPoses(const device::Tensor& translation,
266 const device::Tensor& rotation, Stream producer,
267 QuaternionOrder order, const device::Tensor& rows,
268 const device::Tensor& mask) const {
269
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
270
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ if (!m_state) {
271
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no poses");
272 }
273
0/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ return Poses(m_state).WriteWorld(translation, &rotation, producer, order, rows, mask);
274 ✗ }
275
276 231 device::Tensor View::ReadWorldPoses(device::DType type, Stream consumer,
277 QuaternionOrder order) const {
278
3/4
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 1 time.
✓ Branch 2 taken 230 times.
✗ Branch 3 not taken.
231 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
279
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 230 times.
231 if (!m_state) {
280
2/2
✓ Branch 2 taken 1 time.
✓ Branch 5 taken 1 time.
2 throw Error("An empty view has no poses");
281 }
282
4/6
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 230 times.
✓ Branch 6 taken 230 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 230 times.
690 return Poses(m_state).ReadWorld(type, consumer, order);
283 231 }
284
285 1 device::Tensor View::ReadWorldScales(device::DType type, Stream consumer) const {
286
2/4
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 time.
✗ Branch 3 not taken.
1 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
287
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
1 if (!m_state) {
288
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no poses");
289 }
290
4/6
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✓ Branch 3 taken 1 time.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
3 return Poses(m_state).ReadWorldScales(type, consumer);
291 1 }
292
293 82446 ColumnRef View::Column(std::string_view field) const {
294
2/4
✓ Branch 0 taken 82446 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 82446 times.
✗ Branch 3 not taken.
82446 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
295
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82446 times.
82446 if (!m_state) {
296
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no attributes");
297 }
298
2/2
✓ Branch 0 taken 82342 times.
✓ Branch 1 taken 104 times.
82446 const chrono::batch_render::Prims& prims = m_state->GetStructure().GetPrims();
299
2/2
✓ Branch 0 taken 82342 times.
✓ Branch 1 taken 104 times.
82446 if (m_state->Schema() != SchemaId::None) {
300 82342 uint64_t shared = ~uint64_t(0);
301
2/2
✓ Branch 0 taken 82380 times.
✓ Branch 1 taken 82342 times.
164722 for (const uint32_t prim : m_state->Prims()) {
302
2/3
✓ Branch 1 taken 82380 times.
✓ Branch 3 taken 82380 times.
✗ Branch 4 not taken.
82380 if (prims.Alive(prim)) {
303
1/1
✓ Branch 1 taken 82380 times.
82380 shared &= prims.Record(prim).apis;
304 }
305 }
306
2/3
✓ Branch 1 taken 82342 times.
✓ Branch 3 taken 82342 times.
✗ Branch 4 not taken.
82342 if (const ColumnRef column = FindColumn(m_state->Schema(), shared, field)) {
307 82342 return column;
308 }
309
0/3
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✗ throw Error("{} has no attribute {}", Info(m_state->Schema()).name, field);
310 }
311
1/2
✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
104 for (const uint32_t prim : m_state->Prims()) {
312
2/3
✓ Branch 1 taken 104 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 104 times.
104 if (!prims.Alive(prim)) {
313 ✗ continue;
314 }
315 208 if (const ColumnRef column =
316
4/5
✓ Branch 1 taken 104 times.
✓ Branch 4 taken 104 times.
✓ Branch 7 taken 104 times.
✓ Branch 9 taken 104 times.
✗ Branch 10 not taken.
104 FindColumn(prims.Record(prim).schema, prims.Record(prim).apis, field)) {
317 104 return column;
318 }
319 }
320
0/1
✗ Branch 2 not taken.
✗ throw Error("No prim of the view has an attribute {}", field);
321 82446 }
322
323 82251 UntypedAttribute View::Get(std::string_view field) const {
324
2/4
✓ Branch 0 taken 82251 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 82251 times.
✗ Branch 3 not taken.
82251 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
325
2/2
✓ Branch 1 taken 82251 times.
✓ Branch 4 taken 82251 times.
164502 return Get(Column(field));
326 82251 }
327
328 84677 UntypedAttribute View::Get(ColumnRef column) const {
329
3/4
✓ Branch 0 taken 84677 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84650 times.
✓ Branch 3 taken 27 times.
84677 const auto lock = LockStore(m_state ? m_state->GetColumnStore().Lock() : nullptr);
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84677 times.
84677 if (!m_state) {
331
0/2
✗ Branch 2 not taken.
✗ Branch 5 not taken.
✗ throw Error("An empty view has no attributes");
332 }
333
2/3
✓ Branch 0 taken 84677 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 84677 times.
254031 return UntypedAttribute(m_state, column);
334 84677 }
335
336 }
337