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 QSGCONTEXT_H |
5 | #define QSGCONTEXT_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 <QtCore/QObject> |
19 | #include <QtCore/qabstractanimation.h> |
20 | #include <QtCore/QMutex> |
21 | |
22 | #include <QtGui/QImage> |
23 | #include <QtGui/QSurfaceFormat> |
24 | |
25 | #include <private/qtquickglobal_p.h> |
26 | #include <private/qrawfont_p.h> |
27 | #include <private/qfontengine_p.h> |
28 | |
29 | #include <QtQuick/qsgnode.h> |
30 | #include <QtQuick/qsgrendererinterface.h> |
31 | #include <QtQuick/qsgtextnode.h> |
32 | |
33 | #include <QtCore/qpointer.h> |
34 | |
35 | QT_BEGIN_NAMESPACE |
36 | |
37 | class QSGContextPrivate; |
38 | class QSGInternalRectangleNode; |
39 | class QSGInternalImageNode; |
40 | class QSGInternalTextNode; |
41 | class QSGPainterNode; |
42 | class QSGGlyphNode; |
43 | class QSGRenderer; |
44 | class QSGDistanceFieldGlyphCache; |
45 | class QQuickWindow; |
46 | class QSGTexture; |
47 | class QSGMaterial; |
48 | class QSGRenderLoop; |
49 | class QSGLayer; |
50 | class QQuickTextureFactory; |
51 | class QSGCompressedTextureFactory; |
52 | class QSGContext; |
53 | class QQuickPaintedItem; |
54 | class QSGRendererInterface; |
55 | class QSGShaderEffectNode; |
56 | class QSGGuiThreadShaderEffectManager; |
57 | class QSGRectangleNode; |
58 | class QSGTextNode; |
59 | class QSGImageNode; |
60 | class QSGNinePatchNode; |
61 | class QSGSpriteNode; |
62 | class QSGRenderContext; |
63 | class QSGRenderTarget; |
64 | class QRhi; |
65 | class QRhiRenderTarget; |
66 | class QRhiRenderPassDescriptor; |
67 | class QRhiCommandBuffer; |
68 | class QQuickGraphicsConfiguration; |
69 | class QQuickItem; |
70 | class QSGCurveGlyphAtlas; |
71 | |
72 | Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TIME_RENDERLOOP) |
73 | Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TIME_COMPILATION) |
74 | Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TIME_TEXTURE) |
75 | Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TIME_GLYPH) |
76 | Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_TIME_RENDERER) |
77 | |
78 | Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_INFO) |
79 | Q_DECLARE_LOGGING_CATEGORY(QSG_LOG_RENDERLOOP) |
80 | |
81 | class Q_QUICK_EXPORT QSGContext : public QObject |
82 | { |
83 | Q_OBJECT |
84 | |
85 | public: |
86 | enum AntialiasingMethod { |
87 | UndecidedAntialiasing, |
88 | VertexAntialiasing, |
89 | MsaaAntialiasing |
90 | }; |
91 | |
92 | explicit QSGContext(QObject *parent = nullptr); |
93 | ~QSGContext() override; |
94 | |
95 | virtual void renderContextInitialized(QSGRenderContext *renderContext); |
96 | virtual void renderContextInvalidated(QSGRenderContext *renderContext); |
97 | virtual QSGRenderContext *createRenderContext() = 0; |
98 | |
99 | QSGInternalRectangleNode *createInternalRectangleNode(const QRectF &rect, const QColor &c); |
100 | virtual QSGInternalRectangleNode *createInternalRectangleNode() = 0; |
101 | virtual QSGInternalImageNode *createInternalImageNode(QSGRenderContext *renderContext) = 0; |
102 | virtual QSGInternalTextNode *createInternalTextNode(QSGRenderContext *renderContext); |
103 | virtual QSGPainterNode *createPainterNode(QQuickPaintedItem *item) = 0; |
104 | virtual QSGGlyphNode *createGlyphNode(QSGRenderContext *rc, QSGTextNode::RenderType renderType, int renderTypeQuality) = 0; |
105 | virtual QSGLayer *createLayer(QSGRenderContext *renderContext) = 0; |
106 | virtual QSGGuiThreadShaderEffectManager *createGuiThreadShaderEffectManager(); |
107 | virtual QSGShaderEffectNode *createShaderEffectNode(QSGRenderContext *renderContext); |
108 | #if QT_CONFIG(quick_sprite) |
109 | virtual QSGSpriteNode *createSpriteNode() = 0; |
110 | #endif |
111 | virtual QAnimationDriver *createAnimationDriver(QObject *parent); |
112 | virtual float vsyncIntervalForAnimationDriver(QAnimationDriver *driver); |
113 | virtual bool isVSyncDependent(QAnimationDriver *driver); |
114 | |
115 | virtual QSize minimumFBOSize() const; |
116 | virtual QSurfaceFormat defaultSurfaceFormat() const = 0; |
117 | |
118 | virtual QSGRendererInterface *rendererInterface(QSGRenderContext *renderContext); |
119 | |
120 | virtual QSGTextNode *createTextNode(QSGRenderContext *renderContext); |
121 | virtual QSGRectangleNode *createRectangleNode() = 0; |
122 | virtual QSGImageNode *createImageNode() = 0; |
123 | virtual QSGNinePatchNode *createNinePatchNode() = 0; |
124 | |
125 | static QSGContext *createDefaultContext(); |
126 | static QQuickTextureFactory *createTextureFactoryFromImage(const QImage &image); |
127 | static QSGRenderLoop *createWindowManager(); |
128 | |
129 | static void setBackend(const QString &backend); |
130 | static QString backend(); |
131 | }; |
132 | |
133 | class Q_QUICK_EXPORT QSGRenderContext : public QObject |
134 | { |
135 | Q_OBJECT |
136 | public: |
137 | enum CreateTextureFlags { |
138 | CreateTexture_Alpha = 0x1, |
139 | CreateTexture_Atlas = 0x2, |
140 | CreateTexture_Mipmap = 0x4 |
141 | }; |
142 | |
143 | QSGRenderContext(QSGContext *context); |
144 | ~QSGRenderContext() override; |
145 | |
146 | QSGContext *sceneGraphContext() const { return m_sg; } |
147 | virtual bool isValid() const { return true; } |
148 | |
149 | struct InitParams { }; |
150 | virtual void initialize(const InitParams *params); |
151 | virtual void invalidate(); |
152 | |
153 | using RenderPassCallback = void (*)(void *); |
154 | |
155 | virtual void prepareSync(qreal devicePixelRatio, |
156 | QRhiCommandBuffer *cb, |
157 | const QQuickGraphicsConfiguration &config); |
158 | |
159 | virtual void beginNextFrame(QSGRenderer *renderer, const QSGRenderTarget &renderTarget, |
160 | RenderPassCallback mainPassRecordingStart, |
161 | RenderPassCallback mainPassRecordingEnd, |
162 | void *callbackUserData); |
163 | virtual void renderNextFrame(QSGRenderer *renderer) = 0; |
164 | virtual void endNextFrame(QSGRenderer *renderer); |
165 | |
166 | virtual void endSync(); |
167 | |
168 | virtual void preprocess(); |
169 | virtual void invalidateGlyphCaches(); |
170 | virtual QSGDistanceFieldGlyphCache *distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality); |
171 | virtual QSGCurveGlyphAtlas *curveGlyphAtlas(const QRawFont &font); |
172 | QSGTexture *textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window); |
173 | |
174 | virtual QSGTexture *createTexture(const QImage &image, uint flags = CreateTexture_Alpha) const = 0; |
175 | virtual QSGRenderer *createRenderer(QSGRendererInterface::RenderMode renderMode = QSGRendererInterface::RenderMode2D) = 0; |
176 | virtual QSGTexture *compressedTextureForFactory(const QSGCompressedTextureFactory *) const; |
177 | |
178 | virtual int maxTextureSize() const = 0; |
179 | |
180 | void unregisterFontengineForCleanup(QFontEngine *engine); |
181 | void registerFontengineForCleanup(QFontEngine *engine); |
182 | |
183 | virtual QRhi *rhi() const; |
184 | |
185 | Q_SIGNALS: |
186 | void initialized(); |
187 | void invalidated(); |
188 | void releaseCachedResourcesRequested(); |
189 | |
190 | public Q_SLOTS: |
191 | void textureFactoryDestroyed(QObject *o); |
192 | |
193 | protected: |
194 | struct FontKey { |
195 | FontKey(const QRawFont &font, int renderTypeQuality); |
196 | |
197 | QFontEngine::FaceId faceId; |
198 | QFont::Style style; |
199 | int weight; |
200 | int renderTypeQuality; |
201 | QString familyName; |
202 | QString styleName; |
203 | }; |
204 | friend bool operator==(const QSGRenderContext::FontKey &f1, const QSGRenderContext::FontKey &f2); |
205 | friend size_t qHash(const QSGRenderContext::FontKey &f, size_t seed); |
206 | |
207 | // Hold m_sg with QPointer in the rare case it gets deleted before us. |
208 | QPointer<QSGContext> m_sg; |
209 | |
210 | QMutex m_mutex; |
211 | QHash<QObject *, QSGTexture *> m_textures; |
212 | QSet<QSGTexture *> m_texturesToDelete; |
213 | QHash<FontKey, QSGDistanceFieldGlyphCache *> m_glyphCaches; |
214 | |
215 | // References to font engines that are currently in use by native rendering glyph nodes |
216 | // and which must be kept alive as long as they are used in the render thread. |
217 | QHash<QFontEngine *, int> m_fontEnginesToClean; |
218 | }; |
219 | |
220 | inline bool operator ==(const QSGRenderContext::FontKey &f1, const QSGRenderContext::FontKey &f2) |
221 | { |
222 | return f1.faceId == f2.faceId |
223 | && f1.style == f2.style |
224 | && f1.weight == f2.weight |
225 | && f1.renderTypeQuality == f2.renderTypeQuality |
226 | && f1.familyName == f2.familyName |
227 | && f1.styleName == f2.styleName; |
228 | } |
229 | |
230 | inline size_t qHash(const QSGRenderContext::FontKey &f, size_t seed = 0) |
231 | { |
232 | return qHashMulti(seed, args: f.faceId, args: f.renderTypeQuality, args: f.familyName, args: f.styleName, args: f.style, args: f.weight); |
233 | } |
234 | |
235 | |
236 | QT_END_NAMESPACE |
237 | |
238 | #endif // QSGCONTEXT_H |
239 | |