524void QQuickWindowPrivate::syncSceneGraph()
528 const bool wasRtDirty = redirect.renderTargetDirty;
529 ensureCustomRenderTarget();
531 QRhiCommandBuffer *cb =
nullptr;
533 if (redirect.commandBuffer)
534 cb = redirect.commandBuffer;
536 cb = swapchain->currentFrameCommandBuffer();
538 context->prepareSync(q->effectiveDevicePixelRatio(), cb, graphicsConfig);
540 animationController->beforeNodeSync();
542 emit q->beforeSynchronizing();
543 runAndClearJobs(&beforeSynchronizingJobs);
545 if (pendingFontUpdate) {
547 invalidateFontData(contentItem);
548 context->invalidateGlyphCaches();
551 if (Q_UNLIKELY(!renderer)) {
552 forceUpdate(contentItem);
554 QSGRootNode *rootNode =
new QSGRootNode;
555 rootNode->appendChildNode(QQuickItemPrivate::get(contentItem)->itemNode());
556 const bool useDepth = graphicsConfig.isDepthBufferEnabledFor2D();
557 const QSGRendererInterface::RenderMode renderMode = useDepth ? QSGRendererInterface::RenderMode2D
558 : QSGRendererInterface::RenderMode2DNoDepthBuffer;
559 renderer = context->createRenderer(renderMode);
560 renderer->setRootNode(rootNode);
561 }
else if (Q_UNLIKELY(wasRtDirty)
562 && q->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) {
563 auto softwareRenderer =
static_cast<QSGSoftwareRenderer *>(renderer);
564 softwareRenderer->markDirty();
569 animationController->afterNodeSync();
571 renderer->setClearColor(clearColor);
573 renderer->setVisualizationMode(visualizationMode);
575 if (pendingFontUpdate) {
576 context->flushGlyphCaches();
577 pendingFontUpdate =
false;
580 emit q->afterSynchronizing();
581 runAndClearJobs(&afterSynchronizingJobs);
620void QQuickWindowPrivate::renderSceneGraph()
626 ensureCustomRenderTarget();
628 QSGRenderTarget sgRenderTarget;
630 QRhiRenderTarget *rt;
631 QRhiRenderPassDescriptor *rp;
632 QRhiCommandBuffer *cb;
633 if (redirect.rt.rt.renderTarget) {
634 rt = redirect.rt.rt.renderTarget;
635 rp = rt->renderPassDescriptor();
637 qWarning(
"Custom render target is set but no renderpass descriptor has been provided.");
640 cb = redirect.commandBuffer;
642 qWarning(
"Custom render target is set but no command buffer has been provided.");
647 qWarning(
"QQuickWindow: No render target (neither swapchain nor custom target was provided)");
650 rt = swapchain->currentFrameRenderTarget();
651 rp = rpDescForSwapchain;
652 cb = swapchain->currentFrameCommandBuffer();
654 sgRenderTarget = QSGRenderTarget(rt, rp, cb);
655 sgRenderTarget.multiViewCount = multiViewCount();
657 sgRenderTarget = QSGRenderTarget(redirect.rt.sw.paintDevice);
660 context->beginNextFrame(renderer,
662 emitBeforeRenderPassRecording,
663 emitAfterRenderPassRecording,
666 animationController->advance();
667 emit q->beforeRendering();
668 runAndClearJobs(&beforeRenderingJobs);
670 const qreal devicePixelRatio = q->effectiveDevicePixelRatio();
672 if (redirect.rt.rt.renderTarget)
673 pixelSize = redirect.rt.rt.renderTarget->pixelSize();
674 else if (redirect.rt.sw.paintDevice)
675 pixelSize = QSize(redirect.rt.sw.paintDevice->width(), redirect.rt.sw.paintDevice->height());
677 pixelSize = swapchain->currentPixelSize();
679 pixelSize = q->size() * devicePixelRatio;
681 renderer->setDevicePixelRatio(devicePixelRatio);
682 renderer->setDeviceRect(QRect(QPoint(0, 0), pixelSize));
683 renderer->setViewportRect(QRect(QPoint(0, 0), pixelSize));
685 QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
686 bool flipY = rhi ? !rhi->isYUpInNDC() :
false;
687 if (!customRenderTarget.isNull() && customRenderTarget.mirrorVertically())
690 matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
692 const QRectF rect(QPointF(0, 0), pixelSize / devicePixelRatio);
693 renderer->setProjectionMatrixToRect(rect, matrixFlags, rhi && !rhi->isYUpInNDC());
695 context->renderNextFrame(renderer);
697 emit q->afterRendering();
698 runAndClearJobs(&afterRenderingJobs);
700 context->endNextFrame(renderer);
702 if (renderer && renderer->hasVisualizationModeWithContinuousUpdate()) {
706 QCoreApplication::postEvent(q,
new QEvent(QEvent::Type(FullUpdateRequest)));
781void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
788 contentItem =
new QQuickRootItem;
789 contentItem->setObjectName(q->objectName());
790 QQml_setParent_noEvent(contentItem, c);
791 QQmlEngine::setObjectOwnership(contentItem, QQmlEngine::CppOwnership);
792 QQuickItemPrivate *contentItemPrivate = QQuickItemPrivate::get(contentItem);
793 contentItemPrivate->window = q;
794 contentItemPrivate->windowRefCount = 1;
795 contentItemPrivate->flags |= QQuickItem::ItemIsFocusScope;
796 contentItem->setSize(q->size());
797 deliveryAgent =
new QQuickDeliveryAgent(contentItem);
799 visualizationMode = qgetenv(
"QSG_VISUALIZE");
800 renderControl = control;
802 QQuickRenderControlPrivate::get(renderControl)->window = q;
805 windowManager = QSGRenderLoop::instance();
807 Q_ASSERT(windowManager || renderControl);
809 QObject::connect(
static_cast<QGuiApplication *>(QGuiApplication::instance()),
810 &QGuiApplication::fontDatabaseChanged,
812 &QQuickWindow::handleFontDatabaseChanged);
815 lastReportedItemDevicePixelRatio = q->effectiveDevicePixelRatio();
820 QQuickRenderControlPrivate *renderControlPriv = QQuickRenderControlPrivate::get(renderControl);
821 sg = renderControlPriv->sg;
822 context = renderControlPriv->rc;
824 windowManager->addWindow(q);
825 sg = windowManager->sceneGraphContext();
826 context = windowManager->createRenderContext(sg);
829 q->setSurfaceType(windowManager ? windowManager->windowSurfaceType() : QSurface::OpenGLSurface);
830 q->setFormat(sg->defaultSurfaceFormat());
836 animationController.reset(
new QQuickAnimatorController(q));
839 QObject::connect(context, &QSGRenderContext::initialized, q, &QQuickWindow::sceneGraphInitialized, Qt::DirectConnection),
840 QObject::connect(context, &QSGRenderContext::invalidated, q, &QQuickWindow::sceneGraphInvalidated, Qt::DirectConnection),
841 QObject::connect(context, &QSGRenderContext::invalidated, q, &QQuickWindow::cleanupSceneGraph, Qt::DirectConnection),
843 QObject::connect(q, &QQuickWindow::focusObjectChanged, q, &QQuickWindow::activeFocusItemChanged),
844 QObject::connect(q, &QQuickWindow::screenChanged, q, &QQuickWindow::handleScreenChanged),
845 QObject::connect(qApp, &QGuiApplication::applicationStateChanged, q, &QQuickWindow::handleApplicationStateChanged),
846 QObject::connect(q, &QQuickWindow::frameSwapped, q, &QQuickWindow::runJobsAfterSwap, Qt::DirectConnection),
849 if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
850 service->addWindow(q);
1231QQuickWindow::~QQuickWindow()
1234 d->inDestructor =
true;
1235 if (d->renderControl) {
1236 QQuickRenderControlPrivate::get(d->renderControl)->windowDestroyed();
1237 }
else if (d->windowManager) {
1238 d->windowManager->removeWindow(
this);
1239 d->windowManager->windowDestroyed(
this);
1242 disconnect(
this, &QQuickWindow::focusObjectChanged,
this, &QQuickWindow::activeFocusItemChanged);
1243 disconnect(
this, &QQuickWindow::screenChanged,
this, &QQuickWindow::handleScreenChanged);
1244 disconnect(qApp, &QGuiApplication::applicationStateChanged,
this, &QQuickWindow::handleApplicationStateChanged);
1245 disconnect(
this, &QQuickWindow::frameSwapped,
this, &QQuickWindow::runJobsAfterSwap);
1247 delete d->incubationController; d->incubationController =
nullptr;
1248 QQuickRootItem *root = d->contentItem;
1249 d->contentItem =
nullptr;
1250 root->setParent(
nullptr);
1252 d->deliveryAgent =
nullptr;
1256 const std::lock_guard locker(d->renderJobMutex);
1257 qDeleteAll(std::exchange(d->beforeSynchronizingJobs, {}));
1258 qDeleteAll(std::exchange(d->afterSynchronizingJobs, {}));
1259 qDeleteAll(std::exchange(d->beforeRenderingJobs, {}));
1260 qDeleteAll(std::exchange(d->afterRenderingJobs, {}));;
1261 qDeleteAll(std::exchange(d->afterSwapJobs, {}));
1269 QQuickPixmap::purgeCache();
1271 for (QMetaObject::Connection &connection : d->connections)
1272 disconnect(connection);
1470bool QQuickWindow::event(QEvent *event)
1475 QQuickDeliveryAgent *da = d->deliveryAgent;
1476 if (event->isPointerEvent()) {
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487 if (d->windowEventDispatch)
1490 const bool wasAccepted = event->isAccepted();
1491 QScopedValueRollback windowEventDispatchGuard(d->windowEventDispatch,
true);
1492 qCDebug(lcPtr) <<
"dispatching to window functions in case of override" << event;
1493 QWindow::event(event);
1494 if (event->isAccepted() && !wasAccepted)
1498
1499
1500
1501
1502
1503
1504 auto pe =
static_cast<QPointerEvent *>(event);
1505 if (QQuickDeliveryAgentPrivate::isTouchEvent(pe))
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522 if (pe->pointCount()) {
1523 const bool synthMouse = QQuickDeliveryAgentPrivate::isSynthMouse(pe);
1524 if (QQuickDeliveryAgentPrivate::subsceneAgentsExist) {
1528 QFlatMap<QQuickDeliveryAgent*, QList<QEventPoint>> deliveryAgentsNeedingPoints;
1529 QEventPoint::States eventStates;
1531 auto insert = [&](QQuickDeliveryAgent *ptda,
const QEventPoint &pt) {
1532 if (pt.state() == QEventPoint::Pressed && !synthMouse)
1533 pe->clearPassiveGrabbers(pt);
1534 auto &ptList = deliveryAgentsNeedingPoints[ptda];
1535 auto idEquals = [](
auto id) {
return [id] (
const auto &e) {
return e.id() == id; }; };
1536 if (std::none_of(ptList.cbegin(), ptList.cend(), idEquals(pt.id())))
1540 for (
const auto &pt : pe->points()) {
1541 eventStates |= pt.state();
1542 auto epd = QPointingDevicePrivate::get(
const_cast<QPointingDevice*>(pe->pointingDevice()))->queryPointById(pt.id());
1544 bool foundAgent =
false;
1545 if (!epd->exclusiveGrabber.isNull() && !epd->exclusiveGrabberContext.isNull()) {
1546 if (
auto ptda = qobject_cast<QQuickDeliveryAgent *>(epd->exclusiveGrabberContext.data())) {
1548 qCDebug(lcPtr) << pe->type() <<
"point" << pt.id() << pt.state()
1549 <<
"@" << pt.scenePosition() <<
"will be re-delivered via known grabbing agent" << ptda <<
"to" << epd->exclusiveGrabber.data();
1553 for (
const auto &pgda : std::as_const(epd->passiveGrabbersContext)) {
1554 if (
auto ptda = qobject_cast<QQuickDeliveryAgent *>(pgda.data())) {
1556 qCDebug(lcPtr) << pe->type() <<
"point" << pt.id() << pt.state()
1557 <<
"@" << pt.scenePosition() <<
"will be re-delivered via known passive-grabbing agent" << ptda;
1565 for (
auto daAndPoints : deliveryAgentsNeedingPoints) {
1566 if (pe->pointCount() > 1) {
1567 Q_ASSERT(QQuickDeliveryAgentPrivate::isTouchEvent(pe));
1569 QEvent::Type eventType = pe->type();
1570 switch (eventStates) {
1571 case QEventPoint::State::Pressed:
1572 eventType = QEvent::TouchBegin;
1574 case QEventPoint::State::Released:
1575 eventType = QEvent::TouchEnd;
1578 eventType = QEvent::TouchUpdate;
1582 QMutableTouchEvent te(eventType, pe->pointingDevice(), pe->modifiers(), daAndPoints.second);
1583 te.setTimestamp(pe->timestamp());
1585 qCDebug(lcTouch) << daAndPoints.first <<
"shall now receive" << &te;
1586 ret = daAndPoints.first->event(&te) || ret;
1588 qCDebug(lcPtr) << daAndPoints.first <<
"shall now receive" << pe;
1589 ret = daAndPoints.first->event(pe) || ret;
1594 d->deliveryAgentPrivate()->clearGrabbers(pe);
1597 }
else if (!synthMouse) {
1600 for (
const auto &pt : pe->points()) {
1601 if (pt.state() == QEventPoint::Pressed)
1602 pe->clearPassiveGrabbers(pt);
1611 qCDebug(lcHoverTrace) <<
this <<
"some sort of event" << event;
1612 bool ret = (da && da->event(event));
1614 d->deliveryAgentPrivate()->clearGrabbers(pe);
1616 if (pe->type() == QEvent::MouseButtonPress || pe->type() == QEvent::MouseButtonRelease) {
1619 d->maybeSynthesizeContextMenuEvent(
static_cast<QMouseEvent *>(pe));
1622#if QT_CONFIG(tabletevent)
1629 if (type() == Qt::Popup && QQuickDeliveryAgentPrivate::isTabletEvent(pe) &&
1630 !QRect(QPoint(), size()).contains(pe->points().first().scenePosition().toPoint())) {
1638 }
else if (event->isInputEvent()) {
1639 if (da && da->event(event))
1643 switch (event->type()) {
1645 case QEvent::FocusAboutToChange:
1648 case QEvent::InputMethod:
1649 case QEvent::InputMethodQuery:
1650#if QT_CONFIG(quick_draganddrop)
1651 case QEvent::DragEnter:
1652 case QEvent::DragLeave:
1653 case QEvent::DragMove:
1656 if (d->inDestructor)
1658 if (da && da->event(event))
1661 case QEvent::LanguageChange:
1662 case QEvent::LocaleChange:
1664 QCoreApplication::sendEvent(d->contentItem, event);
1666 case QEvent::UpdateRequest:
1667 if (d->windowManager)
1668 d->windowManager->handleUpdateRequest(
this);
1670 case QEvent::PlatformSurface:
1671 if ((
static_cast<QPlatformSurfaceEvent *>(event))->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) {
1674 if (d->windowManager)
1675 d->windowManager->hide(
this);
1678 case QEvent::WindowDeactivate:
1679 if (
auto da = d->deliveryAgentPrivate())
1680 da->handleWindowDeactivate(
this);
1682 case QEvent::WindowActivate:
1684 QCoreApplication::sendEvent(d->contentItem, event);
1686 case QEvent::ApplicationPaletteChange:
1687 d->inheritPalette(QGuiApplication::palette());
1689 QCoreApplication::sendEvent(d->contentItem, event);
1691 case QEvent::DevicePixelRatioChange:
1692 physicalDpiChanged();
1694 case QEvent::SafeAreaMarginsChange:
1695 QQuickSafeArea::updateSafeAreasRecursively(d->contentItem);
1697 case QEvent::ChildWindowAdded: {
1698 auto *childEvent =
static_cast<QChildWindowEvent*>(event);
1699 auto *childWindow = childEvent->child();
1700 qCDebug(lcQuickWindow) <<
"Child window" << childWindow <<
"added to" <<
this;
1701 if (childWindow->handle()) {
1707 d->updateChildWindowStackingOrder();
1709 qCDebug(lcQuickWindow) <<
"No platform window yet."
1710 <<
"Deferring child window stacking until surface creation";
1718 if (event->type() == QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))
1720 else if (event->type() == QEvent::Type(QQuickWindowPrivate::TriggerContextCreationFailure))
1721 d->windowManager->handleContextCreationFailure(
this);
1723 if (event->isPointerEvent())
1726 return QWindow::event(event);
2202void QQuickWindowPrivate::updateDirtyNode(QQuickItem *item)
2204 QQuickItemPrivate *itemPriv = QQuickItemPrivate::get(item);
2205 quint32 dirty = itemPriv->dirtyAttributes;
2206 itemPriv->dirtyAttributes = 0;
2208 if ((dirty & QQuickItemPrivate::TransformUpdateMask) ||
2209 (dirty & QQuickItemPrivate::Size && itemPriv->origin() != QQuickItem::TopLeft &&
2210 (itemPriv->scale() != 1. || itemPriv->rotation() != 0.))) {
2214 if (itemPriv->x != 0. || itemPriv->y != 0.)
2215 matrix.translate(itemPriv->x, itemPriv->y);
2217 for (
int ii = itemPriv->transforms.size() - 1; ii >= 0; --ii)
2218 itemPriv->transforms.at(ii)->applyTo(&matrix);
2220 if (itemPriv->scale() != 1. || itemPriv->rotation() != 0.) {
2221 QPointF origin = item->transformOriginPoint();
2222 matrix.translate(origin.x(), origin.y());
2223 if (itemPriv->scale() != 1.)
2224 matrix.scale(itemPriv->scale(), itemPriv->scale());
2225 if (itemPriv->rotation() != 0.)
2226 matrix.rotate(itemPriv->rotation(), 0, 0, 1);
2227 matrix.translate(-origin.x(), -origin.y());
2230 itemPriv->itemNode()->setMatrix(matrix);
2233 const bool clipEffectivelyChanged = dirty & (QQuickItemPrivate::Clip | QQuickItemPrivate::Window);
2234 if (clipEffectivelyChanged) {
2235 QSGNode *parent = itemPriv->opacityNode() ? (QSGNode *)itemPriv->opacityNode()
2236 : (QSGNode *)itemPriv->itemNode();
2237 QSGNode *child = itemPriv->rootNode();
2239 if (
bool initializeClipNode = item->clip() && itemPriv->clipNode() ==
nullptr;
2240 initializeClipNode) {
2241 QQuickDefaultClipNode *clip =
new QQuickDefaultClipNode(item->clipRect());
2242 itemPriv->extra.value().clipNode = clip;
2246 parent->reparentChildNodesTo(clip);
2247 parent->appendChildNode(clip);
2249 parent->removeChildNode(child);
2250 clip->appendChildNode(child);
2251 parent->appendChildNode(clip);
2254 }
else if (
bool updateClipNode = item->clip() && itemPriv->clipNode() !=
nullptr;
2256 QQuickDefaultClipNode *clip = itemPriv->clipNode();
2257 clip->setClipRect(item->clipRect());
2259 }
else if (
bool removeClipNode = !item->clip() && itemPriv->clipNode() !=
nullptr;
2261 QQuickDefaultClipNode *clip = itemPriv->clipNode();
2262 parent->removeChildNode(clip);
2264 clip->removeChildNode(child);
2265 parent->appendChildNode(child);
2267 clip->reparentChildNodesTo(parent);
2270 delete itemPriv->clipNode();
2271 itemPriv->extra->clipNode =
nullptr;
2275 const int effectRefCount = itemPriv->extra.isAllocated() ? itemPriv->extra->effectRefCount : 0;
2276 const bool effectRefEffectivelyChanged =
2277 (dirty & (QQuickItemPrivate::EffectReference | QQuickItemPrivate::Window))
2278 && ((effectRefCount == 0) != (itemPriv->rootNode() ==
nullptr));
2279 if (effectRefEffectivelyChanged) {
2280 if (dirty & QQuickItemPrivate::ChildrenUpdateMask)
2281 itemPriv->childContainerNode()->removeAllChildNodes();
2283 QSGNode *parent = itemPriv->clipNode();
2285 parent = itemPriv->opacityNode();
2287 parent = itemPriv->itemNode();
2289 if (itemPriv->extra.isAllocated() && itemPriv->extra->effectRefCount) {
2290 Q_ASSERT(itemPriv->rootNode() ==
nullptr);
2291 QSGRootNode *root =
new QSGRootNode();
2292 itemPriv->extra->rootNode = root;
2293 parent->reparentChildNodesTo(root);
2294 parent->appendChildNode(root);
2296 Q_ASSERT(itemPriv->rootNode() !=
nullptr);
2297 QSGRootNode *root = itemPriv->rootNode();
2298 parent->removeChildNode(root);
2299 root->reparentChildNodesTo(parent);
2300 delete itemPriv->rootNode();
2301 itemPriv->extra->rootNode =
nullptr;
2305 if (dirty & QQuickItemPrivate::ChildrenUpdateMask) {
2307 bool fetchedPaintNode =
false;
2308 QList<QQuickItem *> orderedChildren = itemPriv->paintOrderChildItems();
2309 int desiredNodesSize = orderedChildren.size() + (itemPriv->paintNode ? 1 : 0);
2317 int desiredNodesProcessed = 0;
2322 QSGNode *groupNode = itemPriv->childContainerNode();
2323 QSGNode *currentNode = groupNode->firstChild();
2324 QSGNode *desiredNode =
nullptr;
2326 while (currentNode && (desiredNode = fetchNextNode(itemPriv, ii, fetchedPaintNode))) {
2327 if (currentNode != desiredNode) {
2330 if (currentNode->nextSibling() == desiredNode) {
2332 groupNode->removeChildNode(currentNode);
2337 if (desiredNode->parent()) {
2338 desiredNode->parent()->removeChildNode(desiredNode);
2340 groupNode->insertChildNodeBefore(desiredNode, currentNode);
2344 currentNode = desiredNode;
2347 currentNode = currentNode->nextSibling();
2348 desiredNodesProcessed++;
2354 if (desiredNodesProcessed < desiredNodesSize) {
2355 while ((desiredNode = fetchNextNode(itemPriv, ii, fetchedPaintNode))) {
2356 if (desiredNode->parent())
2357 desiredNode->parent()->removeChildNode(desiredNode);
2358 groupNode->appendChildNode(desiredNode);
2360 }
else if (currentNode) {
2364 while (currentNode) {
2365 QSGNode *node = currentNode->nextSibling();
2366 groupNode->removeChildNode(currentNode);
2372 if ((dirty & QQuickItemPrivate::Size) && itemPriv->clipNode()) {
2373 itemPriv->clipNode()->setRect(item->clipRect());
2374 itemPriv->clipNode()->update();
2377 if (dirty & (QQuickItemPrivate::OpacityValue | QQuickItemPrivate::Visible
2378 | QQuickItemPrivate::HideReference | QQuickItemPrivate::Window))
2380 qreal opacity = itemPriv->explicitVisible && (!itemPriv->extra.isAllocated() || itemPriv->extra->hideRefCount == 0)
2381 ? itemPriv->opacity() : qreal(0);
2383 if (opacity != 1 && !itemPriv->opacityNode()) {
2384 QSGOpacityNode *node =
new QSGOpacityNode;
2385 itemPriv->extra.value().opacityNode = node;
2387 QSGNode *parent = itemPriv->itemNode();
2388 QSGNode *child = itemPriv->clipNode();
2390 child = itemPriv->rootNode();
2393 parent->removeChildNode(child);
2394 node->appendChildNode(child);
2395 parent->appendChildNode(node);
2397 parent->reparentChildNodesTo(node);
2398 parent->appendChildNode(node);
2401 if (itemPriv->opacityNode())
2402 itemPriv->opacityNode()->setOpacity(opacity);
2405 if (dirty & QQuickItemPrivate::ContentUpdateMask) {
2407 if (itemPriv->flags & QQuickItem::ItemHasContents) {
2408 updatePaintNodeData.transformNode = itemPriv->itemNode();
2409 itemPriv->paintNode = item->updatePaintNode(itemPriv->paintNode, &updatePaintNodeData);
2411 Q_ASSERT(itemPriv->paintNode ==
nullptr ||
2412 itemPriv->paintNode->parent() ==
nullptr ||
2413 itemPriv->paintNode->parent() == itemPriv->childContainerNode());
2415 if (itemPriv->paintNode) {
2416 if (itemPriv->paintNode->parent() ==
nullptr) {
2417 QSGNode *before = qquickitem_before_paintNode(itemPriv);
2418 if (before && before->parent()) {
2419 Q_ASSERT(before->parent() == itemPriv->childContainerNode());
2420 itemPriv->childContainerNode()->insertChildNodeAfter(itemPriv->paintNode, before);
2422 itemPriv->childContainerNode()->prependChildNode(itemPriv->paintNode);
2429 if (itemPriv->extra.isAllocated() && itemPriv->extra->mutabilityGroupSet) {
2430 QSGNodePrivate::setMutabilityGroupOfSubtree(itemPriv->paintNode,
2431 itemPriv->extra->mutabilityGroup);
2435 }
else if (itemPriv->paintNode) {
2436 delete itemPriv->paintNode;
2437 itemPriv->paintNode =
nullptr;
2444 QList<QSGNode *> nodes;
2445 nodes << itemPriv->itemNodeInstance
2446 << itemPriv->opacityNode()
2447 << itemPriv->clipNode()
2448 << itemPriv->rootNode()
2449 << itemPriv->paintNode;
2450 nodes.removeAll(
nullptr);
2452 Q_ASSERT(nodes.constFirst() == itemPriv->itemNodeInstance);
2453 for (
int i=1; i<nodes.size(); ++i) {
2454 QSGNode *n = nodes.at(i);
2456 Q_ASSERT(n->parent() == nodes.at(i-1));
2458 Q_ASSERT(n == itemPriv->paintNode || n == itemPriv->childContainerNode() || n->childCount() == 1);