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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtdeclarative/src/quick/scenegraph/qsgadaptationlayer_p.h