Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qsgrhitextureglyphcache.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 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
6#include <qrgb.h>
7#include <private/qdrawhelper_p.h>
8
10
13 const QColor &color)
15 m_rc(rc),
16 m_rhi(rc->rhi())
17{
18 // Some OpenGL implementations, for instance macOS, have issues with
19 // GL_ALPHA render targets. Similarly, BGRA may be problematic on GLES 2.0.
20 // So stick with plain image uploads on GL.
21 m_resizeWithTextureCopy = m_rhi->backend() != QRhi::OpenGLES2;
22}
23
25{
26 m_rc->deferredReleaseGlyphCacheTexture(m_texture);
27}
28
29QRhiTexture *QSGRhiTextureGlyphCache::createEmptyTexture(QRhiTexture::Format format)
30{
32 if (!t->create()) {
33 qWarning("Failed to build new glyph cache texture of size %dx%d", m_size.width(), m_size.height());
34 return nullptr;
35 }
36
37 QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates();
38
39 // The new texture must be cleared to 0 always, this cannot be avoided
40 // otherwise artifacts will occur around the glyphs.
43 data.fill(0, m_size.width() * m_size.height());
44 else
45 data.fill(0, m_size.width() * m_size.height() * 4);
46 QRhiTextureSubresourceUploadDescription subresDesc(data.constData(), data.size());
47 subresDesc.setSourceSize(m_size);
48 resourceUpdates->uploadTexture(t, QRhiTextureUploadEntry(0, 0, subresDesc));
49
50 return t;
51}
52
54{
55 width = qMax(128, width);
56 height = qMax(32, height);
57
58 if (!m_resizeWithTextureCopy)
60
61 m_size = QSize(width, height);
62}
63
65{
66 width = qMax(128, width);
67 height = qMax(32, height);
68
69 if (m_size.width() >= width && m_size.height() >= height)
70 return;
71
72 m_size = QSize(width, height);
73
74 if (m_texture) {
75 QRhiTexture *t = createEmptyTexture(m_texture->format());
76 if (!t)
77 return;
78
79 QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates();
80 if (m_resizeWithTextureCopy) {
81 resourceUpdates->copyTexture(t, m_texture);
82 } else {
84 QImage img = image();
85 prepareGlyphImage(&img);
87 const QSize oldSize = m_texture->pixelSize();
88 subresDesc.setSourceSize(QSize(qMin(oldSize.width(), width), qMin(oldSize.height(), height)));
89 resourceUpdates->uploadTexture(t, QRhiTextureUploadEntry(0, 0, subresDesc));
90 }
91
92 m_rc->deferredReleaseGlyphCacheTexture(m_texture);
93 m_texture = t;
94 }
95}
96
98{
99 Q_ASSERT(m_uploads.isEmpty());
100}
101
102void QSGRhiTextureGlyphCache::prepareGlyphImage(QImage *img)
103{
104 const int maskWidth = img->width();
105 const int maskHeight = img->height();
106#if Q_BYTE_ORDER != Q_BIG_ENDIAN
107 const bool supportsBgra = m_rhi->isTextureFormatSupported(QRhiTexture::BGRA8);
108#endif
109 m_bgra = false;
110
111 if (img->format() == QImage::Format_Mono) {
112 *img = img->convertToFormat(QImage::Format_Grayscale8);
113 } else if (img->depth() == 32) {
114 if (img->format() == QImage::Format_RGB32 || img->format() == QImage::Format_ARGB32_Premultiplied) {
115 // We need to make the alpha component equal to the average of the RGB values.
116 // This is needed when drawing sub-pixel antialiased text on translucent targets.
117 for (int y = 0; y < maskHeight; ++y) {
118 QRgb *src = (QRgb *) img->scanLine(y);
119 for (int x = 0; x < maskWidth; ++x) {
120 int r = qRed(src[x]);
121 int g = qGreen(src[x]);
122 int b = qBlue(src[x]);
123 int avg;
124 if (img->format() == QImage::Format_RGB32)
125 avg = (r + g + b + 1) / 3; // "+1" for rounding.
126 else // Format_ARGB_Premultiplied
127 avg = qAlpha(src[x]);
128
129 src[x] = qRgba(r, g, b, avg);
130#if Q_BYTE_ORDER != Q_BIG_ENDIAN
131 if (supportsBgra) {
132 m_bgra = true;
133 } else {
134 // swizzle the bits to accommodate for the RGBA upload.
135 src[x] = ARGB2RGBA(src[x]);
136 m_bgra = false;
137 }
138#endif
139 }
140 }
141 }
142 }
143}
144
145void QSGRhiTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, const QFixedPoint &subPixelPosition)
146{
148 QImage mask;
149
150 if (!m_resizeWithTextureCopy) {
151 QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition);
152 mask = image();
153 subresDesc.setSourceTopLeft(QPoint(c.x, c.y));
154 subresDesc.setSourceSize(QSize(c.w, c.h));
155 } else {
156 mask = textureMapForGlyph(glyph, subPixelPosition);
157 }
158
159 prepareGlyphImage(&mask);
160
161 subresDesc.setImage(mask);
162 subresDesc.setDestinationTopLeft(QPoint(c.x, c.y));
163 m_uploads.append(QRhiTextureUploadEntry(0, 0, subresDesc));
164}
165
167{
168 if (m_uploads.isEmpty())
169 return;
170
171 if (!m_texture) {
172 QRhiTexture::Format texFormat;
174 texFormat = m_bgra ? QRhiTexture::BGRA8 : QRhiTexture::RGBA8;
175 else // should be R8, but there is the OpenGL ES 2.0 nonsense
176 texFormat = QRhiTexture::RED_OR_ALPHA8;
177
178 m_texture = createEmptyTexture(texFormat);
179 if (!m_texture)
180 return;
181 }
182
183 QRhiResourceUpdateBatch *resourceUpdates = m_rc->glyphCacheResourceUpdates();
185 desc.setEntries(m_uploads.cbegin(), m_uploads.cend());
186 resourceUpdates->uploadTexture(m_texture, desc);
187 m_uploads.clear();
188}
189
191{
193 return 8;
194 else
195 return 1;
196}
197
199{
200 return m_rhi->resourceLimit(QRhi::TextureSizeMax);
201}
202
204{
205 if (!m_resizeWithTextureCopy)
206 return qMin(1024, m_rhi->resourceLimit(QRhi::TextureSizeMax));
207
208 return m_rhi->resourceLimit(QRhi::TextureSizeMax);
209}
210
212{
213 if (QRhiResourceUpdateBatch *resourceUpdates = m_rc->maybeGlyphCacheResourceUpdates()) {
214 mergeInto->merge(resourceUpdates);
216 }
217}
218
220{
221 // return true when the shaders for 8-bit formats need .a instead of .r
222 // when sampling the texture
224}
225
\inmodule QtCore
Definition qbytearray.h:57
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition qcolor.h:31
QFontEngine::GlyphFormat m_format
virtual void createTextureData(int width, int height) override
virtual void resizeTextureData(int width, int height) override
const QImage & image() const
virtual void fillTexture(const Coord &c, glyph_t glyph, const QFixedPoint &subPixelPosition) override
\inmodule QtGui
Definition qimage.h:37
@ Format_RGB32
Definition qimage.h:46
@ Format_Mono
Definition qimage.h:43
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
@ Format_Grayscale8
Definition qimage.h:66
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtGui
Definition qrhi.h:1694
void merge(QRhiResourceUpdateBatch *other)
Copies all queued operations from the other batch into this one.
Definition qrhi.cpp:8553
void uploadTexture(QRhiTexture *tex, const QRhiTextureUploadDescription &desc)
Enqueues uploading the image data for one or more mip levels in one or more layers of the texture tex...
Definition qrhi.cpp:8681
void copyTexture(QRhiTexture *dst, QRhiTexture *src, const QRhiTextureCopyDescription &desc=QRhiTextureCopyDescription())
Enqueues a texture-to-texture copy operation from src into dst as described by desc.
Definition qrhi.cpp:8718
void setSourceTopLeft(const QPoint &p)
Sets the source top-left position p.
Definition qrhi.h:667
void setDestinationTopLeft(const QPoint &p)
Sets the destination top-left position p.
Definition qrhi.h:661
void setSourceSize(const QSize &size)
Sets the source size in pixels.
Definition qrhi.h:664
void setImage(const QImage &image)
Sets image.
Definition qrhi.h:652
\inmodule QtGui
Definition qrhi.h:704
\inmodule QtGui
Definition qrhi.h:681
\inmodule QtGui
Definition qrhi.h:883
Format format() const
Definition qrhi.h:960
@ UsedAsTransferSource
Definition qrhi.h:890
Format
Specifies the texture format.
Definition qrhi.h:902
@ RED_OR_ALPHA8
Definition qrhi.h:911
QSize pixelSize() const
Definition qrhi.h:963
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags={}) const
Definition qrhi.cpp:9673
int resourceLimit(ResourceLimit limit) const
Definition qrhi.cpp:9692
bool isFeatureSupported(QRhi::Feature feature) const
Definition qrhi.cpp:9681
Implementation backend() const
Definition qrhi.cpp:8289
@ OpenGLES2
Definition qrhi.h:1772
@ TextureSizeMax
Definition qrhi.h:1848
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
Definition qrhi.cpp:10133
@ RedOrAlpha8IsRed
Definition qrhi.h:1804
void deferredReleaseGlyphCacheTexture(QRhiTexture *texture)
QRhiResourceUpdateBatch * maybeGlyphCacheResourceUpdates()
QRhiResourceUpdateBatch * glyphCacheResourceUpdates()
void resizeTextureData(int width, int height) override
void commitResourceUpdates(QRhiResourceUpdateBatch *mergeInto)
int maxTextureHeight() const override
QSGRhiTextureGlyphCache(QSGDefaultRenderContext *rc, QFontEngine::GlyphFormat format, const QTransform &matrix, const QColor &color=QColor())
void fillTexture(const Coord &c, glyph_t glyph, const QFixedPoint &subPixelPosition) override
void createTextureData(int width, int height) override
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:132
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
QImage textureMapForGlyph(glyph_t g, const QFixedPoint &subPixelPosition) const
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
bool isEmpty() const
const_iterator cbegin() const noexcept
const_iterator cend() const noexcept
void append(const T &t)
Combined button and popup list for selecting options.
#define qWarning
Definition qlogging.h:162
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLint GLsizei GLsizei height
GLboolean r
[2]
GLenum src
GLint GLsizei width
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLboolean GLboolean g
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLint y
const GLubyte * c
GLint void * img
Definition qopenglext.h:233
GLuint GLenum matrix
GLdouble GLdouble t
Definition qopenglext.h:243
static quint32 ARGB2RGBA(quint32 x)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
Definition qrgb.h:13
constexpr int qRed(QRgb rgb)
Definition qrgb.h:18
constexpr int qGreen(QRgb rgb)
Definition qrgb.h:21
constexpr QRgb qRgba(int r, int g, int b, int a)
Definition qrgb.h:33
constexpr int qBlue(QRgb rgb)
Definition qrgb.h:24
constexpr int qAlpha(QRgb rgb)
Definition qrgb.h:27
unsigned int glyph_t
@ desc
AvgFunction avg