aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/util/qquickdeliveryagent.cpp
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2021-02-17 13:50:52 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2021-02-17 16:11:50 +0100
commit79f0af6cd097f55eacb763574e173f134c9c0a32 (patch)
treef8ce0383fc12280b15a6e05e29bbe235a624e470 /src/quick/util/qquickdeliveryagent.cpp
parent0ccea574f8e4e9a3954ef3bb95909565957bacbe (diff)
Stage 3: remove non-delivery code from qquickdeliveryagent.cpp
Diffstat (limited to 'src/quick/util/qquickdeliveryagent.cpp')
-rw-r--r--src/quick/util/qquickdeliveryagent.cpp828
1 files changed, 1 insertions, 827 deletions
diff --git a/src/quick/util/qquickdeliveryagent.cpp b/src/quick/util/qquickdeliveryagent.cpp
index acc220bba3..365304128d 100644
--- a/src/quick/util/qquickdeliveryagent.cpp
+++ b/src/quick/util/qquickdeliveryagent.cpp
@@ -37,838 +37,12 @@
**
****************************************************************************/
-#include "qquickwindow.h"
-#include "qquickwindow_p.h"
-
-#include "qquickitem.h"
-#include "qquickitem_p.h"
-#include "qquickevents_p_p.h"
-#include "qquickgraphicsdevice_p.h"
-
-#if QT_CONFIG(quick_draganddrop)
-#include <private/qquickdrag_p.h>
-#endif
-#include <private/qquickhoverhandler_p.h>
-#include <private/qquickpointerhandler_p.h>
-
-#include <QtQuick/private/qsgrenderer_p.h>
-#include <QtQuick/private/qsgplaintexture_p.h>
-#include <private/qsgrenderloop_p.h>
-#include <private/qsgrhisupport_p.h>
-#include <private/qquickrendercontrol_p.h>
-#include <private/qquickanimatorcontroller_p.h>
-#include <private/qquickpointerhandler_p_p.h>
-#include <private/qquickprofiler_p.h>
-
-#include <private/qguiapplication_p.h>
-#include <QtGui/QInputMethod>
-
-#include <private/qabstractanimation_p.h>
-
-#include <QtGui/qpainter.h>
-#include <QtGui/qevent.h>
-#include <QtGui/qmatrix4x4.h>
-#include <QtGui/private/qevent_p.h>
-#include <QtGui/private/qpointingdevice_p.h>
-#include <QtGui/qpa/qplatformtheme.h>
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qabstractanimation.h>
-#include <QtCore/QLibraryInfo>
-#include <QtCore/QRunnable>
-#include <QtQml/qqmlincubator.h>
-#include <QtQml/qqmlinfo.h>
-#include <QtQml/private/qqmlmetatype_p.h>
-
-#include <QtQuick/private/qquickpixmapcache_p.h>
-
-#include <private/qqmldebugserviceinterfaces_p.h>
-#include <private/qqmldebugconnector_p.h>
-#include <private/qsgdefaultrendercontext_p.h>
-#if QT_CONFIG(opengl)
-#include <private/qopengl_p.h>
-#include <QOpenGLContext>
-#endif
-#ifndef QT_NO_DEBUG_STREAM
-#include <private/qdebug_p.h>
-#endif
-
-#include <QtGui/private/qrhi_p.h>
+#include <QtQuick/private/qquickwindow_p.h>
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(lcTouch, "qt.quick.touch")
-Q_LOGGING_CATEGORY(lcTouchCmprs, "qt.quick.touch.compression")
-Q_LOGGING_CATEGORY(lcTouchTarget, "qt.quick.touch.target")
-Q_LOGGING_CATEGORY(lcMouse, "qt.quick.mouse")
-Q_LOGGING_CATEGORY(lcMouseTarget, "qt.quick.mouse.target")
-Q_LOGGING_CATEGORY(lcPtr, "qt.quick.pointer")
-Q_LOGGING_CATEGORY(lcPtrGrab, "qt.quick.pointer.grab")
-Q_LOGGING_CATEGORY(lcTablet, "qt.quick.tablet")
-Q_LOGGING_CATEGORY(lcWheelTarget, "qt.quick.wheel.target")
-Q_LOGGING_CATEGORY(lcGestureTarget, "qt.quick.gesture.target")
-Q_LOGGING_CATEGORY(lcHoverTrace, "qt.quick.hover.trace")
-Q_LOGGING_CATEGORY(lcFocus, "qt.quick.focus")
-Q_LOGGING_CATEGORY(lcDirty, "qt.quick.dirty")
-Q_LOGGING_CATEGORY(lcTransient, "qt.quick.window.transient")
-
extern Q_GUI_EXPORT bool qt_sendShortcutOverrideEvent(QObject *o, ulong timestamp, int k, Qt::KeyboardModifiers mods, const QString &text = QString(), bool autorep = false, ushort count = 1);
-bool QQuickWindowPrivate::defaultAlphaBuffer = false;
-
-#if defined(QT_QUICK_DEFAULT_TEXT_RENDER_TYPE)
-QQuickWindow::TextRenderType QQuickWindowPrivate::textRenderType = QQuickWindow::QT_QUICK_DEFAULT_TEXT_RENDER_TYPE;
-#else
-QQuickWindow::TextRenderType QQuickWindowPrivate::textRenderType = QQuickWindow::QtTextRendering;
-#endif
-
-void QQuickWindowPrivate::updateFocusItemTransform()
-{
-#if QT_CONFIG(im)
- Q_Q(QQuickWindow);
- QQuickItem *focus = q->activeFocusItem();
- if (focus && QGuiApplication::focusObject() == focus) {
- QQuickItemPrivate *focusPrivate = QQuickItemPrivate::get(focus);
- QGuiApplication::inputMethod()->setInputItemTransform(focusPrivate->itemToWindowTransform());
- QGuiApplication::inputMethod()->setInputItemRectangle(QRectF(0, 0, focusPrivate->width, focusPrivate->height));
- focus->updateInputMethod(Qt::ImInputItemClipRectangle);
- }
-#endif
-}
-
-class QQuickWindowIncubationController : public QObject, public QQmlIncubationController
-{
- Q_OBJECT
-
-public:
- QQuickWindowIncubationController(QSGRenderLoop *loop)
- : m_renderLoop(loop), m_timer(0)
- {
- // Allow incubation for 1/3 of a frame.
- m_incubation_time = qMax(1, int(1000 / QGuiApplication::primaryScreen()->refreshRate()) / 3);
-
- QAnimationDriver *animationDriver = m_renderLoop->animationDriver();
- if (animationDriver) {
- connect(animationDriver, SIGNAL(stopped()), this, SLOT(animationStopped()));
- connect(m_renderLoop, SIGNAL(timeToIncubate()), this, SLOT(incubate()));
- }
- }
-
-protected:
- void timerEvent(QTimerEvent *) override
- {
- killTimer(m_timer);
- m_timer = 0;
- incubate();
- }
-
- void incubateAgain() {
- if (m_timer == 0) {
- // Wait for a while before processing the next batch. Using a
- // timer to avoid starvation of system events.
- m_timer = startTimer(m_incubation_time);
- }
- }
-
-public slots:
- void incubate() {
- if (m_renderLoop && incubatingObjectCount()) {
- if (m_renderLoop->interleaveIncubation()) {
- incubateFor(m_incubation_time);
- } else {
- incubateFor(m_incubation_time * 2);
- if (incubatingObjectCount())
- incubateAgain();
- }
- }
- }
-
- void animationStopped() { incubate(); }
-
-protected:
- void incubatingObjectCountChanged(int count) override
- {
- if (count && m_renderLoop && !m_renderLoop->interleaveIncubation())
- incubateAgain();
- }
-
-private:
- QPointer<QSGRenderLoop> m_renderLoop;
- int m_incubation_time;
- int m_timer;
-};
-
-#include "qquickwindow.moc"
-#include "moc_qquickwindow_p.cpp"
-
-
-#if QT_CONFIG(accessibility)
-/*!
- Returns an accessibility interface for this window, or 0 if such an
- interface cannot be created.
-*/
-QAccessibleInterface *QQuickWindow::accessibleRoot() const
-{
- return QAccessible::queryAccessibleInterface(const_cast<QQuickWindow*>(this));
-}
-#endif
-
-
-/*
-Focus behavior
-==============
-
-Prior to being added to a valid window items can set and clear focus with no
-effect. Only once items are added to a window (by way of having a parent set that
-already belongs to a window) do the focus rules apply. Focus goes back to
-having no effect if an item is removed from a window.
-
-When an item is moved into a new focus scope (either being added to a window
-for the first time, or having its parent changed), if the focus scope already has
-a scope focused item that takes precedence over the item being added. Otherwise,
-the focus of the added tree is used. In the case of a tree of items being
-added to a window for the first time, which may have a conflicted focus state (two
-or more items in one scope having focus set), the same rule is applied item by item -
-thus the first item that has focus will get it (assuming the scope doesn't already
-have a scope focused item), and the other items will have their focus cleared.
-*/
-
-QQuickRootItem::QQuickRootItem()
-{
-}
-
-/*! \reimp */
-void QQuickWindow::exposeEvent(QExposeEvent *)
-{
- Q_D(QQuickWindow);
- if (d->windowManager)
- d->windowManager->exposureChanged(this);
-}
-
-/*! \reimp */
-void QQuickWindow::resizeEvent(QResizeEvent *ev)
-{
- Q_D(QQuickWindow);
- if (d->contentItem)
- d->contentItem->setSize(ev->size());
- if (d->windowManager)
- d->windowManager->resize(this);
-}
-
-/*! \reimp */
-void QQuickWindow::showEvent(QShowEvent *)
-{
- Q_D(QQuickWindow);
- if (d->windowManager)
- d->windowManager->show(this);
-}
-
-/*! \reimp */
-void QQuickWindow::hideEvent(QHideEvent *)
-{
- Q_D(QQuickWindow);
- if (d->windowManager)
- d->windowManager->hide(this);
-}
-
-/*! \reimp */
-void QQuickWindow::closeEvent(QCloseEvent *e)
-{
- QQuickCloseEvent qev;
- qev.setAccepted(e->isAccepted());
- emit closing(&qev);
- e->setAccepted(qev.isAccepted());
-}
-
-/*! \reimp */
-void QQuickWindow::focusOutEvent(QFocusEvent *ev)
-{
- Q_D(QQuickWindow);
- if (d->contentItem)
- d->contentItem->setFocus(false, ev->reason());
-}
-
-/*! \reimp */
-void QQuickWindow::focusInEvent(QFocusEvent *ev)
-{
- Q_D(QQuickWindow);
- if (d->contentItem)
- d->contentItem->setFocus(true, ev->reason());
- d->updateFocusItemTransform();
-}
-
-#if QT_CONFIG(im)
-static bool transformDirtyOnItemOrAncestor(const QQuickItem *item)
-{
- while (item) {
- if (QQuickItemPrivate::get(item)->dirtyAttributes & (
- QQuickItemPrivate::TransformOrigin |
- QQuickItemPrivate::Transform |
- QQuickItemPrivate::BasicTransform |
- QQuickItemPrivate::Position |
- QQuickItemPrivate::Size |
- QQuickItemPrivate::ParentChanged |
- QQuickItemPrivate::Clip)) {
- return true;
- }
- item = item->parentItem();
- }
- return false;
-}
-#endif
-
-/*!
- * \internal
-
- A "polish loop" can occur inside QQuickWindowPrivate::polishItems(). It is when an item calls
- polish() on an(other?) item from updatePolish(). If this anomaly happens repeatedly and without
- interruption (of a well-behaved updatePolish() that doesn't call polish()), it is a strong
- indication that we are heading towards an infinite polish loop. A polish loop is not a bug in
- Qt Quick - it is a bug caused by ill-behaved items put in the scene.
-
- We can detect this sequence of polish loops easily, since the
- QQuickWindowPrivate::itemsToPolish is basically a stack: polish() will push to it, and
- polishItems() will pop from it.
- Therefore if updatePolish() calls polish(), the immediate next item polishItems() processes is
- the item that was polished by the previous call to updatePolish().
- We therefore just need to count the number of polish loops we detected in _sequence_.
-*/
-struct PolishLoopDetector
-{
- PolishLoopDetector(const QVector<QQuickItem*> &itemsToPolish)
- : itemsToPolish(itemsToPolish)
- {
- }
-
- /*
- * returns true when it detected a likely infinite loop
- * (suggests it should abort the polish loop)
- **/
- bool check(QQuickItem *item, int itemsRemainingBeforeUpdatePolish)
- {
- if (itemsToPolish.count() > itemsRemainingBeforeUpdatePolish) {
- // Detected potential polish loop.
- ++numPolishLoopsInSequence;
- if (numPolishLoopsInSequence >= 1000) {
- // Start to warn about polish loop after 1000 consecutive polish loops
- if (numPolishLoopsInSequence == 100000) {
- // We have looped 100,000 times without actually reducing the list of items to
- // polish, give up for now.
- // This is not a fix, just a remedy so that the application can be somewhat
- // responsive.
- numPolishLoopsInSequence = 0;
- return true;
- } else if (numPolishLoopsInSequence < 1005) {
- // Show the 5 next items involved in the polish loop.
- // (most likely they will be the same 5 items...)
- QQuickItem *guiltyItem = itemsToPolish.last();
- qmlWarning(item) << "possible QQuickItem::polish() loop";
-
- auto typeAndObjectName = [](QQuickItem *item) {
- QString typeName = QQmlMetaType::prettyTypeName(item);
- QString objName = item->objectName();
- if (!objName.isNull())
- return QLatin1String("%1(%2)").arg(typeName, objName);
- return typeName;
- };
-
- qmlWarning(guiltyItem) << typeAndObjectName(guiltyItem)
- << " called polish() inside updatePolish() of " << typeAndObjectName(item);
-
- if (numPolishLoopsInSequence == 1004)
- // Enough warnings. Reset counter in order to speed things up and re-detect
- // more loops
- numPolishLoopsInSequence = 0;
- }
- }
- } else {
- numPolishLoopsInSequence = 0;
- }
- return false;
- }
- const QVector<QQuickItem*> &itemsToPolish; // Just a ref to the one in polishItems()
- int numPolishLoopsInSequence = 0;
-};
-
-void QQuickWindowPrivate::polishItems()
-{
- // An item can trigger polish on another item, or itself for that matter,
- // during its updatePolish() call. Because of this, we cannot simply
- // iterate through the set, we must continue pulling items out until it
- // is empty.
- // In the case where polish is called from updatePolish() either directly
- // or indirectly, we use a PolishLoopDetector to determine if a warning should
- // be printed to the user.
-
- PolishLoopDetector polishLoopDetector(itemsToPolish);
- while (!itemsToPolish.isEmpty()) {
- QQuickItem *item = itemsToPolish.takeLast();
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- itemPrivate->polishScheduled = false;
- const int itemsRemaining = itemsToPolish.count();
- itemPrivate->updatePolish();
- item->updatePolish();
- if (polishLoopDetector.check(item, itemsRemaining) == true)
- break;
- }
-
-#if QT_CONFIG(im)
- if (QQuickItem *focusItem = q_func()->activeFocusItem()) {
- // If the current focus item, or any of its anchestors, has changed location
- // inside the window, we need inform IM about it. This to ensure that overlays
- // such as selection handles will be updated.
- const bool isActiveFocusItem = (focusItem == QGuiApplication::focusObject());
- const bool hasImEnabled = focusItem->inputMethodQuery(Qt::ImEnabled).toBool();
- if (isActiveFocusItem && hasImEnabled && transformDirtyOnItemOrAncestor(focusItem))
- updateFocusItemTransform();
- }
-#endif
-}
-
-/*!
- * Schedules the window to render another frame.
- *
- * Calling QQuickWindow::update() differs from QQuickItem::update() in that
- * it always triggers a repaint, regardless of changes in the underlying
- * scene graph or not.
- */
-void QQuickWindow::update()
-{
- Q_D(QQuickWindow);
- if (d->windowManager)
- d->windowManager->update(this);
- else if (d->renderControl)
- QQuickRenderControlPrivate::get(d->renderControl)->update();
-}
-
-static void updatePixelRatioHelper(QQuickItem *item, float pixelRatio)
-{
- if (item->flags() & QQuickItem::ItemHasContents) {
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- itemPrivate->itemChange(QQuickItem::ItemDevicePixelRatioHasChanged, pixelRatio);
- }
-
- QList <QQuickItem *> items = item->childItems();
- for (int i = 0; i < items.size(); ++i)
- updatePixelRatioHelper(items.at(i), pixelRatio);
-}
-
-void QQuickWindow::physicalDpiChanged()
-{
- Q_D(QQuickWindow);
- const qreal newPixelRatio = screen()->devicePixelRatio();
- if (qFuzzyCompare(newPixelRatio, d->devicePixelRatio))
- return;
- d->devicePixelRatio = newPixelRatio;
- if (d->contentItem)
- updatePixelRatioHelper(d->contentItem, newPixelRatio);
-}
-
-void QQuickWindow::handleScreenChanged(QScreen *screen)
-{
- Q_D(QQuickWindow);
- if (screen) {
- physicalDpiChanged();
- // When physical DPI changes on the same screen, either the resolution or the device pixel
- // ratio changed. We must check what it is. Device pixel ratio does not have its own
- // ...Changed() signal.
- d->physicalDpiChangedConnection = connect(screen, SIGNAL(physicalDotsPerInchChanged(qreal)),
- this, SLOT(physicalDpiChanged()));
- } else {
- disconnect(d->physicalDpiChangedConnection);
- }
-
- d->forcePolish();
-}
-
-void forcePolishHelper(QQuickItem *item)
-{
- if (item->flags() & QQuickItem::ItemHasContents) {
- item->polish();
- }
-
- QList <QQuickItem *> items = item->childItems();
- for (int i=0; i<items.size(); ++i)
- forcePolishHelper(items.at(i));
-}
-
-/*!
- Schedules polish events on all items in the scene.
-*/
-void QQuickWindowPrivate::forcePolish()
-{
- Q_Q(QQuickWindow);
- if (!q->screen())
- return;
- forcePolishHelper(contentItem);
-}
-
-void forceUpdate(QQuickItem *item)
-{
- if (item->flags() & QQuickItem::ItemHasContents)
- item->update();
- QQuickItemPrivate::get(item)->dirty(QQuickItemPrivate::ChildrenUpdateMask);
-
- QList <QQuickItem *> items = item->childItems();
- for (int i=0; i<items.size(); ++i)
- forceUpdate(items.at(i));
-}
-
-void QQuickWindowRenderTarget::reset(QRhi *rhi, QSGRenderer *renderer)
-{
- if (rhi) {
- if (renderer)
- renderer->invalidatePipelineCacheDependency(rpDesc);
- if (owns) {
- delete renderTarget;
- delete rpDesc;
- delete texture;
- delete depthStencil;
- }
- }
-
- renderTarget = nullptr;
- rpDesc = nullptr;
- texture = nullptr;
- depthStencil = nullptr;
- owns = false;
-}
-
-void QQuickWindowPrivate::ensureCustomRenderTarget()
-{
- // resolve() can be expensive when importing an existing native texture, so
- // it is important to only do it when the QQuickRenderTarget* was really changed
- if (!redirect.renderTargetDirty || !rhi)
- return;
-
- redirect.renderTargetDirty = false;
-
- redirect.rt.reset(rhi, renderer);
-
- // a default constructed QQuickRenderTarget means no redirection
- if (customRenderTarget.isNull())
- return;
-
- QQuickRenderTargetPrivate::get(&customRenderTarget)->resolve(rhi, &redirect.rt);
-}
-
-void QQuickWindowPrivate::setCustomCommandBuffer(QRhiCommandBuffer *cb)
-{
- // ownership not transferred
- redirect.commandBuffer = cb;
-}
-
-void QQuickWindowPrivate::syncSceneGraph()
-{
- Q_Q(QQuickWindow);
-
- ensureCustomRenderTarget();
-
- // Calculate the dpr the same way renderSceneGraph() will.
- qreal devicePixelRatio = q->effectiveDevicePixelRatio();
- if (redirect.rt.renderTarget && !QQuickRenderControl::renderWindowFor(q))
- devicePixelRatio = 1;
-
- QRhiCommandBuffer *cb = nullptr;
- if (rhi) {
- if (redirect.commandBuffer)
- cb = redirect.commandBuffer;
- else
- cb = swapchain->currentFrameCommandBuffer();
- }
- context->prepareSync(devicePixelRatio, cb, graphicsConfig);
-
- animationController->beforeNodeSync();
-
- emit q->beforeSynchronizing();
- runAndClearJobs(&beforeSynchronizingJobs);
- if (!renderer) {
- forceUpdate(contentItem);
-
- QSGRootNode *rootNode = new QSGRootNode;
- rootNode->appendChildNode(QQuickItemPrivate::get(contentItem)->itemNode());
- const bool useDepth = graphicsConfig.isDepthBufferEnabledFor2D();
- const QSGRendererInterface::RenderMode renderMode = useDepth ? QSGRendererInterface::RenderMode2D
- : QSGRendererInterface::RenderMode2DNoDepthBuffer;
- renderer = context->createRenderer(renderMode);
- renderer->setRootNode(rootNode);
- }
-
- updateDirtyNodes();
-
- animationController->afterNodeSync();
-
- // Copy the current state of clearing from window into renderer.
- renderer->setClearColor(clearColor);
- // Cannot skip clearing the color buffer in Qt 6 anymore.
- const QSGAbstractRenderer::ClearMode mode = QSGAbstractRenderer::ClearColorBuffer
- | QSGAbstractRenderer::ClearStencilBuffer
- | QSGAbstractRenderer::ClearDepthBuffer;
- renderer->setClearMode(mode);
-
- renderer->setVisualizationMode(visualizationMode);
-
- emit q->afterSynchronizing();
- runAndClearJobs(&afterSynchronizingJobs);
-}
-
-void QQuickWindowPrivate::emitBeforeRenderPassRecording(void *ud)
-{
- QQuickWindow *w = reinterpret_cast<QQuickWindow *>(ud);
- emit w->beforeRenderPassRecording();
-}
-
-void QQuickWindowPrivate::emitAfterRenderPassRecording(void *ud)
-{
- QQuickWindow *w = reinterpret_cast<QQuickWindow *>(ud);
- emit w->afterRenderPassRecording();
-}
-
-void QQuickWindowPrivate::renderSceneGraph(const QSize &size, const QSize &surfaceSize)
-{
- Q_Q(QQuickWindow);
- if (!renderer)
- return;
-
- if (rhi) {
- ensureCustomRenderTarget();
- QRhiRenderTarget *rt;
- QRhiRenderPassDescriptor *rp;
- QRhiCommandBuffer *cb;
- if (redirect.rt.renderTarget) {
- rt = redirect.rt.renderTarget;
- rp = rt->renderPassDescriptor();
- if (!rp) {
- qWarning("Custom render target is set but no renderpass descriptor has been provided.");
- return;
- }
- cb = redirect.commandBuffer;
- if (!cb) {
- qWarning("Custom render target is set but no command buffer has been provided.");
- return;
- }
- } else {
- if (!swapchain) {
- qWarning("QQuickWindow: No render target (neither swapchain nor custom target was provided)");
- return;
- }
- rt = swapchain->currentFrameRenderTarget();
- rp = rpDescForSwapchain;
- cb = swapchain->currentFrameCommandBuffer();
- }
- context->beginNextRhiFrame(renderer, rt, rp, cb,
- emitBeforeRenderPassRecording,
- emitAfterRenderPassRecording,
- q);
- } else {
- context->beginNextFrame(renderer,
- emitBeforeRenderPassRecording,
- emitAfterRenderPassRecording,
- q);
- }
-
- animationController->advance();
- emit q->beforeRendering();
- runAndClearJobs(&beforeRenderingJobs);
-
- QSGAbstractRenderer::MatrixTransformFlags matrixFlags;
- const bool flipY = rhi ? !rhi->isYUpInNDC() : false;
- if (flipY)
- matrixFlags |= QSGAbstractRenderer::MatrixTransformFlipY;
- const qreal devicePixelRatio = q->effectiveDevicePixelRatio();
- if (redirect.rt.renderTarget) {
- QRect rect(QPoint(0, 0), redirect.rt.renderTarget->pixelSize());
- renderer->setDeviceRect(rect);
- renderer->setViewportRect(rect);
- if (QQuickRenderControl::renderWindowFor(q)) {
- renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), size), matrixFlags);
- renderer->setDevicePixelRatio(devicePixelRatio);
- } else {
- renderer->setProjectionMatrixToRect(QRect(QPoint(0, 0), rect.size()), matrixFlags);
- renderer->setDevicePixelRatio(1);
- }
- } else {
- QSize pixelSize;
- QSizeF logicalSize;
- if (surfaceSize.isEmpty()) {
- pixelSize = size * devicePixelRatio;
- logicalSize = size;
- } else {
- pixelSize = surfaceSize;
- logicalSize = QSizeF(surfaceSize) / devicePixelRatio;
- }
- QRect rect(QPoint(0, 0), pixelSize);
- renderer->setDeviceRect(rect);
- renderer->setViewportRect(rect);
- renderer->setProjectionMatrixToRect(QRectF(QPoint(0, 0), logicalSize), matrixFlags);
- renderer->setDevicePixelRatio(devicePixelRatio);
- }
-
- if (rhi) {
- context->renderNextRhiFrame(renderer);
- } else {
- // This is the software backend (or some custom scenegraph context
- // plugin) in practice, because the default implementation always
- // hits the QRhi-based path in Qt 6.
- context->renderNextFrame(renderer);
- }
-
- emit q->afterRendering();
- runAndClearJobs(&afterRenderingJobs);
-
- if (rhi)
- context->endNextRhiFrame(renderer);
- else
- context->endNextFrame(renderer);
-
- if (renderer && renderer->hasVisualizationModeWithContinuousUpdate()) {
- // For the overdraw visualizer. This update is not urgent so avoid a
- // direct update() call, this is only here to keep the overdraw
- // visualization box rotating even when the scene is static.
- QCoreApplication::postEvent(q, new QEvent(QEvent::Type(FullUpdateRequest)));
- }
-}
-
-QQuickWindowPrivate::QQuickWindowPrivate()
- : contentItem(nullptr)
- , activeFocusItem(nullptr)
-#if QT_CONFIG(cursor)
- , cursorItem(nullptr)
- , cursorHandler(nullptr)
-#endif
-#if QT_CONFIG(quick_draganddrop)
- , dragGrabber(nullptr)
-#endif
- , touchMouseId(-1)
- , touchMouseDevice(nullptr)
- , touchMousePressTimestamp(0)
- , dirtyItemList(nullptr)
- , devicePixelRatio(0)
- , context(nullptr)
- , renderer(nullptr)
- , windowManager(nullptr)
- , renderControl(nullptr)
- , pointerEventRecursionGuard(0)
- , clearColor(Qt::white)
- , persistentGraphics(true)
- , persistentSceneGraph(true)
- , lastWheelEventAccepted(false)
- , componentCompleted(true)
- , allowChildEventFiltering(true)
- , allowDoubleClick(true)
- , lastFocusReason(Qt::OtherFocusReason)
- , incubationController(nullptr)
- , hasActiveSwapchain(false)
- , hasRenderableSwapchain(false)
- , swapchainJustBecameRenderable(false)
-{
-#if QT_CONFIG(quick_draganddrop)
- dragGrabber = new QQuickDragGrabber;
-#endif
-}
-
-QQuickWindowPrivate::~QQuickWindowPrivate()
-{
- redirect.rt.reset(rhi, renderer);
- if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
- service->removeWindow(q_func());
-}
-
-void QQuickWindowPrivate::updateChildrenPalettes(const QPalette &parentPalette)
-{
- Q_Q(QQuickWindow);
- if (auto root = q->contentItem()) {
- for (auto &&child: root->childItems()) {
- QQuickItemPrivate::get(child)->inheritPalette(parentPalette);
- }
- }
-}
-
-void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
-{
- q_ptr = c;
-
-
- Q_Q(QQuickWindow);
-
- contentItem = new QQuickRootItem;
- QQml_setParent_noEvent(contentItem, c);
- QQmlEngine::setObjectOwnership(contentItem, QQmlEngine::CppOwnership);
- QQuickItemPrivate *contentItemPrivate = QQuickItemPrivate::get(contentItem);
- contentItemPrivate->window = q;
- contentItemPrivate->windowRefCount = 1;
- contentItemPrivate->flags |= QQuickItem::ItemIsFocusScope;
- contentItem->setSize(q->size());
-
- visualizationMode = qgetenv("QSG_VISUALIZE");
- renderControl = control;
- if (renderControl)
- QQuickRenderControlPrivate::get(renderControl)->window = q;
-
- if (!renderControl)
- windowManager = QSGRenderLoop::instance();
-
- Q_ASSERT(windowManager || renderControl);
-
- if (QScreen *screen = q->screen())
- devicePixelRatio = screen->devicePixelRatio();
-
- QSGContext *sg;
- if (renderControl) {
- QQuickRenderControlPrivate *renderControlPriv = QQuickRenderControlPrivate::get(renderControl);
- sg = renderControlPriv->sg;
- context = renderControlPriv->rc;
- } else {
- windowManager->addWindow(q);
- sg = windowManager->sceneGraphContext();
- context = windowManager->createRenderContext(sg);
- }
-
- q->setSurfaceType(windowManager ? windowManager->windowSurfaceType() : QSurface::OpenGLSurface);
- q->setFormat(sg->defaultSurfaceFormat());
- // When using Vulkan, associating a scenegraph-managed QVulkanInstance with
- // the window (but only when not using renderControl) is deferred to
- // QSGRhiSupport::createRhi(). This allows applications to set up their own
- // QVulkanInstance and set that on the window, if they wish to.
-
- animationController.reset(new QQuickAnimatorController(q));
-
- QObject::connect(context, SIGNAL(initialized()), q, SIGNAL(sceneGraphInitialized()), Qt::DirectConnection);
- QObject::connect(context, SIGNAL(invalidated()), q, SIGNAL(sceneGraphInvalidated()), Qt::DirectConnection);
- QObject::connect(context, SIGNAL(invalidated()), q, SLOT(cleanupSceneGraph()), Qt::DirectConnection);
-
- QObject::connect(q, SIGNAL(focusObjectChanged(QObject*)), q, SIGNAL(activeFocusItemChanged()));
- QObject::connect(q, SIGNAL(screenChanged(QScreen*)), q, SLOT(handleScreenChanged(QScreen*)));
- QObject::connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)),
- q, SLOT(handleApplicationStateChanged(Qt::ApplicationState)));
- QObject::connect(q, SIGNAL(frameSwapped()), q, SLOT(runJobsAfterSwap()), Qt::DirectConnection);
-
- if (QQmlInspectorService *service = QQmlDebugConnector::service<QQmlInspectorService>())
- service->addWindow(q);
-}
-
-void QQuickWindow::handleApplicationStateChanged(Qt::ApplicationState state)
-{
- Q_D(QQuickWindow);
- if (state != Qt::ApplicationActive && d->contentItem)
- d->handleWindowDeactivate();
-}
-
-/*!
- \property QQuickWindow::data
- \internal
-*/
-
-QQmlListProperty<QObject> QQuickWindowPrivate::data()
-{
- return QQmlListProperty<QObject>(q_func(), nullptr,
- QQuickWindowPrivate::data_append,
- QQuickWindowPrivate::data_count,
- QQuickWindowPrivate::data_at,
- QQuickWindowPrivate::data_clear,
- QQuickWindowPrivate::data_replace,
- QQuickWindowPrivate::data_removeLast);
-}
-
void QQuickWindowPrivate::touchToMouseEvent(QEvent::Type type, const QEventPoint &p, const QTouchEvent *touchEvent, QMutableSinglePointEvent *mouseEvent)
{
Q_ASSERT(QCoreApplication::testAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents));