15#include <QtQuick/private/qsgrenderer_p.h>
16#include <QtQuick/private/qsgplaintexture_p.h>
17#include <QtQuick/private/qquickpointerhandler_p.h>
18#include <QtQuick/private/qquickpointerhandler_p_p.h>
19#include <QtQuick/private/qquicktaphandler_p.h>
20#include <private/qsgrenderloop_p.h>
21#include <private/qsgrhisupport_p.h>
22#include <private/qquickrendercontrol_p.h>
23#include <private/qquickanimatorcontroller_p.h>
24#include <private/qquickprofiler_p.h>
25#include <private/qquicktextinterface_p.h>
27#include <private/qguiapplication_p.h>
29#include <private/qabstractanimation_p.h>
31#include <QtGui/qpainter.h>
32#include <QtGui/qevent.h>
33#include <QtGui/qmatrix4x4.h>
34#include <QtGui/private/qevent_p.h>
35#include <QtGui/private/qpointingdevice_p.h>
36#include <QtCore/qvarlengtharray.h>
37#include <QtCore/qabstractanimation.h>
38#include <QtCore/QLibraryInfo>
39#include <QtCore/QRunnable>
40#include <QtQml/qqmlincubator.h>
41#include <QtQml/qqmlinfo.h>
42#include <QtQml/private/qqmlmetatype_p.h>
44#include <QtQuick/private/qquickpixmap_p.h>
46#include <private/qqmldebugserviceinterfaces_p.h>
47#include <private/qqmldebugconnector_p.h>
48#include <private/qsgdefaultrendercontext_p.h>
49#include <private/qsgsoftwarerenderer_p.h>
51#include <private/qopengl_p.h>
52#include <QOpenGLContext>
54#ifndef QT_NO_DEBUG_STREAM
55#include <private/qdebug_p.h>
57#include <QtCore/qpointer.h>
67Q_LOGGING_CATEGORY(lcQuickWindow,
"qt.quick.window")
69bool QQuickWindowPrivate::defaultAlphaBuffer =
false;
71#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
72QQuickWindow::TextRenderType QQuickWindowPrivate::textRenderType = QQuickWindow::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE;
74QQuickWindow::TextRenderType QQuickWindowPrivate::textRenderType = QQuickWindow::QtTextRendering;
135 int m_incubation_time;
139#if QT_CONFIG(accessibility)
141
142
143
144QAccessibleInterface *QQuickWindow::accessibleRoot()
const
146 return QAccessible::queryAccessibleInterface(
const_cast<QQuickWindow*>(
this));
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
170QQuickRootItem::QQuickRootItem()
174 setFlag(ItemIsViewport);
178void QQuickWindow::exposeEvent(QExposeEvent *)
181 if (d->windowManager)
182 d->windowManager->exposureChanged(
this);
186void QQuickWindow::resizeEvent(QResizeEvent *ev)
190 d->contentItem->setSize(ev->size());
191 if (d->windowManager)
192 d->windowManager->resize(
this);
196void QQuickWindow::showEvent(QShowEvent *)
199 if (d->windowManager)
200 d->windowManager->show(
this);
204void QQuickWindow::hideEvent(QHideEvent *)
207 if (
auto da = d->deliveryAgentPrivate())
208 da->handleWindowHidden(
this);
209 if (d->windowManager)
210 d->windowManager->hide(
this);
214void QQuickWindow::closeEvent(QCloseEvent *e)
216 QQuickCloseEvent qev;
217 qev.setAccepted(e->isAccepted());
219 e->setAccepted(qev.isAccepted());
223void QQuickWindow::focusOutEvent(QFocusEvent *ev)
227 d->contentItem->setFocus(
false, ev->reason());
231void QQuickWindow::focusInEvent(QFocusEvent *ev)
237 d->contentItem->setFocus(
true, ev->reason());
238 if (
auto da = d->deliveryAgentPrivate())
239 da->updateFocusItemTransform();
243static bool transformDirtyOnItemOrAncestor(
const QQuickItem *item)
246 if (QQuickItemPrivate::get(item)->dirtyAttributes & (
247 QQuickItemPrivate::TransformOrigin |
248 QQuickItemPrivate::Transform |
249 QQuickItemPrivate::BasicTransform |
250 QQuickItemPrivate::Position |
251 QQuickItemPrivate::Size |
252 QQuickItemPrivate::ParentChanged |
253 QQuickItemPrivate::Clip)) {
256 item = item->parentItem();
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
286
287
288
289 bool check(QQuickItem *item,
int itemsRemainingBeforeUpdatePolish)
291 if (itemsToPolish.size() > itemsRemainingBeforeUpdatePolish) {
306 QQuickItem *guiltyItem = itemsToPolish.last();
307 qmlWarning(item) <<
"possible QQuickItem::polish() loop";
309 auto typeAndObjectName = [](QQuickItem *item) {
310 QString typeName = QQmlMetaType::prettyTypeName(item);
311 QString objName = item->objectName();
312 if (!objName.isNull())
313 return QLatin1String(
"%1(%2)").arg(typeName, objName);
317 qmlWarning(guiltyItem) << typeAndObjectName(guiltyItem)
318 <<
" called polish() inside updatePolish() of " << typeAndObjectName(item);
329void QQuickWindowPrivate::polishItems()
339 PolishLoopDetector polishLoopDetector(itemsToPolish);
340 while (!itemsToPolish.isEmpty()) {
341 QQuickItem *item = itemsToPolish.takeLast();
342 QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
343 itemPrivate->polishScheduled =
false;
344 const int itemsRemaining = itemsToPolish.size();
345 itemPrivate->updatePolish();
346 item->updatePolish();
347 if (polishLoopDetector.check(item, itemsRemaining) ==
true)
352 if (QQuickItem *focusItem = q_func()->activeFocusItem()) {
356 const bool isActiveFocusItem = (focusItem == QGuiApplication::focusObject());
357 const bool hasImEnabled = focusItem->inputMethodQuery(Qt::ImEnabled).toBool();
358 if (isActiveFocusItem && hasImEnabled && transformDirtyOnItemOrAncestor(focusItem))
359 deliveryAgentPrivate()->updateFocusItemTransform();
363 if (needsChildWindowStackingOrderUpdate) {
364 updateChildWindowStackingOrder();
365 needsChildWindowStackingOrderUpdate =
false;
370
371
372
373
374
375
376void QQuickWindow::update()
379 if (d->windowManager)
380 d->windowManager->update(
this);
381 else if (d->renderControl)
382 QQuickRenderControlPrivate::get(d->renderControl)->update();
387 if (item->flags() & QQuickItem::ItemHasContents) {
388 QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
389 itemPrivate->itemChange(QQuickItem::ItemDevicePixelRatioHasChanged, pixelRatio);
392 QList <QQuickItem *> items = item->childItems();
393 for (
int i = 0; i < items.size(); ++i)
394 updatePixelRatioHelper(items.at(i), pixelRatio);
397void QQuickWindow::physicalDpiChanged()
400 const qreal newPixelRatio = effectiveDevicePixelRatio();
401 if (qFuzzyCompare(newPixelRatio, d->lastReportedItemDevicePixelRatio))
403 d->lastReportedItemDevicePixelRatio = newPixelRatio;
405 updatePixelRatioHelper(d->contentItem, newPixelRatio);
409void QQuickWindow::handleFontDatabaseChanged()
412 d->pendingFontUpdate =
true;
417 if (item->flags() & QQuickItem::ItemHasContents) {
421 QList <QQuickItem *> items = item->childItems();
422 for (
int i=0; i<items.size(); ++i)
423 forcePolishHelper(items.at(i));
426void QQuickWindow::handleScreenChanged(QScreen *screen)
434
435
436void QQuickWindowPrivate::forcePolish()
441 forcePolishHelper(contentItem);
446 if (item->flags() & QQuickItem::ItemHasContents)
448 QQuickItemPrivate::get(item)->dirty(QQuickItemPrivate::ChildrenUpdateMask);
450 QList <QQuickItem *> items = item->childItems();
451 for (
int i=0; i<items.size(); ++i)
452 forceUpdate(items.at(i));
459 delete rt.renderTarget;
473 delete sw.paintDevice;
488void QQuickWindowPrivate::invalidateFontData(QQuickItem *item)
490 QQuickTextInterface *textItem = qobject_cast<QQuickTextInterface *>(item);
491 if (textItem !=
nullptr)
492 textItem->invalidate();
494 QList<QQuickItem *> children = item->childItems();
495 for (QQuickItem *child : children)
496 invalidateFontData(child);
499void QQuickWindowPrivate::ensureCustomRenderTarget()
503 if (!redirect.renderTargetDirty)
506 redirect.renderTargetDirty =
false;
508 redirect.rt.reset(rhi, QQuickWindowRenderTarget::ResetFlag::KeepImplicitBuffers);
510 if (!QQuickRenderTargetPrivate::get(&customRenderTarget)->resolve(rhi, &redirect.rt)) {
511 qWarning(
"Failed to set up render target redirection for QQuickWindow");
512 redirect.rt.reset(rhi);
516void QQuickWindowPrivate::setCustomCommandBuffer(QRhiCommandBuffer *cb)
519 redirect.commandBuffer = cb;
522void QQuickWindowPrivate::syncSceneGraph()
526 const bool wasRtDirty = redirect.renderTargetDirty;
527 ensureCustomRenderTarget();
529 QRhiCommandBuffer *cb =
nullptr;
531 if (redirect.commandBuffer)
532 cb = redirect.commandBuffer;
534 cb = swapchain->currentFrameCommandBuffer();
536 context->prepareSync(q->effectiveDevicePixelRatio(), cb, graphicsConfig);
538 animationController->beforeNodeSync();
540 emit q->beforeSynchronizing();
541 runAndClearJobs(&beforeSynchronizingJobs);
543 if (pendingFontUpdate) {
545 invalidateFontData(contentItem);
546 context->invalidateGlyphCaches();
549 if (Q_UNLIKELY(!renderer)) {
550 forceUpdate(contentItem);
552 QSGRootNode *rootNode =
new QSGRootNode;
553 rootNode->appendChildNode(QQuickItemPrivate::get(contentItem)->itemNode());
554 const bool useDepth = graphicsConfig.isDepthBufferEnabledFor2D();
555 const QSGRendererInterface::RenderMode renderMode = useDepth ? QSGRendererInterface::RenderMode2D
556 : QSGRendererInterface::RenderMode2DNoDepthBuffer;
557 renderer = context->createRenderer(renderMode);
558 renderer->setRootNode(rootNode);
559 }
else if (Q_UNLIKELY(wasRtDirty)
560 && q->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) {
561 auto softwareRenderer =
static_cast<QSGSoftwareRenderer *>(renderer);
562 softwareRenderer->markDirty();
567 animationController->afterNodeSync();
569 renderer->setClearColor(clearColor);
571 renderer->setVisualizationMode(visualizationMode);
573 if (pendingFontUpdate) {
574 context->flushGlyphCaches();
575 pendingFontUpdate =
false;
578 emit q->afterSynchronizing();
579 runAndClearJobs(&afterSynchronizingJobs);
582void QQuickWindowPrivate::emitBeforeRenderPassRecording(
void *ud)
584 QQuickWindow *w =
reinterpret_cast<QQuickWindow *>(ud);
585 emit w->beforeRenderPassRecording();
588void QQuickWindowPrivate::emitAfterRenderPassRecording(
void *ud)
590 QQuickWindow *w =
reinterpret_cast<QQuickWindow *>(ud);
591 emit w->afterRenderPassRecording();
594int QQuickWindowPrivate::multiViewCount()
597 ensureCustomRenderTarget();
598 if (redirect.rt.rt.renderTarget)
599 return redirect.rt.rt.multiViewCount;
609QRhiRenderTarget *QQuickWindowPrivate::activeCustomRhiRenderTarget()
612 ensureCustomRenderTarget();
613 return redirect.rt.rt.renderTarget;
618void QQuickWindowPrivate::renderSceneGraph()
624 ensureCustomRenderTarget();
626 QSGRenderTarget sgRenderTarget;
628 QRhiRenderTarget *rt;
629 QRhiRenderPassDescriptor *rp;
630 QRhiCommandBuffer *cb;
631 if (redirect.rt.rt.renderTarget) {
632 rt = redirect.rt.rt.renderTarget;
633 rp = rt->renderPassDescriptor();
635 qWarning(
"Custom render target is set but no renderpass descriptor has been provided.");
638 cb = redirect.commandBuffer;
640 qWarning(
"Custom render target is set but no command buffer has been provided.");
645 qWarning(
"QQuickWindow: No render target (neither swapchain nor custom target was provided)");
648 rt = swapchain->currentFrameRenderTarget();
649 rp = rpDescForSwapchain;
650 cb = swapchain->currentFrameCommandBuffer();
652 sgRenderTarget = QSGRenderTarget(rt, rp, cb);
653 sgRenderTarget.multiViewCount = multiViewCount();
655 sgRenderTarget = QSGRenderTarget(redirect.rt.sw.paintDevice);
658 context->beginNextFrame(renderer,
660 emitBeforeRenderPassRecording,
661 emitAfterRenderPassRecording,
664 animationController->advance();
665 emit q->beforeRendering();
666 runAndClearJobs(&beforeRenderingJobs);
668 const qreal devicePixelRatio = q->effectiveDevicePixelRatio();
670 if (redirect.rt.rt.renderTarget)
671 pixelSize = redirect.rt.rt.renderTarget->pixelSize();
672 else if (redirect.rt.sw.paintDevice)
673 pixelSize = QSize(redirect.rt.sw.paintDevice->width(), redirect.rt.sw.paintDevice->height());
675 pixelSize = swapchain->currentPixelSize();
677 pixelSize = q->size() * devicePixelRatio;
679 renderer->setDevicePixelRatio(devicePixelRatio);
680 renderer->setDeviceRect(QRect(QPoint(0, 0), pixelSize));
681 renderer->setViewportRect(QRect(QPoint(0, 0), pixelSize));
683 QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
684 bool flipY = rhi ? !rhi->isYUpInNDC() :
false;
685 if (!customRenderTarget.isNull() && customRenderTarget.mirrorVertically())
688 matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
690 const QRectF rect(QPointF(0, 0), pixelSize / devicePixelRatio);
691 renderer->setProjectionMatrixToRect(rect, matrixFlags, rhi && !rhi->isYUpInNDC());
693 context->renderNextFrame(renderer);
695 emit q->afterRendering();
696 runAndClearJobs(&afterRenderingJobs);
698 context->endNextFrame(renderer);
700 if (renderer && renderer->hasVisualizationModeWithContinuousUpdate()) {
704 QCoreApplication::postEvent(q,
new QEvent(QEvent::Type(FullUpdateRequest)));
708QQuickWindowPrivate::QQuickWindowPrivate()
709 : contentItem(
nullptr)
710 , dirtyItemList(
nullptr)
711 , lastReportedItemDevicePixelRatio(0)
714 , windowManager(
nullptr)
715 , renderControl(
nullptr)
716 , clearColor(Qt::white)
717 , persistentGraphics(
true)
718 , persistentSceneGraph(
true)
719 , inDestructor(
false)
720 , incubationController(
nullptr)
721 , hasActiveSwapchain(
false)
722 , hasRenderableSwapchain(
false)
723 , swapchainJustBecameRenderable(
false)
724 , updatesEnabled(
true)
728QQuickWindowPrivate::~QQuickWindowPrivate()
731 redirect.rt.reset(rhi);
732 if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
733 service->removeWindow(q_func());
734 deliveryAgent =
nullptr;
737void QQuickWindowPrivate::setPalette(QQuickPalette* palette)
739 if (windowPaletteRef == palette)
742 if (windowPaletteRef)
743 disconnect(windowPaletteRef, &QQuickPalette::changed,
this, &QQuickWindowPrivate::updateWindowPalette);
744 windowPaletteRef = palette;
745 updateWindowPalette();
746 if (windowPaletteRef)
747 connect(windowPaletteRef, &QQuickPalette::changed,
this, &QQuickWindowPrivate::updateWindowPalette);
750void QQuickWindowPrivate::updateWindowPalette()
752 QQuickPaletteProviderPrivateBase::setPalette(windowPaletteRef);
755void QQuickWindowPrivate::updateChildrenPalettes(
const QPalette &parentPalette)
758 if (
auto root = q->contentItem()) {
759 for (
auto &&child: root->childItems()) {
760 QQuickItemPrivate::get(child)->inheritPalette(parentPalette);
765void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
772 contentItem =
new QQuickRootItem;
773 contentItem->setObjectName(q->objectName());
774 QQml_setParent_noEvent(contentItem, c);
775 QQmlEngine::setObjectOwnership(contentItem, QQmlEngine::CppOwnership);
776 QQuickItemPrivate *contentItemPrivate = QQuickItemPrivate::get(contentItem);
777 contentItemPrivate->window = q;
778 contentItemPrivate->windowRefCount = 1;
779 contentItemPrivate->flags |= QQuickItem::ItemIsFocusScope;
780 contentItem->setSize(q->size());
781 deliveryAgent =
new QQuickDeliveryAgent(contentItem);
783 visualizationMode = qgetenv(
"QSG_VISUALIZE");
784 renderControl = control;
786 QQuickRenderControlPrivate::get(renderControl)->window = q;
789 windowManager = QSGRenderLoop::instance();
791 Q_ASSERT(windowManager || renderControl);
793 QObject::connect(
static_cast<QGuiApplication *>(QGuiApplication::instance()),
794 &QGuiApplication::fontDatabaseChanged,
796 &QQuickWindow::handleFontDatabaseChanged);
799 lastReportedItemDevicePixelRatio = q->effectiveDevicePixelRatio();
804 QQuickRenderControlPrivate *renderControlPriv = QQuickRenderControlPrivate::get(renderControl);
805 sg = renderControlPriv->sg;
806 context = renderControlPriv->rc;
808 windowManager->addWindow(q);
809 sg = windowManager->sceneGraphContext();
810 context = windowManager->createRenderContext(sg);
813 q->setSurfaceType(windowManager ? windowManager->windowSurfaceType() : QSurface::OpenGLSurface);
814 q->setFormat(sg->defaultSurfaceFormat());
820 animationController.reset(
new QQuickAnimatorController(q));
823 QObject::connect(context, &QSGRenderContext::initialized, q, &QQuickWindow::sceneGraphInitialized, Qt::DirectConnection),
824 QObject::connect(context, &QSGRenderContext::invalidated, q, &QQuickWindow::sceneGraphInvalidated, Qt::DirectConnection),
825 QObject::connect(context, &QSGRenderContext::invalidated, q, &QQuickWindow::cleanupSceneGraph, Qt::DirectConnection),
827 QObject::connect(q, &QQuickWindow::focusObjectChanged, q, &QQuickWindow::activeFocusItemChanged),
828 QObject::connect(q, &QQuickWindow::screenChanged, q, &QQuickWindow::handleScreenChanged),
829 QObject::connect(qApp, &QGuiApplication::applicationStateChanged, q, &QQuickWindow::handleApplicationStateChanged),
830 QObject::connect(q, &QQuickWindow::frameSwapped, q, &QQuickWindow::runJobsAfterSwap, Qt::DirectConnection),
833 if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
834 service->addWindow(q);
837void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state)
840 if (state != Qt::ApplicationActive && d->contentItem) {
841 auto da = d->deliveryAgentPrivate();
843 da->handleWindowDeactivate(
this);
848
849
850
852QQmlListProperty<QObject> QQuickWindowPrivate::data()
854 QQmlListProperty<QObject> ret;
856 ret.object = q_func();
857 ret.append = QQuickWindowPrivate::data_append;
858 ret.count = QQuickWindowPrivate::data_count;
859 ret.at = QQuickWindowPrivate::data_at;
860 ret.clear = QQuickWindowPrivate::data_clear;
862 ret.removeLast = QQuickWindowPrivate::data_removeLast;
867void QQuickWindowPrivate::dirtyItem(QQuickItem *item)
871 QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(item);
872 if (itemPriv->dirtyAttributes & QQuickItemPrivate::ChildrenStackingChanged)
873 needsChildWindowStackingOrderUpdate =
true;
879
880
881
882QQuickItem *QQuickWindow::mouseGrabberItem()
const
884 Q_D(
const QQuickWindow);
885 auto da =
const_cast<QQuickWindowPrivate *>(d)->deliveryAgentPrivate();
889 if (
auto epd = da->mousePointData())
890 return qmlobject_cast<QQuickItem *>(epd->exclusiveGrabber);
892 if (Q_LIKELY(d->deliveryAgentPrivate()->eventsInDelivery.isEmpty()))
894 qCDebug(lcMouse,
"mouse grabber ambiguous: no event is currently being delivered");
898 return qmlobject_cast<QQuickItem *>(QPointingDevicePrivate::get(QPointingDevice::primaryPointingDevice())->
899 firstPointExclusiveGrabber());
902void QQuickWindowPrivate::cleanup(QSGNode *n)
906 Q_ASSERT(!cleanupNodeList.contains(n));
907 cleanupNodeList.append(n);
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
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
956
957
958
959
960
961
962
963
964
965
966
967
968
969
972
973
974
975
976
977
978
979
980
981
982
983
984
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
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1166
1167
1168QQuickWindow::QQuickWindow(QWindow *parent)
1169 : QQuickWindow(*
new QQuickWindowPrivate, parent)
1176
1177
1178QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QWindow *parent)
1179 : QWindow(dd, parent)
1186
1187
1188
1189
1190
1191
1192QQuickWindow::QQuickWindow(QQuickRenderControl *control)
1193 : QWindow(*(
new QQuickWindowPrivate),
nullptr)
1196 d->init(
this, control);
1200
1201
1202QQuickWindow::QQuickWindow(QQuickWindowPrivate &dd, QQuickRenderControl *control)
1203 : QWindow(dd,
nullptr)
1206 d->init(
this, control);
1210
1211
1212QQuickWindow::~QQuickWindow()
1215 d->inDestructor =
true;
1216 if (d->renderControl) {
1217 QQuickRenderControlPrivate::get(d->renderControl)->windowDestroyed();
1218 }
else if (d->windowManager) {
1219 d->windowManager->removeWindow(
this);
1220 d->windowManager->windowDestroyed(
this);
1223 disconnect(
this, &QQuickWindow::focusObjectChanged,
this, &QQuickWindow::activeFocusItemChanged);
1224 disconnect(
this, &QQuickWindow::screenChanged,
this, &QQuickWindow::handleScreenChanged);
1225 disconnect(qApp, &QGuiApplication::applicationStateChanged,
this, &QQuickWindow::handleApplicationStateChanged);
1226 disconnect(
this, &QQuickWindow::frameSwapped,
this, &QQuickWindow::runJobsAfterSwap);
1228 delete d->incubationController; d->incubationController =
nullptr;
1229 QQuickRootItem *root = d->contentItem;
1230 d->contentItem =
nullptr;
1231 root->setParent(
nullptr);
1233 d->deliveryAgent =
nullptr;
1237 const std::lock_guard locker(d->renderJobMutex);
1238 qDeleteAll(std::exchange(d->beforeSynchronizingJobs, {}));
1239 qDeleteAll(std::exchange(d->afterSynchronizingJobs, {}));
1240 qDeleteAll(std::exchange(d->beforeRenderingJobs, {}));
1241 qDeleteAll(std::exchange(d->afterRenderingJobs, {}));;
1242 qDeleteAll(std::exchange(d->afterSwapJobs, {}));
1250 QQuickPixmap::purgeCache();
1252 for (
const QMetaObject::Connection &connection : d->connections)
1253 disconnect(connection);
1256#if QT_CONFIG(quick_shadereffect)
1257void qtquick_shadereffect_purge_gui_thread_shader_cache();
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1286void QQuickWindow::releaseResources()
1289 if (d->windowManager)
1290 d->windowManager->releaseResources(
this);
1291 QQuickPixmap::purgeCache();
1292#if QT_CONFIG(quick_shadereffect)
1293 qtquick_shadereffect_purge_gui_thread_shader_cache();
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1327void QQuickWindow::setPersistentGraphics(
bool persistent)
1330 d->persistentGraphics = persistent;
1336
1337
1338
1339
1340
1341
1342
1344bool QQuickWindow::isPersistentGraphics()
const
1346 Q_D(
const QQuickWindow);
1347 return d->persistentGraphics;
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1374void QQuickWindow::setPersistentSceneGraph(
bool persistent)
1377 d->persistentSceneGraph = persistent;
1383
1384
1385
1386
1387
1388
1390bool QQuickWindow::isPersistentSceneGraph()
const
1392 Q_D(
const QQuickWindow);
1393 return d->persistentSceneGraph;
1397
1398
1399
1400
1401
1402
1403
1406
1407
1408
1409
1410
1411
1412
1413QQuickItem *QQuickWindow::contentItem()
const
1415 Q_D(
const QQuickWindow);
1417 return d->contentItem;
1421
1422
1423
1424
1425
1426
1427
1428QQuickItem *QQuickWindow::activeFocusItem()
const
1430 Q_D(
const QQuickWindow);
1431 auto da = d->deliveryAgentPrivate();
1433 return da->activeFocusItem;
1437
1438
1439
1440QObject *QQuickWindow::focusObject()
const
1442 Q_D(
const QQuickWindow);
1443 auto da = d->deliveryAgentPrivate();
1445 if (!d->inDestructor && da->activeFocusItem)
1446 return da->activeFocusItem;
1447 return const_cast<QQuickWindow*>(
this);
1451bool QQuickWindow::event(QEvent *event)
1456 QQuickDeliveryAgent *da = d->deliveryAgent;
1457 if (event->isPointerEvent()) {
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468 if (d->windowEventDispatch)
1471 const bool wasAccepted = event->isAccepted();
1472 QScopedValueRollback windowEventDispatchGuard(d->windowEventDispatch,
true);
1473 qCDebug(lcPtr) <<
"dispatching to window functions in case of override" << event;
1474 QWindow::event(event);
1475 if (event->isAccepted() && !wasAccepted)
1479
1480
1481
1482
1483
1484
1485 auto pe =
static_cast<QPointerEvent *>(event);
1486 if (QQuickDeliveryAgentPrivate::isTouchEvent(pe))
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503 if (pe->pointCount()) {
1504 const bool synthMouse = QQuickDeliveryAgentPrivate::isSynthMouse(pe);
1505 if (QQuickDeliveryAgentPrivate::subsceneAgentsExist) {
1509 QFlatMap<QQuickDeliveryAgent*, QList<QEventPoint>> deliveryAgentsNeedingPoints;
1510 QEventPoint::States eventStates;
1512 auto insert = [&](QQuickDeliveryAgent *ptda,
const QEventPoint &pt) {
1513 if (pt.state() == QEventPoint::Pressed && !synthMouse)
1514 pe->clearPassiveGrabbers(pt);
1515 auto &ptList = deliveryAgentsNeedingPoints[ptda];
1516 auto idEquals = [](
auto id) {
return [id] (
const auto &e) {
return e.id() == id; }; };
1517 if (std::none_of(ptList.cbegin(), ptList.cend(), idEquals(pt.id())))
1521 for (
const auto &pt : pe->points()) {
1522 eventStates |= pt.state();
1523 auto epd = QPointingDevicePrivate::get(
const_cast<QPointingDevice*>(pe->pointingDevice()))->queryPointById(pt.id());
1525 bool foundAgent =
false;
1526 if (!epd->exclusiveGrabber.isNull() && !epd->exclusiveGrabberContext.isNull()) {
1527 if (
auto ptda = qobject_cast<QQuickDeliveryAgent *>(epd->exclusiveGrabberContext.data())) {
1529 qCDebug(lcPtr) << pe->type() <<
"point" << pt.id() << pt.state()
1530 <<
"@" << pt.scenePosition() <<
"will be re-delivered via known grabbing agent" << ptda <<
"to" << epd->exclusiveGrabber.data();
1534 for (
auto pgda : epd->passiveGrabbersContext) {
1535 if (
auto ptda = qobject_cast<QQuickDeliveryAgent *>(pgda.data())) {
1537 qCDebug(lcPtr) << pe->type() <<
"point" << pt.id() << pt.state()
1538 <<
"@" << pt.scenePosition() <<
"will be re-delivered via known passive-grabbing agent" << ptda;
1546 for (
auto daAndPoints : deliveryAgentsNeedingPoints) {
1547 if (pe->pointCount() > 1) {
1548 Q_ASSERT(QQuickDeliveryAgentPrivate::isTouchEvent(pe));
1550 QEvent::Type eventType = pe->type();
1551 switch (eventStates) {
1552 case QEventPoint::State::Pressed:
1553 eventType = QEvent::TouchBegin;
1555 case QEventPoint::State::Released:
1556 eventType = QEvent::TouchEnd;
1559 eventType = QEvent::TouchUpdate;
1563 QMutableTouchEvent te(eventType, pe->pointingDevice(), pe->modifiers(), daAndPoints.second);
1564 te.setTimestamp(pe->timestamp());
1566 qCDebug(lcTouch) << daAndPoints.first <<
"shall now receive" << &te;
1567 ret = daAndPoints.first->event(&te) || ret;
1569 qCDebug(lcPtr) << daAndPoints.first <<
"shall now receive" << pe;
1570 ret = daAndPoints.first->event(pe) || ret;
1575 d->deliveryAgentPrivate()->clearGrabbers(pe);
1578 }
else if (!synthMouse) {
1581 for (
const auto &pt : pe->points()) {
1582 if (pt.state() == QEventPoint::Pressed)
1583 pe->clearPassiveGrabbers(pt);
1592 qCDebug(lcHoverTrace) <<
this <<
"some sort of event" << event;
1593 bool ret = (da && da->event(event));
1595 d->deliveryAgentPrivate()->clearGrabbers(pe);
1597 if (pe->type() == QEvent::MouseButtonPress || pe->type() == QEvent::MouseButtonRelease) {
1600 d->maybeSynthesizeContextMenuEvent(
static_cast<QMouseEvent *>(pe));
1605 }
else if (event->isInputEvent()) {
1606 if (da && da->event(event))
1610 switch (event->type()) {
1612 case QEvent::FocusAboutToChange:
1615 case QEvent::InputMethod:
1616 case QEvent::InputMethodQuery:
1617#if QT_CONFIG(quick_draganddrop)
1618 case QEvent::DragEnter:
1619 case QEvent::DragLeave:
1620 case QEvent::DragMove:
1623 if (d->inDestructor)
1625 if (da && da->event(event))
1628 case QEvent::LanguageChange:
1629 case QEvent::LocaleChange:
1631 QCoreApplication::sendEvent(d->contentItem, event);
1633 case QEvent::UpdateRequest:
1634 if (d->windowManager)
1635 d->windowManager->handleUpdateRequest(
this);
1637 case QEvent::PlatformSurface:
1638 if ((
static_cast<QPlatformSurfaceEvent *>(event))->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) {
1641 if (d->windowManager)
1642 d->windowManager->hide(
this);
1645 case QEvent::WindowDeactivate:
1646 if (
auto da = d->deliveryAgentPrivate())
1647 da->handleWindowDeactivate(
this);
1649 case QEvent::WindowActivate:
1651 QCoreApplication::sendEvent(d->contentItem, event);
1653 case QEvent::ApplicationPaletteChange:
1654 d->inheritPalette(QGuiApplication::palette());
1656 QCoreApplication::sendEvent(d->contentItem, event);
1658 case QEvent::DevicePixelRatioChange:
1659 physicalDpiChanged();
1661 case QEvent::SafeAreaMarginsChange:
1662 QQuickSafeArea::updateSafeAreasRecursively(d->contentItem);
1664 case QEvent::ChildWindowAdded: {
1665 auto *childEvent =
static_cast<QChildWindowEvent*>(event);
1666 auto *childWindow = childEvent->child();
1667 qCDebug(lcQuickWindow) <<
"Child window" << childWindow <<
"added to" <<
this;
1668 if (childWindow->handle()) {
1674 d->updateChildWindowStackingOrder();
1676 qCDebug(lcQuickWindow) <<
"No platform window yet."
1677 <<
"Deferring child window stacking until surface creation";
1685 if (event->type() == QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))
1687 else if (event->type() == QEvent::Type(QQuickWindowPrivate::TriggerContextCreationFailure))
1688 d->windowManager->handleContextCreationFailure(
this);
1690 if (event->isPointerEvent())
1693 return QWindow::event(event);
1696void QQuickWindowPrivate::maybeSynthesizeContextMenuEvent(QMouseEvent *event)
1705 if (windowEventDispatch || !rmbContextMenuEventEnabled)
1708#if QT_VERSION < QT_VERSION_CHECK(7
, 0
, 0
)
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724 const auto &firstPoint = event->points().first();
1725 auto hasRightButtonTapHandler = [](
const auto &passiveGrabbers) {
1726 return std::find_if(passiveGrabbers.constBegin(), passiveGrabbers.constEnd(),
1727 [](
const auto grabber) {
1728 auto *tapHandler = qmlobject_cast<QQuickTapHandler *>(grabber);
1729 return tapHandler && tapHandler->acceptedButtons().testFlag(Qt::RightButton); })
1730 != passiveGrabbers.constEnd();
1732 if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::RightButton &&
1733 (qmlobject_cast<QQuickMouseArea *>(event->exclusiveGrabber(firstPoint))
1734 || hasRightButtonTapHandler(event->passiveGrabbers(firstPoint)))) {
1735 qCDebug(lcPtr) <<
"skipping QContextMenuEvent synthesis due to grabber(s)" << event;
1740 QWindowPrivate::maybeSynthesizeContextMenuEvent(event);
1743void QQuickWindowPrivate::updateChildWindowStackingOrder(QQuickItem *item)
1748 qCDebug(lcQuickWindow) <<
"Updating child window stacking order for" << q;
1751 auto *itemPrivate = QQuickItemPrivate::get(item);
1752 const auto paintOrderChildItems = itemPrivate->paintOrderChildItems();
1753 for (
auto *child : paintOrderChildItems) {
1754 if (
auto *windowContainer = qobject_cast<QQuickWindowContainer*>(child)) {
1755 auto *window = windowContainer->containedWindow();
1757 qCDebug(lcQuickWindow) << windowContainer <<
"has no contained window yet";
1760 if (window->parent() != q) {
1761 qCDebug(lcQuickWindow) << window <<
"is not yet child of this window";
1764 qCDebug(lcQuickWindow) <<
"Raising" << window <<
"owned by" << windowContainer;
1768 updateChildWindowStackingOrder(child);
1773void QQuickWindow::keyPressEvent(QKeyEvent *e)
1776 if (d->windowEventDispatch)
1778 auto da = d->deliveryAgentPrivate();
1780 da->deliverKeyEvent(e);
1784void QQuickWindow::keyReleaseEvent(QKeyEvent *e)
1787 if (d->windowEventDispatch)
1789 auto da = d->deliveryAgentPrivate();
1791 da->deliverKeyEvent(e);
1794#if QT_CONFIG(wheelevent)
1796void QQuickWindow::wheelEvent(QWheelEvent *event)
1799 if (d->windowEventDispatch)
1801 auto da = d->deliveryAgentPrivate();
1803 da->deliverSinglePointEventUntilAccepted(event);
1807#if QT_CONFIG(tabletevent)
1809void QQuickWindow::tabletEvent(QTabletEvent *event)
1812 if (d->windowEventDispatch)
1814 auto da = d->deliveryAgentPrivate();
1816 da->deliverPointerEvent(event);
1821void QQuickWindow::mousePressEvent(QMouseEvent *event)
1824 if (d->windowEventDispatch)
1826 auto da = d->deliveryAgentPrivate();
1828 da->handleMouseEvent(event);
1831void QQuickWindow::mouseMoveEvent(QMouseEvent *event)
1834 if (d->windowEventDispatch)
1836 auto da = d->deliveryAgentPrivate();
1838 da->handleMouseEvent(event);
1841void QQuickWindow::mouseDoubleClickEvent(QMouseEvent *event)
1844 if (d->windowEventDispatch)
1846 auto da = d->deliveryAgentPrivate();
1848 da->handleMouseEvent(event);
1851void QQuickWindow::mouseReleaseEvent(QMouseEvent *event)
1854 if (d->windowEventDispatch)
1856 auto da = d->deliveryAgentPrivate();
1858 da->handleMouseEvent(event);
1861#if QT_CONFIG(cursor)
1862void QQuickWindowPrivate::updateCursor(
const QPointF &scenePos, QQuickItem *rootItem)
1866 rootItem = contentItem;
1867 auto cursorItemAndHandler = findCursorItemAndHandler(rootItem, scenePos);
1868 if (cursorItem != cursorItemAndHandler.first || cursorHandler != cursorItemAndHandler.second ||
1869 (cursorItemAndHandler.second && QQuickPointerHandlerPrivate::get(cursorItemAndHandler.second)->cursorDirty)) {
1870 QWindow *renderWindow = QQuickRenderControl::renderWindowFor(q);
1871 QWindow *window = renderWindow ? renderWindow : q;
1872 cursorItem = cursorItemAndHandler.first;
1873 cursorHandler = cursorItemAndHandler.second;
1875 QQuickPointerHandlerPrivate::get(cursorItemAndHandler.second)->cursorDirty =
false;
1877 const auto cursor = QQuickItemPrivate::get(cursorItem)->effectiveCursor(cursorHandler);
1878 qCDebug(lcHoverTrace) <<
"setting cursor" << cursor <<
"from" << cursorHandler <<
"or" << cursorItem;
1879 window->setCursor(cursor);
1881 qCDebug(lcHoverTrace) <<
"unsetting cursor";
1882 window->unsetCursor();
1887std::pair<QQuickItem*, QQuickPointerHandler*> QQuickWindowPrivate::findCursorItemAndHandler(QQuickItem *item,
const QPointF &scenePos)
const
1889 QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
1890 if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
1891 QPointF p = item->mapFromScene(scenePos);
1892 if (!item->contains(p))
1893 return {
nullptr,
nullptr};
1896 if (itemPrivate->subtreeCursorEnabled) {
1897 QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
1898 for (
int ii = children.size() - 1; ii >= 0; --ii) {
1899 QQuickItem *child = children.at(ii);
1900 if (!child->isVisible() || !child->isEnabled() || QQuickItemPrivate::get(child)->culled)
1902 auto ret = findCursorItemAndHandler(child, scenePos);
1906 if (itemPrivate->hasCursorHandler) {
1907 if (
auto handler = itemPrivate->effectiveCursorHandler()) {
1908 if (handler->parentContains(scenePos))
1909 return {item, handler};
1912 if (itemPrivate->hasCursor) {
1913 QPointF p = item->mapFromScene(scenePos);
1914 if (item->contains(p))
1915 return {item,
nullptr};
1919 return {
nullptr,
nullptr};
1923void QQuickWindowPrivate::clearFocusObject()
1925 if (
auto da = deliveryAgentPrivate())
1926 da->clearFocusObject();
1929void QQuickWindowPrivate::setFocusToTarget(FocusTarget target, Qt::FocusReason reason)
1934 QQuickItem *newFocusItem =
nullptr;
1936 case FocusTarget::First:
1937 case FocusTarget::Last: {
1938 const bool forward = (target == FocusTarget::First);
1939 newFocusItem = QQuickItemPrivate::nextPrevItemInTabFocusChain(contentItem, forward);
1941 const auto *itemPriv = QQuickItemPrivate::get(newFocusItem);
1942 if (itemPriv->subFocusItem && itemPriv->flags & QQuickItem::ItemIsFocusScope)
1943 deliveryAgentPrivate()->clearFocusInScope(newFocusItem, itemPriv->subFocusItem, reason);
1947 case FocusTarget::Next:
1948 case FocusTarget::Prev: {
1949 const auto da = deliveryAgentPrivate();
1951 QQuickItem *focusItem = da->focusTargetItem() ? da->focusTargetItem() : contentItem;
1952 bool forward = (target == FocusTarget::Next);
1953 newFocusItem = QQuickItemPrivate::nextPrevItemInTabFocusChain(focusItem, forward);
1961 newFocusItem->forceActiveFocus(reason);
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1988void QQuickWindowPrivate::data_append(QQmlListProperty<QObject> *property, QObject *o)
1992 QQuickWindow *that =
static_cast<QQuickWindow *>(property->object);
1993 QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(that->contentItem())->data();
1994 itemProperty.append(&itemProperty, o);
1997qsizetype QQuickWindowPrivate::data_count(QQmlListProperty<QObject> *property)
1999 QQuickWindow *win =
static_cast<QQuickWindow*>(property->object);
2000 if (!win || !win->contentItem() || !QQuickItemPrivate::get(win->contentItem())->data().count)
2002 QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
2003 return itemProperty.count(&itemProperty);
2006QObject *QQuickWindowPrivate::data_at(QQmlListProperty<QObject> *property, qsizetype i)
2008 QQuickWindow *win =
static_cast<QQuickWindow*>(property->object);
2009 QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
2010 return itemProperty.at(&itemProperty, i);
2013void QQuickWindowPrivate::data_clear(QQmlListProperty<QObject> *property)
2015 QQuickWindow *win =
static_cast<QQuickWindow*>(property->object);
2016 QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
2017 itemProperty.clear(&itemProperty);
2020void QQuickWindowPrivate::data_removeLast(QQmlListProperty<QObject> *property)
2022 QQuickWindow *win =
static_cast<QQuickWindow*>(property->object);
2023 QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
2024 itemProperty.removeLast(&itemProperty);
2027bool QQuickWindowPrivate::isRenderable()
const
2029 Q_Q(
const QQuickWindow);
2030 return ((q->isExposed() && q->isVisible())) && q->geometry().isValid();
2033void QQuickWindowPrivate::rhiCreationFailureMessage(
const QString &backendName,
2034 QString *translatedMessage,
2035 QString *untranslatedMessage)
2037 const char msg[] = QT_TRANSLATE_NOOP(
"QQuickWindow",
2038 "Failed to initialize graphics backend for %1.");
2039 *translatedMessage = QQuickWindow::tr(msg).arg(backendName);
2040 *untranslatedMessage = QString::fromLatin1(msg).arg(backendName);
2043void QQuickWindowPrivate::cleanupNodes()
2045 qDeleteAll(cleanupNodeList);
2046 cleanupNodeList.clear();
2049void QQuickWindowPrivate::cleanupNodesOnShutdown(QQuickItem *item)
2051 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
2052 if (p->itemNodeInstance) {
2053 delete p->itemNodeInstance;
2054 p->itemNodeInstance =
nullptr;
2056 if (p->extra.isAllocated()) {
2057 p->extra->opacityNode =
nullptr;
2058 p->extra->clipNode =
nullptr;
2059 p->extra->rootNode =
nullptr;
2062 p->paintNode =
nullptr;
2064 p->dirty(QQuickItemPrivate::Window);
2068 if (p->flags & QQuickItem::ItemHasContents) {
2069 const QMetaObject *mo = item->metaObject();
2070 int index = mo->indexOfSlot(
"invalidateSceneGraph()");
2072 const QMetaMethod &method = mo->method(index);
2074 if (strstr(method.enclosingMetaObject()->className(),
"_QML_") ==
nullptr)
2075 method.invoke(item, Qt::DirectConnection);
2079 for (
int ii = 0; ii < p->childItems.size(); ++ii)
2080 cleanupNodesOnShutdown(p->childItems.at(ii));
2084void QQuickWindowPrivate::cleanupNodesOnShutdown()
2088 cleanupNodesOnShutdown(contentItem);
2089 for (QSet<QQuickItem *>::const_iterator it = parentlessItems.begin(), cend = parentlessItems.end(); it != cend; ++it)
2090 cleanupNodesOnShutdown(*it);
2091 animationController->windowNodesDestroyed();
2092 q->cleanupSceneGraph();
2095void QQuickWindowPrivate::updateDirtyNodes()
2097 qCDebug(lcDirty) <<
"QQuickWindowPrivate::updateDirtyNodes():";
2101 QQuickItem *updateList = dirtyItemList;
2102 dirtyItemList =
nullptr;
2103 if (updateList) QQuickItemPrivate::get(updateList)->prevDirtyItem = &updateList;
2105 while (updateList) {
2106 QQuickItem *item = updateList;
2107 QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(item);
2108 itemPriv->removeFromDirtyList();
2110 qCDebug(lcDirty) <<
" QSGNode:" << item << qPrintable(itemPriv->dirtyToString());
2111 updateDirtyNode(item);
2117 const QList<QQuickItem *> childItems = d->paintOrderChildItems();
2118 QQuickItem *before =
nullptr;
2119 for (
int i=0; i<childItems.size(); ++i) {
2120 QQuickItemPrivate *dd = QQuickItemPrivate::get(childItems.at(i));
2122 if (dd->z() < 0 && (dd->explicitVisible || (dd->extra.isAllocated() && dd->extra->effectRefCount)))
2123 before = childItems.at(i);
2127 return Q_UNLIKELY(before) ? QQuickItemPrivate::get(before)->itemNode() :
nullptr;
2130static QSGNode *
fetchNextNode(QQuickItemPrivate *itemPriv,
int &ii,
bool &returnedPaintNode)
2132 QList<QQuickItem *> orderedChildren = itemPriv->paintOrderChildItems();
2134 for (; ii < orderedChildren.size() && orderedChildren.at(ii)->z() < 0; ++ii) {
2135 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(orderedChildren.at(ii));
2136 if (!childPrivate->explicitVisible &&
2137 (!childPrivate->extra.isAllocated() || !childPrivate->extra->effectRefCount))
2141 return childPrivate->itemNode();
2144 if (itemPriv->paintNode && !returnedPaintNode) {
2145 returnedPaintNode =
true;
2146 return itemPriv->paintNode;
2149 for (; ii < orderedChildren.size(); ++ii) {
2150 QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(orderedChildren.at(ii));
2151 if (!childPrivate->explicitVisible &&
2152 (!childPrivate->extra.isAllocated() || !childPrivate->extra->effectRefCount))
2156 return childPrivate->itemNode();
2162void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
2164 QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(item);
2165 quint32 dirty = itemPriv->dirtyAttributes;
2166 itemPriv->dirtyAttributes = 0;
2168 if ((dirty & QQuickItemPrivate::TransformUpdateMask) ||
2169 (dirty & QQuickItemPrivate::Size && itemPriv->origin() != QQuickItem::TopLeft &&
2170 (itemPriv->scale() != 1. || itemPriv->rotation() != 0.))) {
2174 if (itemPriv->x != 0. || itemPriv->y != 0.)
2175 matrix.translate(itemPriv->x, itemPriv->y);
2177 for (
int ii = itemPriv->transforms.size() - 1; ii >= 0; --ii)
2178 itemPriv->transforms.at(ii)->applyTo(&matrix);
2180 if (itemPriv->scale() != 1. || itemPriv->rotation() != 0.) {
2181 QPointF origin = item->transformOriginPoint();
2182 matrix.translate(origin.x(), origin.y());
2183 if (itemPriv->scale() != 1.)
2184 matrix.scale(itemPriv->scale(), itemPriv->scale());
2185 if (itemPriv->rotation() != 0.)
2186 matrix.rotate(itemPriv->rotation(), 0, 0, 1);
2187 matrix.translate(-origin.x(), -origin.y());
2190 itemPriv->itemNode()->setMatrix(matrix);
2193 const bool clipEffectivelyChanged = dirty & (QQuickItemPrivate::Clip | QQuickItemPrivate::Window);
2194 if (clipEffectivelyChanged) {
2195 QSGNode *parent = itemPriv->opacityNode() ? (QSGNode *)itemPriv->opacityNode()
2196 : (QSGNode *)itemPriv->itemNode();
2197 QSGNode *child = itemPriv->rootNode();
2199 if (
bool initializeClipNode = item->clip() && itemPriv->clipNode() ==
nullptr;
2200 initializeClipNode) {
2201 QQuickDefaultClipNode *clip =
new QQuickDefaultClipNode(item->clipRect());
2202 itemPriv->extra.value().clipNode = clip;
2206 parent->reparentChildNodesTo(clip);
2207 parent->appendChildNode(clip);
2209 parent->removeChildNode(child);
2210 clip->appendChildNode(child);
2211 parent->appendChildNode(clip);
2214 }
else if (
bool updateClipNode = item->clip() && itemPriv->clipNode() !=
nullptr;
2216 QQuickDefaultClipNode *clip = itemPriv->clipNode();
2217 clip->setClipRect(item->clipRect());
2219 }
else if (
bool removeClipNode = !item->clip() && itemPriv->clipNode() !=
nullptr;
2221 QQuickDefaultClipNode *clip = itemPriv->clipNode();
2222 parent->removeChildNode(clip);
2224 clip->removeChildNode(child);
2225 parent->appendChildNode(child);
2227 clip->reparentChildNodesTo(parent);
2230 delete itemPriv->clipNode();
2231 itemPriv->extra->clipNode =
nullptr;
2235 const int effectRefCount = itemPriv->extra.isAllocated() ? itemPriv->extra->effectRefCount : 0;
2236 const bool effectRefEffectivelyChanged =
2237 (dirty & (QQuickItemPrivate::EffectReference | QQuickItemPrivate::Window))
2238 && ((effectRefCount == 0) != (itemPriv->rootNode() ==
nullptr));
2239 if (effectRefEffectivelyChanged) {
2240 if (dirty & QQuickItemPrivate::ChildrenUpdateMask)
2241 itemPriv->childContainerNode()->removeAllChildNodes();
2243 QSGNode *parent = itemPriv->clipNode();
2245 parent = itemPriv->opacityNode();
2247 parent = itemPriv->itemNode();
2249 if (itemPriv->extra.isAllocated() && itemPriv->extra->effectRefCount) {
2250 Q_ASSERT(itemPriv->rootNode() ==
nullptr);
2251 QSGRootNode *root =
new QSGRootNode();
2252 itemPriv->extra->rootNode = root;
2253 parent->reparentChildNodesTo(root);
2254 parent->appendChildNode(root);
2256 Q_ASSERT(itemPriv->rootNode() !=
nullptr);
2257 QSGRootNode *root = itemPriv->rootNode();
2258 parent->removeChildNode(root);
2259 root->reparentChildNodesTo(parent);
2260 delete itemPriv->rootNode();
2261 itemPriv->extra->rootNode =
nullptr;
2265 if (dirty & QQuickItemPrivate::ChildrenUpdateMask) {
2267 bool fetchedPaintNode =
false;
2268 QList<QQuickItem *> orderedChildren = itemPriv->paintOrderChildItems();
2269 int desiredNodesSize = orderedChildren.size() + (itemPriv->paintNode ? 1 : 0);
2277 int desiredNodesProcessed = 0;
2282 QSGNode *groupNode = itemPriv->childContainerNode();
2283 QSGNode *currentNode = groupNode->firstChild();
2284 QSGNode *desiredNode =
nullptr;
2286 while (currentNode && (desiredNode = fetchNextNode(itemPriv, ii, fetchedPaintNode))) {
2287 if (currentNode != desiredNode) {
2290 if (currentNode->nextSibling() == desiredNode) {
2292 groupNode->removeChildNode(currentNode);
2297 if (desiredNode->parent()) {
2298 desiredNode->parent()->removeChildNode(desiredNode);
2300 groupNode->insertChildNodeBefore(desiredNode, currentNode);
2304 currentNode = desiredNode;
2307 currentNode = currentNode->nextSibling();
2308 desiredNodesProcessed++;
2314 if (desiredNodesProcessed < desiredNodesSize) {
2315 while ((desiredNode = fetchNextNode(itemPriv, ii, fetchedPaintNode))) {
2316 if (desiredNode->parent())
2317 desiredNode->parent()->removeChildNode(desiredNode);
2318 groupNode->appendChildNode(desiredNode);
2320 }
else if (currentNode) {
2324 while (currentNode) {
2325 QSGNode *node = currentNode->nextSibling();
2326 groupNode->removeChildNode(currentNode);
2332 if ((dirty & QQuickItemPrivate::Size) && itemPriv->clipNode()) {
2333 itemPriv->clipNode()->setRect(item->clipRect());
2334 itemPriv->clipNode()->update();
2337 if (dirty & (QQuickItemPrivate::OpacityValue | QQuickItemPrivate::Visible
2338 | QQuickItemPrivate::HideReference | QQuickItemPrivate::Window))
2340 qreal opacity = itemPriv->explicitVisible && (!itemPriv->extra.isAllocated() || itemPriv->extra->hideRefCount == 0)
2341 ? itemPriv->opacity() : qreal(0);
2343 if (opacity != 1 && !itemPriv->opacityNode()) {
2344 QSGOpacityNode *node =
new QSGOpacityNode;
2345 itemPriv->extra.value().opacityNode = node;
2347 QSGNode *parent = itemPriv->itemNode();
2348 QSGNode *child = itemPriv->clipNode();
2350 child = itemPriv->rootNode();
2353 parent->removeChildNode(child);
2354 node->appendChildNode(child);
2355 parent->appendChildNode(node);
2357 parent->reparentChildNodesTo(node);
2358 parent->appendChildNode(node);
2361 if (itemPriv->opacityNode())
2362 itemPriv->opacityNode()->setOpacity(opacity);
2365 if (dirty & QQuickItemPrivate::ContentUpdateMask) {
2367 if (itemPriv->flags & QQuickItem::ItemHasContents) {
2368 updatePaintNodeData.transformNode = itemPriv->itemNode();
2369 itemPriv->paintNode = item->updatePaintNode(itemPriv->paintNode, &updatePaintNodeData);
2371 Q_ASSERT(itemPriv->paintNode ==
nullptr ||
2372 itemPriv->paintNode->parent() ==
nullptr ||
2373 itemPriv->paintNode->parent() == itemPriv->childContainerNode());
2375 if (itemPriv->paintNode && itemPriv->paintNode->parent() ==
nullptr) {
2376 QSGNode *before = qquickitem_before_paintNode(itemPriv);
2377 if (before && before->parent()) {
2378 Q_ASSERT(before->parent() == itemPriv->childContainerNode());
2379 itemPriv->childContainerNode()->insertChildNodeAfter(itemPriv->paintNode, before);
2381 itemPriv->childContainerNode()->prependChildNode(itemPriv->paintNode);
2384 }
else if (itemPriv->paintNode) {
2385 delete itemPriv->paintNode;
2386 itemPriv->paintNode =
nullptr;
2393 QList<QSGNode *> nodes;
2394 nodes << itemPriv->itemNodeInstance
2395 << itemPriv->opacityNode()
2396 << itemPriv->clipNode()
2397 << itemPriv->rootNode()
2398 << itemPriv->paintNode;
2399 nodes.removeAll(
nullptr);
2401 Q_ASSERT(nodes.constFirst() == itemPriv->itemNodeInstance);
2402 for (
int i=1; i<nodes.size(); ++i) {
2403 QSGNode *n = nodes.at(i);
2405 Q_ASSERT(n->parent() == nodes.at(i-1));
2407 Q_ASSERT(n == itemPriv->paintNode || n == itemPriv->childContainerNode() || n->childCount() == 1);
2413bool QQuickWindowPrivate::emitError(QQuickWindow::SceneGraphError error,
const QString &msg)
2416 static const QMetaMethod errorSignal = QMetaMethod::fromSignal(&QQuickWindow::sceneGraphError);
2417 if (q->isSignalConnected(errorSignal)) {
2418 emit q->sceneGraphError(error, msg);
2424void QQuickWindow::maybeUpdate()
2427 if (d->renderControl)
2428 QQuickRenderControlPrivate::get(d->renderControl)->maybeUpdate();
2429 else if (d->windowManager)
2430 d->windowManager->maybeUpdate(
this);
2433void QQuickWindow::cleanupSceneGraph()
2439 delete d->renderer->rootNode();
2441 d->renderer =
nullptr;
2443 d->runAndClearJobs(&d->beforeSynchronizingJobs);
2444 d->runAndClearJobs(&d->afterSynchronizingJobs);
2445 d->runAndClearJobs(&d->beforeRenderingJobs);
2446 d->runAndClearJobs(&d->afterRenderingJobs);
2447 d->runAndClearJobs(&d->afterSwapJobs);
2450QOpenGLContext *QQuickWindowPrivate::openglContext()
2452#if QT_CONFIG(opengl)
2453 if (context && context->isValid()) {
2454 QSGRendererInterface *rif = context->sceneGraphContext()->rendererInterface(context);
2457 return reinterpret_cast<QOpenGLContext *>(rif->getResource(q, QSGRendererInterface::OpenGLContextResource));
2465
2466
2467bool QQuickWindow::isSceneGraphInitialized()
const
2469 Q_D(
const QQuickWindow);
2470 return d->context !=
nullptr && d->context->isValid();
2474
2475
2476
2477
2478
2479
2480
2481
2484
2485
2486
2487
2488
2489
2492
2493
2494
2495
2496
2497
2500
2501
2502
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2522
2523
2524
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2555
2556
2557
2558
2559
2560
2561
2562
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2577
2578
2579
2580
2581
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672void QQuickWindow::setRenderTarget(
const QQuickRenderTarget &target)
2675 if (target != d->customRenderTarget) {
2676 d->customRenderTarget = target;
2677 d->redirect.renderTargetDirty =
true;
2682
2683
2684
2685
2686
2687
2688
2689QQuickRenderTarget QQuickWindow::renderTarget()
const
2691 Q_D(
const QQuickWindow);
2692 return d->customRenderTarget;
2696class GrabWindowForProtectedContent :
public QRunnable
2699 GrabWindowForProtectedContent(QQuickWindow *window, QImage *image, QWaitCondition *condition)
2702 , m_condition(condition)
2706 bool checkGrabbable()
2712 if (!QQuickWindowPrivate::get(m_window))
2720 if (!checkGrabbable())
2723 *m_image = QSGRhiSupport::instance()->grabOffscreenForProtectedContent(m_window);
2725 m_condition->wakeOne();
2730 QQuickWindow *m_window;
2732 QWaitCondition *m_condition;
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757QImage QQuickWindow::grabWindow()
2761 if (!d->isRenderable() && !d->renderControl) {
2763 if (d->windowManager && (d->windowManager->flags() & QSGRenderLoop::SupportsGrabWithoutExpose))
2764 return d->windowManager->grab(
this);
2766 if (!isSceneGraphInitialized()) {
2773 return QSGRhiSupport::instance()->grabOffscreen(
this);
2778 if (requestedFormat().testOption(QSurfaceFormat::ProtectedContent)) {
2781 QWaitCondition condition;
2783 GrabWindowForProtectedContent *job =
new GrabWindowForProtectedContent(
this, &image, &condition);
2785 qWarning(
"QQuickWindow::grabWindow: Failed to create a job for capturing protected content");
2789 scheduleRenderJob(job, QQuickWindow::NoStage);
2790 condition.wait(&mutex);
2799 if (d->renderControl)
2800 return QQuickRenderControlPrivate::get(d->renderControl)->grab();
2801 else if (d->windowManager)
2802 return d->windowManager->grab(
this);
2808
2809
2810
2811
2812
2813
2814
2815QQmlIncubationController *QQuickWindow::incubationController()
const
2817 Q_D(
const QQuickWindow);
2819 if (!d->windowManager)
2822 if (!d->incubationController)
2823 d->incubationController =
new QQuickWindowIncubationController(d->windowManager);
2824 return d->incubationController;
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2918
2919
2920
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2945
2946
2947
2948
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2981
2982
2983
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3016
3017
3018
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3051
3052
3053
3054
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3108
3109
3110
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3133
3134
3135
3138
3139
3140
3141
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3158
3159
3160
3161
3162
3163
3164
3165
3166
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3192
3193
3194
3195
3198
3199
3201QSGTexture *QQuickWindow::createTextureFromImage(
const QImage &image)
const
3203 return createTextureFromImage(image, {});
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3252QSGTexture *QQuickWindow::createTextureFromImage(
const QImage &image, CreateTextureOptions options)
const
3254 Q_D(
const QQuickWindow);
3255 if (!isSceneGraphInitialized())
3258 if (options & TextureCanUseAtlas) flags |= QSGRenderContext::CreateTexture_Atlas;
3259 if (options & TextureHasMipmaps) flags |= QSGRenderContext::CreateTexture_Mipmap;
3260 if (!(options & TextureIsOpaque)) flags |= QSGRenderContext::CreateTexture_Alpha;
3261 return d->context->createTexture(image, flags);
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297QSGTexture *QQuickWindow::createTextureFromRhiTexture(QRhiTexture *texture, CreateTextureOptions options)
const
3299 Q_D(
const QQuickWindow);
3303 QSGPlainTexture *t =
new QSGPlainTexture;
3304 t->setOwnsTexture(
true);
3305 t->setTexture(texture);
3306 t->setHasAlphaChannel(options & QQuickWindow::TextureHasAlphaChannel);
3307 t->setTextureSize(texture->pixelSize());
3314QSGTexture *QQuickWindowPrivate::createTextureFromNativeTexture(quint64 nativeObjectHandle,
3315 int nativeLayoutOrState,
3318 QQuickWindow::CreateTextureOptions options,
3319 TextureFromNativeTextureFlags flags)
const
3324 QSGPlainTexture *texture =
new QSGPlainTexture;
3325 texture->setTextureFromNativeTexture(rhi, nativeObjectHandle, nativeLayoutOrState, nativeFormat,
3326 size, options, flags);
3327 texture->setHasAlphaChannel(options & QQuickWindow::TextureHasAlphaChannel);
3329 texture->setOwnsTexture(
true);
3330 texture->setTextureSize(size);
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3347
3348
3349
3350
3351
3352
3353
3355void QQuickWindow::setColor(
const QColor &color)
3358 if (color == d->clearColor)
3361 if (color.alpha() != d->clearColor.alpha()) {
3362 QSurfaceFormat fmt = requestedFormat();
3363 if (color.alpha() < 255)
3364 fmt.setAlphaBufferSize(8);
3366 fmt.setAlphaBufferSize(-1);
3369 d->clearColor = color;
3370 emit colorChanged(color);
3374QColor QQuickWindow::color()
const
3376 return d_func()->clearColor;
3380
3381
3382
3383
3384
3385bool QQuickWindow::hasDefaultAlphaBuffer()
3387 return QQuickWindowPrivate::defaultAlphaBuffer;
3391
3392
3393
3394
3395
3396
3397
3398
3399void QQuickWindow::setDefaultAlphaBuffer(
bool useAlpha)
3401 QQuickWindowPrivate::defaultAlphaBuffer = useAlpha;
3405
3406
3407
3408
3409
3410
3411
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3450
3451
3452
3453
3454
3455
3456
3459
3460
3461
3462
3463
3464
3465
3466
3467const QQuickWindow::GraphicsStateInfo &QQuickWindow::graphicsStateInfo()
3471 d->rhiStateInfo.currentFrameSlot = d->rhi->currentFrameSlot();
3472 d->rhiStateInfo.framesInFlight = d->rhi->resourceLimit(QRhi::FramesInFlight);
3474 return d->rhiStateInfo;
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518void QQuickWindow::beginExternalCommands()
3521 if (d->rhi && d->context && d->context->isValid()) {
3522 QSGDefaultRenderContext *rc =
static_cast<QSGDefaultRenderContext *>(d->context);
3523 QRhiCommandBuffer *cb = rc->currentFrameCommandBuffer();
3525 cb->beginExternal();
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555void QQuickWindow::endExternalCommands()
3558 if (d->rhi && d->context && d->context->isValid()) {
3559 QSGDefaultRenderContext *rc =
static_cast<QSGDefaultRenderContext *>(d->context);
3560 QRhiCommandBuffer *cb = rc->currentFrameCommandBuffer();
3567
3568
3569
3570
3571
3572
3573
3574
3575
3578
3579
3580
3581
3582
3583
3584
3585
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3605
3606
3607
3608
3609
3610
3613
3614
3615
3616
3617
3618
3619
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3645
3646
3647
3648
3649
3650
3651
3652
3653
3656
3657
3658
3659
3660
3661
3662
3663
3664
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3718
3719
3720
3721
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3839
3840
3841
3842
3843
3844
3847
3848
3849
3850
3851
3852
3853
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3881
3882
3883
3884
3885
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3913
3914
3915
3916
3917
3918
3921
3922
3923
3924
3925
3926
3929
3930
3931
3932
3933
3934
3935
3936
3937
3940
3941
3942
3943
3944
3945
3946
3947
3950
3951
3952
3953
3954
3955
3958
3959
3960
3961
3962
3963
3966
3967
3968
3969
3970
3971
3974
3975
3976
3977
3978
3979
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4032void QQuickWindow::scheduleRenderJob(QRunnable *job, RenderStage stage)
4036 d->renderJobMutex.lock();
4037 if (stage == BeforeSynchronizingStage) {
4038 d->beforeSynchronizingJobs << job;
4039 }
else if (stage == AfterSynchronizingStage) {
4040 d->afterSynchronizingJobs << job;
4041 }
else if (stage == BeforeRenderingStage) {
4042 d->beforeRenderingJobs << job;
4043 }
else if (stage == AfterRenderingStage) {
4044 d->afterRenderingJobs << job;
4045 }
else if (stage == AfterSwapStage) {
4046 d->afterSwapJobs << job;
4047 }
else if (stage == NoStage) {
4048 if (d->renderControl && d->rhi && d->rhi->thread() == QThread::currentThread()) {
4051 }
else if (isExposed()) {
4052 d->windowManager->postJob(
this, job);
4057 d->renderJobMutex.unlock();
4060void QQuickWindowPrivate::runAndClearJobs(QList<QRunnable *> *jobs)
4062 renderJobMutex.lock();
4063 QList<QRunnable *> jobList = *jobs;
4065 renderJobMutex.unlock();
4067 for (QRunnable *r : std::as_const(jobList)) {
4073void QQuickWindow::runJobsAfterSwap()
4076 d->runAndClearJobs(&d->afterSwapJobs);
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094qreal QQuickWindow::effectiveDevicePixelRatio()
const
4096 Q_D(
const QQuickWindow);
4097 QWindow *w = QQuickRenderControl::renderWindowFor(
const_cast<QQuickWindow *>(
this));
4099 return w->devicePixelRatio();
4101 if (!d->customRenderTarget.isNull())
4102 return d->customRenderTarget.devicePixelRatio();
4104 return devicePixelRatio();
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128QSGRendererInterface *QQuickWindow::rendererInterface()
const
4130 Q_D(
const QQuickWindow);
4138 return d->context->sceneGraphContext()->rendererInterface(d->context);
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161QRhi *QQuickWindow::rhi()
const
4163 Q_D(
const QQuickWindow);
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177QRhiSwapChain *QQuickWindow::swapChain()
const
4179 Q_D(
const QQuickWindow);
4180 return d->swapchain;
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229void QQuickWindow::setGraphicsApi(QSGRendererInterface::GraphicsApi api)
4233 case QSGRendererInterface::Software:
4234 setSceneGraphBackend(QStringLiteral(
"software"));
4236 case QSGRendererInterface::OpenVG:
4237 setSceneGraphBackend(QStringLiteral(
"openvg"));
4245 if (QSGRendererInterface::isApiRhiBased(api) || api == QSGRendererInterface::Unknown)
4246 QSGRhiSupport::instance_internal()->configure(api);
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278QSGRendererInterface::GraphicsApi QQuickWindow::graphicsApi()
4284 return QSGRhiSupport::instance()->graphicsApi();
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307void QQuickWindow::setSceneGraphBackend(
const QString &backend)
4309 QSGContext::setBackend(backend);
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324QString QQuickWindow::sceneGraphBackend()
4326 return QSGContext::backend();
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392void QQuickWindow::setGraphicsDevice(
const QQuickGraphicsDevice &device)
4395 d->customDeviceObjects = device;
4399
4400
4401
4402
4403
4404
4405
4406QQuickGraphicsDevice QQuickWindow::graphicsDevice()
const
4408 Q_D(
const QQuickWindow);
4409 return d->customDeviceObjects;
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439void QQuickWindow::setGraphicsConfiguration(
const QQuickGraphicsConfiguration &config)
4442 d->graphicsConfig = config;
4446
4447
4448
4449
4450
4451
4452
4453QQuickGraphicsConfiguration QQuickWindow::graphicsConfiguration()
const
4455 Q_D(
const QQuickWindow);
4456 return d->graphicsConfig;
4460
4461
4462
4463
4464
4465QSGTextNode *QQuickWindow::createTextNode()
const
4467 Q_D(
const QQuickWindow);
4468 return isSceneGraphInitialized() ? d->context->sceneGraphContext()->createTextNode(d->context) :
nullptr;
4472
4473
4474
4475
4476
4477
4478
4479QSGRectangleNode *QQuickWindow::createRectangleNode()
const
4481 Q_D(
const QQuickWindow);
4482 return isSceneGraphInitialized() ? d->context->sceneGraphContext()->createRectangleNode() :
nullptr;
4486
4487
4488
4489
4490
4491
4492
4493QSGImageNode *QQuickWindow::createImageNode()
const
4495 Q_D(
const QQuickWindow);
4496 return isSceneGraphInitialized() ? d->context->sceneGraphContext()->createImageNode() :
nullptr;
4500
4501
4502
4503
4504QSGNinePatchNode *QQuickWindow::createNinePatchNode()
const
4506 Q_D(
const QQuickWindow);
4507 return isSceneGraphInitialized() ? d->context->sceneGraphContext()->createNinePatchNode() :
nullptr;
4511
4512
4513
4514
4515
4516
4517
4518QQuickWindow::TextRenderType QQuickWindow::textRenderType()
4520 return QQuickWindowPrivate::textRenderType;
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533void QQuickWindow::setTextRenderType(QQuickWindow::TextRenderType renderType)
4535 QQuickWindowPrivate::textRenderType = renderType;
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4558#ifndef QT_NO_DEBUG_STREAM
4561 QDebugStateSaver saver(debug);
4564 debug <<
"QQuickWindow(nullptr)";
4568 debug << win->metaObject()->className() <<
'(' <<
static_cast<
const void *>(win);
4569 if (win->isActive())
4571 if (win->isExposed())
4572 debug <<
" exposed";
4573 debug <<
", visibility=" << win->visibility() <<
", flags=" << win->flags();
4574 if (!win->title().isEmpty())
4575 debug <<
", title=" << win->title();
4576 if (!win->objectName().isEmpty())
4577 debug <<
", name=" << win->objectName();
4579 debug <<
", parent=" <<
static_cast<
const void *>(win->parent());
4580 if (win->transientParent())
4581 debug <<
", transientParent=" <<
static_cast<
const void *>(win->transientParent());
4582 debug <<
", geometry=";
4583 QtDebugUtils::formatQRect(debug, win->geometry());
4591#include "qquickwindow.moc"
4592#include "moc_qquickwindow_p.cpp"
4593#include "moc_qquickwindow.cpp"
Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core")
static void updatePixelRatioHelper(QQuickItem *item, float pixelRatio)
void forcePolishHelper(QQuickItem *item)
void forceUpdate(QQuickItem *item)
QDebug operator<<(QDebug debug, const QQuickWindow *win)
static QSGNode * qquickitem_before_paintNode(QQuickItemPrivate *d)
static QSGNode * fetchNextNode(QQuickItemPrivate *itemPriv, int &ii, bool &returnedPaintNode)
bool check(QQuickItem *item, int itemsRemainingBeforeUpdatePolish)
const QVector< QQuickItem * > & itemsToPolish
int numPolishLoopsInSequence
PolishLoopDetector(const QVector< QQuickItem * > &itemsToPolish)
QRhiRenderBuffer * depthStencil
QRhiTexture * multisampleTexture
QRhiTexture * depthStencilTexture
QRhiRenderPassDescriptor * rpDesc
QRhiRenderBuffer * renderBuffer