Line data Source code
1 : /**
2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
3 :
4 : Permission is hereby granted, free of charge, to any person obtaining a copy
5 : of this software and associated documentation files (the "Software"), to deal
6 : in the Software without restriction, including without limitation the rights
7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : copies of the Software, and to permit persons to whom the Software is
9 : furnished to do so, subject to the following conditions:
10 :
11 : The above copyright notice and this permission notice shall be included in
12 : all copies or substantial portions of the Software.
13 :
14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : THE SOFTWARE.
21 : **/
22 :
23 : #include "XL2dCommandList.h"
24 :
25 : namespace STAPPLER_VERSIONIZED stappler::xenolith::basic2d {
26 :
27 634 : void CmdSdfGroup2D::addCircle2D(Vec2 origin, float r) {
28 634 : auto p = data.get_allocator().getPool();
29 :
30 634 : auto circle = new (memory::pool::palloc(p, sizeof(SdfCircle2D))) SdfCircle2D;
31 634 : circle->origin = origin;
32 634 : circle->radius = r;
33 :
34 634 : data.emplace_back(SdfPrimitive2DHeader{SdfShape::Circle2D, BytesView(reinterpret_cast<const uint8_t *>(circle), sizeof(SdfCircle2D))});
35 634 : }
36 :
37 984 : void CmdSdfGroup2D::addRect2D(Rect r) {
38 984 : auto p = data.get_allocator().getPool();
39 :
40 984 : auto rect = new (memory::pool::palloc(p, sizeof(SdfRect2D))) SdfRect2D;
41 984 : rect->origin = Vec2(r.getMidX(), r.getMidY());
42 984 : rect->size = Size2(r.size / 2.0f);
43 :
44 984 : data.emplace_back(SdfPrimitive2DHeader{SdfShape::Rect2D, BytesView(reinterpret_cast<const uint8_t *>(rect), sizeof(SdfRect2D))});
45 984 : }
46 :
47 1435 : void CmdSdfGroup2D::addRoundedRect2D(Rect rect, float r) {
48 1435 : auto p = data.get_allocator().getPool();
49 :
50 1435 : auto roundedRect = new (memory::pool::palloc(p, sizeof(SdfRoundedRect2D))) SdfRoundedRect2D;
51 1435 : roundedRect->origin = Vec2(rect.getMidX(), rect.getMidY());
52 1435 : roundedRect->size = Size2(rect.size / 2.0f);
53 1435 : roundedRect->radius = Vec4(r, r, r, r);
54 :
55 1435 : data.emplace_back(SdfPrimitive2DHeader{SdfShape::RoundedRect2D, BytesView(reinterpret_cast<const uint8_t *>(roundedRect), sizeof(SdfRoundedRect2D))});
56 1435 : }
57 :
58 0 : void CmdSdfGroup2D::addRoundedRect2D(Rect rect, Vec4 r) {
59 0 : auto p = data.get_allocator().getPool();
60 :
61 0 : auto roundedRect = new (memory::pool::palloc(p, sizeof(SdfRoundedRect2D))) SdfRoundedRect2D;
62 0 : roundedRect->origin = Vec2(rect.getMidX(), rect.getMidY());
63 0 : roundedRect->size = Size2(rect.size / 2.0f);
64 0 : roundedRect->radius = Vec4(r);
65 :
66 0 : data.emplace_back(SdfPrimitive2DHeader{SdfShape::RoundedRect2D, BytesView(reinterpret_cast<const uint8_t *>(roundedRect), sizeof(SdfRoundedRect2D))});
67 0 : }
68 :
69 634 : void CmdSdfGroup2D::addTriangle2D(Vec2 origin, Vec2 a, Vec2 b, Vec2 c) {
70 634 : auto p = data.get_allocator().getPool();
71 :
72 634 : auto triangle = new (memory::pool::palloc(p, sizeof(SdfTriangle2D))) SdfTriangle2D;
73 634 : triangle->origin = origin;
74 634 : triangle->a = a;
75 634 : triangle->b = b;
76 634 : triangle->c = c;
77 :
78 634 : data.emplace_back(SdfPrimitive2DHeader{SdfShape::Triangle2D, BytesView(reinterpret_cast<const uint8_t *>(triangle), sizeof(SdfTriangle2D))});
79 634 : }
80 :
81 1004 : void CmdSdfGroup2D::addPolygon2D(SpanView<Vec2> view) {
82 1004 : auto p = data.get_allocator().getPool();
83 :
84 1004 : auto polygon = new (memory::pool::palloc(p, sizeof(SdfPolygon2D))) SdfPolygon2D;
85 1004 : polygon->points = view.pdup(p);
86 :
87 1004 : data.emplace_back(SdfPrimitive2DHeader{SdfShape::Polygon2D, BytesView(reinterpret_cast<const uint8_t *>(polygon), sizeof(SdfPolygon2D))});
88 1004 : }
89 :
90 139584 : Command *Command::create(memory::pool_t *p, CommandType t, CommandFlags f) {
91 139584 : auto commandSize = sizeof(Command);
92 :
93 139584 : auto bytes = memory::pool::palloc(p, commandSize);
94 139584 : auto c = new (bytes) Command;
95 139584 : c->next = nullptr;
96 139584 : c->type = t;
97 139584 : c->flags = f;
98 139584 : switch (t) {
99 0 : case CommandType::CommandGroup:
100 0 : c->data = nullptr;
101 0 : break;
102 52163 : case CommandType::VertexArray:
103 52163 : c->data = new ( memory::pool::palloc(p, sizeof(CmdVertexArray)) ) CmdVertexArray;
104 52163 : break;
105 79560 : case CommandType::Deferred:
106 79560 : c->data = new ( memory::pool::palloc(p, sizeof(CmdDeferred)) ) CmdDeferred;
107 79560 : break;
108 0 : case CommandType::ShadowArray:
109 0 : c->data = new ( memory::pool::palloc(p, sizeof(CmdShadowArray)) ) CmdShadowArray;
110 0 : break;
111 3170 : case CommandType::ShadowDeferred:
112 3170 : c->data = new ( memory::pool::palloc(p, sizeof(CmdShadowDeferred)) ) CmdShadowDeferred;
113 3170 : break;
114 4691 : case CommandType::SdfGroup2D:
115 4691 : c->data = new ( memory::pool::palloc(p, sizeof(CmdSdfGroup2D)) ) CmdSdfGroup2D;
116 4691 : break;
117 : }
118 139584 : return c;
119 : }
120 :
121 139584 : void Command::release() {
122 139584 : switch (type) {
123 0 : case CommandType::CommandGroup:
124 0 : break;
125 52163 : case CommandType::VertexArray:
126 52163 : if (CmdVertexArray *d = reinterpret_cast<CmdVertexArray *>(data)) {
127 104326 : for (auto &it : d->vertexes) {
128 52163 : const_cast<TransformVertexData &>(it).data = nullptr;
129 : }
130 : }
131 52163 : break;
132 79560 : case CommandType::Deferred:
133 79560 : if (CmdDeferred *d = reinterpret_cast<CmdDeferred *>(data)) {
134 79560 : d->deferred = nullptr;
135 : }
136 79560 : break;
137 0 : case CommandType::ShadowArray:
138 0 : if (CmdShadowArray *d = reinterpret_cast<CmdShadowArray *>(data)) {
139 0 : for (auto &it : d->vertexes) {
140 0 : const_cast<TransformVertexData &>(it).data = nullptr;
141 : }
142 : }
143 0 : break;
144 3170 : case CommandType::ShadowDeferred:
145 3170 : if (CmdShadowDeferred *d = reinterpret_cast<CmdShadowDeferred *>(data)) {
146 3170 : d->deferred = nullptr;
147 : }
148 3170 : break;
149 4691 : case CommandType::SdfGroup2D:
150 4691 : break;
151 : }
152 139584 : }
153 :
154 18600 : CommandList::~CommandList() {
155 9300 : if (!_first) {
156 3545 : return;
157 : }
158 :
159 5755 : memory::pool::push(_pool->getPool());
160 :
161 5755 : auto cmd = _first;
162 : do {
163 139584 : cmd->release();
164 139584 : cmd = cmd->next;
165 139584 : } while (cmd);
166 :
167 5755 : memory::pool::pop();
168 22145 : }
169 :
170 9300 : bool CommandList::init(const Rc<PoolRef> &pool) {
171 9300 : _pool = pool;
172 9300 : return true;
173 : }
174 :
175 52163 : void CommandList::pushVertexArray(Rc<VertexData> &&vert, const Mat4 &t, SpanView<ZOrder> zPath,
176 : core::MaterialId material, StateId state, RenderingLevel level, float depthValue, CommandFlags flags) {
177 52163 : _pool->perform([&, this] {
178 52163 : auto cmd = Command::create(_pool->getPool(), CommandType::VertexArray, flags);
179 52163 : auto cmdData = reinterpret_cast<CmdVertexArray *>(cmd->data);
180 :
181 : // pool memory is 16-bytes aligned, no problems with Mat4
182 52163 : auto p = new (memory::pool::palloc(_pool->getPool(), sizeof(TransformVertexData))) TransformVertexData();
183 :
184 52163 : p->transform = t;
185 52163 : p->data = move(vert);
186 :
187 52163 : cmdData->vertexes = makeSpanView(p, 1);
188 :
189 90954 : while (!zPath.empty() && zPath.back() == ZOrder(0)) {
190 38791 : zPath.pop_back();
191 : }
192 :
193 52163 : cmdData->zPath = zPath.pdup(_pool->getPool());
194 52163 : cmdData->material = material;
195 52163 : cmdData->state = state;
196 52163 : cmdData->renderingLevel = level;
197 52163 : cmdData->depthValue = depthValue;
198 :
199 52163 : addCommand(cmd);
200 52163 : });
201 52163 : }
202 :
203 0 : void CommandList::pushVertexArray(SpanView<TransformVertexData> data, SpanView<ZOrder> zPath,
204 : core::MaterialId material, StateId state, RenderingLevel level, float depthValue, CommandFlags flags) {
205 0 : _pool->perform([&, this] {
206 0 : auto cmd = Command::create(_pool->getPool(), CommandType::VertexArray, flags);
207 0 : auto cmdData = reinterpret_cast<CmdVertexArray *>(cmd->data);
208 :
209 0 : cmdData->vertexes = data;
210 :
211 0 : while (!zPath.empty() && zPath.back() == ZOrder(0)) {
212 0 : zPath.pop_back();
213 : }
214 :
215 0 : cmdData->zPath = zPath.pdup(_pool->getPool());
216 0 : cmdData->material = material;
217 0 : cmdData->state = state;
218 0 : cmdData->renderingLevel = level;
219 0 : cmdData->depthValue = depthValue;
220 :
221 0 : addCommand(cmd);
222 0 : });
223 0 : }
224 :
225 79560 : void CommandList::pushDeferredVertexResult(const Rc<DeferredVertexResult> &res, const Mat4 &viewT, const Mat4 &modelT, bool normalized,
226 : SpanView<ZOrder> zPath, core::MaterialId material, StateId state, RenderingLevel level, float depthValue, CommandFlags flags) {
227 79560 : _pool->perform([&, this] {
228 79560 : auto cmd = Command::create(_pool->getPool(), CommandType::Deferred, flags);
229 79560 : auto cmdData = reinterpret_cast<CmdDeferred *>(cmd->data);
230 :
231 79560 : cmdData->deferred = res;
232 79560 : cmdData->viewTransform = viewT;
233 79560 : cmdData->modelTransform = modelT;
234 79560 : cmdData->normalized = normalized;
235 :
236 189755 : while (!zPath.empty() && zPath.back() == ZOrder(0)) {
237 110195 : zPath.pop_back();
238 : }
239 :
240 79560 : cmdData->zPath = zPath.pdup(_pool->getPool());
241 79560 : cmdData->material = material;
242 79560 : cmdData->state = state;
243 79560 : cmdData->renderingLevel = level;
244 79560 : cmdData->depthValue = depthValue;
245 :
246 79560 : addCommand(cmd);
247 79560 : });
248 79560 : }
249 :
250 0 : void CommandList::pushShadowArray(Rc<VertexData> &&vert, const Mat4 &t, StateId state, float value) {
251 0 : _pool->perform([&, this] {
252 0 : auto cmd = Command::create(_pool->getPool(), CommandType::ShadowArray, CommandFlags::None);
253 0 : auto cmdData = reinterpret_cast<CmdShadowArray *>(cmd->data);
254 :
255 : // pool memory is 16-bytes aligned, no problems with Mat4
256 0 : auto p = new (memory::pool::palloc(_pool->getPool(), sizeof(TransformVertexData))) TransformVertexData();
257 :
258 0 : p->transform = t;
259 0 : p->data = move(vert);
260 :
261 0 : cmdData->value = value;
262 0 : cmdData->vertexes = makeSpanView(p, 1);
263 0 : cmdData->state = state;
264 :
265 0 : addCommand(cmd);
266 0 : });
267 0 : }
268 :
269 0 : void CommandList::pushShadowArray(SpanView<TransformVertexData> data, StateId state, float value) {
270 0 : _pool->perform([&, this] {
271 0 : auto cmd = Command::create(_pool->getPool(), CommandType::ShadowArray, CommandFlags::None);
272 0 : auto cmdData = reinterpret_cast<CmdShadowArray *>(cmd->data);
273 :
274 0 : cmdData->vertexes = data;
275 0 : cmdData->value = value;
276 0 : cmdData->state = state;
277 :
278 0 : addCommand(cmd);
279 0 : });
280 0 : }
281 :
282 3170 : void CommandList::pushDeferredShadow(const Rc<DeferredVertexResult> &res, const Mat4 &viewT, const Mat4 &modelT, StateId state, bool normalized, float value) {
283 3170 : _pool->perform([&, this] {
284 3170 : auto cmd = Command::create(_pool->getPool(), CommandType::ShadowDeferred, CommandFlags::None);
285 3170 : auto cmdData = reinterpret_cast<CmdShadowDeferred *>(cmd->data);
286 :
287 3170 : cmdData->deferred = res;
288 3170 : cmdData->viewTransform = viewT;
289 3170 : cmdData->modelTransform = modelT;
290 3170 : cmdData->normalized = normalized;
291 3170 : cmdData->value = value;
292 3170 : cmdData->state = state;
293 :
294 3170 : addCommand(cmd);
295 3170 : });
296 3170 : }
297 :
298 4691 : void CommandList::pushSdfGroup(const Mat4 &modelT, StateId state, float value, const Callback<void(CmdSdfGroup2D &)> &cb) {
299 4691 : _pool->perform([&, this] {
300 4691 : auto cmd = Command::create(_pool->getPool(), CommandType::SdfGroup2D, CommandFlags::None);
301 4691 : auto cmdData = reinterpret_cast<CmdSdfGroup2D *>(cmd->data);
302 :
303 4691 : cmdData->modelTransform = modelT;
304 4691 : cmdData->value = value;
305 4691 : cmdData->state = state;
306 :
307 4691 : cb(*cmdData);
308 :
309 4691 : addCommand(cmd);
310 4691 : });
311 4691 : }
312 :
313 139584 : void CommandList::addCommand(Command *cmd) {
314 139584 : if (!_last) {
315 5755 : _first = cmd;
316 : } else {
317 133829 : _last->next = cmd;
318 : }
319 139584 : _last = cmd;
320 139584 : ++ _size;
321 139584 : }
322 :
323 : }
|