OpenCoverage

qsgsoftwarethreadedrenderloop.cpp

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtQuick module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include "qsgsoftwarethreadedrenderloop_p.h"-
41#include "qsgsoftwarecontext_p.h"-
42#include "qsgsoftwarerenderer_p.h"-
43-
44#include <private/qsgrenderer_p.h>-
45#include <private/qquickwindow_p.h>-
46#include <private/qquickprofiler_p.h>-
47#include <private/qquickanimatorcontroller_p.h>-
48#include <private/qquickprofiler_p.h>-
49#include <private/qqmldebugserviceinterfaces_p.h>-
50#include <private/qqmldebugconnector_p.h>-
51-
52#include <qpa/qplatformbackingstore.h>-
53-
54#include <QtCore/QQueue>-
55#include <QtCore/QElapsedTimer>-
56#include <QtCore/QThread>-
57#include <QtCore/QMutex>-
58#include <QtCore/QWaitCondition>-
59#include <QtGui/QGuiApplication>-
60#include <QtGui/QBackingStore>-
61#include <QtQuick/QQuickWindow>-
62-
63QT_BEGIN_NAMESPACE-
64-
65// Passed from the RL to the RT when a window is removed obscured and should be-
66// removed from the render loop.-
67const QEvent::Type WM_Obscure = QEvent::Type(QEvent::User + 1);-
68-
69// Passed from the RL to RT when GUI has been locked, waiting for sync.-
70const QEvent::Type WM_RequestSync = QEvent::Type(QEvent::User + 2);-
71-
72// Passed by the RT to itself to trigger another render pass. This is typically-
73// a result of QQuickWindow::update().-
74const QEvent::Type WM_RequestRepaint = QEvent::Type(QEvent::User + 3);-
75-
76// Passed by the RL to the RT to maybe release resource if no windows are-
77// rendering.-
78const QEvent::Type WM_TryRelease = QEvent::Type(QEvent::User + 4);-
79-
80// Passed by the RL to the RT when a QQuickWindow::grabWindow() is called.-
81const QEvent::Type WM_Grab = QEvent::Type(QEvent::User + 5);-
82-
83// Passed by the window when there is a render job to run.-
84const QEvent::Type WM_PostJob = QEvent::Type(QEvent::User + 6);-
85-
86class QSGSoftwareWindowEvent : public QEvent-
87{-
88public:-
89 QSGSoftwareWindowEvent(QQuickWindow *c, QEvent::Type type) : QEvent(type), window(c) { }
never executed: end of block
0
90 QQuickWindow *window;-
91};-
92-
93class QSGSoftwareTryReleaseEvent : public QSGSoftwareWindowEvent-
94{-
95public:-
96 QSGSoftwareTryReleaseEvent(QQuickWindow *win, bool destroy)-
97 : QSGSoftwareWindowEvent(win, WM_TryRelease), destroying(destroy) { }
never executed: end of block
0
98 bool destroying;-
99};-
100-
101class QSGSoftwareSyncEvent : public QSGSoftwareWindowEvent-
102{-
103public:-
104 QSGSoftwareSyncEvent(QQuickWindow *c, bool inExpose, bool force)-
105 : QSGSoftwareWindowEvent(c, WM_RequestSync)-
106 , size(c->size())-
107 , dpr(c->effectiveDevicePixelRatio())-
108 , syncInExpose(inExpose)-
109 , forceRenderPass(force) { }
never executed: end of block
0
110 QSize size;-
111 float dpr;-
112 bool syncInExpose;-
113 bool forceRenderPass;-
114};-
115-
116class QSGSoftwareGrabEvent : public QSGSoftwareWindowEvent-
117{-
118public:-
119 QSGSoftwareGrabEvent(QQuickWindow *c, QImage *result)-
120 : QSGSoftwareWindowEvent(c, WM_Grab), image(result) { }
never executed: end of block
0
121 QImage *image;-
122};-
123-
124class QSGSoftwareJobEvent : public QSGSoftwareWindowEvent-
125{-
126public:-
127 QSGSoftwareJobEvent(QQuickWindow *c, QRunnable *postedJob)-
128 : QSGSoftwareWindowEvent(c, WM_PostJob), job(postedJob) { }
never executed: end of block
0
129 ~QSGSoftwareJobEvent() { delete job; }
never executed: end of block
0
130 QRunnable *job;-
131};-
132-
133class QSGSoftwareEventQueue : public QQueue<QEvent *>-
134{-
135public:-
136 void addEvent(QEvent *e) {-
137 mutex.lock();-
138 enqueue(e);-
139 if (waiting)
waitingDescription
TRUEnever evaluated
FALSEnever evaluated
0
140 condition.wakeOne();
never executed: condition.wakeOne();
0
141 mutex.unlock();-
142 }
never executed: end of block
0
143-
144 QEvent *takeEvent(bool wait) {-
145 mutex.lock();-
146 if (isEmpty() && wait) {
isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
waitDescription
TRUEnever evaluated
FALSEnever evaluated
0
147 waiting = true;-
148 condition.wait(&mutex);-
149 waiting = false;-
150 }
never executed: end of block
0
151 QEvent *e = dequeue();-
152 mutex.unlock();-
153 return e;
never executed: return e;
0
154 }-
155-
156 bool hasMoreEvents() {-
157 mutex.lock();-
158 bool has = !isEmpty();-
159 mutex.unlock();-
160 return has;
never executed: return has;
0
161 }-
162-
163private:-
164 QMutex mutex;-
165 QWaitCondition condition;-
166 bool waiting = false;-
167};-
168-
169static inline int qsgrl_animation_interval()-
170{-
171 const qreal refreshRate = QGuiApplication::primaryScreen() ? QGuiApplication::primaryScreen()->refreshRate() : 0;
QGuiApplicatio...rimaryScreen()Description
TRUEnever evaluated
FALSEnever evaluated
0
172 return refreshRate < 1 ? 16 : int(1000 / refreshRate);
never executed: return refreshRate < 1 ? 16 : int(1000 / refreshRate);
0
173}-
174-
175class QSGSoftwareRenderThread : public QThread-
176{-
177 Q_OBJECT-
178public:-
179 QSGSoftwareRenderThread(QSGSoftwareThreadedRenderLoop *rl, QSGRenderContext *renderContext)-
180 : renderLoop(rl)-
181 {-
182 rc = static_cast<QSGSoftwareRenderContext *>(renderContext);-
183 vsyncDelta = qsgrl_animation_interval();-
184 }
never executed: end of block
0
185-
186 ~QSGSoftwareRenderThread()-
187 {-
188 delete rc;-
189 }
never executed: end of block
0
190-
191 bool event(QEvent *e) override;-
192 void run() override;-
193-
194 void syncAndRender();-
195 void sync(bool inExpose);-
196-
197 void requestRepaint()-
198 {-
199 if (sleeping)
sleepingDescription
TRUEnever evaluated
FALSEnever evaluated
0
200 stopEventProcessing = true;
never executed: stopEventProcessing = true;
0
201 if (exposedWindow)
exposedWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
202 pendingUpdate |= RepaintRequest;
never executed: pendingUpdate |= RepaintRequest;
0
203 }
never executed: end of block
0
204-
205 void processEventsAndWaitForMore();-
206 void processEvents();-
207 void postEvent(QEvent *e);-
208-
209 enum UpdateRequest {-
210 SyncRequest = 0x01,-
211 RepaintRequest = 0x02,-
212 ExposeRequest = 0x04 | RepaintRequest | SyncRequest-
213 };-
214-
215 QSGSoftwareThreadedRenderLoop *renderLoop;-
216 QSGSoftwareRenderContext *rc;-
217 QAnimationDriver *rtAnim = nullptr;-
218 volatile bool active = false;-
219 uint pendingUpdate = 0;-
220 bool sleeping = false;-
221 bool syncResultedInChanges = false;-
222 float vsyncDelta;-
223 QMutex mutex;-
224 QWaitCondition waitCondition;-
225 QQuickWindow *exposedWindow = nullptr;-
226 QBackingStore *backingStore = nullptr;-
227 bool stopEventProcessing = false;-
228 QSGSoftwareEventQueue eventQueue;-
229 QElapsedTimer renderThrottleTimer;-
230 qint64 syncTime;-
231 qint64 renderTime;-
232 qint64 sinceLastTime;-
233-
234public slots:-
235 void onSceneGraphChanged() {-
236 syncResultedInChanges = true;-
237 }
never executed: end of block
0
238};-
239-
240bool QSGSoftwareRenderThread::event(QEvent *e)-
241{-
242 switch ((int)e->type()) {-
243-
244 case WM_Obscure:
never executed: case WM_Obscure:
0
245 Q_ASSERT(!exposedWindow || exposedWindow == static_cast<QSGSoftwareWindowEvent *>(e)->window);-
246 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "RT - WM_Obscure" << exposedWindow;
never executed: QMessageLogger(__FILE__, 246, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "RT - WM_Obscure" << exposedWindow;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
247 mutex.lock();-
248 if (exposedWindow) {
exposedWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
249 QQuickWindowPrivate::get(exposedWindow)->fireAboutToStop();-
250 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_Obscure - window removed");
never executed: QMessageLogger(__FILE__, 250, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_Obscure - window removed");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
251 exposedWindow = nullptr;-
252 delete backingStore;-
253 backingStore = nullptr;-
254 }
never executed: end of block
0
255 waitCondition.wakeOne();-
256 mutex.unlock();-
257 return true;
never executed: return true;
0
258-
259 case WM_RequestSync: {
never executed: case WM_RequestSync:
0
260 QSGSoftwareSyncEvent *wme = static_cast<QSGSoftwareSyncEvent *>(e);-
261 if (sleeping)
sleepingDescription
TRUEnever evaluated
FALSEnever evaluated
0
262 stopEventProcessing = true;
never executed: stopEventProcessing = true;
0
263 exposedWindow = wme->window;-
264 if (backingStore == nullptr)
backingStore == nullptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
265 backingStore = new QBackingStore(exposedWindow);
never executed: backingStore = new QBackingStore(exposedWindow);
0
266 if (backingStore->size() != exposedWindow->size())
backingStore->...Window->size()Description
TRUEnever evaluated
FALSEnever evaluated
0
267 backingStore->resize(exposedWindow->size());
never executed: backingStore->resize(exposedWindow->size());
0
268 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "RT - WM_RequestSync" << exposedWindow;
never executed: QMessageLogger(__FILE__, 268, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "RT - WM_RequestSync" << exposedWindow;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
269 pendingUpdate |= SyncRequest;-
270 if (wme->syncInExpose) {
wme->syncInExposeDescription
TRUEnever evaluated
FALSEnever evaluated
0
271 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_RequestSync - triggered from expose");
never executed: QMessageLogger(__FILE__, 271, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_RequestSync - triggered from expose");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
272 pendingUpdate |= ExposeRequest;-
273 }
never executed: end of block
0
274 if (wme->forceRenderPass) {
wme->forceRenderPassDescription
TRUEnever evaluated
FALSEnever evaluated
0
275 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_RequestSync - repaint regardless");
never executed: QMessageLogger(__FILE__, 275, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_RequestSync - repaint regardless");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
276 pendingUpdate |= RepaintRequest;-
277 }
never executed: end of block
0
278 return true;
never executed: return true;
0
279 }-
280-
281 case WM_TryRelease: {
never executed: case WM_TryRelease:
0
282 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_TryRelease");
never executed: QMessageLogger(__FILE__, 282, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_TryRelease");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
283 mutex.lock();-
284 renderLoop->lockedForSync = true;-
285 QSGSoftwareTryReleaseEvent *wme = static_cast<QSGSoftwareTryReleaseEvent *>(e);-
286 // Only when no windows are exposed anymore or we are shutting down.-
287 if (!exposedWindow || wme->destroying) {
!exposedWindowDescription
TRUEnever evaluated
FALSEnever evaluated
wme->destroyingDescription
TRUEnever evaluated
FALSEnever evaluated
0
288 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_TryRelease - invalidating rc");
never executed: QMessageLogger(__FILE__, 288, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_TryRelease - invalidating rc");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
289 if (wme->window) {
wme->windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
290 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(wme->window);-
291 if (wme->destroying) {
wme->destroyingDescription
TRUEnever evaluated
FALSEnever evaluated
0
292 // Bye bye nodes...-
293 wd->cleanupNodesOnShutdown();-
294 }
never executed: end of block
0
295 rc->invalidate();-
296 QCoreApplication::processEvents();-
297 QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);-
298 if (wme->destroying)
wme->destroyingDescription
TRUEnever evaluated
FALSEnever evaluated
0
299 delete wd->animationController;
never executed: delete wd->animationController;
0
300 }
never executed: end of block
0
301 if (wme->destroying)
wme->destroyingDescription
TRUEnever evaluated
FALSEnever evaluated
0
302 active = false;
never executed: active = false;
0
303 if (sleeping)
sleepingDescription
TRUEnever evaluated
FALSEnever evaluated
0
304 stopEventProcessing = true;
never executed: stopEventProcessing = true;
0
305 } else {
never executed: end of block
0
306 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_TryRelease - not releasing because window is still active");
never executed: QMessageLogger(__FILE__, 306, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_TryRelease - not releasing because window is still active");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
307 }
never executed: end of block
0
308 waitCondition.wakeOne();-
309 renderLoop->lockedForSync = false;-
310 mutex.unlock();-
311 return true;
never executed: return true;
0
312 }-
313-
314 case WM_Grab: {
never executed: case WM_Grab:
0
315 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_Grab");
never executed: QMessageLogger(__FILE__, 315, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_Grab");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
316 QSGSoftwareGrabEvent *wme = static_cast<QSGSoftwareGrabEvent *>(e);-
317 Q_ASSERT(wme->window);-
318 Q_ASSERT(wme->window == exposedWindow || !exposedWindow);-
319 mutex.lock();-
320 if (wme->window) {
wme->windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
321 // Grabbing is generally done by rendering a frame and reading the-
322 // color buffer contents back, without presenting, and then-
323 // creating a QImage from the returned data. It is terribly-
324 // inefficient since it involves a full blocking wait for the GPU.-
325 // However, our hands are tied by the existing, synchronous APIs of-
326 // QQuickWindow and such.-
327 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(wme->window);-
328 auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(wd->renderer);-
329 if (softwareRenderer)
softwareRendererDescription
TRUEnever evaluated
FALSEnever evaluated
0
330 softwareRenderer->setBackingStore(backingStore);
never executed: softwareRenderer->setBackingStore(backingStore);
0
331 rc->initialize(nullptr);-
332 wd->syncSceneGraph();-
333 rc->endSync();-
334 wd->renderSceneGraph(wme->window->size());-
335 *wme->image = backingStore->handle()->toImage();-
336 }
never executed: end of block
0
337 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_Grab - waking gui to handle result");
never executed: QMessageLogger(__FILE__, 337, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_Grab - waking gui to handle result");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
338 waitCondition.wakeOne();-
339 mutex.unlock();-
340 return true;
never executed: return true;
0
341 }-
342-
343 case WM_PostJob: {
never executed: case WM_PostJob:
0
344 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_PostJob");
never executed: QMessageLogger(__FILE__, 344, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_PostJob");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
345 QSGSoftwareJobEvent *wme = static_cast<QSGSoftwareJobEvent *>(e);-
346 Q_ASSERT(wme->window == exposedWindow);-
347 if (exposedWindow) {
exposedWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
348 wme->job->run();-
349 delete wme->job;-
350 wme->job = nullptr;-
351 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_PostJob - job done");
never executed: QMessageLogger(__FILE__, 351, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_PostJob - job done");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
352 }
never executed: end of block
0
353 return true;
never executed: return true;
0
354 }-
355-
356 case WM_RequestRepaint:
never executed: case WM_RequestRepaint:
0
357 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - WM_RequestPaint");
never executed: QMessageLogger(__FILE__, 357, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - WM_RequestPaint");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
358 // When GUI posts this event, it is followed by a polishAndSync, so we-
359 // must not exit the event loop yet.-
360 pendingUpdate |= RepaintRequest;-
361 break;
never executed: break;
0
362-
363 default:
never executed: default:
0
364 break;
never executed: break;
0
365 }-
366-
367 return QThread::event(e);
never executed: return QThread::event(e);
0
368}-
369-
370void QSGSoftwareRenderThread::postEvent(QEvent *e)-
371{-
372 eventQueue.addEvent(e);-
373}
never executed: end of block
0
374-
375void QSGSoftwareRenderThread::processEvents()-
376{-
377 while (eventQueue.hasMoreEvents()) {
eventQueue.hasMoreEvents()Description
TRUEnever evaluated
FALSEnever evaluated
0
378 QEvent *e = eventQueue.takeEvent(false);-
379 event(e);-
380 delete e;-
381 }
never executed: end of block
0
382}
never executed: end of block
0
383-
384void QSGSoftwareRenderThread::processEventsAndWaitForMore()-
385{-
386 stopEventProcessing = false;-
387 while (!stopEventProcessing) {
!stopEventProcessingDescription
TRUEnever evaluated
FALSEnever evaluated
0
388 QEvent *e = eventQueue.takeEvent(true);-
389 event(e);-
390 delete e;-
391 }
never executed: end of block
0
392}
never executed: end of block
0
393-
394void QSGSoftwareRenderThread::run()-
395{-
396 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - run()");
never executed: QMessageLogger(__FILE__, 396, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - run()");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
397-
398 rtAnim = rc->sceneGraphContext()->createAnimationDriver(nullptr);-
399 rtAnim->install();-
400-
401 if (QQmlDebugConnector::service<QQmlProfilerService>())
QQmlDebugConne...ilerService>()Description
TRUEnever evaluated
FALSEnever evaluated
0
402 QQuickProfiler::registerAnimationCallback();
never executed: QQuickProfiler::registerAnimationCallback();
0
403-
404 renderThrottleTimer.start();-
405-
406 while (active) {
activeDescription
TRUEnever evaluated
FALSEnever evaluated
0
407 if (exposedWindow)
exposedWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
408 syncAndRender();
never executed: syncAndRender();
0
409-
410 processEvents();-
411 QCoreApplication::processEvents();-
412-
413 if (pendingUpdate == 0 || !exposedWindow) {
pendingUpdate == 0Description
TRUEnever evaluated
FALSEnever evaluated
!exposedWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
414 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - done drawing, sleep");
never executed: QMessageLogger(__FILE__, 414, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - done drawing, sleep");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
415 sleeping = true;-
416 processEventsAndWaitForMore();-
417 sleeping = false;-
418 }
never executed: end of block
0
419 }
never executed: end of block
0
420-
421 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - run() exiting");
never executed: QMessageLogger(__FILE__, 421, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - run() exiting");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
422-
423 delete rtAnim;-
424 rtAnim = nullptr;-
425-
426 rc->moveToThread(renderLoop->thread());-
427 moveToThread(renderLoop->thread());-
428}
never executed: end of block
0
429-
430void QSGSoftwareRenderThread::sync(bool inExpose)-
431{-
432 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - sync");
never executed: QMessageLogger(__FILE__, 432, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - sync");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
433-
434 mutex.lock();-
435 Q_ASSERT_X(renderLoop->lockedForSync, "QSGD3D12RenderThread::sync()", "sync triggered with gui not locked");-
436-
437 if (exposedWindow) {
exposedWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
438 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow);-
439 bool hadRenderer = wd->renderer != nullptr;-
440 // If the scene graph was touched since the last sync() make sure it sends the-
441 // changed signal.-
442 if (wd->renderer)
wd->rendererDescription
TRUEnever evaluated
FALSEnever evaluated
0
443 wd->renderer->clearChangedFlag();
never executed: wd->renderer->clearChangedFlag();
0
444-
445 rc->initialize(nullptr);-
446 wd->syncSceneGraph();-
447 rc->endSync();-
448-
449 if (!hadRenderer && wd->renderer) {
!hadRendererDescription
TRUEnever evaluated
FALSEnever evaluated
wd->rendererDescription
TRUEnever evaluated
FALSEnever evaluated
0
450 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - created renderer");
never executed: QMessageLogger(__FILE__, 450, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - created renderer");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
451 syncResultedInChanges = true;-
452 connect(wd->renderer, &QSGRenderer::sceneGraphChanged, this,-
453 &QSGSoftwareRenderThread::onSceneGraphChanged, Qt::DirectConnection);-
454 }
never executed: end of block
0
455-
456 // Process deferred deletes now, directly after the sync as deleteLater-
457 // on the GUI must now also have resulted in SG changes and the delete-
458 // is a safe operation.-
459 QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);-
460 }
never executed: end of block
0
461-
462 if (!inExpose) {
!inExposeDescription
TRUEnever evaluated
FALSEnever evaluated
0
463 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - sync complete, waking gui");
never executed: QMessageLogger(__FILE__, 463, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - sync complete, waking gui");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
464 waitCondition.wakeOne();-
465 mutex.unlock();-
466 }
never executed: end of block
0
467}
never executed: end of block
0
468-
469void QSGSoftwareRenderThread::syncAndRender()-
470{-
471 Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphRenderLoopFrame);
never executed: end of block
never executed: (void)0;
QQuickProfiler...ileSceneGraph)Description
TRUEnever evaluated
FALSEnever evaluated
0
472-
473 QElapsedTimer waitTimer;-
474 waitTimer.start();-
475-
476 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - syncAndRender()");
never executed: QMessageLogger(__FILE__, 476, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - syncAndRender()");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
477-
478 syncResultedInChanges = false;-
479 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(exposedWindow);-
480-
481 const bool repaintRequested = (pendingUpdate & RepaintRequest) || wd->customRenderStage;
(pendingUpdate...epaintRequest)Description
TRUEnever evaluated
FALSEnever evaluated
wd->customRenderStageDescription
TRUEnever evaluated
FALSEnever evaluated
0
482 const bool syncRequested = pendingUpdate & SyncRequest;-
483 const bool exposeRequested = (pendingUpdate & ExposeRequest) == ExposeRequest;-
484 pendingUpdate = 0;-
485-
486 if (syncRequested)
syncRequestedDescription
TRUEnever evaluated
FALSEnever evaluated
0
487 sync(exposeRequested);
never executed: sync(exposeRequested);
0
488-
489 Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
never executed: end of block
never executed: (void)0 ;
QQuickProfiler...ileSceneGraph)Description
TRUEnever evaluated
FALSEnever evaluated
0
490 QQuickProfiler::SceneGraphRenderLoopSync);
never executed: (void)0 ;
0
491-
492 if (!syncResultedInChanges && !repaintRequested) {
!syncResultedInChangesDescription
TRUEnever evaluated
FALSEnever evaluated
!repaintRequestedDescription
TRUEnever evaluated
FALSEnever evaluated
0
493 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - no changes, render aborted");
never executed: QMessageLogger(__FILE__, 493, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - no changes, render aborted");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
494 int waitTime = vsyncDelta - (int) waitTimer.elapsed();-
495 if (waitTime > 0)
waitTime > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
496 msleep(waitTime);
never executed: msleep(waitTime);
0
497 return;
never executed: return;
0
498 }-
499-
500 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - rendering started");
never executed: QMessageLogger(__FILE__, 500, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - rendering started");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
501-
502 if (rtAnim->isRunning()) {
rtAnim->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
503 wd->animationController->lock();-
504 rtAnim->advance();-
505 wd->animationController->unlock();-
506 }
never executed: end of block
0
507-
508 bool canRender = wd->renderer != nullptr;-
509-
510 if (canRender) {
canRenderDescription
TRUEnever evaluated
FALSEnever evaluated
0
511 auto softwareRenderer = static_cast<QSGSoftwareRenderer*>(wd->renderer);-
512 if (softwareRenderer)
softwareRendererDescription
TRUEnever evaluated
FALSEnever evaluated
0
513 softwareRenderer->setBackingStore(backingStore);
never executed: softwareRenderer->setBackingStore(backingStore);
0
514 wd->renderSceneGraph(exposedWindow->size());-
515-
516 Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
never executed: end of block
never executed: (void)0 ;
QQuickProfiler...ileSceneGraph)Description
TRUEnever evaluated
FALSEnever evaluated
0
517 QQuickProfiler::SceneGraphRenderLoopRender);
never executed: (void)0 ;
0
518-
519 if (softwareRenderer && (!wd->customRenderStage || !wd->customRenderStage->swap()))
softwareRendererDescription
TRUEnever evaluated
FALSEnever evaluated
!wd->customRenderStageDescription
TRUEnever evaluated
FALSEnever evaluated
!wd->customRenderStage->swap()Description
TRUEnever evaluated
FALSEnever evaluated
0
520 backingStore->flush(softwareRenderer->flushRegion());
never executed: backingStore->flush(softwareRenderer->flushRegion());
0
521-
522 // Since there is no V-Sync with QBackingStore, throttle rendering the refresh-
523 // rate of the current screen the window is on.-
524 int blockTime = vsyncDelta - (int) renderThrottleTimer.elapsed();-
525 if (blockTime > 0) {
blockTime > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
526 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - blocking for %d ms", blockTime);
never executed: QMessageLogger(__FILE__, 526, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - blocking for %d ms", blockTime);
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
527 msleep(blockTime);-
528 }
never executed: end of block
0
529 renderThrottleTimer.restart();-
530-
531 wd->fireFrameSwapped();-
532 } else {
never executed: end of block
0
533 Q_QUICK_SG_PROFILE_SKIP(QQuickProfiler::SceneGraphRenderLoopFrame,
never executed: end of block
never executed: (void)0 ;
QQuickProfiler...ileSceneGraph)Description
TRUEnever evaluated
FALSEnever evaluated
0
534 QQuickProfiler::SceneGraphRenderLoopSync, 1);
never executed: (void)0 ;
0
535 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - window not ready, skipping render");
never executed: QMessageLogger(__FILE__, 535, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - window not ready, skipping render");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
536 }
never executed: end of block
0
537-
538 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - rendering done");
never executed: QMessageLogger(__FILE__, 538, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - rendering done");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
539-
540 if (exposeRequested) {
exposeRequestedDescription
TRUEnever evaluated
FALSEnever evaluated
0
541 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "RT - wake gui after initial expose");
never executed: QMessageLogger(__FILE__, 541, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("RT - wake gui after initial expose");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
542 waitCondition.wakeOne();-
543 mutex.unlock();-
544 }
never executed: end of block
0
545-
546 Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
never executed: end of block
never executed: (void)0 ;
QQuickProfiler...ileSceneGraph)Description
TRUEnever evaluated
FALSEnever evaluated
0
547 QQuickProfiler::SceneGraphRenderLoopSwap);
never executed: (void)0 ;
0
548}-
549-
550template<class T> T *windowFor(const QVector<T> &list, QQuickWindow *window)-
551{-
552 for (const T &t : list) {-
553 if (t.window == window)
t.window == windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
554 return const_cast<T *>(&t);
never executed: return const_cast<T *>(&t);
0
555 }
never executed: end of block
0
556 return nullptr;
never executed: return nullptr;
0
557}-
558-
559-
560QSGSoftwareThreadedRenderLoop::QSGSoftwareThreadedRenderLoop()-
561{-
562 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "software threaded render loop constructor");
never executed: QMessageLogger(__FILE__, 562, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("software threaded render loop constructor");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
563 m_sg = new QSGSoftwareContext;-
564 m_anim = m_sg->createAnimationDriver(this);-
565 connect(m_anim, &QAnimationDriver::started, this, &QSGSoftwareThreadedRenderLoop::onAnimationStarted);-
566 connect(m_anim, &QAnimationDriver::stopped, this, &QSGSoftwareThreadedRenderLoop::onAnimationStopped);-
567 m_anim->install();-
568}
never executed: end of block
0
569-
570QSGSoftwareThreadedRenderLoop::~QSGSoftwareThreadedRenderLoop()-
571{-
572 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "software threaded render loop destructor");
never executed: QMessageLogger(__FILE__, 572, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("software threaded render loop destructor");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
573 delete m_sg;-
574}
never executed: end of block
0
575-
576void QSGSoftwareThreadedRenderLoop::show(QQuickWindow *window)-
577{-
578 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "show" << window;
never executed: QMessageLogger(__FILE__, 578, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "show" << window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
579}
never executed: end of block
0
580-
581void QSGSoftwareThreadedRenderLoop::hide(QQuickWindow *window)-
582{-
583 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "hide" << window;
never executed: QMessageLogger(__FILE__, 583, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "hide" << window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
584-
585 if (window->isExposed())
window->isExposed()Description
TRUEnever evaluated
FALSEnever evaluated
0
586 handleObscurity(windowFor(m_windows, window));
never executed: handleObscurity(windowFor(m_windows, window));
0
587-
588 releaseResources(window);-
589}
never executed: end of block
0
590-
591void QSGSoftwareThreadedRenderLoop::resize(QQuickWindow *window)-
592{-
593 if (!window->isExposed() || window->size().isEmpty())
!window->isExposed()Description
TRUEnever evaluated
FALSEnever evaluated
window->size().isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
594 return;
never executed: return;
0
595-
596 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "resize" << window << window->size();
never executed: QMessageLogger(__FILE__, 596, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "resize" << window << window->size();
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
597}
never executed: end of block
0
598-
599void QSGSoftwareThreadedRenderLoop::windowDestroyed(QQuickWindow *window)-
600{-
601 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "window destroyed" << window;
never executed: QMessageLogger(__FILE__, 601, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "window destroyed" << window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
602-
603 WindowData *w = windowFor(m_windows, window);-
604 if (!w)
!wDescription
TRUEnever evaluated
FALSEnever evaluated
0
605 return;
never executed: return;
0
606-
607 handleObscurity(w);-
608 handleResourceRelease(w, true);-
609-
610 QSGSoftwareRenderThread *thread = w->thread;-
611 while (thread->isRunning())
thread->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
612 QThread::yieldCurrentThread();
never executed: QThread::yieldCurrentThread();
0
613-
614 Q_ASSERT(thread->thread() == QThread::currentThread());-
615 delete thread;-
616-
617 for (int i = 0; i < m_windows.size(); ++i) {
i < m_windows.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
618 if (m_windows.at(i).window == window) {
m_windows.at(i...ndow == windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
619 m_windows.removeAt(i);-
620 break;
never executed: break;
0
621 }-
622 }
never executed: end of block
0
623-
624 // Now that we altered the window list, we may need to stop the animation-
625 // timer even if we didn't via handleObscurity. This covers the case where-
626 // we destroy a visible & exposed QQuickWindow.-
627 startOrStopAnimationTimer();-
628}
never executed: end of block
0
629-
630void QSGSoftwareThreadedRenderLoop::exposureChanged(QQuickWindow *window)-
631{-
632 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "exposure changed" << window;
never executed: QMessageLogger(__FILE__, 632, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "exposure changed" << window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
633-
634 if (window->isExposed()) {
window->isExposed()Description
TRUEnever evaluated
FALSEnever evaluated
0
635 handleExposure(window);-
636 } else {
never executed: end of block
0
637 WindowData *w = windowFor(m_windows, window);-
638 if (w)
wDescription
TRUEnever evaluated
FALSEnever evaluated
0
639 handleObscurity(w);
never executed: handleObscurity(w);
0
640 }
never executed: end of block
0
641}-
642-
643QImage QSGSoftwareThreadedRenderLoop::grab(QQuickWindow *window)-
644{-
645 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "grab" << window;
never executed: QMessageLogger(__FILE__, 645, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "grab" << window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
646-
647 WindowData *w = windowFor(m_windows, window);-
648 // Have to support invisible (but created()'ed) windows as well.-
649 // Unlike with GL, leaving that case for QQuickWindow to handle is not feasible.-
650 const bool tempExpose = !w;-
651 if (tempExpose) {
tempExposeDescription
TRUEnever evaluated
FALSEnever evaluated
0
652 handleExposure(window);-
653 w = windowFor(m_windows, window);-
654 Q_ASSERT(w);-
655 }
never executed: end of block
0
656-
657 if (!w->thread->isRunning())
!w->thread->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
658 return QImage();
never executed: return QImage();
0
659-
660 if (!window->handle())
!window->handle()Description
TRUEnever evaluated
FALSEnever evaluated
0
661 window->create();
never executed: window->create();
0
662-
663 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);-
664 wd->polishItems();-
665-
666 QImage result;-
667 w->thread->mutex.lock();-
668 lockedForSync = true;-
669 w->thread->postEvent(new QSGSoftwareGrabEvent(window, &result));-
670 w->thread->waitCondition.wait(&w->thread->mutex);-
671 lockedForSync = false;-
672 w->thread->mutex.unlock();-
673-
674 result.setDevicePixelRatio(window->effectiveDevicePixelRatio());-
675-
676 if (tempExpose)
tempExposeDescription
TRUEnever evaluated
FALSEnever evaluated
0
677 handleObscurity(w);
never executed: handleObscurity(w);
0
678-
679 return result;
never executed: return result;
0
680}-
681-
682void QSGSoftwareThreadedRenderLoop::update(QQuickWindow *window)-
683{-
684 WindowData *w = windowFor(m_windows, window);-
685 if (!w)
!wDescription
TRUEnever evaluated
FALSEnever evaluated
0
686 return;
never executed: return;
0
687-
688 if (w->thread == QThread::currentThread()) {
w->thread == Q...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
0
689 w->thread->requestRepaint();-
690 return;
never executed: return;
0
691 }-
692-
693 // We set forceRenderPass because we want to make sure the QQuickWindow-
694 // actually does a full render pass after the next sync.-
695 w->forceRenderPass = true;-
696 scheduleUpdate(w);-
697}
never executed: end of block
0
698-
699void QSGSoftwareThreadedRenderLoop::maybeUpdate(QQuickWindow *window)-
700{-
701 WindowData *w = windowFor(m_windows, window);-
702 if (w)
wDescription
TRUEnever evaluated
FALSEnever evaluated
0
703 scheduleUpdate(w);
never executed: scheduleUpdate(w);
0
704}
never executed: end of block
0
705-
706void QSGSoftwareThreadedRenderLoop::handleUpdateRequest(QQuickWindow *window)-
707{-
708 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "handleUpdateRequest" << window;
never executed: QMessageLogger(__FILE__, 708, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "handleUpdateRequest" << window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
709-
710 WindowData *w = windowFor(m_windows, window);-
711 if (w)
wDescription
TRUEnever evaluated
FALSEnever evaluated
0
712 polishAndSync(w, false);
never executed: polishAndSync(w, false);
0
713}
never executed: end of block
0
714-
715QAnimationDriver *QSGSoftwareThreadedRenderLoop::animationDriver() const-
716{-
717 return m_anim;
never executed: return m_anim;
0
718}-
719-
720QSGContext *QSGSoftwareThreadedRenderLoop::sceneGraphContext() const-
721{-
722 return m_sg;
never executed: return m_sg;
0
723}-
724-
725QSGRenderContext *QSGSoftwareThreadedRenderLoop::createRenderContext(QSGContext *) const-
726{-
727 return m_sg->createRenderContext();
never executed: return m_sg->createRenderContext();
0
728}-
729-
730void QSGSoftwareThreadedRenderLoop::releaseResources(QQuickWindow *window)-
731{-
732 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "releaseResources" << window;
never executed: QMessageLogger(__FILE__, 732, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "releaseResources" << window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
733-
734 WindowData *w = windowFor(m_windows, window);-
735 if (w)
wDescription
TRUEnever evaluated
FALSEnever evaluated
0
736 handleResourceRelease(w, false);
never executed: handleResourceRelease(w, false);
0
737}
never executed: end of block
0
738-
739void QSGSoftwareThreadedRenderLoop::postJob(QQuickWindow *window, QRunnable *job)-
740{-
741 WindowData *w = windowFor(m_windows, window);-
742 if (w && w->thread && w->thread->exposedWindow)
wDescription
TRUEnever evaluated
FALSEnever evaluated
w->threadDescription
TRUEnever evaluated
FALSEnever evaluated
w->thread->exposedWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
743 w->thread->postEvent(new QSGSoftwareJobEvent(window, job));
never executed: w->thread->postEvent(new QSGSoftwareJobEvent(window, job));
0
744 else-
745 delete job;
never executed: delete job;
0
746}-
747-
748QSurface::SurfaceType QSGSoftwareThreadedRenderLoop::windowSurfaceType() const-
749{-
750 return QSurface::RasterSurface;
never executed: return QSurface::RasterSurface;
0
751}-
752-
753bool QSGSoftwareThreadedRenderLoop::interleaveIncubation() const-
754{-
755 bool somethingVisible = false;-
756 for (const WindowData &w : m_windows) {-
757 if (w.window->isVisible() && w.window->isExposed()) {
w.window->isVisible()Description
TRUEnever evaluated
FALSEnever evaluated
w.window->isExposed()Description
TRUEnever evaluated
FALSEnever evaluated
0
758 somethingVisible = true;-
759 break;
never executed: break;
0
760 }-
761 }
never executed: end of block
0
762 return somethingVisible && m_anim->isRunning();
never executed: return somethingVisible && m_anim->isRunning();
0
763}-
764-
765int QSGSoftwareThreadedRenderLoop::flags() const-
766{-
767 return SupportsGrabWithoutExpose;
never executed: return SupportsGrabWithoutExpose;
0
768}-
769-
770bool QSGSoftwareThreadedRenderLoop::event(QEvent *e)-
771{-
772 if (e->type() == QEvent::Timer) {
e->type() == QEvent::TimerDescription
TRUEnever evaluated
FALSEnever evaluated
0
773 QTimerEvent *te = static_cast<QTimerEvent *>(e);-
774 if (te->timerId() == animationTimer) {
te->timerId() ...animationTimerDescription
TRUEnever evaluated
FALSEnever evaluated
0
775 m_anim->advance();-
776 emit timeToIncubate();-
777 return true;
never executed: return true;
0
778 }-
779 }
never executed: end of block
0
780-
781 return QObject::event(e);
never executed: return QObject::event(e);
0
782}-
783-
784void QSGSoftwareThreadedRenderLoop::onAnimationStarted()-
785{-
786 startOrStopAnimationTimer();-
787-
788 for (const WindowData &w : qAsConst(m_windows))-
789 w.window->requestUpdate();
never executed: w.window->requestUpdate();
0
790}
never executed: end of block
0
791-
792void QSGSoftwareThreadedRenderLoop::onAnimationStopped()-
793{-
794 startOrStopAnimationTimer();-
795}
never executed: end of block
0
796-
797void QSGSoftwareThreadedRenderLoop::startOrStopAnimationTimer()-
798{-
799 int exposedWindowCount = 0;-
800 const WindowData *exposed = nullptr;-
801-
802 for (int i = 0; i < m_windows.size(); ++i) {
i < m_windows.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
803 const WindowData &w(m_windows[i]);-
804 if (w.window->isVisible() && w.window->isExposed()) {
w.window->isVisible()Description
TRUEnever evaluated
FALSEnever evaluated
w.window->isExposed()Description
TRUEnever evaluated
FALSEnever evaluated
0
805 ++exposedWindowCount;-
806 exposed = &w;-
807 }
never executed: end of block
0
808 }
never executed: end of block
0
809-
810 if (animationTimer && (exposedWindowCount == 1 || !m_anim->isRunning())) {
animationTimerDescription
TRUEnever evaluated
FALSEnever evaluated
exposedWindowCount == 1Description
TRUEnever evaluated
FALSEnever evaluated
!m_anim->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
811 killTimer(animationTimer);-
812 animationTimer = 0;-
813 // If animations are running, make sure we keep on animating-
814 if (m_anim->isRunning())
m_anim->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
815 exposed->window->requestUpdate();
never executed: exposed->window->requestUpdate();
0
816 } else if (!animationTimer && exposedWindowCount != 1 && m_anim->isRunning()) {
never executed: end of block
!animationTimerDescription
TRUEnever evaluated
FALSEnever evaluated
exposedWindowCount != 1Description
TRUEnever evaluated
FALSEnever evaluated
m_anim->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
817 animationTimer = startTimer(qsgrl_animation_interval());-
818 }
never executed: end of block
0
819}
never executed: end of block
0
820-
821void QSGSoftwareThreadedRenderLoop::handleExposure(QQuickWindow *window)-
822{-
823 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "handleExposure" << window;
never executed: QMessageLogger(__FILE__, 823, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "handleExposure" << window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
824-
825 WindowData *w = windowFor(m_windows, window);-
826 if (!w) {
!wDescription
TRUEnever evaluated
FALSEnever evaluated
0
827 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "adding window to list");
never executed: QMessageLogger(__FILE__, 827, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("adding window to list");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
828 WindowData win;-
829 win.window = window;-
830 QSGRenderContext *rc = QQuickWindowPrivate::get(window)->context; // will transfer ownership-
831 win.thread = new QSGSoftwareRenderThread(this, rc);-
832 win.updateDuringSync = false;-
833 win.forceRenderPass = true; // also covered by polishAndSync(inExpose=true), but doesn't hurt-
834 m_windows.append(win);-
835 w = &m_windows.last();-
836 }
never executed: end of block
0
837-
838 // set this early as we'll be rendering shortly anyway and this avoids-
839 // special casing exposure in polishAndSync.-
840 w->thread->exposedWindow = window;-
841-
842 if (w->window->size().isEmpty()
w->window->size().isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
843 || (w->window->isTopLevel() && !w->window->geometry().intersects(w->window->screen()->availableGeometry()))) {
w->window->isTopLevel()Description
TRUEnever evaluated
FALSEnever evaluated
!w->window->ge...bleGeometry())Description
TRUEnever evaluated
FALSEnever evaluated
0
844#ifndef QT_NO_DEBUG-
845 qWarning().noquote().nospace() << "QSGSotwareThreadedRenderLoop: expose event received for window "-
846 << w->window << " with invalid geometry: " << w->window->geometry()-
847 << " on " << w->window->screen();-
848#endif-
849 }
never executed: end of block
0
850-
851 if (!w->window->handle())
!w->window->handle()Description
TRUEnever evaluated
FALSEnever evaluated
0
852 w->window->create();
never executed: w->window->create();
0
853-
854 // Start render thread if it is not running-
855 if (!w->thread->isRunning()) {
!w->thread->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
856 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "starting render thread");
never executed: QMessageLogger(__FILE__, 856, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("starting render thread");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
857 // Push a few things to the render thread.-
858 QQuickAnimatorController *controller = QQuickWindowPrivate::get(w->window)->animationController;-
859 if (controller->thread() != w->thread)
controller->th...) != w->threadDescription
TRUEnever evaluated
FALSEnever evaluated
0
860 controller->moveToThread(w->thread);
never executed: controller->moveToThread(w->thread);
0
861 if (w->thread->thread() == QThread::currentThread()) {
w->thread->thr...urrentThread()Description
TRUEnever evaluated
FALSEnever evaluated
0
862 w->thread->rc->moveToThread(w->thread);-
863 w->thread->moveToThread(w->thread);-
864 }
never executed: end of block
0
865-
866 w->thread->active = true;-
867 w->thread->start();-
868-
869 if (!w->thread->isRunning())
!w->thread->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
870 qFatal("Render thread failed to start, aborting application.");
never executed: QMessageLogger(__FILE__, 870, __PRETTY_FUNCTION__).fatal("Render thread failed to start, aborting application.");
0
871 }
never executed: end of block
0
872-
873 polishAndSync(w, true);-
874-
875 startOrStopAnimationTimer();-
876}
never executed: end of block
0
877-
878void QSGSoftwareThreadedRenderLoop::handleObscurity(QSGSoftwareThreadedRenderLoop::WindowData *w)-
879{-
880 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "handleObscurity" << w->window;
never executed: QMessageLogger(__FILE__, 880, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "handleObscurity" << w->window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
881-
882 if (w->thread->isRunning()) {
w->thread->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
883 w->thread->mutex.lock();-
884 w->thread->postEvent(new QSGSoftwareWindowEvent(w->window, WM_Obscure));-
885 w->thread->waitCondition.wait(&w->thread->mutex);-
886 w->thread->mutex.unlock();-
887 }
never executed: end of block
0
888-
889 startOrStopAnimationTimer();-
890}
never executed: end of block
0
891-
892void QSGSoftwareThreadedRenderLoop::scheduleUpdate(QSGSoftwareThreadedRenderLoop::WindowData *w)-
893{-
894 if (!QCoreApplication::instance())
!QCoreApplication::instance()Description
TRUEnever evaluated
FALSEnever evaluated
0
895 return;
never executed: return;
0
896-
897 if (!w || !w->thread->isRunning())
!wDescription
TRUEnever evaluated
FALSEnever evaluated
!w->thread->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
898 return;
never executed: return;
0
899-
900 QThread *current = QThread::currentThread();-
901 if (current != QCoreApplication::instance()->thread() && (current != w->thread || !lockedForSync)) {
current != QCo...ce()->thread()Description
TRUEnever evaluated
FALSEnever evaluated
current != w->threadDescription
TRUEnever evaluated
FALSEnever evaluated
!lockedForSyncDescription
TRUEnever evaluated
FALSEnever evaluated
0
902 qWarning() << "Updates can only be scheduled from GUI thread or from QQuickItem::updatePaintNode()";-
903 return;
never executed: return;
0
904 }-
905-
906 if (current == w->thread) {
current == w->threadDescription
TRUEnever evaluated
FALSEnever evaluated
0
907 w->updateDuringSync = true;-
908 return;
never executed: return;
0
909 }-
910-
911 w->window->requestUpdate();-
912}
never executed: end of block
0
913-
914void QSGSoftwareThreadedRenderLoop::handleResourceRelease(QSGSoftwareThreadedRenderLoop::WindowData *w, bool destroying)-
915{-
916 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "handleResourceRelease" << (destroying ? "destroying" : "hide/releaseResources") << w->window;
never executed: QMessageLogger(__FILE__, 916, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "handleResourceRelease" << (destroying ? "destroying" : "hide/releaseResources") << w->window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
917-
918 w->thread->mutex.lock();-
919 if (w->thread->isRunning() && w->thread->active) {
w->thread->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
w->thread->activeDescription
TRUEnever evaluated
FALSEnever evaluated
0
920 QQuickWindow *window = w->window;-
921-
922 // Note that window->handle() is typically null by this time because-
923 // the platform window is already destroyed. This should not be a-
924 // problem for the D3D cleanup.-
925-
926 w->thread->postEvent(new QSGSoftwareTryReleaseEvent(window, destroying));-
927 w->thread->waitCondition.wait(&w->thread->mutex);-
928-
929 // Avoid a shutdown race condition.-
930 // If SG is invalidated and 'active' becomes false, the thread's run()-
931 // method will exit. handleExposure() relies on QThread::isRunning() (because it-
932 // potentially needs to start the thread again) and our mutex cannot be used to-
933 // track the thread stopping, so we wait a few nanoseconds extra so the thread-
934 // can exit properly.-
935 if (!w->thread->active)
!w->thread->activeDescription
TRUEnever evaluated
FALSEnever evaluated
0
936 w->thread->wait();
never executed: w->thread->wait();
0
937 }
never executed: end of block
0
938 w->thread->mutex.unlock();-
939}
never executed: end of block
0
940-
941void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop::WindowData *w, bool inExpose)-
942{-
943 qCDebug(QSG_RASTER_LOG_RENDERLOOP) << "polishAndSync" << (inExpose ? "(in expose)" : "(normal)") << w->window;
never executed: QMessageLogger(__FILE__, 943, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug() << "polishAndSync" << (inExpose ? "(in expose)" : "(normal)") << w->window;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
944-
945 QQuickWindow *window = w->window;-
946 if (!w->thread || !w->thread->exposedWindow) {
!w->threadDescription
TRUEnever evaluated
FALSEnever evaluated
!w->thread->exposedWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
947 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - not exposed, abort");
never executed: QMessageLogger(__FILE__, 947, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("polishAndSync - not exposed, abort");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
948 return;
never executed: return;
0
949 }-
950-
951 // Flush pending touch events.-
952 QQuickWindowPrivate::get(window)->flushFrameSynchronousEvents();-
953 // The delivery of the event might have caused the window to stop rendering-
954 w = windowFor(m_windows, window);-
955 if (!w || !w->thread || !w->thread->exposedWindow) {
!wDescription
TRUEnever evaluated
FALSEnever evaluated
!w->threadDescription
TRUEnever evaluated
FALSEnever evaluated
!w->thread->exposedWindowDescription
TRUEnever evaluated
FALSEnever evaluated
0
956 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - removed after touch event flushing, abort");
never executed: QMessageLogger(__FILE__, 956, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("polishAndSync - removed after touch event flushing, abort");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
957 return;
never executed: return;
0
958 }-
959-
960 Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishAndSync);
never executed: end of block
never executed: (void)0;
QQuickProfiler...ileSceneGraph)Description
TRUEnever evaluated
FALSEnever evaluated
0
961-
962 QQuickWindowPrivate *wd = QQuickWindowPrivate::get(window);-
963 wd->polishItems();-
964-
965 Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
never executed: end of block
never executed: (void)0 ;
QQuickProfiler...ileSceneGraph)Description
TRUEnever evaluated
FALSEnever evaluated
0
966 QQuickProfiler::SceneGraphPolishAndSyncPolish);
never executed: (void)0 ;
0
967-
968 w->updateDuringSync = false;-
969-
970 emit window->afterAnimating();-
971-
972 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - lock for sync");
never executed: QMessageLogger(__FILE__, 972, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("polishAndSync - lock for sync");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
973 w->thread->mutex.lock();-
974 lockedForSync = true;-
975 w->thread->postEvent(new QSGSoftwareSyncEvent(window, inExpose, w->forceRenderPass));-
976 w->forceRenderPass = false;-
977-
978 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - wait for sync");
never executed: QMessageLogger(__FILE__, 978, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("polishAndSync - wait for sync");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
979-
980 Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
never executed: end of block
never executed: (void)0 ;
QQuickProfiler...ileSceneGraph)Description
TRUEnever evaluated
FALSEnever evaluated
0
981 QQuickProfiler::SceneGraphPolishAndSyncWait);
never executed: (void)0 ;
0
982 w->thread->waitCondition.wait(&w->thread->mutex);-
983 lockedForSync = false;-
984 w->thread->mutex.unlock();-
985 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - unlock after sync");
never executed: QMessageLogger(__FILE__, 985, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("polishAndSync - unlock after sync");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
986-
987 Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphPolishAndSync,
never executed: end of block
never executed: (void)0 ;
QQuickProfiler...ileSceneGraph)Description
TRUEnever evaluated
FALSEnever evaluated
0
988 QQuickProfiler::SceneGraphPolishAndSyncSync);
never executed: (void)0 ;
0
989-
990 if (!animationTimer && m_anim->isRunning()) {
!animationTimerDescription
TRUEnever evaluated
FALSEnever evaluated
m_anim->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
991 qCDebug(QSG_RASTER_LOG_RENDERLOOP, "polishAndSync - advancing animations");
never executed: QMessageLogger(__FILE__, 991, __PRETTY_FUNCTION__, QSG_RASTER_LOG_RENDERLOOP().categoryName()).debug("polishAndSync - advancing animations");
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
992 m_anim->advance();-
993 // We need to trigger another sync to keep animations running...-
994 w->window->requestUpdate();-
995 emit timeToIncubate();-
996 } else if (w->updateDuringSync) {
never executed: end of block
w->updateDuringSyncDescription
TRUEnever evaluated
FALSEnever evaluated
0
997 w->window->requestUpdate();-
998 }
never executed: end of block
0
999-
1000 Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphPolishAndSync,
never executed: end of block
never executed: (void)0 ;
QQuickProfiler...ileSceneGraph)Description
TRUEnever evaluated
FALSEnever evaluated
0
1001 QQuickProfiler::SceneGraphPolishAndSyncAnimations);
never executed: (void)0 ;
0
1002}-
1003-
1004#include "qsgsoftwarethreadedrenderloop.moc"-
1005#include "moc_qsgsoftwarethreadedrenderloop_p.cpp"-
1006-
1007QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.0