Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qsgadaptationlayer_p.h
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#ifndef QSGADAPTATIONLAYER_P_H
6#define QSGADAPTATIONLAYER_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtQuick/qsgnode.h>
20#include <QtQuick/qsgtexture.h>
21#include <QtQuick/qquickpainteditem.h>
22#include <QtCore/qobject.h>
23#include <QtCore/qrect.h>
24#include <QtGui/qbrush.h>
25#include <QtGui/qcolor.h>
26#include <QtGui/qpainterpath.h>
27#include <QtCore/qsharedpointer.h>
28#include <QtGui/qglyphrun.h>
29#include <QtGui/qpainterpath.h>
30#include <QtCore/qurl.h>
31#include <private/qfontengine_p.h>
32#include <QtGui/private/qdatabuffer_p.h>
33#include <private/qdistancefield_p.h>
34#include <private/qintrusivelist_p.h>
35#include <rhi/qshader.h>
36#include <QtQuick/qsgtextnode.h>
37
38// ### remove
39#include <QtQuick/private/qquicktext_p.h>
40
42
43class QSGNode;
44class QImage;
45class TextureReference;
47class QSGInternalImageNode;
48class QSGPainterNode;
49class QSGInternalRectangleNode;
50class QSGGlyphNode;
51class QSGRootNode;
52class QSGSpriteNode;
53class QSGRenderNode;
54class QSGRenderContext;
55class QRhiTexture;
56
57class Q_QUICK_EXPORT QSGNodeVisitorEx
58{
59public:
60 virtual ~QSGNodeVisitorEx();
61
62 // visit(...) returns true if the children are supposed to be
63 // visisted and false if they're supposed to be skipped by the visitor.
64
65 virtual bool visit(QSGTransformNode *) = 0;
66 virtual void endVisit(QSGTransformNode *) = 0;
67 virtual bool visit(QSGClipNode *) = 0;
68 virtual void endVisit(QSGClipNode *) = 0;
69 virtual bool visit(QSGGeometryNode *) = 0;
70 virtual void endVisit(QSGGeometryNode *) = 0;
71 virtual bool visit(QSGOpacityNode *) = 0;
72 virtual void endVisit(QSGOpacityNode *) = 0;
73 virtual bool visit(QSGInternalImageNode *) = 0;
74 virtual void endVisit(QSGInternalImageNode *) = 0;
75 virtual bool visit(QSGPainterNode *) = 0;
76 virtual void endVisit(QSGPainterNode *) = 0;
77 virtual bool visit(QSGInternalRectangleNode *) = 0;
78 virtual void endVisit(QSGInternalRectangleNode *) = 0;
79 virtual bool visit(QSGGlyphNode *) = 0;
80 virtual void endVisit(QSGGlyphNode *) = 0;
81 virtual bool visit(QSGRootNode *) = 0;
82 virtual void endVisit(QSGRootNode *) = 0;
83#if QT_CONFIG(quick_sprite)
84 virtual bool visit(QSGSpriteNode *) = 0;
85 virtual void endVisit(QSGSpriteNode *) = 0;
86#endif
87 virtual bool visit(QSGRenderNode *) = 0;
88 virtual void endVisit(QSGRenderNode *) = 0;
89
90 void visitChildren(QSGNode *node);
91};
92
93
94class Q_QUICK_EXPORT QSGVisitableNode : public QSGGeometryNode
95{
96public:
97 QSGVisitableNode() { setFlag(IsVisitableNode); }
98 ~QSGVisitableNode() override;
99
100 virtual void accept(QSGNodeVisitorEx *) = 0;
101};
102
103class Q_QUICK_EXPORT QSGInternalRectangleNode : public QSGVisitableNode
104{
105public:
106 ~QSGInternalRectangleNode() override;
107
108 virtual void setRect(const QRectF &rect) = 0;
109 virtual void setColor(const QColor &color) = 0;
110 virtual void setPenColor(const QColor &color) = 0;
111 virtual void setPenWidth(qreal width) = 0;
112 virtual void setGradientStops(const QGradientStops &stops) = 0;
113 virtual void setGradientVertical(bool vertical) = 0;
114 virtual void setRadius(qreal radius) = 0;
115 virtual void setTopLeftRadius(qreal radius) = 0;
116 virtual void setTopRightRadius(qreal radius) = 0;
117 virtual void setBottomLeftRadius(qreal radius) = 0;
118 virtual void setBottomRightRadius(qreal radius) = 0;
119 virtual void resetTopLeftRadius() = 0;
120 virtual void resetTopRightRadius() = 0;
121 virtual void resetBottomLeftRadius() = 0;
122 virtual void resetBottomRightRadius() = 0;
123 virtual void setAntialiasing(bool antialiasing) { Q_UNUSED(antialiasing); }
124 virtual void setAligned(bool aligned) = 0;
125
126 virtual void update() = 0;
127
128 void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(this); visitor->endVisit(this); }
129};
130
131
132class Q_QUICK_EXPORT QSGInternalImageNode : public QSGVisitableNode
133{
134public:
135 ~QSGInternalImageNode() override;
136
137 virtual void setTargetRect(const QRectF &rect) = 0;
138 virtual void setInnerTargetRect(const QRectF &rect) = 0;
139 virtual void setInnerSourceRect(const QRectF &rect) = 0;
140 // The sub-source rect's width and height specify the number of times the inner source rect
141 // is repeated inside the inner target rect. The x and y specify which (normalized) location
142 // in the inner source rect maps to the upper-left corner of the inner target rect.
143 virtual void setSubSourceRect(const QRectF &rect) = 0;
144 virtual void setTexture(QSGTexture *texture) = 0;
145 virtual void setAntialiasing(bool antialiasing) { Q_UNUSED(antialiasing); }
146 virtual void setMirror(bool horizontally, bool vertically) = 0;
147 virtual void setMipmapFiltering(QSGTexture::Filtering filtering) = 0;
148 virtual void setFiltering(QSGTexture::Filtering filtering) = 0;
149 virtual void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) = 0;
150 virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) = 0;
151
152 virtual void update() = 0;
153
154 void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(this); visitor->endVisit(this); }
155};
156
157class Q_QUICK_EXPORT QSGPainterNode : public QSGVisitableNode
158{
159public:
160 ~QSGPainterNode() override;
161
162 virtual void setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target) = 0;
163 virtual void setSize(const QSize &size) = 0;
164 virtual void setDirty(const QRect &dirtyRect = QRect()) = 0;
165 virtual void setOpaquePainting(bool opaque) = 0;
166 virtual void setLinearFiltering(bool linearFiltering) = 0;
167 virtual void setMipmapping(bool mipmapping) = 0;
168 virtual void setSmoothPainting(bool s) = 0;
169 virtual void setFillColor(const QColor &c) = 0;
170 virtual void setContentsScale(qreal s) = 0;
171 virtual void setFastFBOResizing(bool dynamic) = 0;
172 virtual void setTextureSize(const QSize &size) = 0;
173
174 virtual QImage toImage() const = 0;
175 virtual void update() = 0;
176 virtual QSGTexture *texture() const = 0;
177
178 void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(this); visitor->endVisit(this); }
179};
180
181class Q_QUICK_EXPORT QSGLayer : public QSGDynamicTexture
182{
183 Q_OBJECT
184public:
185 ~QSGLayer() override;
186
187 enum Format {
188 RGBA8 = 1,
189 RGBA16F,
190 RGBA32F
191 };
192 virtual void setItem(QSGNode *item) = 0;
193 virtual void setRect(const QRectF &logicalRect) = 0;
194 virtual void setSize(const QSize &pixelSize) = 0;
195 virtual void scheduleUpdate() = 0;
196 virtual QImage toImage() const = 0;
197 virtual void setLive(bool live) = 0;
198 virtual void setRecursive(bool recursive) = 0;
199 virtual void setFormat(Format format) = 0;
200 virtual void setHasMipmaps(bool mipmap) = 0;
201 virtual void setDevicePixelRatio(qreal ratio) = 0;
202 virtual void setMirrorHorizontal(bool mirror) = 0;
203 virtual void setMirrorVertical(bool mirror) = 0;
204 virtual void setSamples(int samples) = 0;
205 Q_SLOT virtual void markDirtyTexture() = 0;
206 Q_SLOT virtual void invalidated() = 0;
207
208Q_SIGNALS:
209 void updateRequested();
210 void scheduledUpdateCompleted();
211
212protected:
213 QSGLayer(QSGTexturePrivate &dd);
214};
215
216#if QT_CONFIG(quick_sprite)
217
218class Q_QUICK_EXPORT QSGSpriteNode : public QSGVisitableNode
219{
220public:
221 ~QSGSpriteNode() override;
222
223 virtual void setTexture(QSGTexture *texture) = 0;
224 virtual void setTime(float time) = 0;
225 virtual void setSourceA(const QPoint &source) = 0;
226 virtual void setSourceB(const QPoint &source) = 0;
227 virtual void setSpriteSize(const QSize &size) = 0;
228 virtual void setSheetSize(const QSize &size) = 0;
229 virtual void setSize(const QSizeF &size) = 0;
230 virtual void setFiltering(QSGTexture::Filtering filtering) = 0;
231
232 virtual void update() = 0;
233
234 void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(this); visitor->endVisit(this); }
235};
236
237#endif
238
239class Q_QUICK_EXPORT QSGGuiThreadShaderEffectManager : public QObject
240{
241 Q_OBJECT
242
243public:
244 ~QSGGuiThreadShaderEffectManager() override;
245
246 enum Status {
247 Compiled,
248 Uncompiled,
249 Error
250 };
251
252 virtual bool hasSeparateSamplerAndTextureObjects() const = 0;
253
254 virtual QString log() const = 0;
255 virtual Status status() const = 0;
256
257 struct ShaderInfo {
258 enum Type {
259 TypeVertex,
260 TypeFragment,
261 TypeOther
262 };
263 enum VariableType {
264 Constant, // cbuffer members or uniforms
265 Sampler,
266 Texture // for APIs with separate texture and sampler objects
267 };
268 struct Variable {
269 VariableType type = Constant;
270 QByteArray name;
271 uint offset = 0; // for cbuffer members
272 uint size = 0; // for cbuffer members
273 int bindPoint = 0; // for textures/samplers, where applicable
274 };
275
276 QString name; // optional, f.ex. the filename, used for debugging purposes only
277 QShader rhiShader;
278 Type type;
279 QList<Variable> variables;
280
281 // Vertex inputs are not tracked here as QSGGeometry::AttributeSet
282 // hardwires that anyways so it is up to the shader to provide
283 // compatible inputs (e.g. compatible with
284 // QSGGeometry::defaultAttributes_TexturedPoint2D()).
285 };
286
287 virtual void prepareShaderCode(ShaderInfo::Type typeHint, const QUrl &src, ShaderInfo *result) = 0;
288
289Q_SIGNALS:
290 void shaderCodePrepared(bool ok, ShaderInfo::Type typeHint, const QUrl &src, ShaderInfo *result);
291 void logAndStatusChanged();
292};
293
294#ifndef QT_NO_DEBUG_STREAM
295Q_QUICK_EXPORT QDebug operator<<(QDebug debug, const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &v);
296#endif
297
298class Q_QUICK_EXPORT QSGShaderEffectNode : public QObject, public QSGVisitableNode
299{
300 Q_OBJECT
301
302public:
303 ~QSGShaderEffectNode() override;
304
305 enum DirtyShaderFlag {
306 DirtyShaders = 0x01,
307 DirtyShaderConstant = 0x02,
308 DirtyShaderTexture = 0x04,
309 DirtyShaderGeometry = 0x08,
310 DirtyShaderMesh = 0x10,
311
312 DirtyShaderAll = 0xFF
313 };
314 Q_DECLARE_FLAGS(DirtyShaderFlags, DirtyShaderFlag)
315
316 enum CullMode { // must match ShaderEffect
317 NoCulling,
318 BackFaceCulling,
319 FrontFaceCulling
320 };
321
322 struct VariableData {
323 enum SpecialType { None, Unused, Source, SubRect, Opacity, Matrix };
324
325 QVariant value;
326 SpecialType specialType;
327 int propertyIndex = -1;
328 };
329
330 struct ShaderData {
331 ShaderData() {}
332 bool hasShaderCode = false;
333 QSGGuiThreadShaderEffectManager::ShaderInfo shaderInfo;
334 QList<VariableData> varData;
335 };
336
337 struct SyncData {
338 DirtyShaderFlags dirty;
339 CullMode cullMode;
340 bool blending;
341 struct ShaderSyncData {
342 const ShaderData *shader;
343 const QSet<int> *dirtyConstants;
344 const QSet<int> *dirtyTextures;
345 };
346 ShaderSyncData vertex;
347 ShaderSyncData fragment;
348 void *materialTypeCacheKey;
349 qint8 viewCount;
350 };
351
352 // Each ShaderEffect item has one node (render thread) and one manager (gui thread).
353
354 virtual QRectF updateNormalizedTextureSubRect(bool supportsAtlasTextures) = 0;
355 virtual void syncMaterial(SyncData *syncData) = 0;
356
357 void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(this); visitor->endVisit(this); }
358
359Q_SIGNALS:
360 void textureChanged();
361};
362
363Q_DECLARE_OPERATORS_FOR_FLAGS(QSGShaderEffectNode::DirtyShaderFlags)
364
365#ifndef QT_NO_DEBUG_STREAM
366Q_QUICK_EXPORT QDebug operator<<(QDebug debug, const QSGShaderEffectNode::VariableData &vd);
367#endif
368
369class Q_QUICK_EXPORT QSGGlyphNode : public QSGVisitableNode
370{
371public:
372 enum AntialiasingMode
373 {
374 DefaultAntialiasing = -1,
375 GrayAntialiasing,
376 LowQualitySubPixelAntialiasing,
377 HighQualitySubPixelAntialiasing
378 };
379
380 QSGGlyphNode(QSGTextNode::RenderType renderType) : m_renderType(renderType) {}
381 ~QSGGlyphNode() override;
382
383 virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) = 0;
384 virtual void setColor(const QColor &color) = 0;
385 virtual void setStyle(QQuickText::TextStyle style) = 0;
386 virtual void setStyleColor(const QColor &color) = 0;
387 virtual QPointF baseLine() const = 0;
388
389 virtual QRectF boundingRect() const { return m_bounding_rect; }
390 virtual void setBoundingRect(const QRectF &bounds) { m_bounding_rect = bounds; }
391
392 virtual void setPreferredAntialiasingMode(AntialiasingMode) = 0;
393 virtual void setRenderTypeQuality(int renderTypeQuality) { Q_UNUSED(renderTypeQuality) }
394
395 QSGTextNode::RenderType renderType() const { return m_renderType; }
396
397 virtual void recycle();
398
399 virtual void update() = 0;
400
401 void accept(QSGNodeVisitorEx *visitor) override { visitor->visit(this); visitor->endVisit(this); }
402protected:
403 QRectF m_bounding_rect;
404 QSGTextNode::RenderType m_renderType;
405};
406
408{
409public:
410 virtual ~QSGDistanceFieldGlyphConsumer();
411
412 virtual void invalidateGlyphs(const QList<quint32> &glyphs) = 0;
413 QIntrusiveListNode node;
414};
416
417class Q_QUICK_EXPORT QSGDistanceFieldGlyphCache
418{
419 Q_DISABLE_COPY_MOVE(QSGDistanceFieldGlyphCache)
420public:
421 QSGDistanceFieldGlyphCache(const QRawFont &font,
422 int renderTypeQuality);
423 virtual ~QSGDistanceFieldGlyphCache();
424
425 struct Metrics {
430
431 bool isNull() const { return width == 0 || height == 0; }
432 };
433
434 struct TexCoord {
435 qreal x = 0;
436 qreal y = 0;
441
443
444 bool isNull() const { return width <= 0 || height <= 0; }
445 bool isValid() const { return width >= 0 && height >= 0; }
446 };
447
448 struct Texture {
449 QRhiTexture *texture = nullptr;
451
452 bool operator == (const Texture &other) const {
453 return texture == other.texture;
454 }
455 };
456
457 const QRawFont &referenceFont() const { return m_referenceFont; }
458
459 qreal fontScale(qreal pixelSize) const
460 {
461 return pixelSize / baseFontSize();
462 }
464 {
465 return QT_DISTANCEFIELD_RADIUS(m_doubleGlyphResolution) / qreal(QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution));
466 }
467 int glyphCount() const { return m_glyphCount; }
468 bool doubleGlyphResolution() const { return m_doubleGlyphResolution; }
469 int renderTypeQuality() const { return m_renderTypeQuality; }
470
471 Metrics glyphMetrics(glyph_t glyph, qreal pixelSize);
472 inline TexCoord glyphTexCoord(glyph_t glyph);
473 inline const Texture *glyphTexture(glyph_t glyph);
474
475 void populate(const QList<glyph_t> &glyphs);
476 void release(const QList<glyph_t> &glyphs);
477
478 void update();
479
480 void registerGlyphNode(QSGDistanceFieldGlyphConsumer *node) { m_registeredNodes.insert(node); }
481 void unregisterGlyphNode(QSGDistanceFieldGlyphConsumer *node) { m_registeredNodes.remove(node); }
482
483 virtual void processPendingGlyphs();
484
485 virtual bool eightBitFormatIsAlphaSwizzled() const = 0;
486 virtual bool screenSpaceDerivativesSupported() const = 0;
487 virtual bool isActive() const;
488
489protected:
490 struct GlyphPosition {
491 glyph_t glyph;
492 QPointF position;
493 };
494
504
505 virtual void requestGlyphs(const QSet<glyph_t> &glyphs) = 0;
506 virtual void storeGlyphs(const QList<QDistanceField> &glyphs) = 0;
507 virtual void referenceGlyphs(const QSet<glyph_t> &glyphs) = 0;
508 virtual void releaseGlyphs(const QSet<glyph_t> &glyphs) = 0;
509
510 void setGlyphsPosition(const QList<GlyphPosition> &glyphs);
511 void setGlyphsTexture(const QList<glyph_t> &glyphs, const Texture &tex);
512 void markGlyphsToRender(const QList<glyph_t> &glyphs);
513 inline void removeGlyph(glyph_t glyph);
514
515 void updateRhiTexture(QRhiTexture *oldTex, QRhiTexture *newTex, const QSize &newTexSize);
516
517 inline bool containsGlyph(glyph_t glyph);
518
519 GlyphData &glyphData(glyph_t glyph);
520 GlyphData &emptyData(glyph_t glyph);
521
522 int baseFontSize() const;
523
524#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
525 virtual void saveTexture(QRhiTexture *texture, const QString &nameBase) const = 0;
526#endif
527
530
531protected:
532 QRawFont m_referenceFont;
533
534private:
535 int m_glyphCount;
536 QList<Texture *> m_textures; // Owned. Entries should live for as long as the cache lives
537 // (external nodes share the data)
538 QHash<glyph_t, GlyphData> m_glyphsData;
539 QDataBuffer<glyph_t> m_pendingGlyphs;
540 QSet<glyph_t> m_populatingGlyphs;
541 QSGDistanceFieldGlyphConsumerList m_registeredNodes;
542
543 static Texture s_emptyTexture;
544};
545
546inline QSGDistanceFieldGlyphCache::TexCoord QSGDistanceFieldGlyphCache::glyphTexCoord(glyph_t glyph)
547{
548 return glyphData(glyph).texCoord;
549}
550
551inline const QSGDistanceFieldGlyphCache::Texture *QSGDistanceFieldGlyphCache::glyphTexture(glyph_t glyph)
552{
553 return glyphData(glyph).texture;
554}
555
556inline void QSGDistanceFieldGlyphCache::removeGlyph(glyph_t glyph)
557{
558 GlyphData &gd = glyphData(glyph);
559 gd.texCoord = TexCoord();
560 gd.texture = &s_emptyTexture;
561}
562
563inline bool QSGDistanceFieldGlyphCache::containsGlyph(glyph_t glyph)
564{
565 return glyphData(glyph).texCoord.isValid();
566}
567
568QT_END_NAMESPACE
569
570Q_DECLARE_METATYPE(QSGGuiThreadShaderEffectManager::ShaderInfo::Type)
571
572#endif
bool isActive() const
Returns true if begin() has been called and end() has not yet been called; otherwise returns false.
virtual bool screenSpaceDerivativesSupported() const =0
void unregisterGlyphNode(QSGDistanceFieldGlyphConsumer *node)
Metrics glyphMetrics(glyph_t glyph, qreal pixelSize)
qreal fontScale(qreal pixelSize) const
void setGlyphsTexture(const QList< glyph_t > &glyphs, const Texture &tex)
void markGlyphsToRender(const QList< glyph_t > &glyphs)
GlyphData & emptyData(glyph_t glyph)
void populate(const QList< glyph_t > &glyphs)
void setGlyphsPosition(const QList< GlyphPosition > &glyphs)
virtual void releaseGlyphs(const QSet< glyph_t > &glyphs)=0
const Texture * glyphTexture(glyph_t glyph)
void release(const QList< glyph_t > &glyphs)
TexCoord glyphTexCoord(glyph_t glyph)
virtual void storeGlyphs(const QList< QDistanceField > &glyphs)=0
void updateRhiTexture(QRhiTexture *oldTex, QRhiTexture *newTex, const QSize &newTexSize)
void registerGlyphNode(QSGDistanceFieldGlyphConsumer *node)
GlyphData & glyphData(glyph_t glyph)
virtual void referenceGlyphs(const QSet< glyph_t > &glyphs)=0
virtual bool eightBitFormatIsAlphaSwizzled() const =0
const QRawFont & referenceFont() const
virtual void requestGlyphs(const QSet< glyph_t > &glyphs)=0
Combined button and popup list for selecting options.
Q_CORE_EXPORT QDebug operator<<(QDebug debug, QDir::Filters filters)
Definition qdir.cpp:2620
QDebug operator<<(QDebug dbg, const QFileInfo &fi)
QIntrusiveList< QSGDistanceFieldGlyphConsumer, &QSGDistanceFieldGlyphConsumer::node > QSGDistanceFieldGlyphConsumerList
bool operator==(const Texture &other) const