Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qsgsoftwarerenderloop.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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
5
7
8#include <QtCore/QCoreApplication>
9
10#include <private/qquickwindow_p.h>
11#include <private/qquickitem_p.h>
12#include <QElapsedTimer>
13#include <private/qquickanimatorcontroller_p.h>
14#include <private/qquickprofiler_p.h>
15#include <private/qsgsoftwarerenderer_p.h>
16#include <qpa/qplatformbackingstore.h>
17
18#include <QtGui/QBackingStore>
19
20#include <qtquick_tracepoints_p.h>
21
23
29
31{
32 delete rc;
33 delete sg;
34}
35
37{
39 data.updatePending = false;
40 data.grabOnly = false;
42
43 if (m_backingStores[window] == nullptr) {
45 }
46
48}
49
55
57{
58 m_windows.remove(window);
59 delete m_backingStores[window];
61 hide(window);
62
64 d->cleanupNodesOnShutdown();
65
66 if (m_windows.size() == 0) {
67 rc->invalidate();
68 }
69
70 d->animationController.reset();
71}
72
74{
76 if (!m_windows.contains(window))
77 return;
78
79 WindowData &data = const_cast<WindowData &>(m_windows[window]);
80
81 //If were not in grabOnly mode, dont render a non-renderable window
82 if (!data.grabOnly && !cd->isRenderable())
83 return;
84
85 //Resize the backing store if necessary
86 if (m_backingStores[window]->size() != window->size()) {
87 m_backingStores[window]->resize(window->size());
88 }
89
90 // ### create QPainter and set up pointer to current window/painter
93
94 bool alsoSwap = data.updatePending;
95 data.updatePending = false;
96
97 if (!data.grabOnly) {
99 // Event delivery/processing triggered the window to be deleted or stop rendering.
100 if (!m_windows.contains(window))
101 return;
102 }
103
104 Q_TRACE_SCOPE(QSG_renderWindow)
105 QElapsedTimer renderTimer;
106 qint64 renderTime = 0, syncTime = 0, polishTime = 0;
107 bool profileFrames = QSG_RASTER_LOG_TIME_RENDERLOOP().isDebugEnabled();
108 if (profileFrames)
109 renderTimer.start();
110 Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
111 Q_TRACE(QSG_polishItems_entry);
112
113 cd->polishItems();
114
115 if (profileFrames)
116 polishTime = renderTimer.nsecsElapsed();
117 Q_TRACE(QSG_polishItems_exit);
118 Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
119 QQuickProfiler::SceneGraphRenderLoopFrame,
120 QQuickProfiler::SceneGraphPolishPolish);
121 Q_TRACE(QSG_sync_entry);
122
123 emit window->afterAnimating();
124
125 emit window->beforeFrameBegin();
126
127 cd->syncSceneGraph();
128 rc->endSync();
129
130 if (profileFrames)
131 syncTime = renderTimer.nsecsElapsed();
132 Q_TRACE(QSG_sync_exit);
133 Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
134 QQuickProfiler::SceneGraphRenderLoopSync);
135 Q_TRACE(QSG_render_entry);
136
137 //Tell the renderer about the windows backing store
138 auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(cd->renderer);
139 if (softwareRenderer)
140 softwareRenderer->setBackingStore(m_backingStores[window]);
141
142 cd->renderSceneGraph();
143
144 if (profileFrames)
145 renderTime = renderTimer.nsecsElapsed();
146 Q_TRACE(QSG_render_exit);
147 Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
148 QQuickProfiler::SceneGraphRenderLoopRender);
149 Q_TRACE(QSG_swap_entry);
150
151 if (data.grabOnly) {
152 grabContent = m_backingStores[window]->handle()->toImage();
153 data.grabOnly = false;
154 }
155
156 if (alsoSwap && window->isVisible()) {
157 //Flush backingstore to window
158 if (!isNewExpose)
159 m_backingStores[window]->flush(softwareRenderer->flushRegion());
160 else
161 m_backingStores[window]->flush(QRegion(QRect(QPoint(0,0), window->size())));
162 cd->fireFrameSwapped();
163 }
164
165 emit window->afterFrameEnd();
166
167 qint64 swapTime = 0;
168 if (profileFrames)
169 swapTime = renderTimer.nsecsElapsed();
170 Q_TRACE(QSG_swap_exit);
171 Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
172 QQuickProfiler::SceneGraphRenderLoopSwap);
173
174 if (QSG_RASTER_LOG_TIME_RENDERLOOP().isDebugEnabled()) {
175 static QTime lastFrameTime = QTime::currentTime();
176 qCDebug(QSG_RASTER_LOG_TIME_RENDERLOOP,
177 "Frame rendered with 'software' renderloop in %dms, polish=%d, sync=%d, render=%d, swap=%d, frameDelta=%d",
178 int(swapTime / 1000000),
179 int(polishTime / 1000000),
180 int((syncTime - polishTime) / 1000000),
181 int((renderTime - syncTime) / 1000000),
182 int((swapTime - renderTime) / 1000000),
183 int(lastFrameTime.msecsTo(QTime::currentTime())));
184 lastFrameTime = QTime::currentTime();
185 }
186
187 // Might have been set during syncSceneGraph()
188 if (data.updatePending)
190}
191
193{
194 if (window->isExposed()) {
195 m_windows[window].updatePending = true;
196 renderWindow(window, true);
197 }
198}
199
201{
202 //If the window was never shown, create a new backing store
205 // Call create on window to make sure platform window is created
206 window->create();
207 }
208
209 //If there is no WindowData, add one
210 if (!m_windows.contains(window)) {
212 data.updatePending = false;
214 }
215
216 m_windows[window].grabOnly = true;
217
219
220 QImage grabbed = grabContent;
221 grabbed.detach();
223 return grabbed;
224}
225
226
227
229{
230 if (!m_windows.contains(window))
231 return;
232
233 m_windows[window].updatePending = true;
234 window->requestUpdate();
235}
236
241
242
243
248
249
254
256
257#include "moc_qsgsoftwarerenderloop_p.cpp"
The QBackingStore class provides a drawing area for QWindow.
\inmodule QtCore
void start() noexcept
\typealias QElapsedTimer::Duration Synonym for std::chrono::nanoseconds.
bool remove(const Key &key)
Removes the item that has the key from the hash.
Definition qhash.h:958
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
Definition qhash.h:1007
\inmodule QtGui
Definition qimage.h:37
void detach()
Definition qimage.cpp:1128
\inmodule QtCore\reentrant
Definition qpoint.h:25
void flushFrameSynchronousEvents(QQuickWindow *win)
static QQuickWindowPrivate * get(QQuickWindow *c)
QSGRenderContext * context
QSGRenderer * renderer
QQuickDeliveryAgentPrivate * deliveryAgentPrivate() const
bool isRenderable() const
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
\inmodule QtCore\reentrant
Definition qrect.h:30
The QRegion class specifies a clip region for a painter.
Definition qregion.h:27
The QSGContext holds the scene graph entry points for one QML engine.
virtual QSGRenderContext * createRenderContext()=0
virtual void invalidate()
virtual void endSync()
QHash< QQuickWindow *, QBackingStore * > m_backingStores
QImage grab(QQuickWindow *window) override
void exposureChanged(QQuickWindow *window) override
QHash< QQuickWindow *, WindowData > m_windows
void maybeUpdate(QQuickWindow *window) override
QSGContext * sceneGraphContext() const override
void show(QQuickWindow *window) override
void hide(QQuickWindow *window) override
void handleUpdateRequest(QQuickWindow *) override
void windowDestroyed(QQuickWindow *window) override
QSurface::SurfaceType windowSurfaceType() const override
void renderWindow(QQuickWindow *window, bool isNewExpose=false)
void setBackingStore(QBackingStore *backingStore)
SurfaceType
The SurfaceType enum describes what type of surface this is.
Definition qsurface.h:30
@ RasterSurface
Definition qsurface.h:31
\inmodule QtCore \reentrant
Definition qdatetime.h:215
static QTime currentTime()
Returns the current time as reported by the system clock.
int msecsTo(QTime t) const
Returns the number of milliseconds from this time to t.
EGLContext ctx
Combined button and popup list for selecting options.
#define qCDebug(category,...)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
#define Q_QUICK_SG_PROFILE_END(Type, position)
#define Q_QUICK_SG_PROFILE_SWITCH(Type1, Type2, position)
#define Q_QUICK_SG_PROFILE_RECORD(Type, position)
#define Q_QUICK_SG_PROFILE_START(Type)
#define emit
#define Q_TRACE_SCOPE(x,...)
Definition qtrace_p.h:146
#define Q_TRACE(x,...)
Definition qtrace_p.h:144
long long qint64
Definition qtypes.h:60
edit hide()
aWidget window() -> setWindowTitle("New Window Title")
[2]