| Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quick/items/qquickshadereffectsource.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 "qquickshadereffectsource_p.h" | - | ||||||||||||||||||
| 41 | - | |||||||||||||||||||
| 42 | #include "qquickitem_p.h" | - | ||||||||||||||||||
| 43 | #include "qquickwindow_p.h" | - | ||||||||||||||||||
| 44 | #include <private/qsgadaptationlayer_p.h> | - | ||||||||||||||||||
| 45 | #include <QtQuick/private/qsgrenderer_p.h> | - | ||||||||||||||||||
| 46 | #include <qsgsimplerectnode.h> | - | ||||||||||||||||||
| 47 | - | |||||||||||||||||||
| 48 | #include "qmath.h" | - | ||||||||||||||||||
| 49 | #include <QtQuick/private/qsgtexture_p.h> | - | ||||||||||||||||||
| 50 | #include <QtCore/QRunnable> | - | ||||||||||||||||||
| 51 | - | |||||||||||||||||||
| 52 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||
| 53 | - | |||||||||||||||||||
| 54 | class QQuickShaderEffectSourceTextureProvider : public QSGTextureProvider | - | ||||||||||||||||||
| 55 | { | - | ||||||||||||||||||
| 56 | Q_OBJECT | - | ||||||||||||||||||
| 57 | public: | - | ||||||||||||||||||
| 58 | QQuickShaderEffectSourceTextureProvider() | - | ||||||||||||||||||
| 59 | : sourceTexture(nullptr) | - | ||||||||||||||||||
| 60 | , mipmapFiltering(QSGTexture::None) | - | ||||||||||||||||||
| 61 | , filtering(QSGTexture::Nearest) | - | ||||||||||||||||||
| 62 | , horizontalWrap(QSGTexture::ClampToEdge) | - | ||||||||||||||||||
| 63 | , verticalWrap(QSGTexture::ClampToEdge) | - | ||||||||||||||||||
| 64 | { | - | ||||||||||||||||||
| 65 | } executed 57 times by 3 tests: end of blockExecuted by:
| 57 | ||||||||||||||||||
| 66 | - | |||||||||||||||||||
| 67 | QSGTexture *texture() const override { | - | ||||||||||||||||||
| 68 | sourceTexture->setMipmapFiltering(mipmapFiltering); | - | ||||||||||||||||||
| 69 | sourceTexture->setFiltering(filtering); | - | ||||||||||||||||||
| 70 | sourceTexture->setHorizontalWrapMode(horizontalWrap); | - | ||||||||||||||||||
| 71 | sourceTexture->setVerticalWrapMode(verticalWrap); | - | ||||||||||||||||||
| 72 | return sourceTexture; executed 598 times by 3 tests: return sourceTexture;Executed by:
| 598 | ||||||||||||||||||
| 73 | } | - | ||||||||||||||||||
| 74 | - | |||||||||||||||||||
| 75 | QSGLayer *sourceTexture; | - | ||||||||||||||||||
| 76 | - | |||||||||||||||||||
| 77 | QSGTexture::Filtering mipmapFiltering; | - | ||||||||||||||||||
| 78 | QSGTexture::Filtering filtering; | - | ||||||||||||||||||
| 79 | QSGTexture::WrapMode horizontalWrap; | - | ||||||||||||||||||
| 80 | QSGTexture::WrapMode verticalWrap; | - | ||||||||||||||||||
| 81 | }; | - | ||||||||||||||||||
| 82 | - | |||||||||||||||||||
| 83 | class QQuickShaderEffectSourceCleanup : public QRunnable | - | ||||||||||||||||||
| 84 | { | - | ||||||||||||||||||
| 85 | public: | - | ||||||||||||||||||
| 86 | QQuickShaderEffectSourceCleanup(QSGLayer *t, QQuickShaderEffectSourceTextureProvider *p) | - | ||||||||||||||||||
| 87 | : texture(t) | - | ||||||||||||||||||
| 88 | , provider(p) | - | ||||||||||||||||||
| 89 | {} executed 93 times by 4 tests: end of blockExecuted by:
| 93 | ||||||||||||||||||
| 90 | void run() override { | - | ||||||||||||||||||
| 91 | delete texture; | - | ||||||||||||||||||
| 92 | delete provider; | - | ||||||||||||||||||
| 93 | } executed 93 times by 4 tests: end of blockExecuted by:
| 93 | ||||||||||||||||||
| 94 | QSGLayer *texture; | - | ||||||||||||||||||
| 95 | QQuickShaderEffectSourceTextureProvider *provider; | - | ||||||||||||||||||
| 96 | }; | - | ||||||||||||||||||
| 97 | - | |||||||||||||||||||
| 98 | /*! | - | ||||||||||||||||||
| 99 | \qmltype ShaderEffectSource | - | ||||||||||||||||||
| 100 | \instantiates QQuickShaderEffectSource | - | ||||||||||||||||||
| 101 | \inqmlmodule QtQuick | - | ||||||||||||||||||
| 102 | \since 5.0 | - | ||||||||||||||||||
| 103 | \inherits Item | - | ||||||||||||||||||
| 104 | \ingroup qtquick-effects | - | ||||||||||||||||||
| 105 | \brief Renders a \l {Qt Quick} item into a texture and displays it. | - | ||||||||||||||||||
| 106 | - | |||||||||||||||||||
| 107 | The ShaderEffectSource type renders \l sourceItem into a texture and | - | ||||||||||||||||||
| 108 | displays it in the scene. \l sourceItem is drawn into the texture as though | - | ||||||||||||||||||
| 109 | it was a fully opaque root item. Thus \l sourceItem itself can be | - | ||||||||||||||||||
| 110 | invisible, but still appear in the texture. | - | ||||||||||||||||||
| 111 | - | |||||||||||||||||||
| 112 | ShaderEffectSource can be used as: | - | ||||||||||||||||||
| 113 | \list | - | ||||||||||||||||||
| 114 | \li a texture source in a \l ShaderEffect. | - | ||||||||||||||||||
| 115 | This allows you to apply custom shader effects to any \l {Qt Quick} item. | - | ||||||||||||||||||
| 116 | \li a cache for a complex item. | - | ||||||||||||||||||
| 117 | The complex item can be rendered once into the texture, which can | - | ||||||||||||||||||
| 118 | then be animated freely without the need to render the complex item | - | ||||||||||||||||||
| 119 | again every frame. | - | ||||||||||||||||||
| 120 | \li an opacity layer. | - | ||||||||||||||||||
| 121 | ShaderEffectSource allows you to apply an opacity to items as a group | - | ||||||||||||||||||
| 122 | rather than each item individually. | - | ||||||||||||||||||
| 123 | \endlist | - | ||||||||||||||||||
| 124 | - | |||||||||||||||||||
| 125 | \table | - | ||||||||||||||||||
| 126 | \row | - | ||||||||||||||||||
| 127 | \li \image declarative-shadereffectsource.png | - | ||||||||||||||||||
| 128 | \li \qml | - | ||||||||||||||||||
| 129 | import QtQuick 2.0 | - | ||||||||||||||||||
| 130 | - | |||||||||||||||||||
| 131 | Rectangle { | - | ||||||||||||||||||
| 132 | width: 200 | - | ||||||||||||||||||
| 133 | height: 100 | - | ||||||||||||||||||
| 134 | gradient: Gradient { | - | ||||||||||||||||||
| 135 | GradientStop { position: 0; color: "white" } | - | ||||||||||||||||||
| 136 | GradientStop { position: 1; color: "black" } | - | ||||||||||||||||||
| 137 | } | - | ||||||||||||||||||
| 138 | Row { | - | ||||||||||||||||||
| 139 | opacity: 0.5 | - | ||||||||||||||||||
| 140 | Item { | - | ||||||||||||||||||
| 141 | id: foo | - | ||||||||||||||||||
| 142 | width: 100; height: 100 | - | ||||||||||||||||||
| 143 | Rectangle { x: 5; y: 5; width: 60; height: 60; color: "red" } | - | ||||||||||||||||||
| 144 | Rectangle { x: 20; y: 20; width: 60; height: 60; color: "orange" } | - | ||||||||||||||||||
| 145 | Rectangle { x: 35; y: 35; width: 60; height: 60; color: "yellow" } | - | ||||||||||||||||||
| 146 | } | - | ||||||||||||||||||
| 147 | ShaderEffectSource { | - | ||||||||||||||||||
| 148 | width: 100; height: 100 | - | ||||||||||||||||||
| 149 | sourceItem: foo | - | ||||||||||||||||||
| 150 | } | - | ||||||||||||||||||
| 151 | } | - | ||||||||||||||||||
| 152 | } | - | ||||||||||||||||||
| 153 | \endqml | - | ||||||||||||||||||
| 154 | \endtable | - | ||||||||||||||||||
| 155 | - | |||||||||||||||||||
| 156 | The ShaderEffectSource type does not redirect any mouse or keyboard | - | ||||||||||||||||||
| 157 | input to \l sourceItem. If you hide the \l sourceItem by setting | - | ||||||||||||||||||
| 158 | \l{Item::visible}{visible} to false or \l{Item::opacity}{opacity} to zero, | - | ||||||||||||||||||
| 159 | it will no longer react to input. In cases where the ShaderEffectSource is | - | ||||||||||||||||||
| 160 | meant to replace the \l sourceItem, you typically want to hide the | - | ||||||||||||||||||
| 161 | \l sourceItem while still handling input. For this, you can use | - | ||||||||||||||||||
| 162 | the \l hideSource property. | - | ||||||||||||||||||
| 163 | - | |||||||||||||||||||
| 164 | \note If \l sourceItem is a \l Rectangle with border, by default half the | - | ||||||||||||||||||
| 165 | border width falls outside the texture. To get the whole border, you can | - | ||||||||||||||||||
| 166 | extend the \l sourceRect. | - | ||||||||||||||||||
| 167 | - | |||||||||||||||||||
| 168 | \note The ShaderEffectSource relies on FBO multisampling support | - | ||||||||||||||||||
| 169 | to antialias edges. If the underlying hardware does not support this, | - | ||||||||||||||||||
| 170 | which is the case for most embedded graphics chips, edges rendered | - | ||||||||||||||||||
| 171 | inside a ShaderEffectSource will not be antialiased. One way to remedy | - | ||||||||||||||||||
| 172 | this is to double the size of the effect source and render it with | - | ||||||||||||||||||
| 173 | \c {smooth: true} (this is the default value of smooth). | - | ||||||||||||||||||
| 174 | This will be equivalent to 4x multisampling, at the cost of lower performance | - | ||||||||||||||||||
| 175 | and higher memory use. | - | ||||||||||||||||||
| 176 | - | |||||||||||||||||||
| 177 | \warning In most cases, using a ShaderEffectSource will decrease | - | ||||||||||||||||||
| 178 | performance, and in all cases, it will increase video memory usage. | - | ||||||||||||||||||
| 179 | Rendering through a ShaderEffectSource might also lead to lower quality | - | ||||||||||||||||||
| 180 | since some OpenGL implementations support multisampled backbuffer, | - | ||||||||||||||||||
| 181 | but not multisampled framebuffer objects. | - | ||||||||||||||||||
| 182 | */ | - | ||||||||||||||||||
| 183 | - | |||||||||||||||||||
| 184 | QQuickShaderEffectSource::QQuickShaderEffectSource(QQuickItem *parent) | - | ||||||||||||||||||
| 185 | : QQuickItem(parent) | - | ||||||||||||||||||
| 186 | , m_provider(nullptr) | - | ||||||||||||||||||
| 187 | , m_texture(nullptr) | - | ||||||||||||||||||
| 188 | , m_wrapMode(ClampToEdge) | - | ||||||||||||||||||
| 189 | , m_sourceItem(nullptr) | - | ||||||||||||||||||
| 190 | , m_textureSize(0, 0) | - | ||||||||||||||||||
| 191 | , m_format(RGBA) | - | ||||||||||||||||||
| 192 | , m_samples(0) | - | ||||||||||||||||||
| 193 | , m_live(true) | - | ||||||||||||||||||
| 194 | , m_hideSource(false) | - | ||||||||||||||||||
| 195 | , m_mipmap(false) | - | ||||||||||||||||||
| 196 | , m_recursive(false) | - | ||||||||||||||||||
| 197 | , m_grab(true) | - | ||||||||||||||||||
| 198 | , m_textureMirroring(MirrorVertically) | - | ||||||||||||||||||
| 199 | { | - | ||||||||||||||||||
| 200 | setFlag(ItemHasContents); | - | ||||||||||||||||||
| 201 | } executed 108 times by 4 tests: end of blockExecuted by:
| 108 | ||||||||||||||||||
| 202 | - | |||||||||||||||||||
| 203 | QQuickShaderEffectSource::~QQuickShaderEffectSource() | - | ||||||||||||||||||
| 204 | { | - | ||||||||||||||||||
| 205 | if (window()) {
| 2-106 | ||||||||||||||||||
| 206 | window()->scheduleRenderJob(new QQuickShaderEffectSourceCleanup(m_texture, m_provider), | - | ||||||||||||||||||
| 207 | QQuickWindow::AfterSynchronizingStage); | - | ||||||||||||||||||
| 208 | } else { executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 209 | // If we don't have a window, these should already have been | - | ||||||||||||||||||
| 210 | // released in invalidateSG or in releaseResrouces() | - | ||||||||||||||||||
| 211 | Q_ASSERT(!m_texture); | - | ||||||||||||||||||
| 212 | Q_ASSERT(!m_provider); | - | ||||||||||||||||||
| 213 | } executed 106 times by 4 tests: end of blockExecuted by:
| 106 | ||||||||||||||||||
| 214 | - | |||||||||||||||||||
| 215 | if (m_sourceItem) {
| 10-98 | ||||||||||||||||||
| 216 | QQuickItemPrivate *sd = QQuickItemPrivate::get(m_sourceItem); | - | ||||||||||||||||||
| 217 | sd->removeItemChangeListener(this, QQuickItemPrivate::Geometry); | - | ||||||||||||||||||
| 218 | sd->derefFromEffectItem(m_hideSource); | - | ||||||||||||||||||
| 219 | if (window())
| 2-96 | ||||||||||||||||||
| 220 | sd->derefWindow(); executed 2 times by 1 test: sd->derefWindow();Executed by:
| 2 | ||||||||||||||||||
| 221 | } executed 98 times by 4 tests: end of blockExecuted by:
| 98 | ||||||||||||||||||
| 222 | } executed 108 times by 4 tests: end of blockExecuted by:
| 108 | ||||||||||||||||||
| 223 | - | |||||||||||||||||||
| 224 | void QQuickShaderEffectSource::ensureTexture() | - | ||||||||||||||||||
| 225 | { | - | ||||||||||||||||||
| 226 | if (m_texture)
| 101-139 | ||||||||||||||||||
| 227 | return; executed 139 times by 4 tests: return;Executed by:
| 139 | ||||||||||||||||||
| 228 | - | |||||||||||||||||||
| 229 | Q_ASSERT_X(QQuickItemPrivate::get(this)->window | - | ||||||||||||||||||
| 230 | && QQuickItemPrivate::get(this)->sceneGraphRenderContext() | - | ||||||||||||||||||
| 231 | && QThread::currentThread() == QQuickItemPrivate::get(this)->sceneGraphRenderContext()->thread(), | - | ||||||||||||||||||
| 232 | "QQuickShaderEffectSource::ensureTexture", | - | ||||||||||||||||||
| 233 | "Cannot be used outside the rendering thread"); | - | ||||||||||||||||||
| 234 | - | |||||||||||||||||||
| 235 | QSGRenderContext *rc = QQuickItemPrivate::get(this)->sceneGraphRenderContext(); | - | ||||||||||||||||||
| 236 | m_texture = rc->sceneGraphContext()->createLayer(rc); | - | ||||||||||||||||||
| 237 | connect(QQuickItemPrivate::get(this)->window, SIGNAL(sceneGraphInvalidated()), m_texture, SLOT(invalidated()), Qt::DirectConnection); | - | ||||||||||||||||||
| 238 | connect(m_texture, SIGNAL(updateRequested()), this, SLOT(update())); | - | ||||||||||||||||||
| 239 | connect(m_texture, SIGNAL(scheduledUpdateCompleted()), this, SIGNAL(scheduledUpdateCompleted())); | - | ||||||||||||||||||
| 240 | } executed 101 times by 4 tests: end of blockExecuted by:
| 101 | ||||||||||||||||||
| 241 | - | |||||||||||||||||||
| 242 | static void get_wrap_mode(QQuickShaderEffectSource::WrapMode mode, QSGTexture::WrapMode *hWrap, QSGTexture::WrapMode *vWrap); | - | ||||||||||||||||||
| 243 | - | |||||||||||||||||||
| 244 | QSGTextureProvider *QQuickShaderEffectSource::textureProvider() const | - | ||||||||||||||||||
| 245 | { | - | ||||||||||||||||||
| 246 | const QQuickItemPrivate *d = QQuickItemPrivate::get(this); | - | ||||||||||||||||||
| 247 | if (!d->window || !d->sceneGraphRenderContext() || QThread::currentThread() != d->sceneGraphRenderContext()->thread()) {
| 0-58 | ||||||||||||||||||
| 248 | qWarning("QQuickShaderEffectSource::textureProvider: can only be queried on the rendering thread of an exposed window"); | - | ||||||||||||||||||
| 249 | return nullptr; never executed: return nullptr; | 0 | ||||||||||||||||||
| 250 | } | - | ||||||||||||||||||
| 251 | - | |||||||||||||||||||
| 252 | if (!m_provider) {
| 1-57 | ||||||||||||||||||
| 253 | const_cast<QQuickShaderEffectSource *>(this)->m_provider = new QQuickShaderEffectSourceTextureProvider(); | - | ||||||||||||||||||
| 254 | const_cast<QQuickShaderEffectSource *>(this)->ensureTexture(); | - | ||||||||||||||||||
| 255 | connect(m_texture, SIGNAL(updateRequested()), m_provider, SIGNAL(textureChanged())); | - | ||||||||||||||||||
| 256 | - | |||||||||||||||||||
| 257 | get_wrap_mode(m_wrapMode, &m_provider->horizontalWrap, &m_provider->verticalWrap); | - | ||||||||||||||||||
| 258 | m_provider->mipmapFiltering = mipmap() ? QSGTexture::Linear : QSGTexture::None;
| 0-57 | ||||||||||||||||||
| 259 | m_provider->filtering = smooth() ? QSGTexture::Linear : QSGTexture::Nearest;
| 19-38 | ||||||||||||||||||
| 260 | m_provider->sourceTexture = m_texture; | - | ||||||||||||||||||
| 261 | } executed 57 times by 3 tests: end of blockExecuted by:
| 57 | ||||||||||||||||||
| 262 | return m_provider; executed 58 times by 3 tests: return m_provider;Executed by:
| 58 | ||||||||||||||||||
| 263 | } | - | ||||||||||||||||||
| 264 | - | |||||||||||||||||||
| 265 | /*! | - | ||||||||||||||||||
| 266 | \qmlproperty enumeration QtQuick::ShaderEffectSource::wrapMode | - | ||||||||||||||||||
| 267 | - | |||||||||||||||||||
| 268 | This property defines the OpenGL wrap modes associated with the texture. | - | ||||||||||||||||||
| 269 | Modifying this property makes most sense when the item is used as a | - | ||||||||||||||||||
| 270 | source texture of a \l ShaderEffect. | - | ||||||||||||||||||
| 271 | - | |||||||||||||||||||
| 272 | The default value is \c{ShaderEffectSource.ClampToEdge}. | - | ||||||||||||||||||
| 273 | - | |||||||||||||||||||
| 274 | \list | - | ||||||||||||||||||
| 275 | \li ShaderEffectSource.ClampToEdge - GL_CLAMP_TO_EDGE both horizontally and vertically | - | ||||||||||||||||||
| 276 | \li ShaderEffectSource.RepeatHorizontally - GL_REPEAT horizontally, GL_CLAMP_TO_EDGE vertically | - | ||||||||||||||||||
| 277 | \li ShaderEffectSource.RepeatVertically - GL_CLAMP_TO_EDGE horizontally, GL_REPEAT vertically | - | ||||||||||||||||||
| 278 | \li ShaderEffectSource.Repeat - GL_REPEAT both horizontally and vertically | - | ||||||||||||||||||
| 279 | \endlist | - | ||||||||||||||||||
| 280 | - | |||||||||||||||||||
| 281 | \note Some OpenGL ES 2 implementations do not support the GL_REPEAT | - | ||||||||||||||||||
| 282 | wrap mode with non-power-of-two textures. | - | ||||||||||||||||||
| 283 | */ | - | ||||||||||||||||||
| 284 | - | |||||||||||||||||||
| 285 | QQuickShaderEffectSource::WrapMode QQuickShaderEffectSource::wrapMode() const | - | ||||||||||||||||||
| 286 | { | - | ||||||||||||||||||
| 287 | return m_wrapMode; never executed: return m_wrapMode; | 0 | ||||||||||||||||||
| 288 | } | - | ||||||||||||||||||
| 289 | - | |||||||||||||||||||
| 290 | void QQuickShaderEffectSource::setWrapMode(WrapMode mode) | - | ||||||||||||||||||
| 291 | { | - | ||||||||||||||||||
| 292 | if (mode == m_wrapMode)
| 0-82 | ||||||||||||||||||
| 293 | return; executed 82 times by 2 tests: return;Executed by:
| 82 | ||||||||||||||||||
| 294 | m_wrapMode = mode; | - | ||||||||||||||||||
| 295 | update(); | - | ||||||||||||||||||
| 296 | emit wrapModeChanged(); | - | ||||||||||||||||||
| 297 | } never executed: end of block | 0 | ||||||||||||||||||
| 298 | - | |||||||||||||||||||
| 299 | /*! | - | ||||||||||||||||||
| 300 | \qmlproperty Item QtQuick::ShaderEffectSource::sourceItem | - | ||||||||||||||||||
| 301 | - | |||||||||||||||||||
| 302 | This property holds the item to be rendered into the texture. | - | ||||||||||||||||||
| 303 | Setting this to null while \l live is true, will release the texture | - | ||||||||||||||||||
| 304 | resources. | - | ||||||||||||||||||
| 305 | */ | - | ||||||||||||||||||
| 306 | - | |||||||||||||||||||
| 307 | QQuickItem *QQuickShaderEffectSource::sourceItem() const | - | ||||||||||||||||||
| 308 | { | - | ||||||||||||||||||
| 309 | return m_sourceItem; executed 183 times by 4 tests: return m_sourceItem;Executed by:
| 183 | ||||||||||||||||||
| 310 | } | - | ||||||||||||||||||
| 311 | - | |||||||||||||||||||
| 312 | void QQuickShaderEffectSource::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &) | - | ||||||||||||||||||
| 313 | { | - | ||||||||||||||||||
| 314 | Q_ASSERT(item == m_sourceItem); | - | ||||||||||||||||||
| 315 | Q_UNUSED(item); | - | ||||||||||||||||||
| 316 | if (change.sizeChange())
| 8-24 | ||||||||||||||||||
| 317 | update(); executed 24 times by 3 tests: update();Executed by:
| 24 | ||||||||||||||||||
| 318 | } executed 32 times by 3 tests: end of blockExecuted by:
| 32 | ||||||||||||||||||
| 319 | - | |||||||||||||||||||
| 320 | void QQuickShaderEffectSource::setSourceItem(QQuickItem *item) | - | ||||||||||||||||||
| 321 | { | - | ||||||||||||||||||
| 322 | if (item == m_sourceItem)
| 0-108 | ||||||||||||||||||
| 323 | return; never executed: return; | 0 | ||||||||||||||||||
| 324 | if (m_sourceItem) {
| 0-108 | ||||||||||||||||||
| 325 | QQuickItemPrivate *d = QQuickItemPrivate::get(m_sourceItem); | - | ||||||||||||||||||
| 326 | d->derefFromEffectItem(m_hideSource); | - | ||||||||||||||||||
| 327 | d->removeItemChangeListener(this, QQuickItemPrivate::Geometry); | - | ||||||||||||||||||
| 328 | disconnect(m_sourceItem, SIGNAL(destroyed(QObject*)), this, SLOT(sourceItemDestroyed(QObject*))); | - | ||||||||||||||||||
| 329 | if (window())
| 0 | ||||||||||||||||||
| 330 | d->derefWindow(); never executed: d->derefWindow(); | 0 | ||||||||||||||||||
| 331 | } never executed: end of block | 0 | ||||||||||||||||||
| 332 | - | |||||||||||||||||||
| 333 | m_sourceItem = item; | - | ||||||||||||||||||
| 334 | - | |||||||||||||||||||
| 335 | if (m_sourceItem) {
| 0-108 | ||||||||||||||||||
| 336 | if (window() == m_sourceItem->window()
| 0-108 | ||||||||||||||||||
| 337 | || (window() == nullptr && m_sourceItem->window())
| 0 | ||||||||||||||||||
| 338 | || (m_sourceItem->window() == nullptr && window())) {
| 0 | ||||||||||||||||||
| 339 | QQuickItemPrivate *d = QQuickItemPrivate::get(item); | - | ||||||||||||||||||
| 340 | // 'item' needs a window to get a scene graph node. It usually gets one through its | - | ||||||||||||||||||
| 341 | // parent, but if the source item is "inline" rather than a reference -- i.e. | - | ||||||||||||||||||
| 342 | // "sourceItem: Item { }" instead of "sourceItem: foo" -- it will not get a parent. | - | ||||||||||||||||||
| 343 | // In those cases, 'item' should get the window from 'this'. | - | ||||||||||||||||||
| 344 | if (window())
| 22-86 | ||||||||||||||||||
| 345 | d->refWindow(window()); executed 22 times by 2 tests: d->refWindow(window());Executed by:
| 22 | ||||||||||||||||||
| 346 | else if (m_sourceItem->window())
| 0-86 | ||||||||||||||||||
| 347 | d->refWindow(m_sourceItem->window()); never executed: d->refWindow(m_sourceItem->window()); | 0 | ||||||||||||||||||
| 348 | d->refFromEffectItem(m_hideSource); | - | ||||||||||||||||||
| 349 | d->addItemChangeListener(this, QQuickItemPrivate::Geometry); | - | ||||||||||||||||||
| 350 | connect(m_sourceItem, SIGNAL(destroyed(QObject*)), this, SLOT(sourceItemDestroyed(QObject*))); | - | ||||||||||||||||||
| 351 | } else { executed 108 times by 4 tests: end of blockExecuted by:
| 108 | ||||||||||||||||||
| 352 | qWarning("ShaderEffectSource: sourceItem and ShaderEffectSource must both be children of the same window."); | - | ||||||||||||||||||
| 353 | m_sourceItem = nullptr; | - | ||||||||||||||||||
| 354 | } never executed: end of block | 0 | ||||||||||||||||||
| 355 | } | - | ||||||||||||||||||
| 356 | update(); | - | ||||||||||||||||||
| 357 | emit sourceItemChanged(); | - | ||||||||||||||||||
| 358 | } executed 108 times by 4 tests: end of blockExecuted by:
| 108 | ||||||||||||||||||
| 359 | - | |||||||||||||||||||
| 360 | void QQuickShaderEffectSource::sourceItemDestroyed(QObject *item) | - | ||||||||||||||||||
| 361 | { | - | ||||||||||||||||||
| 362 | Q_ASSERT(item == m_sourceItem); | - | ||||||||||||||||||
| 363 | Q_UNUSED(item); | - | ||||||||||||||||||
| 364 | m_sourceItem = nullptr; | - | ||||||||||||||||||
| 365 | update(); | - | ||||||||||||||||||
| 366 | emit sourceItemChanged(); | - | ||||||||||||||||||
| 367 | } executed 10 times by 2 tests: end of blockExecuted by:
| 10 | ||||||||||||||||||
| 368 | - | |||||||||||||||||||
| 369 | - | |||||||||||||||||||
| 370 | /*! | - | ||||||||||||||||||
| 371 | \qmlproperty rect QtQuick::ShaderEffectSource::sourceRect | - | ||||||||||||||||||
| 372 | - | |||||||||||||||||||
| 373 | This property defines which rectangular area of the \l sourceItem to | - | ||||||||||||||||||
| 374 | render into the texture. The source rectangle can be larger than | - | ||||||||||||||||||
| 375 | \l sourceItem itself. If the rectangle is null, which is the default, | - | ||||||||||||||||||
| 376 | the whole \l sourceItem is rendered to texture. | - | ||||||||||||||||||
| 377 | */ | - | ||||||||||||||||||
| 378 | - | |||||||||||||||||||
| 379 | QRectF QQuickShaderEffectSource::sourceRect() const | - | ||||||||||||||||||
| 380 | { | - | ||||||||||||||||||
| 381 | return m_sourceRect; never executed: return m_sourceRect; | 0 | ||||||||||||||||||
| 382 | } | - | ||||||||||||||||||
| 383 | - | |||||||||||||||||||
| 384 | void QQuickShaderEffectSource::setSourceRect(const QRectF &rect) | - | ||||||||||||||||||
| 385 | { | - | ||||||||||||||||||
| 386 | if (rect == m_sourceRect)
| 2-80 | ||||||||||||||||||
| 387 | return; executed 80 times by 2 tests: return;Executed by:
| 80 | ||||||||||||||||||
| 388 | m_sourceRect = rect; | - | ||||||||||||||||||
| 389 | update(); | - | ||||||||||||||||||
| 390 | emit sourceRectChanged(); | - | ||||||||||||||||||
| 391 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 392 | - | |||||||||||||||||||
| 393 | /*! | - | ||||||||||||||||||
| 394 | \qmlproperty size QtQuick::ShaderEffectSource::textureSize | - | ||||||||||||||||||
| 395 | - | |||||||||||||||||||
| 396 | This property holds the requested size of the texture. If it is empty, | - | ||||||||||||||||||
| 397 | which is the default, the size of the source rectangle is used. | - | ||||||||||||||||||
| 398 | - | |||||||||||||||||||
| 399 | \note Some platforms have a limit on how small framebuffer objects can be, | - | ||||||||||||||||||
| 400 | which means the actual texture size might be larger than the requested | - | ||||||||||||||||||
| 401 | size. | - | ||||||||||||||||||
| 402 | */ | - | ||||||||||||||||||
| 403 | - | |||||||||||||||||||
| 404 | QSize QQuickShaderEffectSource::textureSize() const | - | ||||||||||||||||||
| 405 | { | - | ||||||||||||||||||
| 406 | return m_textureSize; never executed: return m_textureSize; | 0 | ||||||||||||||||||
| 407 | } | - | ||||||||||||||||||
| 408 | - | |||||||||||||||||||
| 409 | void QQuickShaderEffectSource::setTextureSize(const QSize &size) | - | ||||||||||||||||||
| 410 | { | - | ||||||||||||||||||
| 411 | if (size == m_textureSize)
| 0-82 | ||||||||||||||||||
| 412 | return; never executed: return; | 0 | ||||||||||||||||||
| 413 | m_textureSize = size; | - | ||||||||||||||||||
| 414 | update(); | - | ||||||||||||||||||
| 415 | emit textureSizeChanged(); | - | ||||||||||||||||||
| 416 | } executed 82 times by 2 tests: end of blockExecuted by:
| 82 | ||||||||||||||||||
| 417 | - | |||||||||||||||||||
| 418 | /*! | - | ||||||||||||||||||
| 419 | \qmlproperty enumeration QtQuick::ShaderEffectSource::format | - | ||||||||||||||||||
| 420 | - | |||||||||||||||||||
| 421 | This property defines the internal OpenGL format of the texture. | - | ||||||||||||||||||
| 422 | Modifying this property makes most sense when the item is used as a | - | ||||||||||||||||||
| 423 | source texture of a \l ShaderEffect. Depending on the OpenGL | - | ||||||||||||||||||
| 424 | implementation, this property might allow you to save some texture memory. | - | ||||||||||||||||||
| 425 | - | |||||||||||||||||||
| 426 | \list | - | ||||||||||||||||||
| 427 | \li ShaderEffectSource.Alpha - GL_ALPHA | - | ||||||||||||||||||
| 428 | \li ShaderEffectSource.RGB - GL_RGB | - | ||||||||||||||||||
| 429 | \li ShaderEffectSource.RGBA - GL_RGBA | - | ||||||||||||||||||
| 430 | \endlist | - | ||||||||||||||||||
| 431 | - | |||||||||||||||||||
| 432 | \note Some OpenGL implementations do not support the GL_ALPHA format. | - | ||||||||||||||||||
| 433 | */ | - | ||||||||||||||||||
| 434 | - | |||||||||||||||||||
| 435 | QQuickShaderEffectSource::Format QQuickShaderEffectSource::format() const | - | ||||||||||||||||||
| 436 | { | - | ||||||||||||||||||
| 437 | return m_format; never executed: return m_format; | 0 | ||||||||||||||||||
| 438 | } | - | ||||||||||||||||||
| 439 | - | |||||||||||||||||||
| 440 | void QQuickShaderEffectSource::setFormat(QQuickShaderEffectSource::Format format) | - | ||||||||||||||||||
| 441 | { | - | ||||||||||||||||||
| 442 | if (format == m_format)
| 0-82 | ||||||||||||||||||
| 443 | return; executed 82 times by 2 tests: return;Executed by:
| 82 | ||||||||||||||||||
| 444 | m_format = format; | - | ||||||||||||||||||
| 445 | update(); | - | ||||||||||||||||||
| 446 | emit formatChanged(); | - | ||||||||||||||||||
| 447 | } never executed: end of block | 0 | ||||||||||||||||||
| 448 | - | |||||||||||||||||||
| 449 | /*! | - | ||||||||||||||||||
| 450 | \qmlproperty bool QtQuick::ShaderEffectSource::live | - | ||||||||||||||||||
| 451 | - | |||||||||||||||||||
| 452 | If this property is true, the texture is updated whenever the | - | ||||||||||||||||||
| 453 | \l sourceItem updates. Otherwise, it will be a frozen image, even if | - | ||||||||||||||||||
| 454 | \l sourceItem is assigned a new item. The property is true by default. | - | ||||||||||||||||||
| 455 | */ | - | ||||||||||||||||||
| 456 | - | |||||||||||||||||||
| 457 | bool QQuickShaderEffectSource::live() const | - | ||||||||||||||||||
| 458 | { | - | ||||||||||||||||||
| 459 | return m_live; never executed: return m_live; | 0 | ||||||||||||||||||
| 460 | } | - | ||||||||||||||||||
| 461 | - | |||||||||||||||||||
| 462 | void QQuickShaderEffectSource::setLive(bool live) | - | ||||||||||||||||||
| 463 | { | - | ||||||||||||||||||
| 464 | if (live == m_live)
| 0 | ||||||||||||||||||
| 465 | return; never executed: return; | 0 | ||||||||||||||||||
| 466 | m_live = live; | - | ||||||||||||||||||
| 467 | update(); | - | ||||||||||||||||||
| 468 | emit liveChanged(); | - | ||||||||||||||||||
| 469 | } never executed: end of block | 0 | ||||||||||||||||||
| 470 | - | |||||||||||||||||||
| 471 | /*! | - | ||||||||||||||||||
| 472 | \qmlproperty bool QtQuick::ShaderEffectSource::hideSource | - | ||||||||||||||||||
| 473 | - | |||||||||||||||||||
| 474 | If this property is true, the \l sourceItem is hidden, though it will still | - | ||||||||||||||||||
| 475 | be rendered into the texture. As opposed to hiding the \l sourceItem by | - | ||||||||||||||||||
| 476 | setting \l{Item::visible}{visible} to false, setting this property to true | - | ||||||||||||||||||
| 477 | will not prevent mouse or keyboard input from reaching \l sourceItem. | - | ||||||||||||||||||
| 478 | The property is useful when the ShaderEffectSource is anchored on top of, | - | ||||||||||||||||||
| 479 | and meant to replace the \l sourceItem. | - | ||||||||||||||||||
| 480 | */ | - | ||||||||||||||||||
| 481 | - | |||||||||||||||||||
| 482 | bool QQuickShaderEffectSource::hideSource() const | - | ||||||||||||||||||
| 483 | { | - | ||||||||||||||||||
| 484 | return m_hideSource; never executed: return m_hideSource; | 0 | ||||||||||||||||||
| 485 | } | - | ||||||||||||||||||
| 486 | - | |||||||||||||||||||
| 487 | void QQuickShaderEffectSource::setHideSource(bool hide) | - | ||||||||||||||||||
| 488 | { | - | ||||||||||||||||||
| 489 | if (hide == m_hideSource)
| 0-96 | ||||||||||||||||||
| 490 | return; never executed: return; | 0 | ||||||||||||||||||
| 491 | if (m_sourceItem) {
| 6-90 | ||||||||||||||||||
| 492 | QQuickItemPrivate::get(m_sourceItem)->refFromEffectItem(hide); | - | ||||||||||||||||||
| 493 | QQuickItemPrivate::get(m_sourceItem)->derefFromEffectItem(m_hideSource); | - | ||||||||||||||||||
| 494 | } executed 90 times by 4 tests: end of blockExecuted by:
| 90 | ||||||||||||||||||
| 495 | m_hideSource = hide; | - | ||||||||||||||||||
| 496 | update(); | - | ||||||||||||||||||
| 497 | emit hideSourceChanged(); | - | ||||||||||||||||||
| 498 | } executed 96 times by 4 tests: end of blockExecuted by:
| 96 | ||||||||||||||||||
| 499 | - | |||||||||||||||||||
| 500 | /*! | - | ||||||||||||||||||
| 501 | \qmlproperty bool QtQuick::ShaderEffectSource::mipmap | - | ||||||||||||||||||
| 502 | - | |||||||||||||||||||
| 503 | If this property is true, mipmaps are generated for the texture. | - | ||||||||||||||||||
| 504 | - | |||||||||||||||||||
| 505 | \note Some OpenGL ES 2 implementations do not support mipmapping of | - | ||||||||||||||||||
| 506 | non-power-of-two textures. | - | ||||||||||||||||||
| 507 | */ | - | ||||||||||||||||||
| 508 | - | |||||||||||||||||||
| 509 | bool QQuickShaderEffectSource::mipmap() const | - | ||||||||||||||||||
| 510 | { | - | ||||||||||||||||||
| 511 | return m_mipmap; executed 57 times by 3 tests: return m_mipmap;Executed by:
| 57 | ||||||||||||||||||
| 512 | } | - | ||||||||||||||||||
| 513 | - | |||||||||||||||||||
| 514 | void QQuickShaderEffectSource::setMipmap(bool enabled) | - | ||||||||||||||||||
| 515 | { | - | ||||||||||||||||||
| 516 | if (enabled == m_mipmap)
| 2-80 | ||||||||||||||||||
| 517 | return; executed 80 times by 2 tests: return;Executed by:
| 80 | ||||||||||||||||||
| 518 | m_mipmap = enabled; | - | ||||||||||||||||||
| 519 | update(); | - | ||||||||||||||||||
| 520 | emit mipmapChanged(); | - | ||||||||||||||||||
| 521 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 522 | - | |||||||||||||||||||
| 523 | /*! | - | ||||||||||||||||||
| 524 | \qmlproperty bool QtQuick::ShaderEffectSource::recursive | - | ||||||||||||||||||
| 525 | - | |||||||||||||||||||
| 526 | Set this property to true if the ShaderEffectSource has a dependency on | - | ||||||||||||||||||
| 527 | itself. ShaderEffectSources form a dependency chain, where one | - | ||||||||||||||||||
| 528 | ShaderEffectSource can be part of the \l sourceItem of another. | - | ||||||||||||||||||
| 529 | If there is a loop in this chain, a ShaderEffectSource could end up trying | - | ||||||||||||||||||
| 530 | to render into the same texture it is using as source, which is not allowed | - | ||||||||||||||||||
| 531 | by OpenGL. When this property is set to true, an extra texture is allocated | - | ||||||||||||||||||
| 532 | so that ShaderEffectSource can keep a copy of the texture from the previous | - | ||||||||||||||||||
| 533 | frame. It can then render into one texture and use the texture from the | - | ||||||||||||||||||
| 534 | previous frame as source. | - | ||||||||||||||||||
| 535 | - | |||||||||||||||||||
| 536 | Setting both this property and \l live to true will cause the scene graph | - | ||||||||||||||||||
| 537 | to render continuously. Since the ShaderEffectSource depends on itself, | - | ||||||||||||||||||
| 538 | updating it means that it immediately becomes dirty again. | - | ||||||||||||||||||
| 539 | */ | - | ||||||||||||||||||
| 540 | - | |||||||||||||||||||
| 541 | bool QQuickShaderEffectSource::recursive() const | - | ||||||||||||||||||
| 542 | { | - | ||||||||||||||||||
| 543 | return m_recursive; never executed: return m_recursive; | 0 | ||||||||||||||||||
| 544 | } | - | ||||||||||||||||||
| 545 | - | |||||||||||||||||||
| 546 | void QQuickShaderEffectSource::setRecursive(bool enabled) | - | ||||||||||||||||||
| 547 | { | - | ||||||||||||||||||
| 548 | if (enabled == m_recursive)
| 0 | ||||||||||||||||||
| 549 | return; never executed: return; | 0 | ||||||||||||||||||
| 550 | m_recursive = enabled; | - | ||||||||||||||||||
| 551 | emit recursiveChanged(); | - | ||||||||||||||||||
| 552 | } never executed: end of block | 0 | ||||||||||||||||||
| 553 | - | |||||||||||||||||||
| 554 | /*! | - | ||||||||||||||||||
| 555 | \qmlproperty enumeration QtQuick::ShaderEffectSource::textureMirroring | - | ||||||||||||||||||
| 556 | \since 5.6 | - | ||||||||||||||||||
| 557 | - | |||||||||||||||||||
| 558 | This property defines how the generated OpenGL texture should be mirrored. | - | ||||||||||||||||||
| 559 | The default value is \c{ShaderEffectSource.MirrorVertically}. | - | ||||||||||||||||||
| 560 | Custom mirroring can be useful if the generated texture is directly accessed by custom shaders, | - | ||||||||||||||||||
| 561 | such as those specified by ShaderEffect. Mirroring has no effect on the UI representation of | - | ||||||||||||||||||
| 562 | the ShaderEffectSource item itself. | - | ||||||||||||||||||
| 563 | - | |||||||||||||||||||
| 564 | \list | - | ||||||||||||||||||
| 565 | \li ShaderEffectSource.NoMirroring - No mirroring | - | ||||||||||||||||||
| 566 | \li ShaderEffectSource.MirrorHorizontally - The generated texture is flipped along X-axis. | - | ||||||||||||||||||
| 567 | \li ShaderEffectSource.MirrorVertically - The generated texture is flipped along Y-axis. | - | ||||||||||||||||||
| 568 | \endlist | - | ||||||||||||||||||
| 569 | */ | - | ||||||||||||||||||
| 570 | - | |||||||||||||||||||
| 571 | QQuickShaderEffectSource::TextureMirroring QQuickShaderEffectSource::textureMirroring() const | - | ||||||||||||||||||
| 572 | { | - | ||||||||||||||||||
| 573 | return QQuickShaderEffectSource::TextureMirroring(m_textureMirroring); never executed: return QQuickShaderEffectSource::TextureMirroring(m_textureMirroring); | 0 | ||||||||||||||||||
| 574 | } | - | ||||||||||||||||||
| 575 | - | |||||||||||||||||||
| 576 | void QQuickShaderEffectSource::setTextureMirroring(TextureMirroring mirroring) | - | ||||||||||||||||||
| 577 | { | - | ||||||||||||||||||
| 578 | if (mirroring == QQuickShaderEffectSource::TextureMirroring(m_textureMirroring))
| 42-66 | ||||||||||||||||||
| 579 | return; executed 66 times by 2 tests: return;Executed by:
| 66 | ||||||||||||||||||
| 580 | m_textureMirroring = mirroring; | - | ||||||||||||||||||
| 581 | update(); | - | ||||||||||||||||||
| 582 | emit textureMirroringChanged(); | - | ||||||||||||||||||
| 583 | } executed 42 times by 1 test: end of blockExecuted by:
| 42 | ||||||||||||||||||
| 584 | - | |||||||||||||||||||
| 585 | /*! | - | ||||||||||||||||||
| 586 | \qmlproperty int QtQuick::ShaderEffectSource::samples | - | ||||||||||||||||||
| 587 | \since 5.10 | - | ||||||||||||||||||
| 588 | - | |||||||||||||||||||
| 589 | This property allows requesting multisampled rendering. | - | ||||||||||||||||||
| 590 | - | |||||||||||||||||||
| 591 | By default multisampling is enabled whenever multisampling is enabled for | - | ||||||||||||||||||
| 592 | the entire window, assuming the scenegraph renderer in use and the | - | ||||||||||||||||||
| 593 | underlying graphics API supports this. | - | ||||||||||||||||||
| 594 | - | |||||||||||||||||||
| 595 | By setting the value to 2, 4, etc. multisampled rendering can be requested | - | ||||||||||||||||||
| 596 | for a part of the scene without enabling multisampling for the entire | - | ||||||||||||||||||
| 597 | scene. This way multisampling is applied only to a given subtree, which can | - | ||||||||||||||||||
| 598 | lead to significant performance gains since multisampling is not applied to | - | ||||||||||||||||||
| 599 | other parts of the scene. | - | ||||||||||||||||||
| 600 | - | |||||||||||||||||||
| 601 | \note Enabling multisampling can be potentially expensive regardless of the | - | ||||||||||||||||||
| 602 | layer's size, as it incurs a hardware and driver dependent performance and | - | ||||||||||||||||||
| 603 | memory cost. | - | ||||||||||||||||||
| 604 | - | |||||||||||||||||||
| 605 | \note This property is only functional when support for multisample | - | ||||||||||||||||||
| 606 | renderbuffers and framebuffer blits is available. Otherwise the value is | - | ||||||||||||||||||
| 607 | silently ignored. | - | ||||||||||||||||||
| 608 | */ | - | ||||||||||||||||||
| 609 | int QQuickShaderEffectSource::samples() const | - | ||||||||||||||||||
| 610 | { | - | ||||||||||||||||||
| 611 | return m_samples; never executed: return m_samples; | 0 | ||||||||||||||||||
| 612 | } | - | ||||||||||||||||||
| 613 | - | |||||||||||||||||||
| 614 | void QQuickShaderEffectSource::setSamples(int count) | - | ||||||||||||||||||
| 615 | { | - | ||||||||||||||||||
| 616 | if (count == m_samples)
| 2-80 | ||||||||||||||||||
| 617 | return; executed 80 times by 2 tests: return;Executed by:
| 80 | ||||||||||||||||||
| 618 | m_samples = count; | - | ||||||||||||||||||
| 619 | update(); | - | ||||||||||||||||||
| 620 | emit samplesChanged(); | - | ||||||||||||||||||
| 621 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 622 | - | |||||||||||||||||||
| 623 | /*! | - | ||||||||||||||||||
| 624 | \qmlmethod QtQuick::ShaderEffectSource::scheduleUpdate() | - | ||||||||||||||||||
| 625 | - | |||||||||||||||||||
| 626 | Schedules a re-rendering of the texture for the next frame. | - | ||||||||||||||||||
| 627 | Use this to update the texture when \l live is false. | - | ||||||||||||||||||
| 628 | */ | - | ||||||||||||||||||
| 629 | - | |||||||||||||||||||
| 630 | void QQuickShaderEffectSource::scheduleUpdate() | - | ||||||||||||||||||
| 631 | { | - | ||||||||||||||||||
| 632 | if (m_grab)
| 0 | ||||||||||||||||||
| 633 | return; never executed: return; | 0 | ||||||||||||||||||
| 634 | m_grab = true; | - | ||||||||||||||||||
| 635 | update(); | - | ||||||||||||||||||
| 636 | } never executed: end of block | 0 | ||||||||||||||||||
| 637 | - | |||||||||||||||||||
| 638 | static void get_wrap_mode(QQuickShaderEffectSource::WrapMode mode, QSGTexture::WrapMode *hWrap, QSGTexture::WrapMode *vWrap) | - | ||||||||||||||||||
| 639 | { | - | ||||||||||||||||||
| 640 | switch (mode) { | - | ||||||||||||||||||
| 641 | case QQuickShaderEffectSource::RepeatHorizontally: never executed: case QQuickShaderEffectSource::RepeatHorizontally: | 0 | ||||||||||||||||||
| 642 | *hWrap = QSGTexture::Repeat; | - | ||||||||||||||||||
| 643 | *vWrap = QSGTexture::ClampToEdge; | - | ||||||||||||||||||
| 644 | break; never executed: break; | 0 | ||||||||||||||||||
| 645 | case QQuickShaderEffectSource::RepeatVertically: never executed: case QQuickShaderEffectSource::RepeatVertically: | 0 | ||||||||||||||||||
| 646 | *vWrap = QSGTexture::Repeat; | - | ||||||||||||||||||
| 647 | *hWrap = QSGTexture::ClampToEdge; | - | ||||||||||||||||||
| 648 | break; never executed: break; | 0 | ||||||||||||||||||
| 649 | case QQuickShaderEffectSource::Repeat: never executed: case QQuickShaderEffectSource::Repeat: | 0 | ||||||||||||||||||
| 650 | *hWrap = *vWrap = QSGTexture::Repeat; | - | ||||||||||||||||||
| 651 | break; never executed: break; | 0 | ||||||||||||||||||
| 652 | default: executed 240 times by 4 tests: default:Executed by:
| 240 | ||||||||||||||||||
| 653 | // QQuickShaderEffectSource::ClampToEdge | - | ||||||||||||||||||
| 654 | *hWrap = *vWrap = QSGTexture::ClampToEdge; | - | ||||||||||||||||||
| 655 | break; executed 240 times by 4 tests: break;Executed by:
| 240 | ||||||||||||||||||
| 656 | } | - | ||||||||||||||||||
| 657 | } | - | ||||||||||||||||||
| 658 | - | |||||||||||||||||||
| 659 | - | |||||||||||||||||||
| 660 | void QQuickShaderEffectSource::releaseResources() | - | ||||||||||||||||||
| 661 | { | - | ||||||||||||||||||
| 662 | if (m_texture || m_provider) {
| 0-91 | ||||||||||||||||||
| 663 | window()->scheduleRenderJob(new QQuickShaderEffectSourceCleanup(m_texture, m_provider), | - | ||||||||||||||||||
| 664 | QQuickWindow::AfterSynchronizingStage); | - | ||||||||||||||||||
| 665 | m_texture = nullptr; | - | ||||||||||||||||||
| 666 | m_provider = nullptr; | - | ||||||||||||||||||
| 667 | } executed 91 times by 4 tests: end of blockExecuted by:
| 91 | ||||||||||||||||||
| 668 | } executed 101 times by 4 tests: end of blockExecuted by:
| 101 | ||||||||||||||||||
| 669 | - | |||||||||||||||||||
| 670 | class QQuickShaderSourceAttachedNode : public QObject, public QSGNode | - | ||||||||||||||||||
| 671 | { | - | ||||||||||||||||||
| 672 | Q_OBJECT | - | ||||||||||||||||||
| 673 | public: | - | ||||||||||||||||||
| 674 | Q_SLOT void markTextureDirty() { | - | ||||||||||||||||||
| 675 | QSGNode *pn = QSGNode::parent(); | - | ||||||||||||||||||
| 676 | if (pn) {
| 0-52 | ||||||||||||||||||
| 677 | Q_ASSERT(pn->type() == QSGNode::GeometryNodeType); | - | ||||||||||||||||||
| 678 | pn->markDirty(DirtyMaterial); | - | ||||||||||||||||||
| 679 | } executed 52 times by 2 tests: end of blockExecuted by:
| 52 | ||||||||||||||||||
| 680 | } executed 52 times by 2 tests: end of blockExecuted by:
| 52 | ||||||||||||||||||
| 681 | }; | - | ||||||||||||||||||
| 682 | - | |||||||||||||||||||
| 683 | QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) | - | ||||||||||||||||||
| 684 | { | - | ||||||||||||||||||
| 685 | if (!m_sourceItem || m_sourceItem->width() <= 0 || m_sourceItem->height() <= 0) {
| 0-183 | ||||||||||||||||||
| 686 | if (m_texture)
| 0-4 | ||||||||||||||||||
| 687 | m_texture->setItem(nullptr); executed 4 times by 1 test: m_texture->setItem(nullptr);Executed by:
| 4 | ||||||||||||||||||
| 688 | delete oldNode; | - | ||||||||||||||||||
| 689 | return nullptr; executed 4 times by 1 test: return nullptr;Executed by:
| 4 | ||||||||||||||||||
| 690 | } | - | ||||||||||||||||||
| 691 | - | |||||||||||||||||||
| 692 | ensureTexture(); | - | ||||||||||||||||||
| 693 | - | |||||||||||||||||||
| 694 | m_texture->setLive(m_live); | - | ||||||||||||||||||
| 695 | m_texture->setItem(QQuickItemPrivate::get(m_sourceItem)->itemNode()); | - | ||||||||||||||||||
| 696 | QRectF sourceRect = m_sourceRect.width() == 0 || m_sourceRect.height() == 0
| 0-179 | ||||||||||||||||||
| 697 | ? QRectF(0, 0, m_sourceItem->width(), m_sourceItem->height()) | - | ||||||||||||||||||
| 698 | : m_sourceRect; | - | ||||||||||||||||||
| 699 | m_texture->setRect(sourceRect); | - | ||||||||||||||||||
| 700 | QSize textureSize = m_textureSize.isEmpty()
| 2-181 | ||||||||||||||||||
| 701 | ? QSize(qCeil(qAbs(sourceRect.width())), qCeil(qAbs(sourceRect.height()))) | - | ||||||||||||||||||
| 702 | : m_textureSize; | - | ||||||||||||||||||
| 703 | Q_ASSERT(!textureSize.isEmpty()); | - | ||||||||||||||||||
| 704 | - | |||||||||||||||||||
| 705 | QQuickItemPrivate *d = static_cast<QQuickItemPrivate *>(QObjectPrivate::get(this)); | - | ||||||||||||||||||
| 706 | - | |||||||||||||||||||
| 707 | // Crate large textures on high-dpi displays. | - | ||||||||||||||||||
| 708 | if (sourceItem())
| 0-183 | ||||||||||||||||||
| 709 | textureSize *= d->window->effectiveDevicePixelRatio(); executed 183 times by 4 tests: textureSize *= d->window->effectiveDevicePixelRatio();Executed by:
| 183 | ||||||||||||||||||
| 710 | - | |||||||||||||||||||
| 711 | const QSize minTextureSize = d->sceneGraphContext()->minimumFBOSize(); | - | ||||||||||||||||||
| 712 | // Keep power-of-two by doubling the size. | - | ||||||||||||||||||
| 713 | while (textureSize.width() < minTextureSize.width())
| 0-183 | ||||||||||||||||||
| 714 | textureSize.rwidth() *= 2; never executed: textureSize.rwidth() *= 2; | 0 | ||||||||||||||||||
| 715 | while (textureSize.height() < minTextureSize.height())
| 0-183 | ||||||||||||||||||
| 716 | textureSize.rheight() *= 2; never executed: textureSize.rheight() *= 2; | 0 | ||||||||||||||||||
| 717 | - | |||||||||||||||||||
| 718 | m_texture->setDevicePixelRatio(d->window->effectiveDevicePixelRatio()); | - | ||||||||||||||||||
| 719 | m_texture->setSize(textureSize); | - | ||||||||||||||||||
| 720 | m_texture->setRecursive(m_recursive); | - | ||||||||||||||||||
| 721 | m_texture->setFormat(m_format); | - | ||||||||||||||||||
| 722 | m_texture->setHasMipmaps(m_mipmap); | - | ||||||||||||||||||
| 723 | m_texture->setMirrorHorizontal(m_textureMirroring & MirrorHorizontally); | - | ||||||||||||||||||
| 724 | m_texture->setMirrorVertical(m_textureMirroring & MirrorVertically); | - | ||||||||||||||||||
| 725 | m_texture->setSamples(m_samples); | - | ||||||||||||||||||
| 726 | - | |||||||||||||||||||
| 727 | if (m_grab)
| 82-101 | ||||||||||||||||||
| 728 | m_texture->scheduleUpdate(); executed 101 times by 4 tests: m_texture->scheduleUpdate();Executed by:
| 101 | ||||||||||||||||||
| 729 | m_grab = false; | - | ||||||||||||||||||
| 730 | - | |||||||||||||||||||
| 731 | QSGTexture::Filtering filtering = QQuickItemPrivate::get(this)->smooth
| 53-130 | ||||||||||||||||||
| 732 | ? QSGTexture::Linear | - | ||||||||||||||||||
| 733 | : QSGTexture::Nearest; | - | ||||||||||||||||||
| 734 | QSGTexture::Filtering mmFiltering = m_mipmap ? filtering : QSGTexture::None;
| 4-179 | ||||||||||||||||||
| 735 | QSGTexture::WrapMode hWrap, vWrap; | - | ||||||||||||||||||
| 736 | get_wrap_mode(m_wrapMode, &hWrap, &vWrap); | - | ||||||||||||||||||
| 737 | - | |||||||||||||||||||
| 738 | if (m_provider) {
| 87-96 | ||||||||||||||||||
| 739 | m_provider->mipmapFiltering = mmFiltering; | - | ||||||||||||||||||
| 740 | m_provider->filtering = filtering; | - | ||||||||||||||||||
| 741 | m_provider->horizontalWrap = hWrap; | - | ||||||||||||||||||
| 742 | m_provider->verticalWrap = vWrap; | - | ||||||||||||||||||
| 743 | } executed 96 times by 3 tests: end of blockExecuted by:
| 96 | ||||||||||||||||||
| 744 | - | |||||||||||||||||||
| 745 | // Don't create the paint node if we're not spanning any area | - | ||||||||||||||||||
| 746 | if (width() <= 0 || height() <= 0) {
| 0-120 | ||||||||||||||||||
| 747 | delete oldNode; | - | ||||||||||||||||||
| 748 | return nullptr; executed 63 times by 4 tests: return nullptr;Executed by:
| 63 | ||||||||||||||||||
| 749 | } | - | ||||||||||||||||||
| 750 | - | |||||||||||||||||||
| 751 | QSGInternalImageNode *node = static_cast<QSGInternalImageNode *>(oldNode); | - | ||||||||||||||||||
| 752 | if (!node) {
| 56-64 | ||||||||||||||||||
| 753 | node = d->sceneGraphContext()->createInternalImageNode(); | - | ||||||||||||||||||
| 754 | node->setFlag(QSGNode::UsePreprocess); | - | ||||||||||||||||||
| 755 | node->setTexture(m_texture); | - | ||||||||||||||||||
| 756 | QQuickShaderSourceAttachedNode *attached = new QQuickShaderSourceAttachedNode; | - | ||||||||||||||||||
| 757 | node->appendChildNode(attached); | - | ||||||||||||||||||
| 758 | connect(m_texture, SIGNAL(updateRequested()), attached, SLOT(markTextureDirty())); | - | ||||||||||||||||||
| 759 | } executed 64 times by 2 tests: end of blockExecuted by:
| 64 | ||||||||||||||||||
| 760 | - | |||||||||||||||||||
| 761 | // If live and recursive, update continuously. | - | ||||||||||||||||||
| 762 | if (m_live && m_recursive)
| 0-120 | ||||||||||||||||||
| 763 | node->markDirty(QSGNode::DirtyMaterial); never executed: node->markDirty(QSGNode::DirtyMaterial); | 0 | ||||||||||||||||||
| 764 | - | |||||||||||||||||||
| 765 | node->setMipmapFiltering(mmFiltering); | - | ||||||||||||||||||
| 766 | node->setFiltering(filtering); | - | ||||||||||||||||||
| 767 | node->setHorizontalWrapMode(hWrap); | - | ||||||||||||||||||
| 768 | node->setVerticalWrapMode(vWrap); | - | ||||||||||||||||||
| 769 | node->setTargetRect(QRectF(0, 0, width(), height())); | - | ||||||||||||||||||
| 770 | node->setInnerTargetRect(QRectF(0, 0, width(), height())); | - | ||||||||||||||||||
| 771 | node->update(); | - | ||||||||||||||||||
| 772 | - | |||||||||||||||||||
| 773 | return node; executed 120 times by 2 tests: return node;Executed by:
| 120 | ||||||||||||||||||
| 774 | } | - | ||||||||||||||||||
| 775 | - | |||||||||||||||||||
| 776 | void QQuickShaderEffectSource::invalidateSceneGraph() | - | ||||||||||||||||||
| 777 | { | - | ||||||||||||||||||
| 778 | if (m_texture)
| 0-8 | ||||||||||||||||||
| 779 | delete m_texture; executed 8 times by 1 test: delete m_texture;Executed by:
| 8 | ||||||||||||||||||
| 780 | if (m_provider)
| 2-6 | ||||||||||||||||||
| 781 | delete m_provider; executed 6 times by 1 test: delete m_provider;Executed by:
| 6 | ||||||||||||||||||
| 782 | m_texture = nullptr; | - | ||||||||||||||||||
| 783 | m_provider = nullptr; | - | ||||||||||||||||||
| 784 | } executed 8 times by 1 test: end of blockExecuted by:
| 8 | ||||||||||||||||||
| 785 | - | |||||||||||||||||||
| 786 | void QQuickShaderEffectSource::itemChange(ItemChange change, const ItemChangeData &value) | - | ||||||||||||||||||
| 787 | { | - | ||||||||||||||||||
| 788 | if (change == QQuickItem::ItemSceneChange && m_sourceItem) {
| 24-262 | ||||||||||||||||||
| 789 | // See comment in QQuickShaderEffectSource::setSourceItem(). | - | ||||||||||||||||||
| 790 | if (value.window)
| 81-99 | ||||||||||||||||||
| 791 | QQuickItemPrivate::get(m_sourceItem)->refWindow(value.window); executed 81 times by 4 tests: QQuickItemPrivate::get(m_sourceItem)->refWindow(value.window);Executed by:
| 81 | ||||||||||||||||||
| 792 | else | - | ||||||||||||||||||
| 793 | QQuickItemPrivate::get(m_sourceItem)->derefWindow(); executed 99 times by 3 tests: QQuickItemPrivate::get(m_sourceItem)->derefWindow();Executed by:
| 99 | ||||||||||||||||||
| 794 | } | - | ||||||||||||||||||
| 795 | QQuickItem::itemChange(change, value); | - | ||||||||||||||||||
| 796 | } executed 466 times by 4 tests: end of blockExecuted by:
| 466 | ||||||||||||||||||
| 797 | - | |||||||||||||||||||
| 798 | #include "qquickshadereffectsource.moc" | - | ||||||||||||||||||
| 799 | #include "moc_qquickshadereffectsource_p.cpp" | - | ||||||||||||||||||
| 800 | - | |||||||||||||||||||
| 801 | QT_END_NAMESPACE | - | ||||||||||||||||||
| Source code | Switch to Preprocessed file |