1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQUICKWINDOW_P_H
5#define QQUICKWINDOW_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtQuick/private/qquickdeliveryagent_p_p.h>
19#include <QtQuick/private/qquickevents_p_p.h>
20#include <QtQuick/private/qsgcontext_p.h>
21#include <QtQuick/private/qquickpaletteproviderprivatebase_p.h>
22#include <QtQuick/private/qquickrendertarget_p.h>
23#include <QtQuick/private/qquickgraphicsdevice_p.h>
24#include <QtQuick/private/qquickgraphicsconfiguration_p.h>
25#include <QtQuick/qquickitem.h>
26#include <QtQuick/qquickwindow.h>
27
28#include <QtCore/qthread.h>
29#include <QtCore/qmutex.h>
30#include <QtCore/qwaitcondition.h>
31#include <QtCore/qrunnable.h>
32#include <QtCore/qstack.h>
33
34#include <QtGui/private/qevent_p.h>
35#include <QtGui/private/qpointingdevice_p.h>
36#include <QtGui/private/qwindow_p.h>
37#include <QtGui/qevent.h>
38#include <QtGui/qstylehints.h>
39#include <QtGui/qguiapplication.h>
40
41QT_BEGIN_NAMESPACE
42
43class QOpenGLContext;
44class QQuickAnimatorController;
45class QQuickDragGrabber;
46class QQuickItemPrivate;
47class QPointingDevice;
48class QQuickRenderControl;
49class QQuickWindowIncubationController;
50class QQuickWindowPrivate;
51class QSGRenderLoop;
52class QTouchEvent;
53class QRhi;
54class QRhiSwapChain;
55class QRhiRenderBuffer;
56class QRhiRenderPassDescriptor;
57class QRhiTexture;
58
59//Make it easy to identify and customize the root item if needed
60class Q_QUICK_PRIVATE_EXPORT QQuickRootItem : public QQuickItem
61{
62 Q_OBJECT
63 QML_ANONYMOUS
64 QML_ADDED_IN_VERSION(2, 0)
65public:
66 QQuickRootItem();
67
68public Q_SLOTS:
69 void setWidth(int w) {QQuickItem::setWidth(qreal(w));}
70 void setHeight(int h) {QQuickItem::setHeight(qreal(h));}
71};
72
73class QQuickWindowRenderTarget
74{
75public:
76 void reset(QRhi *rhi);
77 QRhiRenderTarget *renderTarget = nullptr;
78 QRhiRenderPassDescriptor *rpDesc = nullptr;
79 QRhiTexture *texture = nullptr;
80 QRhiRenderBuffer *renderBuffer = nullptr;
81 QRhiRenderBuffer *depthStencil = nullptr;
82 QPaintDevice *paintDevice = nullptr;
83 bool owns = false;
84};
85
86class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate
87 : public QWindowPrivate
88 , public QQuickPaletteProviderPrivateBase<QQuickWindow, QQuickWindowPrivate>
89{
90public:
91 Q_DECLARE_PUBLIC(QQuickWindow)
92
93 enum CustomEvents {
94 FullUpdateRequest = QEvent::User + 1,
95 TriggerContextCreationFailure = QEvent::User + 2
96 };
97
98 static inline QQuickWindowPrivate *get(QQuickWindow *c) { return c->d_func(); }
99 static inline const QQuickWindowPrivate *get(const QQuickWindow *c) { return c->d_func(); }
100
101 QQuickWindowPrivate();
102 ~QQuickWindowPrivate() override;
103
104 void updateChildrenPalettes(const QPalette &parentPalette) override;
105
106 void init(QQuickWindow *, QQuickRenderControl *control = nullptr);
107
108 QQuickRootItem *contentItem;
109 QSet<QQuickItem *> parentlessItems;
110 QQmlListProperty<QObject> data();
111
112 // primary delivery agent for the whole scene, used by default for events that arrive in this window;
113 // but any subscene root can have a QQuickItemPrivate::ExtraData::subsceneDeliveryAgent
114 QQuickDeliveryAgent *deliveryAgent = nullptr;
115 QQuickDeliveryAgentPrivate *deliveryAgentPrivate() const
116 { return deliveryAgent ? static_cast<QQuickDeliveryAgentPrivate *>(QQuickDeliveryAgentPrivate::get(o: deliveryAgent)) : nullptr; }
117
118#if QT_CONFIG(cursor)
119 QQuickItem *cursorItem = nullptr;
120 QQuickPointerHandler *cursorHandler = nullptr;
121 void updateCursor(const QPointF &scenePos, QQuickItem *rootItem = nullptr);
122 QPair<QQuickItem*, QQuickPointerHandler*> findCursorItemAndHandler(QQuickItem *item, const QPointF &scenePos) const;
123#endif
124
125 void clearFocusObject() override;
126
127 void dirtyItem(QQuickItem *);
128 void cleanup(QSGNode *);
129
130 void ensureCustomRenderTarget();
131 void setCustomCommandBuffer(QRhiCommandBuffer *cb);
132
133 void polishItems();
134 void forcePolish();
135 void invalidateFontData(QQuickItem *item);
136 void syncSceneGraph();
137 void renderSceneGraph();
138
139 bool isRenderable() const;
140
141 bool emitError(QQuickWindow::SceneGraphError error, const QString &msg);
142
143 enum TextureFromNativeTextureFlag {
144 NativeTextureIsExternalOES = 0x01
145 };
146 Q_DECLARE_FLAGS(TextureFromNativeTextureFlags, TextureFromNativeTextureFlag)
147
148 QSGTexture *createTextureFromNativeTexture(quint64 nativeObjectHandle,
149 int nativeLayoutOrState,
150 uint nativeFormat,
151 const QSize &size,
152 QQuickWindow::CreateTextureOptions options,
153 TextureFromNativeTextureFlags flags = {}) const;
154 QSGTexture *createTextureFromNativeTexture(quint64 nativeObjectHandle,
155 int nativeLayoutOrState,
156 const QSize &size,
157 QQuickWindow::CreateTextureOptions options,
158 TextureFromNativeTextureFlags flags = {}) const {
159 return createTextureFromNativeTexture(nativeObjectHandle, nativeLayoutOrState, nativeFormat: 0, size, options, flags);
160 }
161
162 QQuickItem::UpdatePaintNodeData updatePaintNodeData;
163
164 QQuickItem *dirtyItemList;
165 QList<QSGNode *> cleanupNodeList;
166
167 QVector<QQuickItem *> itemsToPolish;
168
169 qreal lastReportedItemDevicePixelRatio;
170 QMetaObject::Connection physicalDpiChangedConnection;
171
172 void updateDirtyNodes();
173 void cleanupNodes();
174 void cleanupNodesOnShutdown();
175 bool updateEffectiveOpacity(QQuickItem *);
176 void updateEffectiveOpacityRoot(QQuickItem *, qreal);
177 void updateDirtyNode(QQuickItem *);
178
179 void fireFrameSwapped() { Q_EMIT q_func()->frameSwapped(); }
180 void fireAboutToStop() { Q_EMIT q_func()->sceneGraphAboutToStop(); }
181
182 void clearGrabbers(QPointerEvent *event);
183
184 QSGRenderContext *context;
185 QSGRenderer *renderer;
186 QByteArray visualizationMode; // Default renderer supports "clip", "overdraw", "changes", "batches" and blank.
187
188 QSGRenderLoop *windowManager;
189 QQuickRenderControl *renderControl;
190 QScopedPointer<QQuickAnimatorController> animationController;
191
192 QColor clearColor;
193
194 uint persistentGraphics : 1;
195 uint persistentSceneGraph : 1;
196 uint componentComplete : 1;
197 uint inDestructor : 1;
198
199 // Storage for setRenderTarget(QQuickRenderTarget).
200 // Gets baked into redirect.renderTarget by ensureCustomRenderTarget() when rendering the next frame.
201 QQuickRenderTarget customRenderTarget;
202
203 struct Redirect {
204 QRhiCommandBuffer *commandBuffer = nullptr;
205 QQuickWindowRenderTarget rt;
206 bool renderTargetDirty = false;
207 } redirect;
208
209 QQuickGraphicsDevice customDeviceObjects;
210
211 QQuickGraphicsConfiguration graphicsConfig;
212
213 mutable QQuickWindowIncubationController *incubationController;
214
215 static bool defaultAlphaBuffer;
216 static QQuickWindow::TextRenderType textRenderType;
217
218 // vvv currently in use in Controls 2; TODO remove
219 static bool dragOverThreshold(qreal d, Qt::Axis axis, const QEventPoint *tp, int startDragThreshold = -1)
220 { return QQuickDeliveryAgentPrivate::dragOverThreshold(d, axis, tp: *tp, startDragThreshold); }
221 static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event, int startDragThreshold = -1)
222 { return QQuickDeliveryAgentPrivate::dragOverThreshold(d, axis, event, startDragThreshold); }
223 void clearFocusInScope(QQuickItem *scope, QQuickItem *item, Qt::FocusReason reason)
224 { deliveryAgentPrivate()->clearFocusInScope(scope, item, reason); }
225 // ^^^ currently in use in Controls 2; TODO remove
226
227 // data property
228 static void data_append(QQmlListProperty<QObject> *, QObject *);
229 static qsizetype data_count(QQmlListProperty<QObject> *);
230 static QObject *data_at(QQmlListProperty<QObject> *, qsizetype);
231 static void data_clear(QQmlListProperty<QObject> *);
232 static void data_replace(QQmlListProperty<QObject> *, qsizetype, QObject *);
233 static void data_removeLast(QQmlListProperty<QObject> *);
234
235 static void rhiCreationFailureMessage(const QString &backendName,
236 QString *translatedMessage,
237 QString *untranslatedMessage);
238
239 static void emitBeforeRenderPassRecording(void *ud);
240 static void emitAfterRenderPassRecording(void *ud);
241
242 QMutex renderJobMutex;
243 QList<QRunnable *> beforeSynchronizingJobs;
244 QList<QRunnable *> afterSynchronizingJobs;
245 QList<QRunnable *> beforeRenderingJobs;
246 QList<QRunnable *> afterRenderingJobs;
247 QList<QRunnable *> afterSwapJobs;
248
249 void runAndClearJobs(QList<QRunnable *> *jobs);
250 QOpenGLContext *openglContext();
251
252 QQuickWindow::GraphicsStateInfo rhiStateInfo;
253 QRhi *rhi = nullptr;
254 QRhiSwapChain *swapchain = nullptr;
255 QRhiRenderBuffer *depthStencilForSwapchain = nullptr;
256 QRhiRenderPassDescriptor *rpDescForSwapchain = nullptr;
257 uint hasActiveSwapchain : 1;
258 uint hasRenderableSwapchain : 1;
259 uint swapchainJustBecameRenderable : 1;
260 uint updatesEnabled : 1;
261 bool pendingFontUpdate = false;
262 bool windowEventDispatch = false;
263
264private:
265 static void cleanupNodesOnShutdown(QQuickItem *);
266};
267
268class QQuickWindowQObjectCleanupJob : public QRunnable
269{
270public:
271 QQuickWindowQObjectCleanupJob(QObject *o) : object(o) { }
272 void run() override { delete object; }
273 QObject *object;
274 static void schedule(QQuickWindow *window, QObject *object) {
275 Q_ASSERT(window);
276 Q_ASSERT(object);
277 window->scheduleRenderJob(job: new QQuickWindowQObjectCleanupJob(object), schedule: QQuickWindow::AfterSynchronizingStage);
278 }
279};
280
281Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickWindowPrivate::TextureFromNativeTextureFlags)
282
283QT_END_NAMESPACE
284
285#endif // QQUICKWINDOW_P_H
286

source code of qtdeclarative/src/quick/items/qquickwindow_p.h