OpenCoverage

qquickcontext2dtexture.cpp

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/qtdeclarative/src/qtdeclarative/src/quick/items/context2d/qquickcontext2dtexture.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
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 "qquickcontext2dtexture_p.h"-
41#include "qquickcontext2dtile_p.h"-
42#include "qquickcanvasitem_p.h"-
43#include <private/qquickitem_p.h>-
44#include <QtQuick/private/qsgtexture_p.h>-
45#include "qquickcontext2dcommandbuffer_p.h"-
46#include <QOpenGLPaintDevice>-
47#if QT_CONFIG(opengl)-
48#include <QOpenGLFramebufferObject>-
49#include <QOpenGLFramebufferObjectFormat>-
50#include <QOpenGLFunctions>-
51#include <QtGui/private/qopenglextensions_p.h>-
52#endif-
53#include <QtCore/QThread>-
54#include <QtGui/QGuiApplication>-
55-
56QT_BEGIN_NAMESPACE-
57-
58Q_LOGGING_CATEGORY(lcCanvas, "qt.quick.canvas")
never executed: return category;
0
59-
60#if QT_CONFIG(opengl)-
61#define QT_MINIMUM_FBO_SIZE 64-
62-
63static inline int qt_next_power_of_two(int v)-
64{-
65 v--;-
66 v |= v >> 1;-
67 v |= v >> 2;-
68 v |= v >> 4;-
69 v |= v >> 8;-
70 v |= v >> 16;-
71 ++v;-
72 return v;
never executed: return v;
0
73}-
74-
75struct GLAcquireContext {-
76 GLAcquireContext(QOpenGLContext *c, QSurface *s):ctx(c) {-
77 if (ctx) {
ctxDescription
TRUEnever evaluated
FALSEnever evaluated
0
78 Q_ASSERT(s);-
79 if (!ctx->isValid())
!ctx->isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
80 ctx->create();
never executed: ctx->create();
0
81-
82 if (!ctx->isValid())
!ctx->isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
83 qWarning() << "Unable to create GL context";
never executed: QMessageLogger(__FILE__, 83, __PRETTY_FUNCTION__).warning() << "Unable to create GL context";
0
84 else if (!ctx->makeCurrent(s))
!ctx->makeCurrent(s)Description
TRUEnever evaluated
FALSEnever evaluated
0
85 qWarning() << "Can't make current GL context";
never executed: QMessageLogger(__FILE__, 85, __PRETTY_FUNCTION__).warning() << "Can't make current GL context";
0
86 }
never executed: end of block
0
87 }
never executed: end of block
0
88 ~GLAcquireContext() {-
89 if (ctx)
ctxDescription
TRUEnever evaluated
FALSEnever evaluated
0
90 ctx->doneCurrent();
never executed: ctx->doneCurrent();
0
91 }
never executed: end of block
0
92 QOpenGLContext *ctx;-
93};-
94#endif-
95QQuickContext2DTexture::QQuickContext2DTexture()-
96 : m_context(nullptr)-
97#if QT_CONFIG(opengl)-
98 , m_gl(nullptr)-
99#endif-
100 , m_surface(nullptr)-
101 , m_item(nullptr)-
102 , m_canvasDevicePixelRatio(1)-
103 , m_canvasWindowChanged(false)-
104 , m_dirtyTexture(false)-
105 , m_smooth(true)-
106 , m_antialiasing(false)-
107 , m_tiledCanvas(false)-
108 , m_painting(false)-
109{-
110}
never executed: end of block
0
111-
112QQuickContext2DTexture::~QQuickContext2DTexture()-
113{-
114 clearTiles();-
115}
never executed: end of block
0
116-
117void QQuickContext2DTexture::markDirtyTexture()-
118{-
119 if (m_onCustomThread)
m_onCustomThreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
120 m_mutex.lock();
never executed: m_mutex.lock();
0
121 m_dirtyTexture = true;-
122 emit textureChanged();-
123 if (m_onCustomThread)
m_onCustomThreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
124 m_mutex.unlock();
never executed: m_mutex.unlock();
0
125}
never executed: end of block
0
126-
127bool QQuickContext2DTexture::setCanvasSize(const QSize &size)-
128{-
129 if (m_canvasSize != size) {
m_canvasSize != sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
130 m_canvasSize = size;-
131 return true;
never executed: return true;
0
132 }-
133 return false;
never executed: return false;
0
134}-
135-
136bool QQuickContext2DTexture::setTileSize(const QSize &size)-
137{-
138 if (m_tileSize != size) {
m_tileSize != sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
139 m_tileSize = size;-
140 return true;
never executed: return true;
0
141 }-
142 return false;
never executed: return false;
0
143}-
144-
145void QQuickContext2DTexture::setSmooth(bool smooth)-
146{-
147 m_smooth = smooth;-
148}
never executed: end of block
0
149-
150void QQuickContext2DTexture::setAntialiasing(bool antialiasing)-
151{-
152 m_antialiasing = antialiasing;-
153}
never executed: end of block
0
154-
155void QQuickContext2DTexture::setItem(QQuickCanvasItem* item)-
156{-
157 m_item = item;-
158 if (m_item) {
m_itemDescription
TRUEnever evaluated
FALSEnever evaluated
0
159 m_context = (QQuickContext2D*) item->rawContext(); // FIXME-
160 m_state = m_context->state;-
161 } else {
never executed: end of block
0
162 m_context = nullptr;-
163 }
never executed: end of block
0
164}-
165-
166bool QQuickContext2DTexture::setCanvasWindow(const QRect& r)-
167{-
168 qreal canvasDevicePixelRatio = (m_item && m_item->window()) ?
m_itemDescription
TRUEnever evaluated
FALSEnever evaluated
m_item->window()Description
TRUEnever evaluated
FALSEnever evaluated
0
169 m_item->window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio();-
170 if (!qFuzzyCompare(m_canvasDevicePixelRatio, canvasDevicePixelRatio)) {
!qFuzzyCompare...icePixelRatio)Description
TRUEnever evaluated
FALSEnever evaluated
0
171 qCDebug(lcCanvas, "%s device pixel ratio %.1lf -> %.1lf",
never executed: QMessageLogger( __FILE__ , 173 , __PRETTY_FUNCTION__, lcCanvas().categoryName()).debug("%s device pixel ratio %.1lf -> %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : QtPrivate::asString(m_item->objectName()).toLocal8Bit().constData()), m_canvasDevicePixelRatio, canvasDevicePixelRatio) ;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
172 (m_item->objectName().isEmpty() ? "Canvas" : qPrintable(m_item->objectName())),
never executed: QMessageLogger( __FILE__ , 173 , __PRETTY_FUNCTION__, lcCanvas().categoryName()).debug("%s device pixel ratio %.1lf -> %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : QtPrivate::asString(m_item->objectName()).toLocal8Bit().constData()), m_canvasDevicePixelRatio, canvasDevicePixelRatio) ;
0
173 m_canvasDevicePixelRatio, canvasDevicePixelRatio);
never executed: QMessageLogger( __FILE__ , 173 , __PRETTY_FUNCTION__, lcCanvas().categoryName()).debug("%s device pixel ratio %.1lf -> %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : QtPrivate::asString(m_item->objectName()).toLocal8Bit().constData()), m_canvasDevicePixelRatio, canvasDevicePixelRatio) ;
0
174 m_canvasDevicePixelRatio = canvasDevicePixelRatio;-
175 m_canvasWindowChanged = true;-
176 }
never executed: end of block
0
177-
178 if (m_canvasWindow != r) {
m_canvasWindow != rDescription
TRUEnever evaluated
FALSEnever evaluated
0
179 m_canvasWindow = r;-
180 m_canvasWindowChanged = true;-
181 }
never executed: end of block
0
182-
183 return m_canvasWindowChanged;
never executed: return m_canvasWindowChanged;
0
184}-
185-
186bool QQuickContext2DTexture::setDirtyRect(const QRect &r)-
187{-
188 bool doDirty = false;-
189 if (m_tiledCanvas) {
m_tiledCanvasDescription
TRUEnever evaluated
FALSEnever evaluated
0
190 for (QQuickContext2DTile* t : qAsConst(m_tiles)) {-
191 bool dirty = t->rect().intersected(r).isValid();-
192 t->markDirty(dirty);-
193 if (dirty)
dirtyDescription
TRUEnever evaluated
FALSEnever evaluated
0
194 doDirty = true;
never executed: doDirty = true;
0
195 }
never executed: end of block
0
196 } else {
never executed: end of block
0
197 doDirty = m_canvasWindow.intersected(r).isValid();-
198 }
never executed: end of block
0
199 return doDirty;
never executed: return doDirty;
0
200}-
201-
202void QQuickContext2DTexture::canvasChanged(const QSize& canvasSize, const QSize& tileSize, const QRect& canvasWindow, const QRect& dirtyRect, bool smooth, bool antialiasing)-
203{-
204 QSize ts = tileSize;-
205 if (ts.width() > canvasSize.width())
ts.width() > c...asSize.width()Description
TRUEnever evaluated
FALSEnever evaluated
0
206 ts.setWidth(canvasSize.width());
never executed: ts.setWidth(canvasSize.width());
0
207-
208 if (ts.height() > canvasSize.height())
ts.height() > ...sSize.height()Description
TRUEnever evaluated
FALSEnever evaluated
0
209 ts.setHeight(canvasSize.height());
never executed: ts.setHeight(canvasSize.height());
0
210-
211 setCanvasSize(canvasSize);-
212 setTileSize(ts);-
213 setCanvasWindow(canvasWindow);-
214-
215 if (canvasSize == canvasWindow.size()) {
canvasSize == ...sWindow.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
216 m_tiledCanvas = false;-
217 } else {
never executed: end of block
0
218 m_tiledCanvas = true;-
219 }
never executed: end of block
0
220-
221 if (dirtyRect.isValid())
dirtyRect.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
222 setDirtyRect(dirtyRect);
never executed: setDirtyRect(dirtyRect);
0
223-
224 setSmooth(smooth);-
225 setAntialiasing(antialiasing);-
226}
never executed: end of block
0
227-
228void QQuickContext2DTexture::paintWithoutTiles(QQuickContext2DCommandBuffer *ccb)-
229{-
230 if (!ccb || ccb->isEmpty())
!ccbDescription
TRUEnever evaluated
FALSEnever evaluated
ccb->isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
231 return;
never executed: return;
0
232-
233 QPaintDevice* device = beginPainting();-
234 if (!device) {
!deviceDescription
TRUEnever evaluated
FALSEnever evaluated
0
235 endPainting();-
236 return;
never executed: return;
0
237 }-
238-
239 QPainter p;-
240 p.begin(device);-
241 if (m_antialiasing)
m_antialiasingDescription
TRUEnever evaluated
FALSEnever evaluated
0
242 p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, true);
never executed: p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, true);
0
243 else-
244 p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, false);
never executed: p.setRenderHints(QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing, false);
0
245-
246 if (m_smooth)
m_smoothDescription
TRUEnever evaluated
FALSEnever evaluated
0
247 p.setRenderHint(QPainter::SmoothPixmapTransform, true);
never executed: p.setRenderHint(QPainter::SmoothPixmapTransform, true);
0
248 else-
249 p.setRenderHint(QPainter::SmoothPixmapTransform, false);
never executed: p.setRenderHint(QPainter::SmoothPixmapTransform, false);
0
250-
251 p.setCompositionMode(QPainter::CompositionMode_SourceOver);-
252-
253 ccb->replay(&p, m_state, scaleFactor());-
254 endPainting();-
255 markDirtyTexture();-
256}
never executed: end of block
0
257-
258bool QQuickContext2DTexture::canvasDestroyed()-
259{-
260 return m_item == nullptr;
never executed: return m_item == nullptr;
0
261}-
262-
263void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb)-
264{-
265 QQuickContext2D::mutex.lock();-
266 if (canvasDestroyed()) {
canvasDestroyed()Description
TRUEnever evaluated
FALSEnever evaluated
0
267 delete ccb;-
268 QQuickContext2D::mutex.unlock();-
269 return;
never executed: return;
0
270 }-
271 QQuickContext2D::mutex.unlock();-
272#if QT_CONFIG(opengl)-
273 GLAcquireContext currentContext(m_gl, m_surface);-
274#endif-
275 if (!m_tiledCanvas) {
!m_tiledCanvasDescription
TRUEnever evaluated
FALSEnever evaluated
0
276 paintWithoutTiles(ccb);-
277 delete ccb;-
278 return;
never executed: return;
0
279 }-
280-
281 QRect tiledRegion = createTiles(m_canvasWindow.intersected(QRect(QPoint(0, 0), m_canvasSize)));-
282 if (!tiledRegion.isEmpty()) {
!tiledRegion.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
283 QRect dirtyRect;-
284 for (QQuickContext2DTile* tile : qAsConst(m_tiles)) {-
285 if (tile->dirty()) {
tile->dirty()Description
TRUEnever evaluated
FALSEnever evaluated
0
286 if (dirtyRect.isEmpty())
dirtyRect.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
287 dirtyRect = tile->rect();
never executed: dirtyRect = tile->rect();
0
288 else-
289 dirtyRect |= tile->rect();
never executed: dirtyRect |= tile->rect();
0
290 }-
291 }
never executed: end of block
0
292-
293 if (beginPainting()) {
beginPainting()Description
TRUEnever evaluated
FALSEnever evaluated
0
294 QQuickContext2D::State oldState = m_state;-
295 for (QQuickContext2DTile* tile : qAsConst(m_tiles)) {-
296 if (tile->dirty()) {
tile->dirty()Description
TRUEnever evaluated
FALSEnever evaluated
0
297 ccb->replay(tile->createPainter(m_smooth, m_antialiasing), oldState, scaleFactor());-
298 tile->drawFinished();-
299 tile->markDirty(false);-
300 }
never executed: end of block
0
301 compositeTile(tile);-
302 }
never executed: end of block
0
303 endPainting();-
304 m_state = oldState;-
305 markDirtyTexture();-
306 }
never executed: end of block
0
307 }
never executed: end of block
0
308 delete ccb;-
309}
never executed: end of block
0
310-
311QRect QQuickContext2DTexture::tiledRect(const QRectF& window, const QSize& tileSize)-
312{-
313 if (window.isEmpty())
window.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
314 return QRect();
never executed: return QRect();
0
315-
316 const int tw = tileSize.width();-
317 const int th = tileSize.height();-
318 const int h1 = window.left() / tw;-
319 const int v1 = window.top() / th;-
320-
321 const int htiles = ((window.right() - h1 * tw) + tw - 1)/tw;-
322 const int vtiles = ((window.bottom() - v1 * th) + th - 1)/th;-
323-
324 return QRect(h1 * tw, v1 * th, htiles * tw, vtiles * th);
never executed: return QRect(h1 * tw, v1 * th, htiles * tw, vtiles * th);
0
325}-
326-
327QRect QQuickContext2DTexture::createTiles(const QRect& window)-
328{-
329 QList<QQuickContext2DTile*> oldTiles = m_tiles;-
330 m_tiles.clear();-
331-
332 if (window.isEmpty()) {
window.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
333 return QRect();
never executed: return QRect();
0
334 }-
335-
336 QRect r = tiledRect(window, adjustedTileSize(m_tileSize));-
337-
338 const int tw = m_tileSize.width();-
339 const int th = m_tileSize.height();-
340 const int h1 = window.left() / tw;-
341 const int v1 = window.top() / th;-
342-
343-
344 const int htiles = r.width() / tw;-
345 const int vtiles = r.height() / th;-
346-
347 for (int yy = 0; yy < vtiles; ++yy) {
yy < vtilesDescription
TRUEnever evaluated
FALSEnever evaluated
0
348 for (int xx = 0; xx < htiles; ++xx) {
xx < htilesDescription
TRUEnever evaluated
FALSEnever evaluated
0
349 int ht = xx + h1;-
350 int vt = yy + v1;-
351-
352 QQuickContext2DTile* tile = nullptr;-
353-
354 QPoint pos(ht * tw, vt * th);-
355 QRect rect(pos, m_tileSize);-
356-
357 for (int i = 0; i < oldTiles.size(); i++) {
i < oldTiles.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
358 if (oldTiles[i]->rect() == rect) {
oldTiles[i]->rect() == rectDescription
TRUEnever evaluated
FALSEnever evaluated
0
359 tile = oldTiles.takeAt(i);-
360 break;
never executed: break;
0
361 }-
362 }
never executed: end of block
0
363-
364 if (!tile)
!tileDescription
TRUEnever evaluated
FALSEnever evaluated
0
365 tile = createTile();
never executed: tile = createTile();
0
366-
367 tile->setRect(rect);-
368 m_tiles.append(tile);-
369 }
never executed: end of block
0
370 }
never executed: end of block
0
371-
372 qDeleteAll(oldTiles);-
373-
374 return r;
never executed: return r;
0
375}-
376-
377void QQuickContext2DTexture::clearTiles()-
378{-
379 qDeleteAll(m_tiles);-
380 m_tiles.clear();-
381}
never executed: end of block
0
382-
383QSize QQuickContext2DTexture::adjustedTileSize(const QSize &ts)-
384{-
385 return ts;
never executed: return ts;
0
386}-
387-
388bool QQuickContext2DTexture::event(QEvent *e)-
389{-
390 if ((int) e->type() == QEvent::User + 1) {
(int) e->type(...vent::User + 1Description
TRUEnever evaluated
FALSEnever evaluated
0
391 PaintEvent *pe = static_cast<PaintEvent *>(e);-
392 paint(pe->buffer);-
393 return true;
never executed: return true;
0
394 } else if ((int) e->type() == QEvent::User + 2) {
(int) e->type(...vent::User + 2Description
TRUEnever evaluated
FALSEnever evaluated
0
395 CanvasChangeEvent *ce = static_cast<CanvasChangeEvent *>(e);-
396 canvasChanged(ce->canvasSize, ce->tileSize, ce->canvasWindow, ce->dirtyRect, ce->smooth, ce->antialiasing);-
397 return true;
never executed: return true;
0
398 }-
399 return QObject::event(e);
never executed: return QObject::event(e);
0
400}-
401#if QT_CONFIG(opengl)-
402static inline QSize npotAdjustedSize(const QSize &size)-
403{-
404 static bool checked = false;-
405 static bool npotSupported = false;-
406-
407 if (!checked) {
!checkedDescription
TRUEnever evaluated
FALSEnever evaluated
0
408 npotSupported = QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures);-
409 checked = true;-
410 }
never executed: end of block
0
411-
412 if (npotSupported) {
npotSupportedDescription
TRUEnever evaluated
FALSEnever evaluated
0
413 return QSize(qMax(QT_MINIMUM_FBO_SIZE, size.width()),
never executed: return QSize(qMax(64, size.width()), qMax(64, size.height()));
0
414 qMax(QT_MINIMUM_FBO_SIZE, size.height()));
never executed: return QSize(qMax(64, size.width()), qMax(64, size.height()));
0
415 }-
416-
417 return QSize(qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.width())),
never executed: return QSize(qMax(64, qt_next_power_of_two(size.width())), qMax(64, qt_next_power_of_two(size.height())));
0
418 qMax(QT_MINIMUM_FBO_SIZE, qt_next_power_of_two(size.height())));
never executed: return QSize(qMax(64, qt_next_power_of_two(size.width())), qMax(64, qt_next_power_of_two(size.height())));
0
419}-
420-
421QQuickContext2DFBOTexture::QQuickContext2DFBOTexture()-
422 : QQuickContext2DTexture()-
423 , m_fbo(nullptr)-
424 , m_multisampledFbo(nullptr)-
425 , m_paint_device(nullptr)-
426{-
427 m_displayTextures[0] = 0;-
428 m_displayTextures[1] = 0;-
429 m_displayTexture = -1;-
430}
never executed: end of block
0
431-
432QQuickContext2DFBOTexture::~QQuickContext2DFBOTexture()-
433{-
434 if (m_multisampledFbo)
m_multisampledFboDescription
TRUEnever evaluated
FALSEnever evaluated
0
435 m_multisampledFbo->release();
never executed: m_multisampledFbo->release();
0
436 else if (m_fbo)
m_fboDescription
TRUEnever evaluated
FALSEnever evaluated
0
437 m_fbo->release();
never executed: m_fbo->release();
0
438-
439 delete m_fbo;-
440 delete m_multisampledFbo;-
441 delete m_paint_device;-
442-
443 if (QOpenGLContext::currentContext())
QOpenGLContext...rrentContext()Description
TRUEnever evaluated
FALSEnever evaluated
0
444 QOpenGLContext::currentContext()->functions()->glDeleteTextures(2, m_displayTextures);
never executed: QOpenGLContext::currentContext()->functions()->glDeleteTextures(2, m_displayTextures);
0
445}
never executed: end of block
0
446-
447QVector2D QQuickContext2DFBOTexture::scaleFactor() const-
448{-
449 if (!m_fbo)
!m_fboDescription
TRUEnever evaluated
FALSEnever evaluated
0
450 return QVector2D(1, 1);
never executed: return QVector2D(1, 1);
0
451 return QVector2D(m_fbo->width() / m_fboSize.width(),
never executed: return QVector2D(m_fbo->width() / m_fboSize.width(), m_fbo->height() / m_fboSize.height());
0
452 m_fbo->height() / m_fboSize.height());
never executed: return QVector2D(m_fbo->width() / m_fboSize.width(), m_fbo->height() / m_fboSize.height());
0
453}-
454-
455QSGTexture *QQuickContext2DFBOTexture::textureForNextFrame(QSGTexture *lastTexture, QQuickWindow *)-
456{-
457 QSGPlainTexture *texture = static_cast<QSGPlainTexture *>(lastTexture);-
458-
459 if (m_onCustomThread)
m_onCustomThreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
460 m_mutex.lock();
never executed: m_mutex.lock();
0
461-
462 if (m_fbo) {
m_fboDescription
TRUEnever evaluated
FALSEnever evaluated
0
463 if (!texture) {
!textureDescription
TRUEnever evaluated
FALSEnever evaluated
0
464 texture = new QSGPlainTexture();-
465 texture->setHasAlphaChannel(true);-
466 texture->setOwnsTexture(false);-
467 m_dirtyTexture = true;-
468 }
never executed: end of block
0
469-
470 if (m_dirtyTexture) {
m_dirtyTextureDescription
TRUEnever evaluated
FALSEnever evaluated
0
471 if (!m_gl) {
!m_glDescription
TRUEnever evaluated
FALSEnever evaluated
0
472 // on a rendering thread, use the fbo directly...-
473 texture->setTextureId(m_fbo->texture());-
474 } else {
never executed: end of block
0
475 // on GUI or custom thread, use display textures...-
476 m_displayTexture = m_displayTexture == 0 ? 1 : 0;
m_displayTexture == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
477 texture->setTextureId(m_displayTextures[m_displayTexture]);-
478 }
never executed: end of block
0
479 texture->setTextureSize(m_fbo->size());-
480 m_dirtyTexture = false;-
481 }
never executed: end of block
0
482-
483 }
never executed: end of block
0
484-
485 if (m_onCustomThread) {
m_onCustomThreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
486 m_condition.wakeOne();-
487 m_mutex.unlock();-
488 }
never executed: end of block
0
489-
490 return texture;
never executed: return texture;
0
491}-
492-
493QSize QQuickContext2DFBOTexture::adjustedTileSize(const QSize &ts)-
494{-
495 return npotAdjustedSize(ts);
never executed: return npotAdjustedSize(ts);
0
496}-
497-
498QRectF QQuickContext2DFBOTexture::normalizedTextureSubRect() const-
499{-
500 return QRectF(0
never executed: return QRectF(0 , 0 , qreal(m_canvasWindow.width()) / m_fboSize.width() , qreal(m_canvasWindow.height()) / m_fboSize.height());
0
501 , 0
never executed: return QRectF(0 , 0 , qreal(m_canvasWindow.width()) / m_fboSize.width() , qreal(m_canvasWindow.height()) / m_fboSize.height());
0
502 , qreal(m_canvasWindow.width()) / m_fboSize.width()
never executed: return QRectF(0 , 0 , qreal(m_canvasWindow.width()) / m_fboSize.width() , qreal(m_canvasWindow.height()) / m_fboSize.height());
0
503 , qreal(m_canvasWindow.height()) / m_fboSize.height());
never executed: return QRectF(0 , 0 , qreal(m_canvasWindow.width()) / m_fboSize.width() , qreal(m_canvasWindow.height()) / m_fboSize.height());
0
504}-
505-
506QQuickContext2DTile* QQuickContext2DFBOTexture::createTile() const-
507{-
508 return new QQuickContext2DFBOTile();
never executed: return new QQuickContext2DFBOTile();
0
509}-
510-
511bool QQuickContext2DFBOTexture::doMultisampling() const-
512{-
513 static bool extensionsChecked = false;-
514 static bool multisamplingSupported = false;-
515-
516 if (!extensionsChecked) {
!extensionsCheckedDescription
TRUEnever evaluated
FALSEnever evaluated
0
517 QOpenGLExtensions *e = static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions());-
518 multisamplingSupported = e->hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)
e->hasOpenGLEx...erMultisample)Description
TRUEnever evaluated
FALSEnever evaluated
0
519 && e->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);
e->hasOpenGLEx...amebufferBlit)Description
TRUEnever evaluated
FALSEnever evaluated
0
520 extensionsChecked = true;-
521 }
never executed: end of block
0
522-
523 return multisamplingSupported && m_antialiasing;
never executed: return multisamplingSupported && m_antialiasing;
0
524}-
525-
526void QQuickContext2DFBOTexture::grabImage(const QRectF& rf)-
527{-
528 Q_ASSERT(rf.isValid());-
529 QQuickContext2D::mutex.lock();-
530 if (m_context) {
m_contextDescription
TRUEnever evaluated
FALSEnever evaluated
0
531 if (!m_fbo) {
!m_fboDescription
TRUEnever evaluated
FALSEnever evaluated
0
532 m_context->setGrabbedImage(QImage());-
533 } else {
never executed: end of block
0
534 QImage grabbed;-
535 GLAcquireContext ctx(m_gl, m_surface);-
536 grabbed = m_fbo->toImage().scaled(m_fboSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).mirrored().copy(rf.toRect());-
537 m_context->setGrabbedImage(grabbed);-
538 }
never executed: end of block
0
539 }-
540 QQuickContext2D::mutex.unlock();-
541}
never executed: end of block
0
542-
543void QQuickContext2DFBOTexture::compositeTile(QQuickContext2DTile* tile)-
544{-
545 QQuickContext2DFBOTile* t = static_cast<QQuickContext2DFBOTile*>(tile);-
546 QRect target = t->rect().intersected(m_canvasWindow);-
547 if (target.isValid()) {
target.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
548 QRect source = target;-
549-
550 source.moveTo(source.topLeft() - t->rect().topLeft());-
551 target.moveTo(target.topLeft() - m_canvasWindow.topLeft());-
552-
553 QOpenGLFramebufferObject::blitFramebuffer(m_fbo, target, t->fbo(), source);-
554 }
never executed: end of block
0
555}
never executed: end of block
0
556-
557QQuickCanvasItem::RenderTarget QQuickContext2DFBOTexture::renderTarget() const-
558{-
559 return QQuickCanvasItem::FramebufferObject;
never executed: return QQuickCanvasItem::FramebufferObject;
0
560}-
561-
562QPaintDevice* QQuickContext2DFBOTexture::beginPainting()-
563{-
564 QQuickContext2DTexture::beginPainting();-
565-
566 if (m_canvasWindow.size().isEmpty()) {
m_canvasWindow...ze().isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
567 delete m_fbo;-
568 delete m_multisampledFbo;-
569 delete m_paint_device;-
570 m_fbo = nullptr;-
571 m_multisampledFbo = nullptr;-
572 m_paint_device = nullptr;-
573 return nullptr;
never executed: return nullptr;
0
574 } else if (!m_fbo || m_canvasWindowChanged) {
!m_fboDescription
TRUEnever evaluated
FALSEnever evaluated
m_canvasWindowChangedDescription
TRUEnever evaluated
FALSEnever evaluated
0
575 delete m_fbo;-
576 delete m_multisampledFbo;-
577 delete m_paint_device;-
578 m_paint_device = nullptr;-
579-
580 m_fboSize = npotAdjustedSize(m_canvasWindow.size() * m_canvasDevicePixelRatio);-
581 m_canvasWindowChanged = false;-
582-
583 if (doMultisampling()) {
doMultisampling()Description
TRUEnever evaluated
FALSEnever evaluated
0
584 {-
585 QOpenGLFramebufferObjectFormat format;-
586 format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);-
587 format.setSamples(8);-
588 m_multisampledFbo = new QOpenGLFramebufferObject(m_fboSize, format);-
589 }-
590 {-
591 QOpenGLFramebufferObjectFormat format;-
592 format.setAttachment(QOpenGLFramebufferObject::NoAttachment);-
593 m_fbo = new QOpenGLFramebufferObject(m_fboSize, format);-
594 }-
595 } else {
never executed: end of block
0
596 QOpenGLFramebufferObjectFormat format;-
597 format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);-
598 QSize s = m_fboSize;-
599 if (m_antialiasing) { // do supersampling since multisampling is not available
m_antialiasingDescription
TRUEnever evaluated
FALSEnever evaluated
0
600 GLint max;-
601 QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);-
602 if (s.width() * 2 <= max && s.height() * 2 <= max)
s.width() * 2 <= maxDescription
TRUEnever evaluated
FALSEnever evaluated
s.height() * 2 <= maxDescription
TRUEnever evaluated
FALSEnever evaluated
0
603 s = s * 2;
never executed: s = s * 2;
0
604 }
never executed: end of block
0
605 m_fbo = new QOpenGLFramebufferObject(s, format);-
606 }
never executed: end of block
0
607 }-
608-
609 if (doMultisampling())
doMultisampling()Description
TRUEnever evaluated
FALSEnever evaluated
0
610 m_multisampledFbo->bind();
never executed: m_multisampledFbo->bind();
0
611 else-
612 m_fbo->bind();
never executed: m_fbo->bind();
0
613-
614 if (!m_paint_device) {
!m_paint_deviceDescription
TRUEnever evaluated
FALSEnever evaluated
0
615 QOpenGLPaintDevice *gl_device = new QOpenGLPaintDevice(m_fbo->size());-
616 gl_device->setPaintFlipped(true);-
617 gl_device->setSize(m_fbo->size());-
618 gl_device->setDevicePixelRatio(m_canvasDevicePixelRatio);-
619 qCDebug(lcCanvas, "%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf",
never executed: QMessageLogger( __FILE__ , 621 , __PRETTY_FUNCTION__, lcCanvas().categoryName()).debug("%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : QtPrivate::asString(m_item->objectName()).toLocal8Bit().constData()), m_item->width(), m_item->height(), m_fbo->size().width(), m_fbo->size().height(), m_canvasDevicePixelRatio) ;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
620 (m_item->objectName().isEmpty() ? "Canvas" : qPrintable(m_item->objectName())),
never executed: QMessageLogger( __FILE__ , 621 , __PRETTY_FUNCTION__, lcCanvas().categoryName()).debug("%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : QtPrivate::asString(m_item->objectName()).toLocal8Bit().constData()), m_item->width(), m_item->height(), m_fbo->size().width(), m_fbo->size().height(), m_canvasDevicePixelRatio) ;
0
621 m_item->width(), m_item->height(), m_fbo->size().width(), m_fbo->size().height(), m_canvasDevicePixelRatio);
never executed: QMessageLogger( __FILE__ , 621 , __PRETTY_FUNCTION__, lcCanvas().categoryName()).debug("%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : QtPrivate::asString(m_item->objectName()).toLocal8Bit().constData()), m_item->width(), m_item->height(), m_fbo->size().width(), m_fbo->size().height(), m_canvasDevicePixelRatio) ;
0
622 m_paint_device = gl_device;-
623 }
never executed: end of block
0
624-
625 return m_paint_device;
never executed: return m_paint_device;
0
626}-
627-
628void QQuickContext2DFBOTexture::endPainting()-
629{-
630 QQuickContext2DTexture::endPainting();-
631-
632 // There may not be an FBO due to zero width or height.-
633 if (!m_fbo)
!m_fboDescription
TRUEnever evaluated
FALSEnever evaluated
0
634 return;
never executed: return;
0
635-
636 if (m_multisampledFbo)
m_multisampledFboDescription
TRUEnever evaluated
FALSEnever evaluated
0
637 QOpenGLFramebufferObject::blitFramebuffer(m_fbo, m_multisampledFbo);
never executed: QOpenGLFramebufferObject::blitFramebuffer(m_fbo, m_multisampledFbo);
0
638-
639 if (m_gl) {
m_glDescription
TRUEnever evaluated
FALSEnever evaluated
0
640 /* When rendering happens on the render thread, the fbo's texture is-
641 * used directly for display. If we are on the GUI thread or a-
642 * dedicated Canvas render thread, we need to decouple the FBO from-
643 * the texture we are displaying in the SG rendering thread to avoid-
644 * stalls and read/write issues in the GL pipeline as the FBO's texture-
645 * could then potentially be used in different threads.-
646 *-
647 * We could have gotten away with only one display texture, but this-
648 * would have implied that beginPainting would have to wait for SG-
649 * to release that texture.-
650 */-
651-
652 if (m_onCustomThread)
m_onCustomThreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
653 m_mutex.lock();
never executed: m_mutex.lock();
0
654-
655 QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();-
656 if (m_displayTextures[0] == 0) {
m_displayTextures[0] == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
657 m_displayTexture = 1;-
658 funcs->glGenTextures(2, m_displayTextures);-
659 }
never executed: end of block
0
660-
661 m_fbo->bind();-
662 GLuint target = m_displayTexture == 0 ? 1 : 0;
m_displayTexture == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
663 funcs->glBindTexture(GL_TEXTURE_2D, m_displayTextures[target]);-
664 funcs->glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, m_fbo->width(), m_fbo->height(), 0);-
665-
666 if (m_onCustomThread)
m_onCustomThreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
667 m_mutex.unlock();
never executed: m_mutex.unlock();
0
668 }
never executed: end of block
0
669-
670 m_fbo->bindDefault();-
671}
never executed: end of block
0
672#endif-
673-
674QQuickContext2DImageTexture::QQuickContext2DImageTexture()-
675 : QQuickContext2DTexture()-
676{-
677}
never executed: end of block
0
678-
679QQuickContext2DImageTexture::~QQuickContext2DImageTexture()-
680{-
681}-
682-
683QQuickCanvasItem::RenderTarget QQuickContext2DImageTexture::renderTarget() const-
684{-
685 return QQuickCanvasItem::Image;
never executed: return QQuickCanvasItem::Image;
0
686}-
687-
688QQuickContext2DTile* QQuickContext2DImageTexture::createTile() const-
689{-
690 return new QQuickContext2DImageTile();
never executed: return new QQuickContext2DImageTile();
0
691}-
692-
693void QQuickContext2DImageTexture::grabImage(const QRectF& rf)-
694{-
695 Q_ASSERT(rf.isValid());-
696 QQuickContext2D::mutex.lock();-
697 if (m_context) {
m_contextDescription
TRUEnever evaluated
FALSEnever evaluated
0
698 QImage grabbed = m_displayImage.copy(rf.toRect());-
699 m_context->setGrabbedImage(grabbed);-
700 }
never executed: end of block
0
701 QQuickContext2D::mutex.unlock();-
702}
never executed: end of block
0
703-
704QSGTexture *QQuickContext2DImageTexture::textureForNextFrame(QSGTexture *last, QQuickWindow *window)-
705{-
706 if (m_onCustomThread)
m_onCustomThreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
707 m_mutex.lock();
never executed: m_mutex.lock();
0
708-
709 delete last;-
710-
711 QSGTexture *texture = window->createTextureFromImage(m_displayImage, QQuickWindow::TextureCanUseAtlas);-
712 m_dirtyTexture = false;-
713-
714 if (m_onCustomThread)
m_onCustomThreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
715 m_mutex.unlock();
never executed: m_mutex.unlock();
0
716-
717 return texture;
never executed: return texture;
0
718}-
719-
720QPaintDevice* QQuickContext2DImageTexture::beginPainting()-
721{-
722 QQuickContext2DTexture::beginPainting();-
723-
724 if (m_canvasWindow.size().isEmpty())
m_canvasWindow...ze().isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
725 return nullptr;
never executed: return nullptr;
0
726-
727-
728 if (m_canvasWindowChanged) {
m_canvasWindowChangedDescription
TRUEnever evaluated
FALSEnever evaluated
0
729 m_image = QImage(m_canvasWindow.size() * m_canvasDevicePixelRatio, QImage::Format_ARGB32_Premultiplied);-
730 m_image.setDevicePixelRatio(m_canvasDevicePixelRatio);-
731 m_image.fill(0x00000000);-
732 m_canvasWindowChanged = false;-
733 qCDebug(lcCanvas, "%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf",
never executed: QMessageLogger( __FILE__ , 735 , __PRETTY_FUNCTION__, lcCanvas().categoryName()).debug("%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : QtPrivate::asString(m_item->objectName()).toLocal8Bit().constData()), m_item->width(), m_item->height(), m_image.size().width(), m_image.size().height(), m_canvasDevicePixelRatio) ;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
734 (m_item->objectName().isEmpty() ? "Canvas" : qPrintable(m_item->objectName())),
never executed: QMessageLogger( __FILE__ , 735 , __PRETTY_FUNCTION__, lcCanvas().categoryName()).debug("%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : QtPrivate::asString(m_item->objectName()).toLocal8Bit().constData()), m_item->width(), m_item->height(), m_image.size().width(), m_image.size().height(), m_canvasDevicePixelRatio) ;
0
735 m_item->width(), m_item->height(), m_image.size().width(), m_image.size().height(), m_canvasDevicePixelRatio);
never executed: QMessageLogger( __FILE__ , 735 , __PRETTY_FUNCTION__, lcCanvas().categoryName()).debug("%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf", (m_item->objectName().isEmpty() ? "Canvas" : QtPrivate::asString(m_item->objectName()).toLocal8Bit().constData()), m_item->width(), m_item->height(), m_image.size().width(), m_image.size().height(), m_canvasDevicePixelRatio) ;
0
736 }
never executed: end of block
0
737-
738 return &m_image;
never executed: return &m_image;
0
739}-
740-
741void QQuickContext2DImageTexture::endPainting()-
742{-
743 QQuickContext2DTexture::endPainting();-
744 if (m_onCustomThread)
m_onCustomThreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
745 m_mutex.lock();
never executed: m_mutex.lock();
0
746 m_displayImage = m_image;-
747 if (m_onCustomThread)
m_onCustomThreadDescription
TRUEnever evaluated
FALSEnever evaluated
0
748 m_mutex.unlock();
never executed: m_mutex.unlock();
0
749}
never executed: end of block
0
750-
751void QQuickContext2DImageTexture::compositeTile(QQuickContext2DTile* tile)-
752{-
753 Q_ASSERT(!tile->dirty());-
754 QQuickContext2DImageTile* t = static_cast<QQuickContext2DImageTile*>(tile);-
755 QRect target = t->rect().intersected(m_canvasWindow);-
756 if (target.isValid()) {
target.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
0
757 QRect source = target;-
758 source.moveTo(source.topLeft() - t->rect().topLeft());-
759 target.moveTo(target.topLeft() - m_canvasWindow.topLeft());-
760-
761 m_painter.begin(&m_image);-
762 m_painter.setCompositionMode(QPainter::CompositionMode_Source);-
763 m_painter.drawImage(target, t->image(), source);-
764 m_painter.end();-
765 }
never executed: end of block
0
766}
never executed: end of block
0
767-
768QT_END_NAMESPACE-
769-
770#include "moc_qquickcontext2dtexture_p.cpp"-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.0