1/****************************************************************************
2**
3** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QtTest>
30#include <private/qframeallocator_p.h>
31#include <private/qframeallocator_p_p.h>
32
33class tst_QFrameAllocator : public QObject
34{
35 Q_OBJECT
36public:
37 tst_QFrameAllocator() : QObject() {}
38 ~tst_QFrameAllocator() {}
39
40 struct small
41 {
42 char c;
43 };
44
45 struct medium
46 {
47 int a, b, c;
48 };
49
50 struct big
51 {
52 int t[8];
53 };
54
55 struct huge
56 {
57 int t[64];
58 };
59
60 struct composed
61 {
62 QVector<int> vec;
63 QList<int> list;
64 int t;
65 };
66
67 struct subclass : public composed
68 {
69 float toto;
70 // add some more data to force the subclass into a different bucket
71 char data[32];
72 };
73
74private slots:
75
76 void initQFrameChunk();
77 void singleAllocationQFrameChunk();
78 void qvectorAllocationQFrameChunk();
79 void multipleAllocationQFrameChunk();
80 void overflowAllocationQFrameChunk();
81 void singleDeallocationQFrameChunk();
82 void multipleDeallocationQFrameChunk();
83 void containsCheckQFrameChunk();
84 void clearQFrameChunk();
85 void initQFixedFrameAllocator();
86 void allocateQFixedFrameAllocator();
87 void deallocateQFixedFrameAllocator();
88 void checkFragmentationQFixedFrameAllocator();
89 void clearQFixedFrameAllocator();
90 void initQFrameAllocator();
91 void allocateWithQFrameAllocator();
92 void deallocateWithQFrameAllocator();
93 void testAllocationComposedValues();
94 void allocateSubclass();
95 void deallocateSubclass();
96 void clearQFrameAllocator();
97 void isEmptyQFrameAllocator();
98 void subclassPointerClearing();
99 void allocateWithRawMemoryDeallocate();
100 void allocateDeallocateRawMemory();
101};
102
103void tst_QFrameAllocator::initQFrameChunk()
104{
105 Qt3DCore::QFrameChunk c;
106
107 c.init(blockSize: 16, blocks: 12);
108
109 QVERIFY(c.m_blocksAvailable == c.m_maxBlocksAvailable);
110 QCOMPARE(c.m_blocksAvailable, (uchar)12);
111 QCOMPARE(c.m_firstAvailableBlock, (uchar)0);
112 QVERIFY(c.m_data != nullptr);
113 QVERIFY(c.isEmpty());
114
115 for (int i = 0; i < 12; i++) {
116 QCOMPARE(c.m_data[i * 16], (uchar)(i + 1));
117 }
118}
119
120void tst_QFrameAllocator::singleAllocationQFrameChunk()
121{
122 Qt3DCore::QFrameChunk c;
123
124 c.init(blockSize: 16, blocks: 12);
125
126 void *ptr = c.allocate(blockSize: 16);
127
128 QVERIFY(c.contains(ptr, 16));
129 QVERIFY(!c.isEmpty());
130 QCOMPARE(c.m_blocksAvailable, (uchar)(c.m_maxBlocksAvailable - 1));
131 QVERIFY(ptr != nullptr);
132 QCOMPARE(c.m_firstAvailableBlock, (uchar)1);
133 QCOMPARE(*((uchar*)ptr), (uchar)1);
134}
135
136void tst_QFrameAllocator::qvectorAllocationQFrameChunk()
137{
138 Qt3DCore::QFrameChunk c;
139
140 c.init(blockSize: 16, blocks: 12);
141
142 QVector<int> *v = nullptr;
143
144 QVERIFY(sizeof(v) < 16);
145 v = static_cast<QVector<int> *>(c.allocate(blockSize: 16));
146 QVERIFY(v != nullptr);
147 new (v) QVector<int>();
148 for (int i = 0; i < 1024; i++)
149 v->append(t: i);
150}
151
152void tst_QFrameAllocator::multipleAllocationQFrameChunk()
153{
154 Qt3DCore::QFrameChunk c;
155
156 c.init(blockSize: 16, blocks: 12);
157
158 QList<void *> ptrs;
159 for (int i = 0; i < 6; i++) {
160 ptrs << c.allocate(blockSize: 16);
161 }
162
163 QCOMPARE(c.m_maxBlocksAvailable, (uchar)12);
164 QCOMPARE(c.m_blocksAvailable, (uchar)6);
165 QCOMPARE(c.m_firstAvailableBlock, (uchar)6);
166 QVERIFY(!c.isEmpty());
167 for (int i = 0; i < 6; i++) {
168 QVERIFY(ptrs.at(i) != nullptr);
169 QCOMPARE(*((uchar*)ptrs.at(i)), (uchar)(i + 1));
170 }
171}
172
173void tst_QFrameAllocator::overflowAllocationQFrameChunk()
174{
175 Qt3DCore::QFrameChunk c;
176
177 c.init(blockSize: 16, blocks: 12);
178
179 QList<void *> ptrs;
180 for (int i = 0; i < 15; i++) {
181 ptrs << c.allocate(blockSize: 16);
182 }
183
184 QCOMPARE(c.m_maxBlocksAvailable, (uchar)12);
185 QCOMPARE(c.m_blocksAvailable,(uchar) 0);
186 QCOMPARE(c.m_firstAvailableBlock, (uchar)12);
187 QVERIFY(!c.isEmpty());
188 for (int i = 0; i < 15; i++) {
189 if (i < 12) {
190 QVERIFY(ptrs.at(i) != nullptr);
191 QCOMPARE(*((uchar*)ptrs.at(i)), (uchar)(i + 1));
192 }
193 else {
194 QVERIFY(ptrs.at(i) == nullptr);
195 }
196 }
197}
198
199void tst_QFrameAllocator::singleDeallocationQFrameChunk()
200{
201 Qt3DCore::QFrameChunk c;
202
203 c.init(blockSize: 16, blocks: 12);
204
205 void *ptr = c.allocate(blockSize: 16);
206
207 c.deallocate(p: ptr, blockSize: 16);
208
209 QVERIFY(c.m_blocksAvailable == c.m_maxBlocksAvailable);
210 QCOMPARE(c.m_blocksAvailable, (uchar)12);
211 QCOMPARE(c.m_firstAvailableBlock, (uchar)0);
212 QVERIFY(c.m_data != nullptr);
213 QVERIFY(c.isEmpty());
214
215 for (int i = 0; i < 12; i++) {
216 QCOMPARE(c.m_data[i * 16], (uchar)(i + 1));
217 }
218}
219
220void tst_QFrameAllocator::multipleDeallocationQFrameChunk()
221{
222 Qt3DCore::QFrameChunk c;
223
224 c.init(blockSize: 16, blocks: 12);
225
226 QList<void *> ptrs;
227 for (int i = 0; i < 6; i++) {
228 ptrs << c.allocate(blockSize: 16);
229 }
230
231 // Free half
232
233 for (int i = 0; i < 6; i++) {
234 c.deallocate(p: ptrs.at(i), blockSize: 16);
235 QCOMPARE(c.m_firstAvailableBlock, (uchar)(i));
236 }
237
238 QVERIFY(c.m_blocksAvailable == c.m_maxBlocksAvailable);
239 QCOMPARE(c.m_blocksAvailable, (uchar)12);
240 QVERIFY(c.m_data != nullptr);
241 QVERIFY(c.isEmpty());
242
243 // Refill all
244 ptrs.clear();
245 for (int i = 0; i < 12; i++) {
246 void *ptr = c.allocate(blockSize: 16);
247 ptrs << ptr;
248 QVERIFY(ptr != nullptr);
249 }
250 QVERIFY(!c.isEmpty());
251
252 // Free all
253 for (int i = 0; i < 12; i++) {
254 c.deallocate(p: ptrs.at(i), blockSize: 16);
255 }
256 QVERIFY(c.isEmpty());
257
258 // Refill all
259 ptrs.clear();
260
261 for (int i = 0; i < 12; i++) {
262 void *ptr = c.allocate(blockSize: 16);
263 ptrs << ptr;
264 QVERIFY(ptr != nullptr);
265 }
266
267 // Free all in non linear behavior
268 for (int i = 0; i < 6; i++) {
269 c.deallocate(p: ptrs.takeLast(), blockSize: 16);
270 c.deallocate(p: ptrs.takeFirst(), blockSize: 16);
271 }
272 QVERIFY(c.isEmpty());
273
274 // Refill all
275 ptrs.clear();
276 for (int i = 0; i < 12; i++) {
277 void *ptr = c.allocate(blockSize: 16);
278 ptrs << ptr;
279 QVERIFY(ptr != nullptr);
280 }
281 QVERIFY(!c.isEmpty());
282}
283
284void tst_QFrameAllocator::containsCheckQFrameChunk()
285{
286 Qt3DCore::QFrameChunk c;
287 Qt3DCore::QFrameChunk c2;
288
289 c.init(blockSize: 16, blocks: 12);
290 c2.init(blockSize: 16, blocks: 12);
291
292 QList<void *> ptrs;
293 for (int i = 0; i < 6; i++) {
294 ptrs << c.allocate(blockSize: 16);
295 }
296
297 QVERIFY(!c.contains((void *)(quintptr)0xffffffff, 16));
298 QVERIFY(!c2.contains((void *)(quintptr)0xffffffff, 16));
299 QVERIFY(c.contains(ptrs.first(), 16));
300 QVERIFY(!c2.contains(ptrs.first(), 16));
301 QVERIFY(c.contains(ptrs.last(), 16));
302 QVERIFY(!c2.contains(ptrs.last(), 16));
303
304 for (int i = 0; i < 6; i++) {
305 ptrs << c2.allocate(blockSize: 16);
306 }
307
308 QVERIFY(!c.contains((void *)(quintptr)0xffffffff, 16));
309 QVERIFY(!c.contains(ptrs.last(), 16));
310 QVERIFY(c.contains(ptrs.first(), 16));
311 QVERIFY(c2.contains(ptrs.last(), 16));
312 QVERIFY(!c2.contains(ptrs.first(), 16));
313}
314
315void tst_QFrameAllocator::clearQFrameChunk()
316{
317 Qt3DCore::QFrameChunk c;
318
319 c.init(blockSize: 16, blocks: 12);
320 QList<void *> ptrs;
321 for (int i = 0; i < 6; i++) {
322 ptrs << c.allocate(blockSize: 16);
323 }
324 QVERIFY(!c.isEmpty());
325 c.clear(blockSize: 16, blocks: 12);
326 QVERIFY(c.isEmpty());
327 QCOMPARE(c.m_blocksAvailable, c.m_maxBlocksAvailable);
328 QCOMPARE(c.m_firstAvailableBlock, (uchar)0);
329
330 for (int i = 0; i < 12; i++) {
331 QCOMPARE(c.m_data[i * 16], (uchar)(i + 1));
332 }
333}
334
335void tst_QFrameAllocator::initQFixedFrameAllocator()
336{
337 Qt3DCore::QFixedFrameAllocator f;
338
339 f.init(blockSize: 4);
340
341 QCOMPARE(f.chunkCount(), 0);
342 QCOMPARE(f.pageSize(), (uchar)128);
343}
344
345void tst_QFrameAllocator::allocateQFixedFrameAllocator()
346{
347 Qt3DCore::QFixedFrameAllocator f;
348
349 f.init(blockSize: 4, pageSize: 128);
350
351 QList<void *> ptrs;
352
353 // Fill 1 chunck
354 for (int i = 0; i < 128; i++) {
355 void *ptr = f.allocate();
356 QVERIFY(ptr != nullptr);
357 ptrs << ptr;
358 }
359 QCOMPARE(f.chunkCount(), 1);
360 // Fill half of chunk 2
361 for (int i = 0; i < 64; i++) {
362 void *ptr = f.allocate();
363 QVERIFY(ptr != nullptr);
364 ptrs << ptr;
365 }
366 // Free chunk 2
367 QCOMPARE(f.chunkCount(), 2);
368 for (int i = 0; i < 64; i++) {
369 f.deallocate(ptr: ptrs.takeLast());
370 }
371 // Allocate 2 chunks worth of data which should create a single new chunk
372 // as chunk 2 is empty
373 QCOMPARE(f.chunkCount(), 2);
374
375 for (int i = 0; i < 256; i++) {
376 void *ptr = f.allocate();
377 QVERIFY(ptr != nullptr);
378 ptrs << ptr;
379 }
380 QCOMPARE(f.chunkCount(), 3);
381}
382
383void tst_QFrameAllocator::deallocateQFixedFrameAllocator()
384{
385 Qt3DCore::QFixedFrameAllocator f;
386
387 f.init(blockSize: 4);
388
389 QList<void *> ptrs;
390
391 for (int i = 0; i < 128; i++) {
392 void *ptr = f.allocate();
393 QVERIFY(ptr != nullptr);
394 ptrs << ptr;
395 }
396 QCOMPARE(f.chunkCount(), 1);
397 for (int i = 0; i < 64; i++) {
398 void *ptr = f.allocate();
399 QVERIFY(ptr != nullptr);
400 ptrs << ptr;
401 }
402 QCOMPARE(f.chunkCount(), 2);
403 for (int i = 0; i < 64; i++) {
404 f.deallocate(ptr: ptrs.takeLast());
405 }
406 QCOMPARE(f.chunkCount(), 2);
407 f.trim();
408 QCOMPARE(f.chunkCount(), 1);
409
410 for (int i = 0; i < 64; i++) {
411 f.deallocate(ptr: ptrs.takeFirst());
412 }
413 QCOMPARE(f.chunkCount(), 1);
414 for (int i = 0; i < 36; i++) {
415 void *ptr = f.allocate();
416 QVERIFY(ptr != nullptr);
417 ptrs << ptr;
418 }
419 QCOMPARE(f.chunkCount(), 1);
420}
421
422void tst_QFrameAllocator::checkFragmentationQFixedFrameAllocator()
423{
424 Qt3DCore::QFixedFrameAllocator f;
425
426 f.init(blockSize: 4);
427
428 QList<void *> ptrs;
429
430 for (int i = 0; i < 256; i++) {
431 void *ptr = f.allocate();
432 QVERIFY(ptr != nullptr);
433 ptrs << ptr;
434 }
435
436 QCOMPARE(f.chunkCount(), 2);
437
438 for (int i = 0; i < 64; i++) {
439 f.deallocate(ptr: ptrs.takeFirst());
440 }
441
442 QCOMPARE(f.chunkCount(), 2);
443
444 for (int i = 0; i < 64; i++) {
445 void *ptr = f.allocate();
446 QVERIFY(ptr != nullptr);
447 ptrs << ptr;
448 }
449 QCOMPARE(f.chunkCount(), 2);
450}
451
452void tst_QFrameAllocator::clearQFixedFrameAllocator()
453{
454 Qt3DCore::QFixedFrameAllocator f;
455
456 f.init(blockSize: 16);
457
458 QList<void *> ptrs;
459
460 for (int i = 0; i < 256; i++) {
461 void *ptr = f.allocate();
462 QVERIFY(ptr != nullptr);
463 ptrs << ptr;
464 }
465 QCOMPARE(f.chunkCount(), 2);
466
467 f.clear();
468 QCOMPARE(f.chunkCount(), 2);
469
470 for (int i = 0; i < 256; i++) {
471 void *ptr = f.allocate();
472 QVERIFY(ptr != nullptr);
473 ptrs << ptr;
474 }
475 QCOMPARE(f.chunkCount(), 2);
476}
477
478void tst_QFrameAllocator::initQFrameAllocator()
479{
480 Qt3DCore::QFrameAllocator f(4, 4);
481 QCOMPARE(f.allocatorPoolSize(), 1);
482
483
484 Qt3DCore::QFrameAllocator f2(32, 4);
485 QCOMPARE(f2.allocatorPoolSize(), 8);
486}
487
488void tst_QFrameAllocator::allocateWithQFrameAllocator()
489{
490 Qt3DCore::QFrameAllocator f2(256, 4);
491 QCOMPARE(f2.allocatorPoolSize(), 256 / 4);
492
493 QVERIFY(f2.allocate<small>());
494 QVERIFY(f2.allocate<medium>());
495 QVERIFY(f2.allocate<big>());
496 QVERIFY(f2.allocate<huge>());
497
498 QList<medium *> mediums;
499 for (int i = 0; i < 800; i++) {
500 medium *m = f2.allocate<medium>();
501 QVERIFY(m);
502 m->a = i;
503 m->b = 800;
504 m->c = m->b - m->a;
505 mediums.append(t: m);
506 }
507 QCOMPARE(mediums.size(), 800);
508 for (int i = 0; i < 800; i++) {
509 medium *m = mediums.at(i);
510 QCOMPARE(m->a, i);
511 QCOMPARE(m->b, 800);
512 QCOMPARE(m->c, m->b - m->a);
513 }
514
515 QList<huge *> huges;
516 for (int i = 0; i < 250; i++) {
517 huge *m = f2.allocate<huge>();
518 QCOMPARE((int)(sizeof(m->t) / sizeof(int)), 64);
519 for (int j = 0; j < 64; j++)
520 m->t[j] = i * j;
521 huges.append(t: m);
522 }
523 for (int i = 0; i < 250; i++) {
524 huge *m = huges.at(i);
525 for (int j = 0; j < 64; j++)
526 QCOMPARE(m->t[j], i * j);
527 }
528}
529
530void tst_QFrameAllocator::deallocateWithQFrameAllocator()
531{
532 Qt3DCore::QFrameAllocator f2(256, 4);
533 QCOMPARE(f2.allocatorPoolSize(), 256 / 4);
534
535 small *s = f2.allocate<small>();
536 QVERIFY(s);
537 medium *m = f2.allocate<medium>();
538 QVERIFY(m);
539 big *b = f2.allocate<big>();
540 QVERIFY(b);
541 huge *h = f2.allocate<huge>();
542 QVERIFY(h);
543
544 f2.deallocate(ptr: s);
545 f2.deallocate(ptr: m);
546 f2.deallocate(ptr: b);
547 f2.deallocate(ptr: h);
548}
549
550void tst_QFrameAllocator::testAllocationComposedValues()
551{
552 Qt3DCore::QFrameAllocator f(128, 32);
553
554 composed t;
555
556 QVector<int> *v = f.allocate<QVector<int> >();
557
558 QVERIFY(v);
559
560 for (int i = 0; i < 10; i++)
561 v->append(t: 2);
562
563
564 for (int i = 0; i < 100; i++) {
565 t.vec.append(t: i);
566 t.list.append(t: i);
567 }
568
569 composed *composedValues[30];
570
571 for (auto &v : composedValues) {
572 v = f.allocate<composed>();
573 QVERIFY(v);
574 for (int j = 0; j < 100; j++) {
575 v->vec.append(t: j);
576 v->list.append(t: j);
577 v->t = 100;
578 }
579 }
580
581 for (composed *c : composedValues) {
582 QCOMPARE(c->vec.size(), 100);
583 QCOMPARE(c->list.size(), 100);
584 QCOMPARE(c->t, 100);
585
586 for (int j = 0; j < 100; j++) {
587 QCOMPARE(c->vec.at(j), j);
588 QCOMPARE(c->list.at(j), j);
589 }
590 }
591}
592
593void tst_QFrameAllocator::allocateSubclass()
594{
595 Qt3DCore::QFrameAllocator f(128, 32);
596
597 QList<composed *> composeds;
598
599 for (int i = 0; i < 256; i++) {
600 // Allocate a composed object of size subclass
601 // c is actually a subclass
602 composed *c = static_cast<composed*>(f.allocateRawMemory(size: sizeof(subclass)));
603 composeds << c;
604 }
605
606 QCOMPARE(composeds.count(), 256);
607
608 for (composed *c : qAsConst(t&: composeds)) {
609 subclass *s = static_cast<subclass *>(c);
610 s->toto = 2586.0f;
611 }
612
613 for (int i = 0; i < 256; i++) {
614 subclass *s = static_cast<subclass *>(composeds.takeLast());
615 QVERIFY(s->toto == 2586.0f);
616 }
617}
618
619void tst_QFrameAllocator::deallocateSubclass()
620{
621 Qt3DCore::QFrameAllocator f(128, 32);
622
623
624 const int NUM_ITEMS = 256;
625 QVector<void *> allocated(NUM_ITEMS);
626 uint chunkCount = 0;
627
628 for (int l = 0; l < 6; l++) {
629
630 for (int i = 0; i < NUM_ITEMS; i++) {
631 // Allocate a composed object of size subclass
632 // c is actually a subclass
633 allocated[i] = f.allocateRawMemory(size: sizeof(subclass));
634 }
635
636 if (!chunkCount)
637 chunkCount = f.totalChunkCount();
638 else
639 QCOMPARE(chunkCount, f.totalChunkCount());
640
641 for (int i = 0; i < NUM_ITEMS; i++) {
642 f.deallocateRawMemory(ptr: allocated[i], size: sizeof(subclass));
643 }
644 }
645
646}
647
648void tst_QFrameAllocator::clearQFrameAllocator()
649{
650 Qt3DCore::QFrameAllocator f(128, 32);
651
652 for (int i = 0; i < 256; i++) {
653 f.allocate<composed>();
654 }
655 uint chunkCount = f.totalChunkCount();
656 f.clear();
657 QCOMPARE(chunkCount, f.totalChunkCount());
658
659 for (int i = 0; i < 256; i++) {
660 QList<composed *> composeds;
661 for (int j = 0; j < 256; j++) {
662 composed *c = f.allocate<composed>();
663 c ->t = i * j;
664 composeds << c;
665 }
666 QCOMPARE(chunkCount, f.totalChunkCount());
667 for (int j = 0; j < 256; j++) {
668 QCOMPARE(composeds.at(j)->t, i * j);
669 }
670 f.clear();
671 QCOMPARE(chunkCount, f.totalChunkCount());
672 }
673}
674
675void tst_QFrameAllocator::isEmptyQFrameAllocator()
676{
677 // GIVEN
678 Qt3DCore::QFrameAllocator f(128, 32);
679
680
681 // WHEN
682 for (int i = 0; i < 256; ++i)
683 f.allocate<composed>();
684 // THEN
685 QVERIFY(!f.isEmpty());
686
687 // WHEN
688 f.clear();
689 // THEN
690 QVERIFY(f.isEmpty());
691
692 for (int i = 0; i < 256; ++i) {
693
694 // GIVEN
695 QVector<composed *> composeds;
696 for (int j = 0; j < 256; ++j) {
697 composed *c = f.allocate<composed>();
698 c ->t = i * j;
699 composeds << c;
700 }
701 // THEN
702 QVERIFY(!f.isEmpty());
703
704 // WHEN
705 for (int j = 0; j < 256; ++j)
706 f.deallocate(ptr: composeds.takeAt(i: 0));
707 // THEN
708 QVERIFY(f.isEmpty());
709 }
710}
711
712void tst_QFrameAllocator::subclassPointerClearing()
713{
714 // GIVEN
715 Qt3DCore::QFrameAllocator f(128, 32);
716 QVector<composed *> data;
717
718 // WHEN
719 for (int i = 0; i < 32; ++i) {
720 composed *c = (i % 2 == 0) ? f.allocate<composed>() : f.allocate<subclass>();
721 data.append(t: c);
722 }
723 // THEN
724 QVERIFY(!f.isEmpty());
725
726 // WHEN
727 for (int j = 0; j < 32; ++j) {
728 if ((j % 2 == 0))
729 f.deallocate<composed>(ptr: data.takeAt(i: 0));
730 else
731 f.deallocate<subclass>(ptr: static_cast<subclass *>(data.takeAt(i: 0)));
732 }
733
734 // THEN
735 QVERIFY(f.isEmpty());
736}
737
738void tst_QFrameAllocator::allocateWithRawMemoryDeallocate()
739{
740 // GIVEN
741 Qt3DCore::QFrameAllocator f(128, 32);
742 subclass *s = static_cast<subclass *>(f.allocateRawMemory(size: sizeof(subclass)));
743 new (s) subclass();
744
745 // WHEN
746 f.deallocate(ptr: s);
747
748 // THEN
749 QVERIFY(f.isEmpty());
750}
751
752void tst_QFrameAllocator::allocateDeallocateRawMemory()
753{
754 // GIVEN
755 Qt3DCore::QFrameAllocator f(128, 32);
756 subclass *s = f.allocate<subclass>();
757
758 // WHEN
759 f.deallocateRawMemory(ptr: s, size: sizeof(subclass));
760
761 // THEN
762 QVERIFY(f.isEmpty());
763}
764
765QTEST_APPLESS_MAIN(tst_QFrameAllocator)
766
767#include "tst_qframeallocator.moc"
768

source code of qt3d/tests/auto/core/qframeallocator/tst_qframeallocator.cpp