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 | |
39 | QT_BEGIN_NAMESPACE |
40 | |
41 | class QSGNode; |
42 | class QImage; |
43 | class TextureReference; |
44 | class QSGDistanceFieldGlyphNode; |
45 | class QSGInternalImageNode; |
46 | class QSGPainterNode; |
47 | class QSGInternalRectangleNode; |
48 | class QSGGlyphNode; |
49 | class QSGRootNode; |
50 | class QSGSpriteNode; |
51 | class QSGRenderNode; |
52 | class QSGRenderContext; |
53 | class QRhiTexture; |
54 | |
55 | class Q_QUICK_PRIVATE_EXPORT QSGNodeVisitorEx |
56 | { |
57 | public: |
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 | |
92 | class Q_QUICK_PRIVATE_EXPORT QSGVisitableNode : public QSGGeometryNode |
93 | { |
94 | public: |
95 | QSGVisitableNode() { setFlag(IsVisitableNode); } |
96 | ~QSGVisitableNode() override; |
97 | |
98 | virtual void accept(QSGNodeVisitorEx *) = 0; |
99 | }; |
100 | |
101 | class Q_QUICK_PRIVATE_EXPORT QSGInternalRectangleNode : public QSGVisitableNode |
102 | { |
103 | public: |
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 setAntialiasing(bool antialiasing) { Q_UNUSED(antialiasing); } |
114 | virtual void setAligned(bool aligned) = 0; |
115 | |
116 | virtual void update() = 0; |
117 | |
118 | void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(node: this); visitor->endVisit(this); } |
119 | }; |
120 | |
121 | |
122 | class Q_QUICK_PRIVATE_EXPORT QSGInternalImageNode : public QSGVisitableNode |
123 | { |
124 | public: |
125 | ~QSGInternalImageNode() override; |
126 | |
127 | virtual void setTargetRect(const QRectF &rect) = 0; |
128 | virtual void setInnerTargetRect(const QRectF &rect) = 0; |
129 | virtual void setInnerSourceRect(const QRectF &rect) = 0; |
130 | // The sub-source rect's width and height specify the number of times the inner source rect |
131 | // is repeated inside the inner target rect. The x and y specify which (normalized) location |
132 | // in the inner source rect maps to the upper-left corner of the inner target rect. |
133 | virtual void setSubSourceRect(const QRectF &rect) = 0; |
134 | virtual void setTexture(QSGTexture *texture) = 0; |
135 | virtual void setAntialiasing(bool antialiasing) { Q_UNUSED(antialiasing); } |
136 | virtual void setMirror(bool horizontally, bool vertically) = 0; |
137 | virtual void setMipmapFiltering(QSGTexture::Filtering filtering) = 0; |
138 | virtual void setFiltering(QSGTexture::Filtering filtering) = 0; |
139 | virtual void setHorizontalWrapMode(QSGTexture::WrapMode wrapMode) = 0; |
140 | virtual void setVerticalWrapMode(QSGTexture::WrapMode wrapMode) = 0; |
141 | |
142 | virtual void update() = 0; |
143 | |
144 | void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(node: this); visitor->endVisit(this); } |
145 | }; |
146 | |
147 | class Q_QUICK_PRIVATE_EXPORT QSGPainterNode : public QSGVisitableNode |
148 | { |
149 | public: |
150 | ~QSGPainterNode() override; |
151 | |
152 | virtual void setPreferredRenderTarget(QQuickPaintedItem::RenderTarget target) = 0; |
153 | virtual void setSize(const QSize &size) = 0; |
154 | virtual void setDirty(const QRect &dirtyRect = QRect()) = 0; |
155 | virtual void setOpaquePainting(bool opaque) = 0; |
156 | virtual void setLinearFiltering(bool linearFiltering) = 0; |
157 | virtual void setMipmapping(bool mipmapping) = 0; |
158 | virtual void setSmoothPainting(bool s) = 0; |
159 | virtual void setFillColor(const QColor &c) = 0; |
160 | virtual void setContentsScale(qreal s) = 0; |
161 | virtual void setFastFBOResizing(bool dynamic) = 0; |
162 | virtual void setTextureSize(const QSize &size) = 0; |
163 | |
164 | virtual QImage toImage() const = 0; |
165 | virtual void update() = 0; |
166 | virtual QSGTexture *texture() const = 0; |
167 | |
168 | void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(node: this); visitor->endVisit(this); } |
169 | }; |
170 | |
171 | class Q_QUICK_EXPORT QSGLayer : public QSGDynamicTexture |
172 | { |
173 | Q_OBJECT |
174 | public: |
175 | ~QSGLayer() override; |
176 | |
177 | enum Format { |
178 | RGBA8 = 1, |
179 | RGBA16F, |
180 | RGBA32F |
181 | }; |
182 | virtual void setItem(QSGNode *item) = 0; |
183 | virtual void setRect(const QRectF &logicalRect) = 0; |
184 | virtual void setSize(const QSize &pixelSize) = 0; |
185 | virtual void scheduleUpdate() = 0; |
186 | virtual QImage toImage() const = 0; |
187 | virtual void setLive(bool live) = 0; |
188 | virtual void setRecursive(bool recursive) = 0; |
189 | virtual void setFormat(Format format) = 0; |
190 | virtual void setHasMipmaps(bool mipmap) = 0; |
191 | virtual void setDevicePixelRatio(qreal ratio) = 0; |
192 | virtual void setMirrorHorizontal(bool mirror) = 0; |
193 | virtual void setMirrorVertical(bool mirror) = 0; |
194 | virtual void setSamples(int samples) = 0; |
195 | Q_SLOT virtual void markDirtyTexture() = 0; |
196 | Q_SLOT virtual void invalidated() = 0; |
197 | |
198 | Q_SIGNALS: |
199 | void updateRequested(); |
200 | void scheduledUpdateCompleted(); |
201 | |
202 | protected: |
203 | QSGLayer(QSGTexturePrivate &dd); |
204 | }; |
205 | |
206 | #if QT_CONFIG(quick_sprite) |
207 | |
208 | class Q_QUICK_PRIVATE_EXPORT QSGSpriteNode : public QSGVisitableNode |
209 | { |
210 | public: |
211 | ~QSGSpriteNode() override; |
212 | |
213 | virtual void setTexture(QSGTexture *texture) = 0; |
214 | virtual void setTime(float time) = 0; |
215 | virtual void setSourceA(const QPoint &source) = 0; |
216 | virtual void setSourceB(const QPoint &source) = 0; |
217 | virtual void setSpriteSize(const QSize &size) = 0; |
218 | virtual void setSheetSize(const QSize &size) = 0; |
219 | virtual void setSize(const QSizeF &size) = 0; |
220 | virtual void setFiltering(QSGTexture::Filtering filtering) = 0; |
221 | |
222 | virtual void update() = 0; |
223 | |
224 | void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(node: this); visitor->endVisit(this); } |
225 | }; |
226 | |
227 | #endif |
228 | |
229 | class Q_QUICK_PRIVATE_EXPORT QSGGuiThreadShaderEffectManager : public QObject |
230 | { |
231 | Q_OBJECT |
232 | |
233 | public: |
234 | ~QSGGuiThreadShaderEffectManager() override; |
235 | |
236 | enum Status { |
237 | Compiled, |
238 | Uncompiled, |
239 | Error |
240 | }; |
241 | |
242 | virtual bool hasSeparateSamplerAndTextureObjects() const = 0; |
243 | |
244 | virtual QString log() const = 0; |
245 | virtual Status status() const = 0; |
246 | |
247 | struct ShaderInfo { |
248 | enum Type { |
249 | TypeVertex, |
250 | TypeFragment, |
251 | TypeOther |
252 | }; |
253 | enum VariableType { |
254 | Constant, // cbuffer members or uniforms |
255 | Sampler, |
256 | Texture // for APIs with separate texture and sampler objects |
257 | }; |
258 | struct Variable { |
259 | VariableType type = Constant; |
260 | QByteArray name; |
261 | uint offset = 0; // for cbuffer members |
262 | uint size = 0; // for cbuffer members |
263 | int bindPoint = 0; // for textures/samplers, where applicable |
264 | }; |
265 | |
266 | QString name; // optional, f.ex. the filename, used for debugging purposes only |
267 | QShader rhiShader; |
268 | Type type; |
269 | QVector<Variable> variables; |
270 | uint constantDataSize; |
271 | |
272 | // Vertex inputs are not tracked here as QSGGeometry::AttributeSet |
273 | // hardwires that anyways so it is up to the shader to provide |
274 | // compatible inputs (e.g. compatible with |
275 | // QSGGeometry::defaultAttributes_TexturedPoint2D()). |
276 | }; |
277 | |
278 | virtual void prepareShaderCode(ShaderInfo::Type typeHint, const QUrl &src, ShaderInfo *result) = 0; |
279 | |
280 | Q_SIGNALS: |
281 | void shaderCodePrepared(bool ok, ShaderInfo::Type typeHint, const QUrl &src, ShaderInfo *result); |
282 | void logAndStatusChanged(); |
283 | }; |
284 | |
285 | #ifndef QT_NO_DEBUG_STREAM |
286 | Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug debug, const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &v); |
287 | #endif |
288 | |
289 | class Q_QUICK_PRIVATE_EXPORT QSGShaderEffectNode : public QObject, public QSGVisitableNode |
290 | { |
291 | Q_OBJECT |
292 | |
293 | public: |
294 | ~QSGShaderEffectNode() override; |
295 | |
296 | enum DirtyShaderFlag { |
297 | DirtyShaders = 0x01, |
298 | DirtyShaderConstant = 0x02, |
299 | DirtyShaderTexture = 0x04, |
300 | DirtyShaderGeometry = 0x08, |
301 | DirtyShaderMesh = 0x10, |
302 | |
303 | DirtyShaderAll = 0xFF |
304 | }; |
305 | Q_DECLARE_FLAGS(DirtyShaderFlags, DirtyShaderFlag) |
306 | |
307 | enum CullMode { // must match ShaderEffect |
308 | NoCulling, |
309 | BackFaceCulling, |
310 | FrontFaceCulling |
311 | }; |
312 | |
313 | struct VariableData { |
314 | enum SpecialType { None, Unused, Source, SubRect, Opacity, Matrix }; |
315 | |
316 | QVariant value; |
317 | SpecialType specialType; |
318 | int propertyIndex = -1; |
319 | }; |
320 | |
321 | struct ShaderData { |
322 | ShaderData() {} |
323 | bool hasShaderCode = false; |
324 | QSGGuiThreadShaderEffectManager::ShaderInfo shaderInfo; |
325 | QVector<VariableData> varData; |
326 | }; |
327 | |
328 | struct SyncData { |
329 | DirtyShaderFlags dirty; |
330 | CullMode cullMode; |
331 | bool blending; |
332 | struct ShaderSyncData { |
333 | const ShaderData *shader; |
334 | const QSet<int> *dirtyConstants; |
335 | const QSet<int> *dirtyTextures; |
336 | }; |
337 | ShaderSyncData vertex; |
338 | ShaderSyncData fragment; |
339 | void *materialTypeCacheKey; |
340 | }; |
341 | |
342 | // Each ShaderEffect item has one node (render thread) and one manager (gui thread). |
343 | |
344 | virtual QRectF updateNormalizedTextureSubRect(bool supportsAtlasTextures) = 0; |
345 | virtual void syncMaterial(SyncData *syncData) = 0; |
346 | |
347 | void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(node: this); visitor->endVisit(this); } |
348 | |
349 | Q_SIGNALS: |
350 | void textureChanged(); |
351 | }; |
352 | |
353 | Q_DECLARE_OPERATORS_FOR_FLAGS(QSGShaderEffectNode::DirtyShaderFlags) |
354 | |
355 | #ifndef QT_NO_DEBUG_STREAM |
356 | Q_QUICK_PRIVATE_EXPORT QDebug operator<<(QDebug debug, const QSGShaderEffectNode::VariableData &vd); |
357 | #endif |
358 | |
359 | class Q_QUICK_PRIVATE_EXPORT QSGGlyphNode : public QSGVisitableNode |
360 | { |
361 | public: |
362 | enum AntialiasingMode |
363 | { |
364 | DefaultAntialiasing = -1, |
365 | GrayAntialiasing, |
366 | LowQualitySubPixelAntialiasing, |
367 | HighQualitySubPixelAntialiasing |
368 | }; |
369 | |
370 | QSGGlyphNode() {} |
371 | ~QSGGlyphNode() override; |
372 | |
373 | virtual void setGlyphs(const QPointF &position, const QGlyphRun &glyphs) = 0; |
374 | virtual void setColor(const QColor &color) = 0; |
375 | virtual void setStyle(QQuickText::TextStyle style) = 0; |
376 | virtual void setStyleColor(const QColor &color) = 0; |
377 | virtual QPointF baseLine() const = 0; |
378 | |
379 | virtual QRectF boundingRect() const { return m_bounding_rect; } |
380 | virtual void setBoundingRect(const QRectF &bounds) { m_bounding_rect = bounds; } |
381 | |
382 | virtual void setPreferredAntialiasingMode(AntialiasingMode) = 0; |
383 | virtual void setRenderTypeQuality(int renderTypeQuality) { Q_UNUSED(renderTypeQuality) } |
384 | |
385 | virtual void update() = 0; |
386 | |
387 | void setOwnerElement(QQuickItem *ownerElement) { m_ownerElement = ownerElement; } |
388 | QQuickItem *ownerElement() const { return m_ownerElement; } |
389 | |
390 | void accept(QSGNodeVisitorEx *visitor) override { if (visitor->visit(this)) visitor->visitChildren(node: this); visitor->endVisit(this); } |
391 | protected: |
392 | QRectF m_bounding_rect; |
393 | QQuickItem *m_ownerElement = nullptr; |
394 | }; |
395 | |
396 | class Q_QUICK_PRIVATE_EXPORT QSGDistanceFieldGlyphConsumer |
397 | { |
398 | public: |
399 | virtual ~QSGDistanceFieldGlyphConsumer(); |
400 | |
401 | virtual void invalidateGlyphs(const QVector<quint32> &glyphs) = 0; |
402 | QIntrusiveListNode node; |
403 | }; |
404 | typedef QIntrusiveList<QSGDistanceFieldGlyphConsumer, &QSGDistanceFieldGlyphConsumer::node> QSGDistanceFieldGlyphConsumerList; |
405 | |
406 | class Q_QUICK_PRIVATE_EXPORT QSGDistanceFieldGlyphCache |
407 | { |
408 | public: |
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 registerOwnerElement(QQuickItem *ownerElement); |
472 | virtual void unregisterOwnerElement(QQuickItem *ownerElement); |
473 | virtual void processPendingGlyphs(); |
474 | |
475 | virtual bool eightBitFormatIsAlphaSwizzled() const = 0; |
476 | virtual bool screenSpaceDerivativesSupported() const = 0; |
477 | virtual bool isActive() const; |
478 | |
479 | protected: |
480 | struct GlyphPosition { |
481 | glyph_t glyph; |
482 | QPointF position; |
483 | }; |
484 | |
485 | struct GlyphData { |
486 | Texture *texture = nullptr; |
487 | TexCoord texCoord; |
488 | QRectF boundingRect; |
489 | QPainterPath path; |
490 | quint32 ref = 0; |
491 | |
492 | GlyphData() {} |
493 | }; |
494 | |
495 | virtual void requestGlyphs(const QSet<glyph_t> &glyphs) = 0; |
496 | virtual void storeGlyphs(const QList<QDistanceField> &glyphs) = 0; |
497 | virtual void referenceGlyphs(const QSet<glyph_t> &glyphs) = 0; |
498 | virtual void releaseGlyphs(const QSet<glyph_t> &glyphs) = 0; |
499 | |
500 | void setGlyphsPosition(const QList<GlyphPosition> &glyphs); |
501 | void setGlyphsTexture(const QVector<glyph_t> &glyphs, const Texture &tex); |
502 | void markGlyphsToRender(const QVector<glyph_t> &glyphs); |
503 | inline void removeGlyph(glyph_t glyph); |
504 | |
505 | void updateRhiTexture(QRhiTexture *oldTex, QRhiTexture *newTex, const QSize &newTexSize); |
506 | |
507 | inline bool containsGlyph(glyph_t glyph); |
508 | |
509 | GlyphData &glyphData(glyph_t glyph); |
510 | GlyphData &emptyData(glyph_t glyph); |
511 | |
512 | int baseFontSize() const; |
513 | |
514 | #if defined(QSG_DISTANCEFIELD_CACHE_DEBUG) |
515 | virtual void saveTexture(QRhiTexture *texture, const QString &nameBase) const = 0; |
516 | #endif |
517 | |
518 | bool m_doubleGlyphResolution; |
519 | int m_renderTypeQuality; |
520 | |
521 | protected: |
522 | QRawFont m_referenceFont; |
523 | |
524 | private: |
525 | int m_glyphCount; |
526 | QList<Texture> m_textures; |
527 | QHash<glyph_t, GlyphData> m_glyphsData; |
528 | QDataBuffer<glyph_t> m_pendingGlyphs; |
529 | QSet<glyph_t> m_populatingGlyphs; |
530 | QSGDistanceFieldGlyphConsumerList m_registeredNodes; |
531 | |
532 | static Texture s_emptyTexture; |
533 | }; |
534 | |
535 | inline QSGDistanceFieldGlyphCache::TexCoord QSGDistanceFieldGlyphCache::glyphTexCoord(glyph_t glyph) |
536 | { |
537 | return glyphData(glyph).texCoord; |
538 | } |
539 | |
540 | inline const QSGDistanceFieldGlyphCache::Texture *QSGDistanceFieldGlyphCache::glyphTexture(glyph_t glyph) |
541 | { |
542 | return glyphData(glyph).texture; |
543 | } |
544 | |
545 | inline void QSGDistanceFieldGlyphCache::removeGlyph(glyph_t glyph) |
546 | { |
547 | GlyphData &gd = glyphData(glyph); |
548 | gd.texCoord = TexCoord(); |
549 | gd.texture = &s_emptyTexture; |
550 | } |
551 | |
552 | inline bool QSGDistanceFieldGlyphCache::containsGlyph(glyph_t glyph) |
553 | { |
554 | return glyphData(glyph).texCoord.isValid(); |
555 | } |
556 | |
557 | QT_END_NAMESPACE |
558 | |
559 | Q_DECLARE_METATYPE(QSGGuiThreadShaderEffectManager::ShaderInfo::Type) |
560 | |
561 | #endif |
562 | |