Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qquickcontext2dtexture.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
5
#
include
"qquickcontext2dtexture_p.h"
6
#
include
"qquickcontext2dtile_p.h"
7
#
include
"qquickcanvasitem_p.h"
8
#
include
<
private
/
qquickitem_p
.
h
>
9
#
include
<
QtQuick
/
private
/
qsgplaintexture_p
.
h
>
10
#
include
"qquickcontext2dcommandbuffer_p.h"
11
#
include
<
QtCore
/
QThread
>
12
#
include
<
QtGui
/
QGuiApplication
>
13
14
QT_BEGIN_NAMESPACE
15
16
Q_STATIC_LOGGING_CATEGORY(lcCanvas,
"qt.quick.canvas"
)
17
18
QQuickContext2DTexture::QQuickContext2DTexture()
19
: m_context(
nullptr
)
20
, m_surface(
nullptr
)
21
, m_item(
nullptr
)
22
, m_canvasDevicePixelRatio(1)
23
, m_canvasWindowChanged(
false
)
24
, m_dirtyTexture(
false
)
25
, m_smooth(
true
)
26
, m_antialiasing(
false
)
27
, m_tiledCanvas(
false
)
28
, m_painting(
false
)
29
{
30
}
31
32
QQuickContext2DTexture
::~
QQuickContext2DTexture
()
33
{
34
clearTiles
(
)
;
35
}
36
37
void
QQuickContext2DTexture
::
markDirtyTexture
()
38
{
39
if
(m_onCustomThread)
40
m_mutex.lock();
41
m_dirtyTexture =
true
;
42
emit textureChanged();
43
if
(m_onCustomThread)
44
m_mutex.unlock();
45
}
46
47
bool
QQuickContext2DTexture
::
setCanvasSize
(
const
QSize &size)
48
{
49
if
(m_canvasSize != size) {
50
m_canvasSize = size;
51
return
true
;
52
}
53
return
false
;
54
}
55
56
bool
QQuickContext2DTexture
::
setTileSize
(
const
QSize &size)
57
{
58
if
(m_tileSize != size) {
59
m_tileSize = size;
60
return
true
;
61
}
62
return
false
;
63
}
64
65
void
QQuickContext2DTexture
::
setSmooth
(
bool
smooth)
66
{
67
m_smooth = smooth;
68
}
69
70
void
QQuickContext2DTexture
::
setAntialiasing
(
bool
antialiasing)
71
{
72
m_antialiasing = antialiasing;
73
}
74
75
void
QQuickContext2DTexture
::
setItem
(
QQuickCanvasItem
* item)
76
{
77
m_item
= item;
78
if
(
m_item
) {
79
m_context
= (
QQuickContext2D
*) item
->
rawContext
(
)
;
// FIXME
80
m_state = m_context->state;
81
}
else
{
82
m_context
=
nullptr
;
83
}
84
}
85
86
bool
QQuickContext2DTexture
::
setCanvasWindow
(
const
QRect& r)
87
{
88
bool
ok =
false
;
89
static
qreal overriddenDevicePixelRatio =
90
!qEnvironmentVariableIsEmpty(
"QT_CANVAS_OVERRIDE_DEVICEPIXELRATIO"
) ?
91
qgetenv(
"QT_CANVAS_OVERRIDE_DEVICEPIXELRATIO"
).toFloat(&ok) : 0.0;
92
qreal canvasDevicePixelRatio = overriddenDevicePixelRatio;
93
if
(overriddenDevicePixelRatio == 0.0) {
94
canvasDevicePixelRatio = (
m_item
&&
m_item
->window()) ?
95
m_item->window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio();
96
}
97
if
(!qFuzzyCompare(m_canvasDevicePixelRatio, canvasDevicePixelRatio)) {
98
qCDebug(lcCanvas,
"%s device pixel ratio %.1lf -> %.1lf"
,
99
(
m_item
->objectName().isEmpty() ?
"Canvas"
: qPrintable(
m_item
->objectName())),
100
m_canvasDevicePixelRatio, canvasDevicePixelRatio);
101
m_canvasDevicePixelRatio = canvasDevicePixelRatio;
102
m_canvasWindowChanged =
true
;
103
}
104
105
if
(m_canvasWindow != r) {
106
m_canvasWindow = r;
107
m_canvasWindowChanged =
true
;
108
}
109
110
return
m_canvasWindowChanged;
111
}
112
113
bool
QQuickContext2DTexture
::
setDirtyRect
(
const
QRect &r)
114
{
115
bool
doDirty =
false
;
116
if
(m_tiledCanvas) {
117
for
(QQuickContext2DTile* t : std::as_const(m_tiles)) {
118
bool
dirty = t->rect().intersected(r).isValid();
119
t->markDirty(dirty);
120
if
(dirty)
121
doDirty =
true
;
122
}
123
}
else
{
124
doDirty = m_canvasWindow.intersected(r).isValid();
125
}
126
return
doDirty;
127
}
128
129
void
QQuickContext2DTexture
::canvasChanged(
const
QSize& canvasSize,
const
QSize& tileSize,
const
QRect& canvasWindow,
const
QRect& dirtyRect,
bool
smooth,
bool
antialiasing)
130
{
131
QSize ts = tileSize;
132
if
(ts.width() > canvasSize.width())
133
ts.setWidth(canvasSize.width());
134
135
if
(ts.height() > canvasSize.height())
136
ts.setHeight(canvasSize.height());
137
138
setCanvasSize(canvasSize);
139
setTileSize(ts);
140
setCanvasWindow(canvasWindow);
141
142
if
(canvasSize == canvasWindow.size()) {
143
m_tiledCanvas =
false
;
144
}
else
{
145
m_tiledCanvas =
true
;
146
}
147
148
if
(dirtyRect.isValid())
149
setDirtyRect(dirtyRect);
150
151
setSmooth
(
smooth
)
;
152
setAntialiasing
(
antialiasing
)
;
153
}
154
155
void
QQuickContext2DTexture
::
paintWithoutTiles
(
QQuickContext2DCommandBuffer
*ccb)
156
{
157
if
(!ccb || ccb
->
isEmpty
(
)
)
158
return
;
159
160
QPaintDevice* device = beginPainting();
161
if
(!device) {
162
endPainting
(
)
;
163
return
;
164
}
165
166
QPainter p;
167
p.begin(device);
168
p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing, m_antialiasing);
169
p.setRenderHint(QPainter::SmoothPixmapTransform, m_smooth);
170
171
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
172
173
ccb->replay(&p, m_state, scaleFactor());
174
endPainting
(
)
;
175
markDirtyTexture
(
)
;
176
}
177
178
bool
QQuickContext2DTexture
::
canvasDestroyed
()
179
{
180
return
m_item
==
nullptr
;
181
}
182
183
void
QQuickContext2DTexture
::
paint
(
QQuickContext2DCommandBuffer
*ccb)
184
{
185
QQuickContext2D::mutex.lock();
186
if
(
canvasDestroyed
(
)
) {
187
delete
ccb;
188
QQuickContext2D::mutex.unlock();
189
return
;
190
}
191
QQuickContext2D::mutex.unlock();
192
if
(!m_tiledCanvas) {
193
paintWithoutTiles
(
ccb
)
;
194
delete
ccb;
195
return
;
196
}
197
198
QRect tiledRegion = createTiles(m_canvasWindow.intersected(QRect(QPoint(0, 0), m_canvasSize)));
199
if
(!tiledRegion.isEmpty()) {
200
QRect dirtyRect;
201
for
(QQuickContext2DTile* tile : std::as_const(m_tiles)) {
202
if
(tile->dirty()) {
203
if
(dirtyRect.isEmpty())
204
dirtyRect = tile->rect();
205
else
206
dirtyRect |= tile->rect();
207
}
208
}
209
210
if
(beginPainting()) {
211
QQuickContext2D
::
State
oldState = m_state;
212
for
(QQuickContext2DTile* tile : std::as_const(m_tiles)) {
213
if
(tile->dirty()) {
214
ccb->replay(tile->createPainter(m_smooth, m_antialiasing), oldState, scaleFactor());
215
tile->drawFinished();
216
tile->markDirty(
false
);
217
}
218
compositeTile(tile);
219
}
220
endPainting
(
)
;
221
m_state = oldState;
222
markDirtyTexture
(
)
;
223
}
224
}
225
delete
ccb;
226
}
227
228
QRect
QQuickContext2DTexture
::tiledRect(
const
QRectF& window,
const
QSize& tileSize)
229
{
230
if
(window.isEmpty())
231
return
QRect();
232
233
const
int
tw = tileSize.width();
234
const
int
th = tileSize.height();
235
const
int
h1 = window.left() / tw;
236
const
int
v1 = window.top() / th;
237
238
const
int
htiles = ((window.right() - h1 * tw) + tw - 1)/tw;
239
const
int
vtiles = ((window.bottom() - v1 * th) + th - 1)/th;
240
241
return
QRect(h1 * tw, v1 * th, htiles * tw, vtiles * th);
242
}
243
244
QRect
QQuickContext2DTexture
::
createTiles
(
const
QRect& window)
245
{
246
QList<QQuickContext2DTile*> oldTiles = m_tiles;
247
m_tiles.clear();
248
249
if
(window.isEmpty()) {
250
return
QRect();
251
}
252
253
QRect r = tiledRect(window, adjustedTileSize(m_tileSize));
254
255
const
int
tw = m_tileSize.width();
256
const
int
th = m_tileSize.height();
257
const
int
h1 = window.left() / tw;
258
const
int
v1 = window.top() / th;
259
260
261
const
int
htiles = r.width() / tw;
262
const
int
vtiles = r.height() / th;
263
264
for
(
int
yy = 0; yy < vtiles; ++yy) {
265
for
(
int
xx = 0; xx < htiles; ++xx) {
266
int
ht = xx + h1;
267
int
vt = yy + v1;
268
269
QQuickContext2DTile
* tile =
nullptr
;
270
271
QPoint pos(ht * tw, vt * th);
272
QRect rect(pos, m_tileSize);
273
274
for
(
int
i = 0; i < oldTiles.size(); i++) {
275
if
(oldTiles[i]->rect() == rect) {
276
tile = oldTiles.takeAt(i);
277
break
;
278
}
279
}
280
281
if
(!tile)
282
tile =
createTile
(
)
;
283
284
tile->setRect(rect);
285
m_tiles.append(tile);
286
}
287
}
288
289
qDeleteAll(oldTiles);
290
291
return
r;
292
}
293
294
void
QQuickContext2DTexture
::
clearTiles
()
295
{
296
qDeleteAll(m_tiles);
297
m_tiles.clear();
298
}
299
300
QSize
QQuickContext2DTexture
::
adjustedTileSize
(
const
QSize &ts)
301
{
302
return
ts;
303
}
304
305
bool
QQuickContext2DTexture
::
event
(QEvent *e)
306
{
307
if
((
int
) e->type() == QEvent::User + 1) {
308
PaintEvent *pe =
static_cast
<PaintEvent *>(e);
309
paint
(
pe->buffer
)
;
310
return
true
;
311
}
else
if
((
int
) e->type() == QEvent::User + 2) {
312
CanvasChangeEvent
*ce =
static_cast
<
CanvasChangeEvent
*>(e);
313
canvasChanged(ce->canvasSize, ce->tileSize, ce->canvasWindow, ce->dirtyRect, ce->smooth, ce->antialiasing);
314
return
true
;
315
}
316
return
QObject::event(e);
317
}
318
319
QQuickContext2DImageTexture
::QQuickContext2DImageTexture()
320
:
QQuickContext2DTexture
(
)
321
{
322
}
323
324
QQuickContext2DImageTexture
::~
QQuickContext2DImageTexture
()
325
{
326
}
327
328
QQuickCanvasItem
::
RenderTarget
QQuickContext2DImageTexture
::
renderTarget
()
const
329
{
330
return
QQuickCanvasItem::Image;
331
}
332
333
QQuickContext2DTile
*
QQuickContext2DImageTexture
::
createTile
()
const
334
{
335
return
new
QQuickContext2DImageTile
(
)
;
336
}
337
338
void
QQuickContext2DImageTexture
::grabImage(
const
QRectF& rf)
339
{
340
Q_ASSERT(rf.isValid());
341
QQuickContext2D::mutex.lock();
342
if
(m_context) {
343
QImage grabbed = m_displayImage.copy(rf.toRect());
344
m_context->setGrabbedImage(grabbed);
345
}
346
QQuickContext2D::mutex.unlock();
347
}
348
349
QSGTexture *
QQuickContext2DImageTexture
::
textureForNextFrame
(QSGTexture *last, QQuickWindow *window)
350
{
351
if
(m_onCustomThread)
352
m_mutex.lock();
353
354
delete
last;
355
356
QSGTexture *texture = window->createTextureFromImage(m_displayImage, QQuickWindow::TextureCanUseAtlas);
357
m_dirtyTexture =
false
;
358
359
if
(m_onCustomThread)
360
m_mutex.unlock();
361
362
return
texture;
363
}
364
365
QPaintDevice
*
QQuickContext2DImageTexture
::
beginPainting
()
366
{
367
QQuickContext2DTexture::beginPainting();
368
369
if
(m_canvasWindow.size().isEmpty())
370
return
nullptr
;
371
372
373
if
(m_canvasWindowChanged) {
374
m_image = QImage(m_canvasWindow.size() * m_canvasDevicePixelRatio, QImage::Format_ARGB32_Premultiplied);
375
m_image.setDevicePixelRatio(m_canvasDevicePixelRatio);
376
m_image.fill(0x00000000);
377
m_canvasWindowChanged =
false
;
378
qCDebug(lcCanvas,
"%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf"
,
379
(m_item->objectName().isEmpty() ?
"Canvas"
: qPrintable(m_item->objectName())),
380
m_item->width(), m_item->height(), m_image.size().width(), m_image.size().height(), m_canvasDevicePixelRatio);
381
}
382
383
return
&m_image;
384
}
385
386
void
QQuickContext2DImageTexture
::
endPainting
()
387
{
388
QQuickContext2DTexture
::
endPainting
();
389
if
(m_onCustomThread)
390
m_mutex.lock();
391
m_displayImage = m_image;
392
if
(m_onCustomThread)
393
m_mutex.unlock();
394
}
395
396
void
QQuickContext2DImageTexture
::
compositeTile
(
QQuickContext2DTile
* tile)
397
{
398
Q_ASSERT(!tile
->
dirty
(
)
);
399
QQuickContext2DImageTile
* t =
static_cast
<QQuickContext2DImageTile*>(tile);
400
QRect target = t->rect().intersected(m_canvasWindow);
401
if
(target.isValid()) {
402
QRect source = target;
403
source.moveTo(source.topLeft() - t->rect().topLeft());
404
target.moveTo(target.topLeft() - m_canvasWindow.topLeft());
405
406
m_painter.begin(&m_image);
407
m_painter.setCompositionMode(QPainter::CompositionMode_Source);
408
m_painter.drawImage(target, t->image(), source);
409
m_painter.end();
410
}
411
}
412
413
QT_END_NAMESPACE
414
415
#
include
"moc_qquickcontext2dtexture_p.cpp"
QQuickCanvasItem
Definition
qquickcanvasitem_p.h:58
QQuickCanvasItem::rawContext
QQuickCanvasContext * rawContext() const
Definition
qquickcanvasitem.cpp:521
QQuickContext2DCommandBuffer
Definition
qquickcontext2dcommandbuffer_p.h:32
QQuickContext2DCommandBuffer::isEmpty
bool isEmpty() const
Definition
qquickcontext2dcommandbuffer_p.h:40
QQuickContext2DImageTexture
Definition
qquickcontext2dtexture_p.h:139
QQuickContext2DImageTexture::createTile
QQuickContext2DTile * createTile() const override
Definition
qquickcontext2dtexture.cpp:333
QQuickContext2DImageTexture::~QQuickContext2DImageTexture
~QQuickContext2DImageTexture()
Definition
qquickcontext2dtexture.cpp:324
QQuickContext2DImageTexture::endPainting
void endPainting() override
Definition
qquickcontext2dtexture.cpp:386
QQuickContext2DImageTexture::renderTarget
QQuickCanvasItem::RenderTarget renderTarget() const override
Definition
qquickcontext2dtexture.cpp:328
QQuickContext2DImageTexture::compositeTile
void compositeTile(QQuickContext2DTile *tile) override
Definition
qquickcontext2dtexture.cpp:396
QQuickContext2DImageTexture::beginPainting
QPaintDevice * beginPainting() override
Definition
qquickcontext2dtexture.cpp:365
QQuickContext2DImageTexture::textureForNextFrame
QSGTexture * textureForNextFrame(QSGTexture *lastFrame, QQuickWindow *window) override
Definition
qquickcontext2dtexture.cpp:349
QQuickContext2DImageTile
Definition
qquickcontext2dtile_p.h:53
QQuickContext2DImageTile::QQuickContext2DImageTile
QQuickContext2DImageTile()
Definition
qquickcontext2dtile.cpp:61
QQuickContext2DTexture::CanvasChangeEvent
Definition
qquickcontext2dtexture_p.h:45
QQuickContext2DTexture
Definition
qquickcontext2dtexture_p.h:36
QQuickContext2DTexture::event
bool event(QEvent *e) override
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition
qquickcontext2dtexture.cpp:305
QQuickContext2DTexture::canvasDestroyed
bool canvasDestroyed()
Definition
qquickcontext2dtexture.cpp:178
QQuickContext2DTexture::setItem
void setItem(QQuickCanvasItem *item)
Definition
qquickcontext2dtexture.cpp:75
QQuickContext2DTexture::clearTiles
void clearTiles()
Definition
qquickcontext2dtexture.cpp:294
QQuickContext2DTexture::setCanvasWindow
bool setCanvasWindow(const QRect &canvasWindow)
Definition
qquickcontext2dtexture.cpp:86
QQuickContext2DTexture::createTiles
QRect createTiles(const QRect &window)
Definition
qquickcontext2dtexture.cpp:244
QQuickContext2DTexture::createTile
virtual QQuickContext2DTile * createTile() const =0
QQuickContext2DTexture::~QQuickContext2DTexture
~QQuickContext2DTexture()
Definition
qquickcontext2dtexture.cpp:32
QQuickContext2DTexture::paint
void paint(QQuickContext2DCommandBuffer *ccb)
Definition
qquickcontext2dtexture.cpp:183
QQuickContext2DTexture::adjustedTileSize
virtual QSize adjustedTileSize(const QSize &ts)
Definition
qquickcontext2dtexture.cpp:300
QQuickContext2DTexture::endPainting
virtual void endPainting()
Definition
qquickcontext2dtexture_p.h:105
QQuickContext2DTexture::setCanvasSize
bool setCanvasSize(const QSize &size)
Definition
qquickcontext2dtexture.cpp:47
QQuickContext2DTexture::setTileSize
bool setTileSize(const QSize &size)
Definition
qquickcontext2dtexture.cpp:56
QQuickContext2DTexture::setSmooth
void setSmooth(bool smooth)
Definition
qquickcontext2dtexture.cpp:65
QQuickContext2DTexture::markDirtyTexture
void markDirtyTexture()
Definition
qquickcontext2dtexture.cpp:37
QQuickContext2DTexture::paintWithoutTiles
void paintWithoutTiles(QQuickContext2DCommandBuffer *ccb)
Definition
qquickcontext2dtexture.cpp:155
QQuickContext2DTexture::setAntialiasing
void setAntialiasing(bool antialiasing)
Definition
qquickcontext2dtexture.cpp:70
QQuickContext2DTexture::setDirtyRect
bool setDirtyRect(const QRect &dirtyRect)
Definition
qquickcontext2dtexture.cpp:113
QQuickContext2DTexture::QQuickContext2DTexture
QQuickContext2DTexture()
Definition
qquickcontext2dtexture.cpp:18
QQuickContext2DTexture::m_context
QQuickContext2D * m_context
Definition
qquickcontext2dtexture_p.h:114
QQuickContext2DTexture::m_item
QQuickCanvasItem * m_item
Definition
qquickcontext2dtexture_p.h:119
QQuickContext2DTile
Definition
qquickcontext2dtile_p.h:30
QQuickContext2DTile::dirty
bool dirty() const
Definition
qquickcontext2dtile_p.h:35
QQuickContext2D
Definition
qquickcontext2d_p.h:56
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
QQuickContext2D::State
Definition
qquickcontext2d_p.h:98
qtdeclarative
src
quick
items
context2d
qquickcontext2dtexture.cpp
Generated on
for Qt by
1.18.0