| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quick/items/qquickrendercontrol.cpp |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||
|---|---|---|---|---|---|---|---|---|
| 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 "qquickrendercontrol.h" | - | ||||||
| 41 | #include "qquickrendercontrol_p.h" | - | ||||||
| 42 | - | |||||||
| 43 | #include <QtCore/QCoreApplication> | - | ||||||
| 44 | #include <QtCore/QTime> | - | ||||||
| 45 | #include <QtQuick/private/qquickanimatorcontroller_p.h> | - | ||||||
| 46 | - | |||||||
| 47 | #if QT_CONFIG(opengl) | - | ||||||
| 48 | # include <QtGui/QOpenGLContext> | - | ||||||
| 49 | # include <QtQuick/private/qsgdefaultrendercontext_p.h> | - | ||||||
| 50 | #if QT_CONFIG(quick_shadereffect) | - | ||||||
| 51 | # include <QtQuick/private/qquickopenglshadereffectnode_p.h> | - | ||||||
| 52 | #endif | - | ||||||
| 53 | #endif | - | ||||||
| 54 | #include <QtGui/private/qguiapplication_p.h> | - | ||||||
| 55 | #include <qpa/qplatformintegration.h> | - | ||||||
| 56 | - | |||||||
| 57 | #include <QtQml/private/qqmlglobal_p.h> | - | ||||||
| 58 | - | |||||||
| 59 | #include <QtQuick/QQuickWindow> | - | ||||||
| 60 | #include <QtQuick/private/qquickwindow_p.h> | - | ||||||
| 61 | #include <QtQuick/private/qsgsoftwarerenderer_p.h> | - | ||||||
| 62 | #include <QtCore/private/qobject_p.h> | - | ||||||
| 63 | - | |||||||
| 64 | QT_BEGIN_NAMESPACE | - | ||||||
| 65 | #if QT_CONFIG(opengl) | - | ||||||
| 66 | extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); | - | ||||||
| 67 | #endif | - | ||||||
| 68 | /*! | - | ||||||
| 69 | \class QQuickRenderControl | - | ||||||
| 70 | - | |||||||
| 71 | \brief The QQuickRenderControl class provides a mechanism for rendering the Qt | - | ||||||
| 72 | Quick scenegraph onto an offscreen render target in a fully | - | ||||||
| 73 | application-controlled manner. | - | ||||||
| 74 | - | |||||||
| 75 | \since 5.4 | - | ||||||
| 76 | - | |||||||
| 77 | QQuickWindow and QQuickView and their associated internal render loops render | - | ||||||
| 78 | the Qt Quick scene onto a native window. In some cases, for example when | - | ||||||
| 79 | integrating with 3rd party OpenGL renderers, it might be beneficial to get the | - | ||||||
| 80 | scene into a texture that can then be used in arbitrary ways by the external | - | ||||||
| 81 | rendering engine. QQuickRenderControl makes this possible in a hardware | - | ||||||
| 82 | accelerated manner, unlike the performance-wise limited alternative of using | - | ||||||
| 83 | QQuickWindow::grabWindow() | - | ||||||
| 84 | - | |||||||
| 85 | When using a QQuickRenderControl, the QQuickWindow does not have to be shown | - | ||||||
| 86 | or even created at all. This means there will not be an underlying native | - | ||||||
| 87 | window for it. Instead, the QQuickWindow instance is associated with the | - | ||||||
| 88 | render control, using the overload of the QQuickWindow constructor, and an | - | ||||||
| 89 | OpenGL framebuffer object by calling QQuickWindow::setRenderTarget(). | - | ||||||
| 90 | - | |||||||
| 91 | Management of the context and framebuffer object is up to the application. The | - | ||||||
| 92 | context that will be used by Qt Quick must be created before calling | - | ||||||
| 93 | initialize(). The creation of the framebuffer object can be deferred, see | - | ||||||
| 94 | below. Qt 5.4 introduces the ability for QOpenGLContext to adopt existing | - | ||||||
| 95 | native contexts. Together with QQuickRenderControl this makes it possible to | - | ||||||
| 96 | create a QOpenGLContext that shares with an external rendering engine's | - | ||||||
| 97 | existing context. This new QOpenGLContext can then be used to render the Qt | - | ||||||
| 98 | Quick scene into a texture that is accessible by the other engine's context | - | ||||||
| 99 | too. | - | ||||||
| 100 | - | |||||||
| 101 | Loading and instantiation of the QML components happen by using a | - | ||||||
| 102 | QQmlEngine. Once the root object is created, it will need to be parented to | - | ||||||
| 103 | the QQuickWindow's contentItem(). | - | ||||||
| 104 | - | |||||||
| 105 | Applications will usually have to connect to 4 important signals: | - | ||||||
| 106 | - | |||||||
| 107 | \list | - | ||||||
| 108 | - | |||||||
| 109 | \li QQuickWindow::sceneGraphInitialized() Emitted at some point after calling | - | ||||||
| 110 | QQuickRenderControl::initialize(). Upon this signal, the application is | - | ||||||
| 111 | expected to create its framebuffer object and associate it with the | - | ||||||
| 112 | QQuickWindow. | - | ||||||
| 113 | - | |||||||
| 114 | \li QQuickWindow::sceneGraphInvalidated() When the scenegraph resources are | - | ||||||
| 115 | released, the framebuffer object can be destroyed too. | - | ||||||
| 116 | - | |||||||
| 117 | \li QQuickRenderControl::renderRequested() Indicates that the scene has to be | - | ||||||
| 118 | rendered by calling render(). After making the context current, applications | - | ||||||
| 119 | are expected to call render(). | - | ||||||
| 120 | - | |||||||
| 121 | \li QQuickRenderControl::sceneChanged() Indicates that the scene has changed | - | ||||||
| 122 | meaning that, before rendering, polishing and synchronizing is also necessary. | - | ||||||
| 123 | - | |||||||
| 124 | \endlist | - | ||||||
| 125 | - | |||||||
| 126 | To send events, for example mouse or keyboard events, to the scene, use | - | ||||||
| 127 | QCoreApplication::sendEvent() with the QQuickWindow instance as the receiver. | - | ||||||
| 128 | - | |||||||
| 129 | \note In general QQuickRenderControl is supported in combination with all Qt | - | ||||||
| 130 | Quick backends. However, some functionality, in particular grab(), may not be | - | ||||||
| 131 | available in all cases. | - | ||||||
| 132 | - | |||||||
| 133 | \inmodule QtQuick | - | ||||||
| 134 | */ | - | ||||||
| 135 | - | |||||||
| 136 | QSGContext *QQuickRenderControlPrivate::sg = nullptr; | - | ||||||
| 137 | - | |||||||
| 138 | QQuickRenderControlPrivate::QQuickRenderControlPrivate() | - | ||||||
| 139 | : initialized(0), | - | ||||||
| 140 | window(nullptr) | - | ||||||
| 141 | { | - | ||||||
| 142 | if (!sg) {
| 4-114 | ||||||
| 143 | qAddPostRoutine(cleanup); | - | ||||||
| 144 | sg = QSGContext::createDefaultContext(); | - | ||||||
| 145 | } executed 4 times by 2 tests: end of blockExecuted by:
| 4 | ||||||
| 146 | rc = sg->createRenderContext(); | - | ||||||
| 147 | } executed 118 times by 2 tests: end of blockExecuted by:
| 118 | ||||||
| 148 | - | |||||||
| 149 | void QQuickRenderControlPrivate::cleanup() | - | ||||||
| 150 | { | - | ||||||
| 151 | delete sg; | - | ||||||
| 152 | sg = nullptr; | - | ||||||
| 153 | } executed 4 times by 2 tests: end of blockExecuted by:
| 4 | ||||||
| 154 | - | |||||||
| 155 | /*! | - | ||||||
| 156 | Constructs a QQuickRenderControl object, with parent | - | ||||||
| 157 | object \a parent. | - | ||||||
| 158 | */ | - | ||||||
| 159 | QQuickRenderControl::QQuickRenderControl(QObject *parent) | - | ||||||
| 160 | : QObject(*(new QQuickRenderControlPrivate), parent) | - | ||||||
| 161 | { | - | ||||||
| 162 | } executed 118 times by 2 tests: end of blockExecuted by:
| 118 | ||||||
| 163 | - | |||||||
| 164 | /*! | - | ||||||
| 165 | Destroys the instance. Releases all scenegraph resources. | - | ||||||
| 166 | - | |||||||
| 167 | \sa invalidate() | - | ||||||
| 168 | */ | - | ||||||
| 169 | QQuickRenderControl::~QQuickRenderControl() | - | ||||||
| 170 | { | - | ||||||
| 171 | Q_D(QQuickRenderControl); | - | ||||||
| 172 | - | |||||||
| 173 | invalidate(); | - | ||||||
| 174 | - | |||||||
| 175 | if (d->window)
| 0-118 | ||||||
| 176 | QQuickWindowPrivate::get(d->window)->renderControl = nullptr; executed 118 times by 2 tests: QQuickWindowPrivate::get(d->window)->renderControl = nullptr;Executed by:
| 118 | ||||||
| 177 | - | |||||||
| 178 | // It is likely that the cleanup in windowDestroyed() is not called since | - | ||||||
| 179 | // the standard pattern is to destroy the rendercontrol before the QQuickWindow. | - | ||||||
| 180 | // Do it here. | - | ||||||
| 181 | d->windowDestroyed(); | - | ||||||
| 182 | - | |||||||
| 183 | delete d->rc; | - | ||||||
| 184 | } executed 118 times by 2 tests: end of blockExecuted by:
| 118 | ||||||
| 185 | - | |||||||
| 186 | void QQuickRenderControlPrivate::windowDestroyed() | - | ||||||
| 187 | { | - | ||||||
| 188 | if (window) {
| 0-118 | ||||||
| 189 | rc->invalidate(); | - | ||||||
| 190 | - | |||||||
| 191 | delete QQuickWindowPrivate::get(window)->animationController; | - | ||||||
| 192 | QQuickWindowPrivate::get(window)->animationController = nullptr; | - | ||||||
| 193 | - | |||||||
| 194 | #if QT_CONFIG(quick_shadereffect) && QT_CONFIG(opengl) | - | ||||||
| 195 | QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache(); | - | ||||||
| 196 | #endif | - | ||||||
| 197 | - | |||||||
| 198 | window = nullptr; | - | ||||||
| 199 | } executed 118 times by 2 tests: end of blockExecuted by:
| 118 | ||||||
| 200 | } executed 118 times by 2 tests: end of blockExecuted by:
| 118 | ||||||
| 201 | - | |||||||
| 202 | /*! | - | ||||||
| 203 | Prepares rendering the Qt Quick scene outside the gui thread. | - | ||||||
| 204 | - | |||||||
| 205 | \a targetThread specifies the thread on which synchronization and | - | ||||||
| 206 | rendering will happen. There is no need to call this function in a | - | ||||||
| 207 | single threaded scenario. | - | ||||||
| 208 | */ | - | ||||||
| 209 | void QQuickRenderControl::prepareThread(QThread *targetThread) | - | ||||||
| 210 | { | - | ||||||
| 211 | Q_D(QQuickRenderControl); | - | ||||||
| 212 | d->rc->moveToThread(targetThread); | - | ||||||
| 213 | QQuickWindowPrivate::get(d->window)->animationController->moveToThread(targetThread); | - | ||||||
| 214 | } never executed: end of block | 0 | ||||||
| 215 | - | |||||||
| 216 | /*! | - | ||||||
| 217 | Initializes the scene graph resources. The context \a gl has to be the | - | ||||||
| 218 | current OpenGL context or null if it is not relevant because a Qt Quick | - | ||||||
| 219 | backend other than OpenGL is in use. | - | ||||||
| 220 | - | |||||||
| 221 | \note Qt Quick does not take ownership of the context. It is up to the | - | ||||||
| 222 | application to destroy it after a call to invalidate() or after the | - | ||||||
| 223 | QQuickRenderControl instance is destroyed. | - | ||||||
| 224 | */ | - | ||||||
| 225 | void QQuickRenderControl::initialize(QOpenGLContext *gl) | - | ||||||
| 226 | { | - | ||||||
| 227 | - | |||||||
| 228 | Q_D(QQuickRenderControl); | - | ||||||
| 229 | #if QT_CONFIG(opengl) | - | ||||||
| 230 | if (!d->window) {
| 0-112 | ||||||
| 231 | qWarning("QQuickRenderControl::initialize called with no associated window"); | - | ||||||
| 232 | return; never executed: return; | 0 | ||||||
| 233 | } | - | ||||||
| 234 | - | |||||||
| 235 | if (QOpenGLContext::currentContext() != gl) {
| 0-112 | ||||||
| 236 | qWarning("QQuickRenderControl::initialize called with incorrect current context"); | - | ||||||
| 237 | return; never executed: return; | 0 | ||||||
| 238 | } | - | ||||||
| 239 | - | |||||||
| 240 | // It is the caller's responsiblity to make a context/surface current. | - | ||||||
| 241 | // It cannot be done here since the surface to use may not be the | - | ||||||
| 242 | // surface belonging to window. In fact window may not have a native | - | ||||||
| 243 | // window/surface at all. | - | ||||||
| 244 | d->rc->initialize(gl); | - | ||||||
| 245 | #else | - | ||||||
| 246 | Q_UNUSED(gl) | - | ||||||
| 247 | #endif | - | ||||||
| 248 | d->initialized = true; | - | ||||||
| 249 | } executed 112 times by 2 tests: end of blockExecuted by:
| 112 | ||||||
| 250 | - | |||||||
| 251 | /*! | - | ||||||
| 252 | This function should be called as late as possible before | - | ||||||
| 253 | sync(). In a threaded scenario, rendering can happen in parallel | - | ||||||
| 254 | with this function. | - | ||||||
| 255 | */ | - | ||||||
| 256 | void QQuickRenderControl::polishItems() | - | ||||||
| 257 | { | - | ||||||
| 258 | Q_D(QQuickRenderControl); | - | ||||||
| 259 | if (!d->window)
| 0-324 | ||||||
| 260 | return; never executed: return; | 0 | ||||||
| 261 | - | |||||||
| 262 | QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window); | - | ||||||
| 263 | cd->flushFrameSynchronousEvents(); | - | ||||||
| 264 | if (!d->window)
| 0-324 | ||||||
| 265 | return; never executed: return; | 0 | ||||||
| 266 | cd->polishItems(); | - | ||||||
| 267 | } executed 324 times by 2 tests: end of blockExecuted by:
| 324 | ||||||
| 268 | - | |||||||
| 269 | /*! | - | ||||||
| 270 | This function is used to synchronize the QML scene with the rendering scene | - | ||||||
| 271 | graph. | - | ||||||
| 272 | - | |||||||
| 273 | If a dedicated render thread is used, the GUI thread should be blocked for the | - | ||||||
| 274 | duration of this call. | - | ||||||
| 275 | - | |||||||
| 276 | \return \e true if the synchronization changed the scene graph. | - | ||||||
| 277 | */ | - | ||||||
| 278 | bool QQuickRenderControl::sync() | - | ||||||
| 279 | { | - | ||||||
| 280 | Q_D(QQuickRenderControl); | - | ||||||
| 281 | if (!d->window)
| 0-324 | ||||||
| 282 | return false; never executed: return false; | 0 | ||||||
| 283 | - | |||||||
| 284 | QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window); | - | ||||||
| 285 | cd->syncSceneGraph(); | - | ||||||
| 286 | d->rc->endSync(); | - | ||||||
| 287 | - | |||||||
| 288 | // TODO: find out if the sync actually caused a scenegraph update. | - | ||||||
| 289 | return true; executed 324 times by 2 tests: return true;Executed by:
| 324 | ||||||
| 290 | } | - | ||||||
| 291 | - | |||||||
| 292 | /*! | - | ||||||
| 293 | Stop rendering and release resources. Requires a current context. | - | ||||||
| 294 | - | |||||||
| 295 | This is the equivalent of the cleanup operations that happen with a | - | ||||||
| 296 | real QQuickWindow when the window becomes hidden. | - | ||||||
| 297 | - | |||||||
| 298 | This function is called from the destructor. Therefore there will | - | ||||||
| 299 | typically be no need to call it directly. Pay attention however to | - | ||||||
| 300 | the fact that this requires the context, that was passed to | - | ||||||
| 301 | initialize(), to be the current one at the time of destroying the | - | ||||||
| 302 | QQuickRenderControl instance. | - | ||||||
| 303 | - | |||||||
| 304 | Once invalidate() has been called, it is possible to reuse the | - | ||||||
| 305 | QQuickRenderControl instance by calling initialize() again. | - | ||||||
| 306 | - | |||||||
| 307 | \note This function does not take | - | ||||||
| 308 | QQuickWindow::persistentSceneGraph() or | - | ||||||
| 309 | QQuickWindow::persistentOpenGLContext() into account. This means | - | ||||||
| 310 | that context-specific resources are always released. | - | ||||||
| 311 | */ | - | ||||||
| 312 | void QQuickRenderControl::invalidate() | - | ||||||
| 313 | { | - | ||||||
| 314 | Q_D(QQuickRenderControl); | - | ||||||
| 315 | if (!d->initialized)
| 112-118 | ||||||
| 316 | return; executed 118 times by 2 tests: return;Executed by:
| 118 | ||||||
| 317 | - | |||||||
| 318 | if (!d->window)
| 0-112 | ||||||
| 319 | return; never executed: return; | 0 | ||||||
| 320 | - | |||||||
| 321 | QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window); | - | ||||||
| 322 | cd->fireAboutToStop(); | - | ||||||
| 323 | cd->cleanupNodesOnShutdown(); | - | ||||||
| 324 | - | |||||||
| 325 | // We must invalidate since the context can potentially be destroyed by the | - | ||||||
| 326 | // application right after returning from this function. Invalidating is | - | ||||||
| 327 | // also essential to allow a subsequent initialize() to succeed. | - | ||||||
| 328 | d->rc->invalidate(); | - | ||||||
| 329 | - | |||||||
| 330 | d->initialized = false; | - | ||||||
| 331 | } executed 112 times by 2 tests: end of blockExecuted by:
| 112 | ||||||
| 332 | - | |||||||
| 333 | /*! | - | ||||||
| 334 | Renders the scenegraph using the current context. | - | ||||||
| 335 | */ | - | ||||||
| 336 | void QQuickRenderControl::render() | - | ||||||
| 337 | { | - | ||||||
| 338 | Q_D(QQuickRenderControl); | - | ||||||
| 339 | if (!d->window)
| 0-336 | ||||||
| 340 | return; never executed: return; | 0 | ||||||
| 341 | - | |||||||
| 342 | QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window); | - | ||||||
| 343 | cd->renderSceneGraph(d->window->size()); | - | ||||||
| 344 | } executed 336 times by 2 tests: end of blockExecuted by:
| 336 | ||||||
| 345 | - | |||||||
| 346 | /*! | - | ||||||
| 347 | \fn void QQuickRenderControl::renderRequested() | - | ||||||
| 348 | - | |||||||
| 349 | This signal is emitted when the scene graph needs to be rendered. It is not necessary to call sync(). | - | ||||||
| 350 | - | |||||||
| 351 | \note Avoid triggering rendering directly when this signal is | - | ||||||
| 352 | emitted. Instead, prefer deferring it by using a timer for example. This | - | ||||||
| 353 | will lead to better performance. | - | ||||||
| 354 | */ | - | ||||||
| 355 | - | |||||||
| 356 | /*! | - | ||||||
| 357 | \fn void QQuickRenderControl::sceneChanged() | - | ||||||
| 358 | - | |||||||
| 359 | This signal is emitted when the scene graph is updated, meaning that | - | ||||||
| 360 | polishItems() and sync() needs to be called. If sync() returns | - | ||||||
| 361 | true, then render() needs to be called. | - | ||||||
| 362 | - | |||||||
| 363 | \note Avoid triggering polishing, synchronization and rendering directly | - | ||||||
| 364 | when this signal is emitted. Instead, prefer deferring it by using a timer | - | ||||||
| 365 | for example. This will lead to better performance. | - | ||||||
| 366 | */ | - | ||||||
| 367 | - | |||||||
| 368 | /*! | - | ||||||
| 369 | Grabs the contents of the scene and returns it as an image. | - | ||||||
| 370 | - | |||||||
| 371 | \note Requires the context to be current. | - | ||||||
| 372 | */ | - | ||||||
| 373 | QImage QQuickRenderControl::grab() | - | ||||||
| 374 | { | - | ||||||
| 375 | Q_D(QQuickRenderControl); | - | ||||||
| 376 | if (!d->window)
| 0-8 | ||||||
| 377 | return QImage(); never executed: return QImage(); | 0 | ||||||
| 378 | - | |||||||
| 379 | QImage grabContent; | - | ||||||
| 380 | - | |||||||
| 381 | if (d->window->rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL) {
| 0-8 | ||||||
| 382 | #if QT_CONFIG(opengl) | - | ||||||
| 383 | QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window); | - | ||||||
| 384 | cd->polishItems(); | - | ||||||
| 385 | cd->syncSceneGraph(); | - | ||||||
| 386 | d->rc->endSync(); | - | ||||||
| 387 | render(); | - | ||||||
| 388 | grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), false, false); | - | ||||||
| 389 | if (QQuickRenderControl::renderWindowFor(d->window)) {
| 4 | ||||||
| 390 | grabContent.setDevicePixelRatio(d->window->effectiveDevicePixelRatio()); | - | ||||||
| 391 | } executed 4 times by 1 test: end of blockExecuted by:
| 4 | ||||||
| 392 | #endif | - | ||||||
| 393 | } else if (d->window->rendererInterface()->graphicsApi() == QSGRendererInterface::Software) { executed 8 times by 1 test: end of blockExecuted by:
| 0-8 | ||||||
| 394 | QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window); | - | ||||||
| 395 | cd->polishItems(); | - | ||||||
| 396 | cd->syncSceneGraph(); | - | ||||||
| 397 | QSGSoftwareRenderer *softwareRenderer = static_cast<QSGSoftwareRenderer *>(cd->renderer); | - | ||||||
| 398 | if (softwareRenderer) {
| 0 | ||||||
| 399 | const qreal dpr = d->window->effectiveDevicePixelRatio(); | - | ||||||
| 400 | const QSize imageSize = d->window->size() * dpr; | - | ||||||
| 401 | grabContent = QImage(imageSize, QImage::Format_ARGB32_Premultiplied); | - | ||||||
| 402 | grabContent.setDevicePixelRatio(dpr); | - | ||||||
| 403 | QPaintDevice *prevDev = softwareRenderer->currentPaintDevice(); | - | ||||||
| 404 | softwareRenderer->setCurrentPaintDevice(&grabContent); | - | ||||||
| 405 | softwareRenderer->markDirty(); | - | ||||||
| 406 | d->rc->endSync(); | - | ||||||
| 407 | render(); | - | ||||||
| 408 | softwareRenderer->setCurrentPaintDevice(prevDev); | - | ||||||
| 409 | } never executed: end of block | 0 | ||||||
| 410 | } else { never executed: end of block | 0 | ||||||
| 411 | qWarning("QQuickRenderControl: grabs are not supported with the current Qt Quick backend"); | - | ||||||
| 412 | } never executed: end of block | 0 | ||||||
| 413 | - | |||||||
| 414 | return grabContent; executed 8 times by 1 test: return grabContent;Executed by:
| 8 | ||||||
| 415 | } | - | ||||||
| 416 | - | |||||||
| 417 | void QQuickRenderControlPrivate::update() | - | ||||||
| 418 | { | - | ||||||
| 419 | Q_Q(QQuickRenderControl); | - | ||||||
| 420 | emit q->renderRequested(); | - | ||||||
| 421 | } never executed: end of block | 0 | ||||||
| 422 | - | |||||||
| 423 | void QQuickRenderControlPrivate::maybeUpdate() | - | ||||||
| 424 | { | - | ||||||
| 425 | Q_Q(QQuickRenderControl); | - | ||||||
| 426 | emit q->sceneChanged(); | - | ||||||
| 427 | } executed 1290 times by 2 tests: end of blockExecuted by:
| 1290 | ||||||
| 428 | - | |||||||
| 429 | /*! | - | ||||||
| 430 | \fn QWindow *QQuickRenderControl::renderWindow(QPoint *offset) | - | ||||||
| 431 | - | |||||||
| 432 | Reimplemented in subclasses to return the real window this render control | - | ||||||
| 433 | is rendering into. | - | ||||||
| 434 | - | |||||||
| 435 | If \a offset in non-null, it is set to the offset of the control | - | ||||||
| 436 | inside the window. | - | ||||||
| 437 | - | |||||||
| 438 | \note While not mandatory, reimplementing this function becomes essential for | - | ||||||
| 439 | supporting multiple screens with different device pixel ratios and properly positioning | - | ||||||
| 440 | popup windows opened from QML. Therefore providing it in subclasses is highly | - | ||||||
| 441 | recommended. | - | ||||||
| 442 | */ | - | ||||||
| 443 | - | |||||||
| 444 | /*! | - | ||||||
| 445 | Returns the real window that \a win is being rendered to, if any. | - | ||||||
| 446 | - | |||||||
| 447 | If \a offset in non-null, it is set to the offset of the rendering | - | ||||||
| 448 | inside its window. | - | ||||||
| 449 | - | |||||||
| 450 | */ | - | ||||||
| 451 | QWindow *QQuickRenderControl::renderWindowFor(QQuickWindow *win, QPoint *offset) | - | ||||||
| 452 | { | - | ||||||
| 453 | if (!win)
| 0-55655 | ||||||
| 454 | return nullptr; never executed: return nullptr; | 0 | ||||||
| 455 | QQuickRenderControl *rc = QQuickWindowPrivate::get(win)->renderControl; | - | ||||||
| 456 | if (rc)
| 694-54961 | ||||||
| 457 | return rc->renderWindow(offset); executed 694 times by 2 tests: return rc->renderWindow(offset);Executed by:
| 694 | ||||||
| 458 | return nullptr; executed 54961 times by 76 tests: return nullptr;Executed by:
| 54961 | ||||||
| 459 | } | - | ||||||
| 460 | - | |||||||
| 461 | QT_END_NAMESPACE | - | ||||||
| 462 | - | |||||||
| 463 | #include "moc_qquickrendercontrol.cpp" | - | ||||||
| Source code | Switch to Preprocessed file |