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
qsgsoftwarelayer.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// Qt-Security score:significant reason:default
4
6
9
11
12QSGSoftwareLayer::QSGSoftwareLayer(QSGRenderContext *renderContext)
13 : QSGLayer(*(new QSGTexturePrivate(this)))
14 , m_item(nullptr)
15 , m_context(renderContext)
16 , m_renderer(nullptr)
17 , m_device_pixel_ratio(1)
18 , m_mirrorHorizontal(false)
19 , m_mirrorVertical(true)
20 , m_live(true)
21 , m_grab(true)
22 , m_recursive(false)
23 , m_dirtyTexture(true)
24{
25
26}
27
28QSGSoftwareLayer::~QSGSoftwareLayer()
29{
30 invalidated();
31}
32
33qint64 QSGSoftwareLayer::comparisonKey() const
34{
35 return 0;
36}
37
38QSize QSGSoftwareLayer::textureSize() const
39{
40 return m_pixmap.size();
41}
42
43bool QSGSoftwareLayer::hasAlphaChannel() const
44{
45 return m_pixmap.hasAlphaChannel();
46}
47
48bool QSGSoftwareLayer::hasMipmaps() const
49{
50 return false;
51}
52
53bool QSGSoftwareLayer::updateTexture()
54{
55 bool doGrab = (m_live || m_grab) && m_dirtyTexture;
56 if (doGrab)
57 grab();
58 if (m_grab)
59 emit scheduledUpdateCompleted();
60 m_grab = false;
61 return doGrab;
62}
63
64void QSGSoftwareLayer::setItem(QSGNode *item)
65{
66 if (item == m_item)
67 return;
68 m_item = item;
69
70 if (m_live && !m_item)
71 m_pixmap = QPixmap();
72
73 markDirtyTexture();
74}
75
76void QSGSoftwareLayer::setRect(const QRectF &rect)
77{
78 if (rect == m_rect)
79 return;
80 m_rect = rect;
81 markDirtyTexture();
82}
83
84void QSGSoftwareLayer::setSize(const QSize &size)
85{
86 if (size == m_size)
87 return;
88 m_size = size;
89
90 if (m_live && m_size.isNull())
91 m_pixmap = QPixmap();
92
93 markDirtyTexture();
94}
95
96void QSGSoftwareLayer::scheduleUpdate()
97{
98 if (m_grab)
99 return;
100 m_grab = true;
101 if (m_dirtyTexture) {
102 emit updateRequested();
103 }
104}
105
106QImage QSGSoftwareLayer::toImage() const
107{
108 return m_pixmap.toImage();
109}
110
111void QSGSoftwareLayer::setLive(bool live)
112{
113 if (live == m_live)
114 return;
115 m_live = live;
116
117 if (m_live && (!m_item || m_size.isNull()))
118 m_pixmap = QPixmap();
119
120 markDirtyTexture();
121}
122
123void QSGSoftwareLayer::setRecursive(bool recursive)
124{
125 m_recursive = recursive;
126}
127
128void QSGSoftwareLayer::setFormat(Format)
129{
130}
131
132void QSGSoftwareLayer::setHasMipmaps(bool)
133{
134}
135
136void QSGSoftwareLayer::setDevicePixelRatio(qreal ratio)
137{
138 m_device_pixel_ratio = ratio;
139}
140
141void QSGSoftwareLayer::setMirrorHorizontal(bool mirror)
142{
143 if (m_mirrorHorizontal == mirror)
144 return;
145 m_mirrorHorizontal = mirror;
146 markDirtyTexture();
147}
148
149void QSGSoftwareLayer::setMirrorVertical(bool mirror)
150{
151 if (m_mirrorVertical == mirror)
152 return;
153 m_mirrorVertical = mirror;
154 markDirtyTexture();
155}
156
157void QSGSoftwareLayer::markDirtyTexture()
158{
159 m_dirtyTexture = true;
160 if (m_live || m_grab) {
161 emit updateRequested();
162 }
163}
164
165void QSGSoftwareLayer::invalidated()
166{
167 delete m_renderer;
168 m_renderer = nullptr;
169}
170
171void QSGSoftwareLayer::grab()
172{
173 if (!m_item || m_size.isNull()) {
174 m_pixmap = QPixmap();
175 m_dirtyTexture = false;
176 return;
177 }
178 QSGNode *root = m_item;
179 while (root->firstChild() && root->type() != QSGNode::RootNodeType)
180 root = root->firstChild();
181 if (root->type() != QSGNode::RootNodeType)
182 return;
183
184 if (!m_renderer) {
185 m_renderer = new QSGSoftwarePixmapRenderer(m_context);
186 connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture()));
187 }
188 m_renderer->setDevicePixelRatio(m_device_pixel_ratio);
189 m_renderer->setRootNode(static_cast<QSGRootNode *>(root));
190
191 if (m_pixmap.size() != m_size) {
192 m_pixmap = QPixmap(m_size);
193 m_pixmap.setDevicePixelRatio(m_device_pixel_ratio);
194 }
195
196 // Render texture.
197 root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update.
198 m_renderer->nodeChanged(root, QSGNode::DirtyForceUpdate); // Force render list update.
199
200 m_dirtyTexture = false;
201
202 m_renderer->setDeviceRect(m_size);
203 m_renderer->setViewportRect(m_size);
204 QRect mirrored(m_mirrorHorizontal ? m_rect.right() * m_device_pixel_ratio : m_rect.left() * m_device_pixel_ratio,
205 m_mirrorVertical ? m_rect.bottom() * m_device_pixel_ratio : m_rect.top() * m_device_pixel_ratio,
206 m_mirrorHorizontal ? -m_rect.width() * m_device_pixel_ratio : m_rect.width() * m_device_pixel_ratio,
207 m_mirrorVertical ? -m_rect.height() * m_device_pixel_ratio : m_rect.height() * m_device_pixel_ratio);
208 m_renderer->setProjectionRect(mirrored);
209 m_renderer->setClearColor(Qt::transparent);
210
211 m_renderer->renderScene();
212 m_renderer->render(&m_pixmap);
213
214 root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip, opacity and render list update.
215
216 if (m_recursive)
217 markDirtyTexture(); // Continuously update if 'live' and 'recursive'.
218}
219
220QT_END_NAMESPACE
221
222#include "moc_qsgsoftwarelayer_p.cpp"
\inmodule QtQuick
void renderScene() final
Renders the scene.
Combined button and popup list for selecting options.