7#include <private/qqmlglobal_p.h>
8#include <private/qsgmaterialshader_p.h>
9#include <private/qsgrenderer_p.h>
10#include <private/qquickitem_p.h>
11#include <private/qquickwindow_p.h>
12#include <QtCore/private/qnativeinterface_p.h>
15#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && defined(__GLIBC__
)
16#define CAN_BACKTRACE_EXECINFO
19#if defined(Q_OS_APPLE)
20#define CAN_BACKTRACE_EXECINFO
23#if defined(QT_NO_DEBUG)
24#undef CAN_BACKTRACE_EXECINFO
27#if defined(CAN_BACKTRACE_EXECINFO)
33Q_GLOBAL_STATIC(QSet<QSGTexture *>, qsg_valid_texture_set)
34Q_GLOBAL_STATIC(QMutex, qsg_valid_texture_mutex)
39bool operator==(
const QSGSamplerDescription &a,
const QSGSamplerDescription &b)
noexcept
41 return a.filtering == b.filtering
42 && a.mipmapFiltering == b.mipmapFiltering
43 && a.horizontalWrap == b.horizontalWrap
44 && a.verticalWrap == b.verticalWrap
45 && a.anisotropylevel == b.anisotropylevel;
48bool operator!=(
const QSGSamplerDescription &a,
const QSGSamplerDescription &b)
noexcept
53size_t qHash(
const QSGSamplerDescription &s, size_t seed)
noexcept
55 const int f = s.filtering;
56 const int m = s.mipmapFiltering;
57 const int w = s.horizontalWrap;
58 const int a = s.anisotropylevel;
59 return (((f & 7) << 24) | ((m & 7) << 16) | ((w & 7) << 8) | (a & 7)) ^ seed;
62QSGSamplerDescription QSGSamplerDescription::fromTexture(QSGTexture *t)
64 QSGSamplerDescription s;
65 s.filtering = t->filtering();
66 s.mipmapFiltering = t->mipmapFiltering();
67 s.horizontalWrap = t->horizontalWrapMode();
68 s.verticalWrap = t->verticalWrapMode();
69 s.anisotropylevel = t->anisotropyLevel();
73QSGTexturePrivate::QSGTexturePrivate(QSGTexture *t)
75 , filteringChanged(
false)
76 , anisotropyChanged(
false)
77 , horizontalWrap(QSGTexture::ClampToEdge)
78 , verticalWrap(QSGTexture::ClampToEdge)
79 , mipmapMode(QSGTexture::None)
80 , filterMode(QSGTexture::Nearest)
81 , anisotropyLevel(QSGTexture::AnisotropyNone)
83 , m_openglTextureAccessor(t)
86 , m_d3d11TextureAccessor(t)
87 , m_d3d12TextureAccessor(t)
90 , m_metalTextureAccessor(t)
93 , m_vulkanTextureAccessor(t)
103static int qt_debug_texture_count = 0;
105#if (defined(Q_OS_LINUX) || defined (Q_OS_APPLE)) && !defined(Q_OS_ANDROID)
106DEFINE_BOOL_CONFIG_OPTION(qmlDebugLeakBacktrace, QML_DEBUG_LEAK_BACKTRACE)
108#define BACKTRACE_SIZE 20
109class SGTextureTraceItem
112 void *backTrace[BACKTRACE_SIZE];
113 size_t backTraceSize;
116static QHash<QSGTexture*, SGTextureTraceItem*> qt_debug_allocated_textures;
121 qCDebug(lcQsgLeak,
"Number of leaked textures: %i", qt_debug_texture_count);
122 qt_debug_texture_count = -1;
124#if defined(CAN_BACKTRACE_EXECINFO)
125 if (qmlDebugLeakBacktrace()) {
126 while (!qt_debug_allocated_textures.isEmpty()) {
127 QHash<QSGTexture*, SGTextureTraceItem*>::Iterator it = qt_debug_allocated_textures.begin();
128 QSGTexture* texture = it.key();
129 SGTextureTraceItem* item = it.value();
131 qt_debug_allocated_textures.erase(it);
133 qDebug() <<
"------";
134 qDebug() <<
"Leaked" << texture <<
"backtrace:";
136 char** symbols = backtrace_symbols(item->backTrace, item->backTraceSize);
139 for (
int i=0; i<(
int) item->backTraceSize; i++)
140 qDebug(
"Backtrace <%02d>: %s", i, symbols[i]);
144 qDebug() <<
"------";
154#if defined(CAN_BACKTRACE_EXECINFO)
155 if (qmlDebugLeakBacktrace()) {
156 SGTextureTraceItem* item =
new SGTextureTraceItem;
157 item->backTraceSize = backtrace(item->backTrace, BACKTRACE_SIZE);
158 qt_debug_allocated_textures.insert(texture, item);
164 ++qt_debug_texture_count;
166 static bool atexit_registered =
false;
167 if (!atexit_registered) {
168 atexit(qt_debug_print_texture_count);
169 atexit_registered =
true;
175#if defined(CAN_BACKTRACE_EXECINFO)
176 if (qmlDebugLeakBacktrace()) {
177 SGTextureTraceItem* item = qt_debug_allocated_textures.value(texture, 0);
179 qt_debug_allocated_textures.remove(texture);
187 --qt_debug_texture_count;
189 if (qt_debug_texture_count < 0)
190 qDebug(
"Texture destroyed after qt_debug_print_texture_count() was called.");
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
251
252
253
254
255
256
257
258
259
260
261
262
263
264
267
268
269
270
271
272
273
274
275
276
277
278
279
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
301
302
303QSGTexture::QSGTexture()
304 : QObject(*(
new QSGTexturePrivate(
this)))
307 if (lcQsgLeak().isDebugEnabled())
308 qt_debug_add_texture(
this);
310 QMutexLocker locker(qsg_valid_texture_mutex());
311 qsg_valid_texture_set()->insert(
this);
316
317
318QSGTexture::QSGTexture(QSGTexturePrivate &dd)
322 if (lcQsgLeak().isDebugEnabled())
323 qt_debug_add_texture(
this);
325 QMutexLocker locker(qsg_valid_texture_mutex());
326 qsg_valid_texture_set()->insert(
this);
331
332
333QSGTexture::~QSGTexture()
336 if (lcQsgLeak().isDebugEnabled())
337 qt_debug_remove_texture(
this);
339 QMutexLocker locker(qsg_valid_texture_mutex());
340 qsg_valid_texture_set()->remove(
this);
345
346
347
348
349
350
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
378QSGTexture *QSGTexture::removedFromAtlas(QRhiResourceUpdateBatch *resourceUpdates)
const
380 Q_UNUSED(resourceUpdates);
381 Q_ASSERT_X(!isAtlasTexture(),
"QSGTexture::removedFromAtlas()",
"Called on a non-atlas texture");
386
387
388
389
390bool QSGTexture::isAtlasTexture()
const
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
421
422
423
424
427
428
429
430
431
432
433QRectF QSGTexture::normalizedTextureSubRect()
const
435 return QRectF(0, 0, 1, 1);
439
440
441
442
445
446
447
448
452
453
454
455
456
457
458void QSGTexture::setMipmapFiltering(Filtering filter)
461 if (d->mipmapMode != (uint) filter) {
462 d->mipmapMode = filter;
463 d->filteringChanged =
true;
468
469
470QSGTexture::Filtering QSGTexture::mipmapFiltering()
const
472 return (QSGTexture::Filtering) d_func()->mipmapMode;
477
478
479void QSGTexture::setFiltering(QSGTexture::Filtering filter)
482 if (d->filterMode != (uint) filter) {
483 d->filterMode = filter;
484 d->filteringChanged =
true;
489
490
491QSGTexture::Filtering QSGTexture::filtering()
const
493 return (QSGTexture::Filtering) d_func()->filterMode;
497
498
499
500
501
502
503
504
505
506void QSGTexture::setAnisotropyLevel(AnisotropyLevel level)
509 if (d->anisotropyLevel != (uint) level) {
510 d->anisotropyLevel = level;
511 d->anisotropyChanged =
true;
516
517
518
519
520QSGTexture::AnisotropyLevel QSGTexture::anisotropyLevel()
const
522 return (QSGTexture::AnisotropyLevel) d_func()->anisotropyLevel;
528
529
531void QSGTexture::setHorizontalWrapMode(WrapMode hwrap)
534 if ((uint) hwrap != d->horizontalWrap) {
535 d->horizontalWrap = hwrap;
536 d->wrapChanged =
true;
541
542
543QSGTexture::WrapMode QSGTexture::horizontalWrapMode()
const
545 return (QSGTexture::WrapMode) d_func()->horizontalWrap;
551
552
553void QSGTexture::setVerticalWrapMode(WrapMode vwrap)
556 if ((uint) vwrap != d->verticalWrap) {
557 d->verticalWrap = vwrap;
558 d->wrapChanged =
true;
563
564
565QSGTexture::WrapMode QSGTexture::verticalWrapMode()
const
567 return (QSGTexture::WrapMode) d_func()->verticalWrap;
571
572
573
574
575
576
577
578
579
580
581
582
583
584QRhiTexture *QSGTexture::rhiTexture()
const
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604void QSGTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates)
607 Q_UNUSED(resourceUpdates);
610bool QSGTexturePrivate::hasDirtySamplerOptions()
const
612 return wrapChanged || filteringChanged || anisotropyChanged;
615void QSGTexturePrivate::resetDirtySamplerOptions()
617 wrapChanged = filteringChanged = anisotropyChanged =
false;
621
622
623
624
625
626
627
628
629
630
634
635
636
637
638
639
640
641
642
643
644
645
648
649
650QSGDynamicTexture::QSGDynamicTexture(QSGTexturePrivate &dd)
656
657
658QSGDynamicTexture::~QSGDynamicTexture()
662
663
664
665
666
667
668
669
670
671
672
673
674
675
678#if QT_CONFIG(opengl) || defined(Q_QDOC)
679namespace QNativeInterface {
681
682
683
684
685
686
687
688
691
692
693
695QT_DEFINE_NATIVE_INTERFACE(QSGOpenGLTexture);
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723QSGTexture *QSGOpenGLTexture::fromNative(GLuint textureId,
724 QQuickWindow *window,
726 QQuickWindow::CreateTextureOptions options)
728 return QQuickWindowPrivate::get(window)->createTextureFromNativeTexture(quint64(textureId), 0, size, options);
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758QSGTexture *QSGOpenGLTexture::fromNativeExternalOES(GLuint textureId,
759 QQuickWindow *window,
761 QQuickWindow::CreateTextureOptions options)
763 return QQuickWindowPrivate::get(window)->createTextureFromNativeTexture(quint64(textureId),
767 QQuickWindowPrivate::NativeTextureIsExternalOES);
771GLuint QSGTexturePlatformOpenGL::nativeTexture()
const
773 if (
auto *tex = m_texture->rhiTexture())
774 return GLuint(tex->nativeTexture().object);
779#if defined(Q_OS_WIN) || defined(Q_QDOC)
780namespace QNativeInterface {
782
783
784
785
786
787
788
789
792
793
794
796QT_DEFINE_NATIVE_INTERFACE(QSGD3D11Texture);
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823QSGTexture *QSGD3D11Texture::fromNative(
void *texture,
824 QQuickWindow *window,
826 QQuickWindow::CreateTextureOptions options)
828 return QQuickWindowPrivate::get(window)->createTextureFromNativeTexture(quint64(texture), 0, size, options);
832void *QSGTexturePlatformD3D11::nativeTexture()
const
834 if (
auto *tex = m_texture->rhiTexture())
835 return reinterpret_cast<
void *>(quintptr(tex->nativeTexture().object));
839namespace QNativeInterface {
841
842
843
844
845
846
847
848
851
852
853
855QT_DEFINE_NATIVE_INTERFACE(QSGD3D12Texture);
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886QSGTexture *QSGD3D12Texture::fromNative(
void *texture,
888 QQuickWindow *window,
890 QQuickWindow::CreateTextureOptions options)
892 return QQuickWindowPrivate::get(window)->createTextureFromNativeTexture(quint64(texture), resourceState, size, options);
896int QSGTexturePlatformD3D12::nativeResourceState()
const
898 if (
auto *tex = m_texture->rhiTexture())
899 return tex->nativeTexture().layout;
903void *QSGTexturePlatformD3D12::nativeTexture()
const
905 if (
auto *tex = m_texture->rhiTexture())
906 return reinterpret_cast<
void *>(quintptr(tex->nativeTexture().object));
912#if defined(__OBJC__) || defined(Q_QDOC)
913namespace QNativeInterface {
915
916
917
918
919
920
921
922
925
926
927
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
960#if QT_CONFIG(vulkan) || defined(Q_QDOC)
961namespace QNativeInterface {
963
964
965
966
967
968
969
970
973
974
975
978
979
980
982QT_DEFINE_NATIVE_INTERFACE(QSGVulkanTexture);
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011QSGTexture *QSGVulkanTexture::fromNative(VkImage image,
1012 VkImageLayout layout,
1013 QQuickWindow *window,
1015 QQuickWindow::CreateTextureOptions options)
1017 return QQuickWindowPrivate::get(window)->createTextureFromNativeTexture(quint64(image), layout, size, options);
1021VkImage QSGTexturePlatformVulkan::nativeImage()
const
1023 if (
auto *tex = m_texture->rhiTexture())
1024 return VkImage(tex->nativeTexture().object);
1025 return VK_NULL_HANDLE;
1028VkImageLayout QSGTexturePlatformVulkan::nativeImageLayout()
const
1030 if (
auto *tex = m_texture->rhiTexture())
1031 return VkImageLayout(tex->nativeTexture().layout);
1032 return VK_IMAGE_LAYOUT_UNDEFINED;
1036void *QSGTexture::resolveInterface(
const char *name,
int revision)
const
1038 using namespace QNativeInterface;
1042 Q_D(
const QSGTexture);
1043 auto *dd =
const_cast<QSGTexturePrivate *>(d);
1046#if QT_CONFIG(vulkan)
1047 QT_NATIVE_INTERFACE_RETURN_IF(QSGVulkanTexture, &dd->m_vulkanTextureAccessor);
1050 QT_NATIVE_INTERFACE_RETURN_IF(QSGMetalTexture, &dd->m_metalTextureAccessor);
1052#if defined(Q_OS_WIN)
1053 QT_NATIVE_INTERFACE_RETURN_IF(QSGD3D11Texture, &dd->m_d3d11TextureAccessor);
1054 QT_NATIVE_INTERFACE_RETURN_IF(QSGD3D12Texture, &dd->m_d3d12TextureAccessor);
1056#if QT_CONFIG(opengl)
1057 QT_NATIVE_INTERFACE_RETURN_IF(QSGOpenGLTexture, &dd->m_openglTextureAccessor);
1065#include "moc_qsgtexture.cpp"
static void qt_debug_print_texture_count()
static void qt_debug_remove_texture(QSGTexture *texture)
static void qt_debug_add_texture(QSGTexture *texture)