Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsgopenvgrenderloop.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
6
7#include <QtCore/QCoreApplication>
8#include <QtCore/QElapsedTimer>
9
10#include <private/qquickanimatorcontroller_p.h>
11#include <private/qquickwindow_p.h>
12#include <private/qquickprofiler_p.h>
13
14#include <qtquick_tracepoints_p.h>
15
17
19
20QSGOpenVGRenderLoop::QSGOpenVGRenderLoop()
21 : vg(nullptr)
22{
23 sg = QSGContext::createDefaultContext();
24 rc = sg->createRenderContext();
25}
26
28{
29 delete rc;
30 delete sg;
31}
32
33void QSGOpenVGRenderLoop::show(QQuickWindow *window)
34{
35 WindowData data;
36 data.updatePending = false;
37 data.grabOnly = false;
38 m_windows[window] = data;
39
40 maybeUpdate(window);
41}
42
43void QSGOpenVGRenderLoop::hide(QQuickWindow *window)
44{
45 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
46 cd->fireAboutToStop();
47}
48
49void QSGOpenVGRenderLoop::windowDestroyed(QQuickWindow *window)
50{
51 m_windows.remove(window);
52 hide(window);
53
54 QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
55 d->cleanupNodesOnShutdown();
56
57 if (m_windows.size() == 0) {
58 rc->invalidate();
59 delete vg;
60 vg = nullptr;
61 } else if (vg && window == vg->window()) {
62 vg->doneCurrent();
63 }
64
65 d->animationController.reset();
66}
67
68void QSGOpenVGRenderLoop::exposureChanged(QQuickWindow *window)
69{
70 if (window->isExposed()) {
71 m_windows[window].updatePending = true;
72 renderWindow(window);
73 }
74}
75
76QImage QSGOpenVGRenderLoop::grab(QQuickWindow *window)
77{
78 if (!m_windows.contains(window))
79 return QImage();
80
81 m_windows[window].grabOnly = true;
82
83 renderWindow(window);
84
85 QImage grabbed = grabContent;
86 grabContent = QImage();
87 return grabbed;
88}
89
90void QSGOpenVGRenderLoop::update(QQuickWindow *window)
91{
92 maybeUpdate(window);
93}
94
95void QSGOpenVGRenderLoop::handleUpdateRequest(QQuickWindow *window)
96{
97 renderWindow(window);
98}
99
100void QSGOpenVGRenderLoop::maybeUpdate(QQuickWindow *window)
101{
102 if (!m_windows.contains(window))
103 return;
104
105 m_windows[window].updatePending = true;
106 window->requestUpdate();
107}
108
110{
111 return nullptr;
112}
113
115{
116 return sg;
117}
118
119QSGRenderContext *QSGOpenVGRenderLoop::createRenderContext(QSGContext *) const
120{
121 return rc;
122}
123
124void QSGOpenVGRenderLoop::releaseResources(QQuickWindow *window)
125{
126 Q_UNUSED(window);
127}
128
130{
131 return QSurface::OpenVGSurface;
132}
133
134void QSGOpenVGRenderLoop::renderWindow(QQuickWindow *window)
135{
136 QQuickWindowPrivate *cd = QQuickWindowPrivate::get(window);
137 if (!cd->isRenderable() || !m_windows.contains(window))
138 return;
139
140 Q_TRACE_SCOPE(QSG_renderWindow);
141
142 WindowData &data = const_cast<WindowData &>(m_windows[window]);
143
144 if (vg == nullptr) {
145 vg = new QOpenVGContext(window);
146 vg->makeCurrent();
148 params.context = vg;
149 cd->context->initialize(&params);
150 } else {
151 vg->makeCurrent();
152 }
153
154 bool alsoSwap = data.updatePending;
155 data.updatePending = false;
156
157 if (!data.grabOnly) {
158 cd->deliveryAgentPrivate()->flushFrameSynchronousEvents(window);
159 // Event delivery/processing triggered the window to be deleted or stop rendering.
160 if (!m_windows.contains(window))
161 return;
162 }
163 QElapsedTimer renderTimer;
164 qint64 renderTime = 0, syncTime = 0, polishTime = 0;
165 bool profileFrames = QSG_OPENVG_LOG_TIME_RENDERLOOP().isDebugEnabled();
166 if (profileFrames)
167 renderTimer.start();
168 Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphPolishFrame);
169 Q_TRACE(QSG_polishItems_entry);
170
171 cd->polishItems();
172
173 if (profileFrames)
174 polishTime = renderTimer.nsecsElapsed();
175 Q_TRACE(QSG_polishItems_exit);
176 Q_QUICK_SG_PROFILE_SWITCH(QQuickProfiler::SceneGraphPolishFrame,
177 QQuickProfiler::SceneGraphRenderLoopFrame,
178 QQuickProfiler::SceneGraphPolishPolish);
179 Q_TRACE(QSG_sync_entry);
180
181 emit window->afterAnimating();
182
183 cd->syncSceneGraph();
184 rc->endSync();
185
186 if (profileFrames)
187 syncTime = renderTimer.nsecsElapsed();
188 Q_TRACE(QSG_sync_exit);
189 Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
190 QQuickProfiler::SceneGraphRenderLoopSync);
191 Q_TRACE(QSG_render_entry);
192
193 // setup coordinate system for window
194 vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);
195 vgLoadIdentity();
196 vgTranslate(0.0f, window->size().height());
197 vgScale(1.0, -1.0);
198
199 cd->renderSceneGraph();
200
201 if (profileFrames)
202 renderTime = renderTimer.nsecsElapsed();
203 Q_TRACE(QSG_render_exit);
204 Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphRenderLoopFrame,
205 QQuickProfiler::SceneGraphRenderLoopRender);
206 Q_TRACE(QSG_swap_entry);
207
208 if (data.grabOnly) {
209 grabContent = vg->readFramebuffer(window->size() * window->effectiveDevicePixelRatio());
210 data.grabOnly = false;
211 }
212
213 if (alsoSwap && window->isVisible()) {
214 vg->swapBuffers();
215 cd->fireFrameSwapped();
216 }
217
218 qint64 swapTime = 0;
219 if (profileFrames)
220 swapTime = renderTimer.nsecsElapsed();
221 Q_TRACE(QSG_swap_exit);
222 Q_QUICK_SG_PROFILE_END(QQuickProfiler::SceneGraphRenderLoopFrame,
223 QQuickProfiler::SceneGraphRenderLoopSwap);
224
225 if (QSG_OPENVG_LOG_TIME_RENDERLOOP().isDebugEnabled()) {
226 static QTime lastFrameTime = QTime::currentTime();
227 qCDebug(QSG_OPENVG_LOG_TIME_RENDERLOOP,
228 "Frame rendered with 'basic' renderloop in %dms, polish=%d, sync=%d, render=%d, swap=%d, frameDelta=%d",
229 int(swapTime / 1000000),
230 int(polishTime / 1000000),
231 int((syncTime - polishTime) / 1000000),
232 int((renderTime - syncTime) / 1000000),
233 int((swapTime - renderTime) / 10000000),
234 int(lastFrameTime.msecsTo(QTime::currentTime())));
235 lastFrameTime = QTime::currentTime();
236 }
237
238 // Might have been set during syncSceneGraph()
239 if (data.updatePending)
240 maybeUpdate(window);
241}
242
243QT_END_NAMESPACE
void show(QQuickWindow *window) override
QImage grab(QQuickWindow *window) override
void handleUpdateRequest(QQuickWindow *window) override
void exposureChanged(QQuickWindow *window) override
void maybeUpdate(QQuickWindow *window) override
void update(QQuickWindow *window) override
void hide(QQuickWindow *window) override
QAnimationDriver * animationDriver() const override
void releaseResources(QQuickWindow *) override
void windowDestroyed(QQuickWindow *window) override
QSurface::SurfaceType windowSurfaceType() const override
void renderWindow(QQuickWindow *window)
QSGContext * sceneGraphContext() const override