Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quick/items/qquickgenericshadereffect.cpp |
Switch to Source code | Preprocessed file |
Line | Source | Count | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | - | |||||||||||||
2 | - | |||||||||||||
3 | - | |||||||||||||
4 | - | |||||||||||||
5 | - | |||||||||||||
6 | - | |||||||||||||
7 | - | |||||||||||||
8 | - | |||||||||||||
9 | - | |||||||||||||
10 | QQuickGenericShaderEffect::QQuickGenericShaderEffect(QQuickShaderEffect *item, QObject *parent) | - | ||||||||||||
11 | : QObject(parent) | - | ||||||||||||
12 | , m_item(item) | - | ||||||||||||
13 | , m_meshResolution(1, 1) | - | ||||||||||||
14 | , m_mesh(nullptr) | - | ||||||||||||
15 | , m_cullMode(QQuickShaderEffect::NoCulling) | - | ||||||||||||
16 | , m_blending(true) | - | ||||||||||||
17 | , m_supportsAtlasTextures(false) | - | ||||||||||||
18 | , m_mgr(nullptr) | - | ||||||||||||
19 | , m_fragNeedsUpdate(true) | - | ||||||||||||
20 | , m_vertNeedsUpdate(true) | - | ||||||||||||
21 | , m_dirty(nullptr) | - | ||||||||||||
22 | { | - | ||||||||||||
23 | qRegisterMetaType<QSGGuiThreadShaderEffectManager::ShaderInfo::Type>("ShaderInfo::Type"); | - | ||||||||||||
24 | for (int i = 0; i < NShader
| 0 | ||||||||||||
25 | m_inProgress[i] = nullptr; never executed: m_inProgress[i] = nullptr; | 0 | ||||||||||||
26 | } never executed: end of block | 0 | ||||||||||||
27 | - | |||||||||||||
28 | QQuickGenericShaderEffect::~QQuickGenericShaderEffect() | - | ||||||||||||
29 | { | - | ||||||||||||
30 | for (int i = 0; i < NShader
| 0 | ||||||||||||
31 | disconnectSignals(Shader(i)); | - | ||||||||||||
32 | for (const auto &sm : qAsConst(m_signalMappers[i])) | - | ||||||||||||
33 | delete sm.mapper; never executed: delete sm.mapper; | 0 | ||||||||||||
34 | } never executed: end of block | 0 | ||||||||||||
35 | - | |||||||||||||
36 | delete m_mgr; | - | ||||||||||||
37 | } never executed: end of block | 0 | ||||||||||||
38 | - | |||||||||||||
39 | void QQuickGenericShaderEffect::setFragmentShader(const QByteArray &src) | - | ||||||||||||
40 | { | - | ||||||||||||
41 | - | |||||||||||||
42 | - | |||||||||||||
43 | - | |||||||||||||
44 | - | |||||||||||||
45 | if (m_fragShader == src
| 0 | ||||||||||||
46 | return; never executed: return; | 0 | ||||||||||||
47 | - | |||||||||||||
48 | m_fragShader = src; | - | ||||||||||||
49 | - | |||||||||||||
50 | m_fragNeedsUpdate = true; | - | ||||||||||||
51 | if (m_item->isComponentComplete()
| 0 | ||||||||||||
52 | maybeUpdateShaders(); never executed: maybeUpdateShaders(); | 0 | ||||||||||||
53 | - | |||||||||||||
54 | m_item->fragmentShaderChanged(); | - | ||||||||||||
55 | } never executed: end of block | 0 | ||||||||||||
56 | - | |||||||||||||
57 | void QQuickGenericShaderEffect::setVertexShader(const QByteArray &src) | - | ||||||||||||
58 | { | - | ||||||||||||
59 | if (m_vertShader == src
| 0 | ||||||||||||
60 | return; never executed: return; | 0 | ||||||||||||
61 | - | |||||||||||||
62 | m_vertShader = src; | - | ||||||||||||
63 | - | |||||||||||||
64 | m_vertNeedsUpdate = true; | - | ||||||||||||
65 | if (m_item->isComponentComplete()
| 0 | ||||||||||||
66 | maybeUpdateShaders(); never executed: maybeUpdateShaders(); | 0 | ||||||||||||
67 | - | |||||||||||||
68 | m_item->vertexShaderChanged(); | - | ||||||||||||
69 | } never executed: end of block | 0 | ||||||||||||
70 | - | |||||||||||||
71 | void QQuickGenericShaderEffect::setBlending(bool enable) | - | ||||||||||||
72 | { | - | ||||||||||||
73 | if (m_blending == enable
| 0 | ||||||||||||
74 | return; never executed: return; | 0 | ||||||||||||
75 | - | |||||||||||||
76 | m_blending = enable; | - | ||||||||||||
77 | m_item->update(); | - | ||||||||||||
78 | m_item->blendingChanged(); | - | ||||||||||||
79 | } never executed: end of block | 0 | ||||||||||||
80 | - | |||||||||||||
81 | QVariant QQuickGenericShaderEffect::mesh() const | - | ||||||||||||
82 | { | - | ||||||||||||
83 | return never executed: m_mesh ? qVariantFromValue(static_cast<QObject *>(m_mesh))return m_mesh ? qVariantFromValue(static_cast<QObject *>(m_mesh)) : qVariantFromValue(m_meshResolution); never executed: return m_mesh ? qVariantFromValue(static_cast<QObject *>(m_mesh)) : qVariantFromValue(m_meshResolution); | 0 | ||||||||||||
84 | : qVariantFromValue(m_meshResolution); never executed: return m_mesh ? qVariantFromValue(static_cast<QObject *>(m_mesh)) : qVariantFromValue(m_meshResolution); | 0 | ||||||||||||
85 | } | - | ||||||||||||
86 | - | |||||||||||||
87 | void QQuickGenericShaderEffect::setMesh(const QVariant &mesh) | - | ||||||||||||
88 | { | - | ||||||||||||
89 | QQuickShaderEffectMesh *newMesh = qobject_cast<QQuickShaderEffectMesh *>(qvariant_cast<QObject *>(mesh)); | - | ||||||||||||
90 | if (newMesh
| 0 | ||||||||||||
91 | return; never executed: return; | 0 | ||||||||||||
92 | - | |||||||||||||
93 | if (m_mesh
| 0 | ||||||||||||
94 | disconnect(m_mesh, qFlagLocation("2""geometryChanged()" "\0" __FILE__ ":" "137"), this, nullptr); never executed: disconnect(m_mesh, qFlagLocation("2""geometryChanged()" "\0" __FILE__ ":" "137"), this, nullptr); | 0 | ||||||||||||
95 | - | |||||||||||||
96 | m_mesh = newMesh; | - | ||||||||||||
97 | - | |||||||||||||
98 | if (m_mesh
| 0 | ||||||||||||
99 | connect(m_mesh, qFlagLocation("2""geometryChanged()" "\0" __FILE__ ":" "142"), this, qFlagLocation("1""markGeometryDirtyAndUpdate()" "\0" __FILE__ ":" "142")); | - | ||||||||||||
100 | } never executed: else {end of block | 0 | ||||||||||||
101 | if (mesh.canConvert<QSize>()
| 0 | ||||||||||||
102 | m_meshResolution = mesh.toSize(); | - | ||||||||||||
103 | } never executed: else {end of block | 0 | ||||||||||||
104 | QList<QByteArray> res = mesh.toByteArray().split('x'); | - | ||||||||||||
105 | bool ok = res.size() == 2; | - | ||||||||||||
106 | if (ok
| 0 | ||||||||||||
107 | int w = res.at(0).toInt(&ok); | - | ||||||||||||
108 | if (ok
| 0 | ||||||||||||
109 | int h = res.at(1).toInt(&ok); | - | ||||||||||||
110 | if (ok
| 0 | ||||||||||||
111 | m_meshResolution = QSize(w, h); never executed: m_meshResolution = QSize(w, h); | 0 | ||||||||||||
112 | } never executed: end of block | 0 | ||||||||||||
113 | } never executed: end of block | 0 | ||||||||||||
114 | if (!ok
| 0 | ||||||||||||
115 | QMessageLogger(__FILE__, 158, __PRETTY_FUNCTION__).warning("ShaderEffect: mesh property must be a size or an object deriving from QQuickShaderEffectMesh"); never executed: QMessageLogger(__FILE__, 158, __PRETTY_FUNCTION__).warning("ShaderEffect: mesh property must be a size or an object deriving from QQuickShaderEffectMesh"); | 0 | ||||||||||||
116 | } never executed: end of block | 0 | ||||||||||||
117 | m_defaultMesh.setResolution(m_meshResolution); | - | ||||||||||||
118 | } never executed: end of block | 0 | ||||||||||||
119 | - | |||||||||||||
120 | m_dirty |= QSGShaderEffectNode::DirtyShaderMesh; | - | ||||||||||||
121 | m_item->update(); | - | ||||||||||||
122 | - | |||||||||||||
123 | m_item->meshChanged(); | - | ||||||||||||
124 | } never executed: end of block | 0 | ||||||||||||
125 | - | |||||||||||||
126 | void QQuickGenericShaderEffect::setCullMode(QQuickShaderEffect::CullMode face) | - | ||||||||||||
127 | { | - | ||||||||||||
128 | if (m_cullMode == face
| 0 | ||||||||||||
129 | return; never executed: return; | 0 | ||||||||||||
130 | - | |||||||||||||
131 | m_cullMode = face; | - | ||||||||||||
132 | m_item->update(); | - | ||||||||||||
133 | m_item->cullModeChanged(); | - | ||||||||||||
134 | } never executed: end of block | 0 | ||||||||||||
135 | - | |||||||||||||
136 | void QQuickGenericShaderEffect::setSupportsAtlasTextures(bool supports) | - | ||||||||||||
137 | { | - | ||||||||||||
138 | if (m_supportsAtlasTextures == supports
| 0 | ||||||||||||
139 | return; never executed: return; | 0 | ||||||||||||
140 | - | |||||||||||||
141 | m_supportsAtlasTextures = supports; | - | ||||||||||||
142 | markGeometryDirtyAndUpdate(); | - | ||||||||||||
143 | m_item->supportsAtlasTexturesChanged(); | - | ||||||||||||
144 | } never executed: end of block | 0 | ||||||||||||
145 | - | |||||||||||||
146 | QString QQuickGenericShaderEffect::parseLog() | - | ||||||||||||
147 | { | - | ||||||||||||
148 | maybeUpdateShaders(); | - | ||||||||||||
149 | return never executed: log();return log(); never executed: return log(); | 0 | ||||||||||||
150 | } | - | ||||||||||||
151 | - | |||||||||||||
152 | QString QQuickGenericShaderEffect::log() const | - | ||||||||||||
153 | { | - | ||||||||||||
154 | QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager(); | - | ||||||||||||
155 | if (!mgr
| 0 | ||||||||||||
156 | return never executed: QString();return QString(); never executed: return QString(); | 0 | ||||||||||||
157 | - | |||||||||||||
158 | return never executed: mgr->log();return mgr->log(); never executed: return mgr->log(); | 0 | ||||||||||||
159 | } | - | ||||||||||||
160 | - | |||||||||||||
161 | QQuickShaderEffect::Status QQuickGenericShaderEffect::status() const | - | ||||||||||||
162 | { | - | ||||||||||||
163 | QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager(); | - | ||||||||||||
164 | if (!mgr
| 0 | ||||||||||||
165 | return never executed: QQuickShaderEffect::Uncompiled;return QQuickShaderEffect::Uncompiled; never executed: return QQuickShaderEffect::Uncompiled; | 0 | ||||||||||||
166 | - | |||||||||||||
167 | return never executed: QQuickShaderEffect::Status(mgr->status());return QQuickShaderEffect::Status(mgr->status()); never executed: return QQuickShaderEffect::Status(mgr->status()); | 0 | ||||||||||||
168 | } | - | ||||||||||||
169 | - | |||||||||||||
170 | void QQuickGenericShaderEffect::handleEvent(QEvent *event) | - | ||||||||||||
171 | { | - | ||||||||||||
172 | if (event->type() == QEvent::DynamicPropertyChange
| 0-108 | ||||||||||||
173 | QDynamicPropertyChangeEvent *e = static_cast<QDynamicPropertyChangeEvent *>(event); | - | ||||||||||||
174 | for (int shaderType = 0; shaderType < NShader
| 0 | ||||||||||||
175 | const auto &vars(m_shaders[shaderType].shaderInfo.variables); | - | ||||||||||||
176 | for (int idx = 0; idx < vars.count()
| 0 | ||||||||||||
177 | if (vars[idx].name == e->propertyName()
| 0 | ||||||||||||
178 | propertyChanged((shaderType << 16) | idx); | - | ||||||||||||
179 | break; never executed: break; | 0 | ||||||||||||
180 | } | - | ||||||||||||
181 | } never executed: end of block | 0 | ||||||||||||
182 | } never executed: end of block | 0 | ||||||||||||
183 | } never executed: end of block | 0 | ||||||||||||
184 | } executed 108 times by 5 tests: end of block Executed by:
| 108 | ||||||||||||
185 | - | |||||||||||||
186 | void QQuickGenericShaderEffect::handleGeometryChanged(const QRectF &, const QRectF &) | - | ||||||||||||
187 | { | - | ||||||||||||
188 | m_dirty |= QSGShaderEffectNode::DirtyShaderGeometry; | - | ||||||||||||
189 | } never executed: end of block | 0 | ||||||||||||
190 | - | |||||||||||||
191 | QSGNode *QQuickGenericShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) | - | ||||||||||||
192 | { | - | ||||||||||||
193 | QSGShaderEffectNode *node = static_cast<QSGShaderEffectNode *>(oldNode); | - | ||||||||||||
194 | - | |||||||||||||
195 | if (m_item->width() <= 0
| 0 | ||||||||||||
196 | delete node; | - | ||||||||||||
197 | return never executed: nullptr;return nullptr; never executed: return nullptr; | 0 | ||||||||||||
198 | } | - | ||||||||||||
199 | - | |||||||||||||
200 | - | |||||||||||||
201 | if (m_inProgress[Vertex]
| 0 | ||||||||||||
202 | return never executed: node;return node; never executed: return node; | 0 | ||||||||||||
203 | - | |||||||||||||
204 | - | |||||||||||||
205 | QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager(); | - | ||||||||||||
206 | if (!mgr
| 0 | ||||||||||||
207 | delete node; | - | ||||||||||||
208 | return never executed: nullptr;return nullptr; never executed: return nullptr; | 0 | ||||||||||||
209 | } | - | ||||||||||||
210 | - | |||||||||||||
211 | if (!node
| 0 | ||||||||||||
212 | QSGRenderContext *rc = QQuickWindowPrivate::get(m_item->window())->context; | - | ||||||||||||
213 | node = rc->sceneGraphContext()->createShaderEffectNode(rc, mgr); | - | ||||||||||||
214 | m_dirty = QSGShaderEffectNode::DirtyShaderAll; | - | ||||||||||||
215 | } never executed: end of block | 0 | ||||||||||||
216 | - | |||||||||||||
217 | QSGShaderEffectNode::SyncData sd; | - | ||||||||||||
218 | sd.dirty = m_dirty; | - | ||||||||||||
219 | sd.cullMode = QSGShaderEffectNode::CullMode(m_cullMode); | - | ||||||||||||
220 | sd.blending = m_blending; | - | ||||||||||||
221 | sd.vertex.shader = &m_shaders[Vertex]; | - | ||||||||||||
222 | sd.vertex.dirtyConstants = &m_dirtyConstants[Vertex]; | - | ||||||||||||
223 | sd.vertex.dirtyTextures = &m_dirtyTextures[Vertex]; | - | ||||||||||||
224 | sd.fragment.shader = &m_shaders[Fragment]; | - | ||||||||||||
225 | sd.fragment.dirtyConstants = &m_dirtyConstants[Fragment]; | - | ||||||||||||
226 | sd.fragment.dirtyTextures = &m_dirtyTextures[Fragment]; | - | ||||||||||||
227 | node->syncMaterial(&sd); | - | ||||||||||||
228 | - | |||||||||||||
229 | if (m_dirty & QSGShaderEffectNode::DirtyShaderMesh
| 0 | ||||||||||||
230 | node->setGeometry(nullptr); | - | ||||||||||||
231 | m_dirty &= ~QSGShaderEffectNode::DirtyShaderMesh; | - | ||||||||||||
232 | m_dirty |= QSGShaderEffectNode::DirtyShaderGeometry; | - | ||||||||||||
233 | } never executed: end of block | 0 | ||||||||||||
234 | - | |||||||||||||
235 | if (m_dirty & QSGShaderEffectNode::DirtyShaderGeometry
| 0 | ||||||||||||
236 | const QRectF rect(0, 0, m_item->width(), m_item->height()); | - | ||||||||||||
237 | QQuickShaderEffectMesh *mesh = m_mesh
| 0 | ||||||||||||
238 | QSGGeometry *geometry = node->geometry(); | - | ||||||||||||
239 | - | |||||||||||||
240 | const QRectF srcRect = node->updateNormalizedTextureSubRect(m_supportsAtlasTextures); | - | ||||||||||||
241 | geometry = mesh->updateGeometry(geometry, 2, 0, srcRect, rect); | - | ||||||||||||
242 | - | |||||||||||||
243 | node->setFlag(QSGNode::OwnsGeometry, false); | - | ||||||||||||
244 | node->setGeometry(geometry); | - | ||||||||||||
245 | node->setFlag(QSGNode::OwnsGeometry, true); | - | ||||||||||||
246 | - | |||||||||||||
247 | m_dirty &= ~QSGShaderEffectNode::DirtyShaderGeometry; | - | ||||||||||||
248 | } never executed: end of block | 0 | ||||||||||||
249 | - | |||||||||||||
250 | m_dirty = nullptr; | - | ||||||||||||
251 | for (int i = 0; i < NShader
| 0 | ||||||||||||
252 | m_dirtyConstants[i].clear(); | - | ||||||||||||
253 | m_dirtyTextures[i].clear(); | - | ||||||||||||
254 | } never executed: end of block | 0 | ||||||||||||
255 | - | |||||||||||||
256 | return never executed: node;return node; never executed: return node; | 0 | ||||||||||||
257 | } | - | ||||||||||||
258 | - | |||||||||||||
259 | void QQuickGenericShaderEffect::maybeUpdateShaders() | - | ||||||||||||
260 | { | - | ||||||||||||
261 | if (m_vertNeedsUpdate
| 0 | ||||||||||||
262 | m_vertNeedsUpdate = !updateShader(Vertex, m_vertShader); never executed: m_vertNeedsUpdate = !updateShader(Vertex, m_vertShader); | 0 | ||||||||||||
263 | if (m_fragNeedsUpdate
| 0 | ||||||||||||
264 | m_fragNeedsUpdate = !updateShader(Fragment, m_fragShader); never executed: m_fragNeedsUpdate = !updateShader(Fragment, m_fragShader); | 0 | ||||||||||||
265 | if (m_vertNeedsUpdate
| 0 | ||||||||||||
266 | - | |||||||||||||
267 | - | |||||||||||||
268 | - | |||||||||||||
269 | - | |||||||||||||
270 | - | |||||||||||||
271 | - | |||||||||||||
272 | if (!m_item->window()
| 0 | ||||||||||||
273 | m_item->polish(); never executed: m_item->polish(); | 0 | ||||||||||||
274 | } never executed: end of block | 0 | ||||||||||||
275 | } never executed: end of block | 0 | ||||||||||||
276 | - | |||||||||||||
277 | void QQuickGenericShaderEffect::handleItemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) | - | ||||||||||||
278 | { | - | ||||||||||||
279 | - | |||||||||||||
280 | if (change == QQuickItem::ItemSceneChange
| 0 | ||||||||||||
281 | for (int shaderType = 0; shaderType < NShader
| 0 | ||||||||||||
282 | for (const auto &vd : qAsConst(m_shaders[shaderType].varData)) { | - | ||||||||||||
283 | if (vd.specialType == QSGShaderEffectNode::VariableData::Source
| 0 | ||||||||||||
284 | QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(vd.value)); | - | ||||||||||||
285 | if (source
| 0 | ||||||||||||
286 | if (value.window
| 0 | ||||||||||||
287 | QQuickItemPrivate::get(source)->refWindow(value.window); never executed: QQuickItemPrivate::get(source)->refWindow(value.window); | 0 | ||||||||||||
288 | else | - | ||||||||||||
289 | QQuickItemPrivate::get(source)->derefWindow(); never executed: QQuickItemPrivate::get(source)->derefWindow(); | 0 | ||||||||||||
290 | } | - | ||||||||||||
291 | } never executed: end of block | 0 | ||||||||||||
292 | } never executed: end of block | 0 | ||||||||||||
293 | } never executed: end of block | 0 | ||||||||||||
294 | } never executed: end of block | 0 | ||||||||||||
295 | } never executed: end of block | 0 | ||||||||||||
296 | - | |||||||||||||
297 | QSGGuiThreadShaderEffectManager *QQuickGenericShaderEffect::shaderEffectManager() const | - | ||||||||||||
298 | { | - | ||||||||||||
299 | if (!m_mgr
| 0 | ||||||||||||
300 | - | |||||||||||||
301 | if (QThread::currentThread() != m_item->thread()
| 0 | ||||||||||||
302 | return never executed: m_mgr;return m_mgr; never executed: return m_mgr; | 0 | ||||||||||||
303 | QQuickWindow *w = m_item->window(); | - | ||||||||||||
304 | if (w
| 0 | ||||||||||||
305 | m_mgr = QQuickWindowPrivate::get(w)->context->sceneGraphContext()->createGuiThreadShaderEffectManager(); | - | ||||||||||||
306 | if (m_mgr
| 0 | ||||||||||||
307 | connect(m_mgr, qFlagLocation("2""logAndStatusChanged()" "\0" __FILE__ ":" "350"), m_item, qFlagLocation("2""logChanged()" "\0" __FILE__ ":" "350")); | - | ||||||||||||
308 | connect(m_mgr, qFlagLocation("2""logAndStatusChanged()" "\0" __FILE__ ":" "351"), m_item, qFlagLocation("2""statusChanged()" "\0" __FILE__ ":" "351")); | - | ||||||||||||
309 | connect(m_mgr, qFlagLocation("2""textureChanged()" "\0" __FILE__ ":" "352"), this, qFlagLocation("1""markGeometryDirtyAndUpdateIfSupportsAtlas()" "\0" __FILE__ ":" "352")); | - | ||||||||||||
310 | connect(m_mgr, &QSGGuiThreadShaderEffectManager::shaderCodePrepared, this, &QQuickGenericShaderEffect::shaderCodePrepared); | - | ||||||||||||
311 | } never executed: end of block | 0 | ||||||||||||
312 | } never executed: end of block | 0 | ||||||||||||
313 | } never executed: end of block | 0 | ||||||||||||
314 | - | |||||||||||||
315 | return never executed: m_mgr;return m_mgr; never executed: return m_mgr; | 0 | ||||||||||||
316 | } | - | ||||||||||||
317 | - | |||||||||||||
318 | void QQuickGenericShaderEffect::disconnectSignals(Shader shaderType) | - | ||||||||||||
319 | { | - | ||||||||||||
320 | for (auto &sm : m_signalMappers[shaderType]) { | - | ||||||||||||
321 | if (sm.active
| 0 | ||||||||||||
322 | sm.active = false; | - | ||||||||||||
323 | QObject::disconnect(m_item, nullptr, sm.mapper, qFlagLocation("1""map()" "\0" __FILE__ ":" "366")); | - | ||||||||||||
324 | QObject::disconnect(sm.mapper, qFlagLocation("2""mapped(int)" "\0" __FILE__ ":" "367"), this, qFlagLocation("1""propertyChanged(int)" "\0" __FILE__ ":" "367")); | - | ||||||||||||
325 | } never executed: end of block | 0 | ||||||||||||
326 | } never executed: end of block | 0 | ||||||||||||
327 | for (const auto &vd : qAsConst(m_shaders[shaderType].varData)) { | - | ||||||||||||
328 | if (vd.specialType == QSGShaderEffectNode::VariableData::Source
| 0 | ||||||||||||
329 | QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(vd.value)); | - | ||||||||||||
330 | if (source
| 0 | ||||||||||||
331 | if (m_item->window()
| 0 | ||||||||||||
332 | QQuickItemPrivate::get(source)->derefWindow(); never executed: QQuickItemPrivate::get(source)->derefWindow(); | 0 | ||||||||||||
333 | QObject::disconnect(source, qFlagLocation("2""destroyed(QObject*)" "\0" __FILE__ ":" "376"), this, qFlagLocation("1""sourceDestroyed(QObject*)" "\0" __FILE__ ":" "376")); | - | ||||||||||||
334 | } never executed: end of block | 0 | ||||||||||||
335 | } never executed: end of block | 0 | ||||||||||||
336 | } never executed: end of block | 0 | ||||||||||||
337 | } never executed: end of block | 0 | ||||||||||||
338 | - | |||||||||||||
339 | struct ShaderInfoCache | - | ||||||||||||
340 | { | - | ||||||||||||
341 | bool contains(const QByteArray &key) const | - | ||||||||||||
342 | { | - | ||||||||||||
343 | return never executed: m_shaderInfoCache.contains(key);return m_shaderInfoCache.contains(key); never executed: return m_shaderInfoCache.contains(key); | 0 | ||||||||||||
344 | } | - | ||||||||||||
345 | - | |||||||||||||
346 | QSGGuiThreadShaderEffectManager::ShaderInfo value(const QByteArray &key) const | - | ||||||||||||
347 | { | - | ||||||||||||
348 | return never executed: m_shaderInfoCache.value(key);return m_shaderInfoCache.value(key); never executed: return m_shaderInfoCache.value(key); | 0 | ||||||||||||
349 | } | - | ||||||||||||
350 | - | |||||||||||||
351 | void insert(const QByteArray &key, const QSGGuiThreadShaderEffectManager::ShaderInfo &value) | - | ||||||||||||
352 | { | - | ||||||||||||
353 | m_shaderInfoCache.insert(key, value); | - | ||||||||||||
354 | } never executed: end of block | 0 | ||||||||||||
355 | - | |||||||||||||
356 | QHash<QByteArray, QSGGuiThreadShaderEffectManager::ShaderInfo> m_shaderInfoCache; | - | ||||||||||||
357 | }; | - | ||||||||||||
358 | - | |||||||||||||
359 | namespace { namespace Q_QGS_shaderInfoCache { typedef ShaderInfoCache Type; QBasicAtomicInt guard = { QtGlobalStatic::Uninitialized }; __attribute__((visibility("hidden"))) inline Type *innerFunction() { struct HolderBase { ~HolderBase() noexcept { if (guard.load() == QtGlobalStatic::Initialized
never executed: }guard.store(QtGlobalStatic::Destroyed); never executed: }; static struct Holder : public HolderBase { Type value; Holder() noexcept(noexcept(Type ())) : value () { guard.store(QtGlobalStatic::Initialized); } } holder; returnend of block never executed: &holder.value;return &holder.value; never executed: } } } static QGlobalStatic<ShaderInfoCache, Q_QGS_shaderInfoCache::innerFunction, Q_QGS_shaderInfoCache::guard> shaderInfoCache;return &holder.value; | 0 | ||||||||||||
360 | - | |||||||||||||
361 | bool QQuickGenericShaderEffect::updateShader(Shader shaderType, const QByteArray &src) | - | ||||||||||||
362 | { | - | ||||||||||||
363 | QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager(); | - | ||||||||||||
364 | if (!mgr
| 0 | ||||||||||||
365 | return never executed: false;return false; never executed: return false; | 0 | ||||||||||||
366 | - | |||||||||||||
367 | const bool texturesSeparate = mgr->hasSeparateSamplerAndTextureObjects(); | - | ||||||||||||
368 | - | |||||||||||||
369 | disconnectSignals(shaderType); | - | ||||||||||||
370 | - | |||||||||||||
371 | m_shaders[shaderType].shaderInfo = QSGGuiThreadShaderEffectManager::ShaderInfo(); | - | ||||||||||||
372 | m_shaders[shaderType].varData.clear(); | - | ||||||||||||
373 | - | |||||||||||||
374 | if (!src.isEmpty()
| 0 | ||||||||||||
375 | if (shaderInfoCache()->contains(src)
| 0 | ||||||||||||
376 | m_shaders[shaderType].shaderInfo = shaderInfoCache()->value(src); | - | ||||||||||||
377 | m_shaders[shaderType].hasShaderCode = true; | - | ||||||||||||
378 | } never executed: else {end of block | 0 | ||||||||||||
379 | - | |||||||||||||
380 | - | |||||||||||||
381 | - | |||||||||||||
382 | - | |||||||||||||
383 | m_inProgress[shaderType] = new QSGGuiThreadShaderEffectManager::ShaderInfo; | - | ||||||||||||
384 | const QSGGuiThreadShaderEffectManager::ShaderInfo::Type typeHint = | - | ||||||||||||
385 | shaderType == Vertex
| 0 | ||||||||||||
386 | : QSGGuiThreadShaderEffectManager::ShaderInfo::TypeFragment; | - | ||||||||||||
387 | - | |||||||||||||
388 | - | |||||||||||||
389 | - | |||||||||||||
390 | - | |||||||||||||
391 | mgr->prepareShaderCode(typeHint, src, m_inProgress[shaderType]); | - | ||||||||||||
392 | - | |||||||||||||
393 | return never executed: true;return true; never executed: return true; | 0 | ||||||||||||
394 | } | - | ||||||||||||
395 | } else { | - | ||||||||||||
396 | m_shaders[shaderType].hasShaderCode = false; | - | ||||||||||||
397 | if (shaderType == Fragment
| 0 | ||||||||||||
398 | - | |||||||||||||
399 | - | |||||||||||||
400 | - | |||||||||||||
401 | - | |||||||||||||
402 | - | |||||||||||||
403 | QSGGuiThreadShaderEffectManager::ShaderInfo::Variable v; | - | ||||||||||||
404 | v.name = ([]() -> QByteArray { enum { Size = sizeof("source") - 1 }; static const QStaticByteArrayData<Size> qbytearray_literal = { { { { -1 } }, Size, 0, 0, sizeof(QByteArrayData) }, "source" }; QByteArrayDataPtr holder = { qbytearray_literal.data_ptr() }; const QByteArray ba(holder); return never executed: ba;return ba; never executed: }());return ba; | 0 | ||||||||||||
405 | v.bindPoint = 0; | - | ||||||||||||
406 | v.type = texturesSeparate
| 0 | ||||||||||||
407 | : QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler; | - | ||||||||||||
408 | m_shaders[shaderType].shaderInfo.variables.append(v); | - | ||||||||||||
409 | } never executed: end of block | 0 | ||||||||||||
410 | } never executed: end of block | 0 | ||||||||||||
411 | - | |||||||||||||
412 | updateShaderVars(shaderType); | - | ||||||||||||
413 | m_dirty |= QSGShaderEffectNode::DirtyShaders; | - | ||||||||||||
414 | m_item->update(); | - | ||||||||||||
415 | return never executed: true;return true; never executed: return true; | 0 | ||||||||||||
416 | } | - | ||||||||||||
417 | - | |||||||||||||
418 | void QQuickGenericShaderEffect::shaderCodePrepared(bool ok, QSGGuiThreadShaderEffectManager::ShaderInfo::Type typeHint, | - | ||||||||||||
419 | const QByteArray &src, QSGGuiThreadShaderEffectManager::ShaderInfo *result) | - | ||||||||||||
420 | { | - | ||||||||||||
421 | const Shader shaderType = typeHint == QSGGuiThreadShaderEffectManager::ShaderInfo::TypeVertex
| 0 | ||||||||||||
422 | - | |||||||||||||
423 | - | |||||||||||||
424 | - | |||||||||||||
425 | if (result != m_inProgress[shaderType]
| 0 | ||||||||||||
426 | delete result; | - | ||||||||||||
427 | return; never executed: return; | 0 | ||||||||||||
428 | } | - | ||||||||||||
429 | - | |||||||||||||
430 | m_shaders[shaderType].shaderInfo = *result; | - | ||||||||||||
431 | delete result; | - | ||||||||||||
432 | m_inProgress[shaderType] = nullptr; | - | ||||||||||||
433 | - | |||||||||||||
434 | if (!ok
| 0 | ||||||||||||
435 | QMessageLogger(__FILE__, 478, __PRETTY_FUNCTION__).warning("ShaderEffect: shader preparation failed for %s\n%s\n", src.constData(), QtPrivate::asString(log()).toLocal8Bit().constData()); | - | ||||||||||||
436 | m_shaders[shaderType].hasShaderCode = false; | - | ||||||||||||
437 | return; never executed: return; | 0 | ||||||||||||
438 | } | - | ||||||||||||
439 | - | |||||||||||||
440 | m_shaders[shaderType].hasShaderCode = true; | - | ||||||||||||
441 | shaderInfoCache()->insert(src, m_shaders[shaderType].shaderInfo); | - | ||||||||||||
442 | updateShaderVars(shaderType); | - | ||||||||||||
443 | m_dirty |= QSGShaderEffectNode::DirtyShaders; | - | ||||||||||||
444 | m_item->update(); | - | ||||||||||||
445 | } never executed: end of block | 0 | ||||||||||||
446 | - | |||||||||||||
447 | void QQuickGenericShaderEffect::updateShaderVars(Shader shaderType) | - | ||||||||||||
448 | { | - | ||||||||||||
449 | QSGGuiThreadShaderEffectManager *mgr = shaderEffectManager(); | - | ||||||||||||
450 | if (!mgr
| 0 | ||||||||||||
451 | return; never executed: return; | 0 | ||||||||||||
452 | - | |||||||||||||
453 | const bool texturesSeparate = mgr->hasSeparateSamplerAndTextureObjects(); | - | ||||||||||||
454 | - | |||||||||||||
455 | const int varCount = m_shaders[shaderType].shaderInfo.variables.count(); | - | ||||||||||||
456 | m_shaders[shaderType].varData.resize(varCount); | - | ||||||||||||
457 | - | |||||||||||||
458 | - | |||||||||||||
459 | - | |||||||||||||
460 | if (m_signalMappers[shaderType].count() < varCount
| 0 | ||||||||||||
461 | m_signalMappers[shaderType].resize(varCount); never executed: m_signalMappers[shaderType].resize(varCount); | 0 | ||||||||||||
462 | - | |||||||||||||
463 | - | |||||||||||||
464 | - | |||||||||||||
465 | for (int i = 0; i < varCount
| 0 | ||||||||||||
466 | const auto &v(m_shaders[shaderType].shaderInfo.variables.at(i)); | - | ||||||||||||
467 | QSGShaderEffectNode::VariableData &vd(m_shaders[shaderType].varData[i]); | - | ||||||||||||
468 | const bool isSpecial = v.name.startsWith("qt_"); | - | ||||||||||||
469 | if (isSpecial
| 0 | ||||||||||||
470 | if (v.name == "qt_Opacity"
| 0 | ||||||||||||
471 | vd.specialType = QSGShaderEffectNode::VariableData::Opacity; never executed: vd.specialType = QSGShaderEffectNode::VariableData::Opacity; | 0 | ||||||||||||
472 | else if (v.name == "qt_Matrix"
| 0 | ||||||||||||
473 | vd.specialType = QSGShaderEffectNode::VariableData::Matrix; never executed: vd.specialType = QSGShaderEffectNode::VariableData::Matrix; | 0 | ||||||||||||
474 | else if (v.name.startsWith("qt_SubRect_")
| 0 | ||||||||||||
475 | vd.specialType = QSGShaderEffectNode::VariableData::SubRect; never executed: vd.specialType = QSGShaderEffectNode::VariableData::SubRect; | 0 | ||||||||||||
476 | continue; never executed: continue; | 0 | ||||||||||||
477 | } | - | ||||||||||||
478 | - | |||||||||||||
479 | - | |||||||||||||
480 | - | |||||||||||||
481 | - | |||||||||||||
482 | if (v.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler
| 0 | ||||||||||||
483 | if (texturesSeparate
| 0 | ||||||||||||
484 | vd.specialType = QSGShaderEffectNode::VariableData::Unused; | - | ||||||||||||
485 | continue; never executed: continue; | 0 | ||||||||||||
486 | } else { | - | ||||||||||||
487 | vd.specialType = QSGShaderEffectNode::VariableData::Source; | - | ||||||||||||
488 | } never executed: end of block | 0 | ||||||||||||
489 | } else if (v.type == QSGGuiThreadShaderEffectManager::ShaderInfo::Texture
| 0 | ||||||||||||
490 | ((texturesSeparate) ? static_cast<void>(0) : qt_assert("texturesSeparate", __FILE__, 533)); | - | ||||||||||||
491 | vd.specialType = QSGShaderEffectNode::VariableData::Source; | - | ||||||||||||
492 | } never executed: else {end of block | 0 | ||||||||||||
493 | vd.specialType = QSGShaderEffectNode::VariableData::None; | - | ||||||||||||
494 | } never executed: end of block | 0 | ||||||||||||
495 | - | |||||||||||||
496 | - | |||||||||||||
497 | const int propIdx = m_item->metaObject()->indexOfProperty(v.name.constData()); | - | ||||||||||||
498 | if (propIdx >= 0
| 0 | ||||||||||||
499 | QMetaProperty mp = m_item->metaObject()->property(propIdx); | - | ||||||||||||
500 | if (!mp.hasNotifySignal()
| 0 | ||||||||||||
501 | QMessageLogger(__FILE__, 544, __PRETTY_FUNCTION__).warning("ShaderEffect: property '%s' does not have notification method", v.name.constData()); never executed: QMessageLogger(__FILE__, 544, __PRETTY_FUNCTION__).warning("ShaderEffect: property '%s' does not have notification method", v.name.constData()); | 0 | ||||||||||||
502 | - | |||||||||||||
503 | - | |||||||||||||
504 | auto &sm(m_signalMappers[shaderType][i]); | - | ||||||||||||
505 | if (!sm.mapper
| 0 | ||||||||||||
506 | - | |||||||||||||
507 | #pragma GCC diagnostic push | - | ||||||||||||
508 | - | |||||||||||||
509 | - | |||||||||||||
510 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | - | ||||||||||||
511 | - | |||||||||||||
512 | sm.mapper = new QSignalMapper; | - | ||||||||||||
513 | - | |||||||||||||
514 | #pragma GCC diagnostic pop | - | ||||||||||||
515 | - | |||||||||||||
516 | sm.mapper->setMapping(m_item, i | (shaderType << 16)); | - | ||||||||||||
517 | } never executed: end of block | 0 | ||||||||||||
518 | sm.active = true; | - | ||||||||||||
519 | const QByteArray signalName = '2' + mp.notifySignal().methodSignature(); | - | ||||||||||||
520 | QObject::connect(m_item, signalName, sm.mapper, qFlagLocation("1""map()" "\0" __FILE__ ":" "557")); | - | ||||||||||||
521 | QObject::connect(sm.mapper, qFlagLocation("2""mapped(int)" "\0" __FILE__ ":" "558"), this, qFlagLocation("1""propertyChanged(int)" "\0" __FILE__ ":" "558")); | - | ||||||||||||
522 | } never executed: else {end of block | 0 | ||||||||||||
523 | - | |||||||||||||
524 | if (!m_item->property(v.name.constData()).isValid()
| 0 | ||||||||||||
525 | QMessageLogger(__FILE__, 562, __PRETTY_FUNCTION__).warning("ShaderEffect: '%s' does not have a matching property!", v.name.constData()); never executed: QMessageLogger(__FILE__, 562, __PRETTY_FUNCTION__).warning("ShaderEffect: '%s' does not have a matching property!", v.name.constData()); | 0 | ||||||||||||
526 | } never executed: end of block | 0 | ||||||||||||
527 | - | |||||||||||||
528 | vd.value = m_item->property(v.name.constData()); | - | ||||||||||||
529 | - | |||||||||||||
530 | if (vd.specialType == QSGShaderEffectNode::VariableData::Source
| 0 | ||||||||||||
531 | QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(vd.value)); | - | ||||||||||||
532 | if (source
| 0 | ||||||||||||
533 | if (m_item->window()
| 0 | ||||||||||||
534 | QQuickItemPrivate::get(source)->refWindow(m_item->window()); never executed: QQuickItemPrivate::get(source)->refWindow(m_item->window()); | 0 | ||||||||||||
535 | QObject::connect(source, qFlagLocation("2""destroyed(QObject*)" "\0" __FILE__ ":" "572"), this, qFlagLocation("1""sourceDestroyed(QObject*)" "\0" __FILE__ ":" "572")); | - | ||||||||||||
536 | } never executed: end of block | 0 | ||||||||||||
537 | } never executed: end of block | 0 | ||||||||||||
538 | } never executed: end of block | 0 | ||||||||||||
539 | } never executed: end of block | 0 | ||||||||||||
540 | - | |||||||||||||
541 | bool QQuickGenericShaderEffect::sourceIsUnique(QQuickItem *source, Shader typeToSkip, int indexToSkip) const | - | ||||||||||||
542 | { | - | ||||||||||||
543 | for (int shaderType = 0; shaderType < NShader
| 0 | ||||||||||||
544 | for (int idx = 0; idx < m_shaders[shaderType].varData.count()
| 0 | ||||||||||||
545 | if (shaderType != typeToSkip
| 0 | ||||||||||||
546 | const auto &vd(m_shaders[shaderType].varData[idx]); | - | ||||||||||||
547 | if (vd.specialType == QSGShaderEffectNode::VariableData::Source
| 0 | ||||||||||||
548 | return never executed: false;return false; never executed: return false; | 0 | ||||||||||||
549 | } never executed: end of block | 0 | ||||||||||||
550 | } never executed: end of block | 0 | ||||||||||||
551 | } never executed: end of block | 0 | ||||||||||||
552 | return never executed: true;return true; never executed: return true; | 0 | ||||||||||||
553 | } | - | ||||||||||||
554 | - | |||||||||||||
555 | void QQuickGenericShaderEffect::propertyChanged(int mappedId) | - | ||||||||||||
556 | { | - | ||||||||||||
557 | const Shader type = Shader(mappedId >> 16); | - | ||||||||||||
558 | const int idx = mappedId & 0xFFFF; | - | ||||||||||||
559 | const auto &v(m_shaders[type].shaderInfo.variables[idx]); | - | ||||||||||||
560 | auto &vd(m_shaders[type].varData[idx]); | - | ||||||||||||
561 | - | |||||||||||||
562 | if (vd.specialType == QSGShaderEffectNode::VariableData::Source
| 0 | ||||||||||||
563 | QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(vd.value)); | - | ||||||||||||
564 | if (source
| 0 | ||||||||||||
565 | if (m_item->window()
| 0 | ||||||||||||
566 | QQuickItemPrivate::get(source)->derefWindow(); never executed: QQuickItemPrivate::get(source)->derefWindow(); | 0 | ||||||||||||
567 | - | |||||||||||||
568 | - | |||||||||||||
569 | - | |||||||||||||
570 | - | |||||||||||||
571 | if (sourceIsUnique(source, type, idx)
| 0 | ||||||||||||
572 | QObject::disconnect(source, qFlagLocation("2""destroyed(QObject*)" "\0" __FILE__ ":" "609"), this, qFlagLocation("1""sourceDestroyed(QObject*)" "\0" __FILE__ ":" "609")); never executed: QObject::disconnect(source, qFlagLocation("2""destroyed(QObject*)" "\0" __FILE__ ":" "609"), this, qFlagLocation("1""sourceDestroyed(QObject*)" "\0" __FILE__ ":" "609")); | 0 | ||||||||||||
573 | } never executed: end of block | 0 | ||||||||||||
574 | - | |||||||||||||
575 | vd.value = m_item->property(v.name.constData()); | - | ||||||||||||
576 | - | |||||||||||||
577 | source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(vd.value)); | - | ||||||||||||
578 | if (source
| 0 | ||||||||||||
579 | - | |||||||||||||
580 | - | |||||||||||||
581 | - | |||||||||||||
582 | - | |||||||||||||
583 | if (m_item->window()
| 0 | ||||||||||||
584 | QQuickItemPrivate::get(source)->refWindow(m_item->window()); never executed: QQuickItemPrivate::get(source)->refWindow(m_item->window()); | 0 | ||||||||||||
585 | QObject::connect(source, qFlagLocation("2""destroyed(QObject*)" "\0" __FILE__ ":" "622"), this, qFlagLocation("1""sourceDestroyed(QObject*)" "\0" __FILE__ ":" "622")); | - | ||||||||||||
586 | } never executed: end of block | 0 | ||||||||||||
587 | - | |||||||||||||
588 | m_dirty |= QSGShaderEffectNode::DirtyShaderTexture; | - | ||||||||||||
589 | m_dirtyTextures[type].insert(idx); | - | ||||||||||||
590 | - | |||||||||||||
591 | } never executed: else {end of block | 0 | ||||||||||||
592 | vd.value = m_item->property(v.name.constData()); | - | ||||||||||||
593 | m_dirty |= QSGShaderEffectNode::DirtyShaderConstant; | - | ||||||||||||
594 | m_dirtyConstants[type].insert(idx); | - | ||||||||||||
595 | } never executed: end of block | 0 | ||||||||||||
596 | - | |||||||||||||
597 | m_item->update(); | - | ||||||||||||
598 | } never executed: end of block | 0 | ||||||||||||
599 | - | |||||||||||||
600 | void QQuickGenericShaderEffect::sourceDestroyed(QObject *object) | - | ||||||||||||
601 | { | - | ||||||||||||
602 | for (int shaderType = 0; shaderType < NShader
| 0 | ||||||||||||
603 | for (auto &vd : m_shaders[shaderType].varData) { | - | ||||||||||||
604 | if (vd.specialType == QSGShaderEffectNode::VariableData::Source
| 0 | ||||||||||||
605 | if (qvariant_cast<QObject *>(vd.value) == object
| 0 | ||||||||||||
606 | vd.value = QVariant(); never executed: vd.value = QVariant(); | 0 | ||||||||||||
607 | } never executed: end of block | 0 | ||||||||||||
608 | } never executed: end of block | 0 | ||||||||||||
609 | } never executed: end of block | 0 | ||||||||||||
610 | } never executed: end of block | 0 | ||||||||||||
611 | - | |||||||||||||
612 | void QQuickGenericShaderEffect::markGeometryDirtyAndUpdate() | - | ||||||||||||
613 | { | - | ||||||||||||
614 | m_dirty |= QSGShaderEffectNode::DirtyShaderGeometry; | - | ||||||||||||
615 | m_item->update(); | - | ||||||||||||
616 | } never executed: end of block | 0 | ||||||||||||
617 | - | |||||||||||||
618 | void QQuickGenericShaderEffect::markGeometryDirtyAndUpdateIfSupportsAtlas() | - | ||||||||||||
619 | { | - | ||||||||||||
620 | if (m_supportsAtlasTextures
| 0 | ||||||||||||
621 | markGeometryDirtyAndUpdate(); never executed: markGeometryDirtyAndUpdate(); | 0 | ||||||||||||
622 | } never executed: end of block | 0 | ||||||||||||
623 | - | |||||||||||||
624 | - | |||||||||||||
625 | - | |||||||||||||
Switch to Source code | Preprocessed file |