Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qopengltextureglyphcache.cpp
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
5#include <private/qopenglpaintengine_p.h>
6#include "private/qopenglengineshadersource_p.h"
7#include <private/qopenglextensions_p.h>
8#include <qrgb.h>
9#include <private/qdrawhelper_p.h>
10
12
13
15{
16 Q_CONSTINIT static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0);
17 return 1 + serial.fetchAndAddRelaxed(1);
18}
19
22 , m_textureResource(nullptr)
23 , pex(nullptr)
24 , m_blitProgram(nullptr)
25 , m_filterMode(Nearest)
27 , m_buffer(QOpenGLBuffer::VertexBuffer)
28{
29#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
30 qDebug(" -> QOpenGLTextureGlyphCache() %p for context %p.", this, QOpenGLContext::currentContext());
31#endif
32 m_vertexCoordinateArray[0] = -1.0f;
33 m_vertexCoordinateArray[1] = -1.0f;
34 m_vertexCoordinateArray[2] = 1.0f;
35 m_vertexCoordinateArray[3] = -1.0f;
36 m_vertexCoordinateArray[4] = 1.0f;
37 m_vertexCoordinateArray[5] = 1.0f;
38 m_vertexCoordinateArray[6] = -1.0f;
39 m_vertexCoordinateArray[7] = 1.0f;
40
41 m_textureCoordinateArray[0] = 0.0f;
42 m_textureCoordinateArray[1] = 0.0f;
43 m_textureCoordinateArray[2] = 1.0f;
44 m_textureCoordinateArray[3] = 0.0f;
45 m_textureCoordinateArray[4] = 1.0f;
46 m_textureCoordinateArray[5] = 1.0f;
47 m_textureCoordinateArray[6] = 0.0f;
48 m_textureCoordinateArray[7] = 1.0f;
49}
50
52{
53#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG
54 qDebug(" -> ~QOpenGLTextureGlyphCache() %p.", this);
55#endif
56 clear();
57}
58
59#if !QT_CONFIG(opengles2)
60static inline bool isCoreProfile()
61{
62 return QOpenGLContext::currentContext()->format().profile() == QSurfaceFormat::CoreProfile;
63}
64#endif
65
67{
69 if (ctx == nullptr) {
70 qWarning("QOpenGLTextureGlyphCache::createTextureData: Called with no context");
71 return;
72 }
73
74 // create in QImageTextureGlyphCache baseclass is meant to be called
75 // only to create the initial image and does not preserve the content,
76 // so we don't call when this function is called from resize.
77 if (ctx->d_func()->workaround_brokenFBOReadBack && image().isNull())
79
80 // Make the lower glyph texture size 16 x 16.
81 if (width < 16)
82 width = 16;
83 if (height < 16)
84 height = 16;
85
86 if (m_textureResource && !m_textureResource->m_texture) {
87 delete m_textureResource;
88 m_textureResource = nullptr;
89 }
90
91 if (!m_textureResource)
92 m_textureResource = new QOpenGLGlyphTexture(ctx);
93
94 QOpenGLFunctions *funcs = ctx->functions();
95 funcs->glGenTextures(1, &m_textureResource->m_texture);
96 funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
97
98 m_textureResource->m_width = width;
99 m_textureResource->m_height = height;
100
102 QVarLengthArray<uchar> data(width * height * 4);
103 for (int i = 0; i < data.size(); ++i)
104 data[i] = 0;
105 funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
106 } else {
107 QVarLengthArray<uchar> data(width * height);
108 for (int i = 0; i < data.size(); ++i)
109 data[i] = 0;
110#if !QT_CONFIG(opengles2)
111 const GLint internalFormat = isCoreProfile() ? GL_R8 : GL_ALPHA;
112 const GLenum format = isCoreProfile() ? GL_RED : GL_ALPHA;
113#else
114 const GLint internalFormat = GL_ALPHA;
115 const GLenum format = GL_ALPHA;
116#endif
117 funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, &data[0]);
118 }
119
120 funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
121 funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
122 funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
123 funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
124 m_filterMode = Nearest;
125
126 if (!m_buffer.isCreated()) {
127 m_buffer.create();
128 m_buffer.bind();
129 static GLfloat buf[sizeof(m_vertexCoordinateArray) + sizeof(m_textureCoordinateArray)];
130 memcpy(buf, m_vertexCoordinateArray, sizeof(m_vertexCoordinateArray));
131 memcpy(buf + (sizeof(m_vertexCoordinateArray) / sizeof(GLfloat)),
132 m_textureCoordinateArray,
133 sizeof(m_textureCoordinateArray));
134 m_buffer.allocate(buf, sizeof(buf));
135 m_buffer.release();
136 }
137
138 if (!m_vao.isCreated())
139 m_vao.create();
140}
141
142void QOpenGLTextureGlyphCache::setupVertexAttribs()
143{
144 m_buffer.bind();
145 m_blitProgram->setAttributeBuffer(int(QT_VERTEX_COORDS_ATTR), GL_FLOAT, 0, 2);
146 m_blitProgram->setAttributeBuffer(int(QT_TEXTURE_COORDS_ATTR), GL_FLOAT, sizeof(m_vertexCoordinateArray), 2);
147 m_blitProgram->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR));
148 m_blitProgram->enableAttributeArray(int(QT_TEXTURE_COORDS_ATTR));
149 m_buffer.release();
150}
151
153 QImage &img,
155 int tx, int ty)
156{
157 QOpenGLFunctions *funcs = ctx->functions();
158
159 const int imgWidth = img.width();
160 const int imgHeight = img.height();
161
162 if (img.format() == QImage::Format_Mono) {
163 img = img.convertToFormat(QImage::Format_Grayscale8);
164 } else if (img.depth() == 32) {
165 if (img.format() == QImage::Format_RGB32
166 // We need to make the alpha component equal to the average of the RGB values.
167 // This is needed when drawing sub-pixel antialiased text on translucent targets.
168#if Q_BYTE_ORDER == Q_BIG_ENDIAN
170#else
172 && ctx->isOpenGLES())
173#endif
174 ) {
175 for (int y = 0; y < imgHeight; ++y) {
176 QRgb *src = (QRgb *) img.scanLine(y);
177 for (int x = 0; x < imgWidth; ++x) {
178 int r = qRed(src[x]);
179 int g = qGreen(src[x]);
180 int b = qBlue(src[x]);
181 int avg;
182 if (img.format() == QImage::Format_RGB32)
183 avg = (r + g + b + 1) / 3; // "+1" for rounding.
184 else // Format_ARGB_Premultiplied
185 avg = qAlpha(src[x]);
186
187 src[x] = qRgba(r, g, b, avg);
188 // swizzle the bits to accommodate for the GL_RGBA upload.
189#if Q_BYTE_ORDER != Q_BIG_ENDIAN
190 if (ctx->isOpenGLES())
191#endif
192 src[x] = ARGB2RGBA(src[x]);
193 }
194 }
195 }
196 }
197
198 funcs->glBindTexture(GL_TEXTURE_2D, texture);
199 if (img.depth() == 32) {
200#if QT_CONFIG(opengles2)
202#else
203 GLenum fmt = ctx->isOpenGLES() ? GL_RGBA : GL_BGRA;
204#endif // QT_CONFIG(opengles2)
205
206#if Q_BYTE_ORDER == Q_BIG_ENDIAN
207 fmt = GL_RGBA;
208#endif
209 funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, imgWidth, imgHeight, fmt, GL_UNSIGNED_BYTE, img.constBits());
210 } else {
211 // The scanlines in image are 32-bit aligned, even for mono or 8-bit formats. This
212 // is good because it matches the default of 4 bytes for GL_UNPACK_ALIGNMENT.
213#if !QT_CONFIG(opengles2)
214 const GLenum format = isCoreProfile() ? GL_RED : GL_ALPHA;
215#else
216 const GLenum format = GL_ALPHA;
217#endif
218 funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, tx, ty, imgWidth, imgHeight, format, GL_UNSIGNED_BYTE, img.constBits());
219 }
220}
221
223 const QImage &srcImg,
224 int x, int y,
225 int w, int h,
227 int tx, int ty)
228{
229 Q_ASSERT(x + w <= srcImg.width() && y + h <= srcImg.height());
230
231 QImage img;
232 if (x != 0 || y != 0 || w != srcImg.width() || h != srcImg.height())
233 img = srcImg.copy(x, y, w, h);
234 else
235 img = srcImg;
236
238}
239
241{
243 if (ctx == nullptr) {
244 qWarning("QOpenGLTextureGlyphCache::resizeTextureData: Called with no context");
245 return;
246 }
247
248 QOpenGLFunctions *funcs = ctx->functions();
249 GLint oldFbo;
250 funcs->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFbo);
251
252 int oldWidth = m_textureResource->m_width;
253 int oldHeight = m_textureResource->m_height;
254
255 // Make the lower glyph texture size 16 x 16.
256 if (width < 16)
257 width = 16;
258 if (height < 16)
259 height = 16;
260
261 GLuint oldTexture = m_textureResource->m_texture;
263
264 if (ctx->d_func()->workaround_brokenFBOReadBack) {
266 load_glyph_image_region_to_texture(ctx, image(), 0, 0, qMin(oldWidth, width), qMin(oldHeight, height),
267 m_textureResource->m_texture, 0, 0);
268 return;
269 }
270
271 // ### the QTextureGlyphCache API needs to be reworked to allow
272 // ### resizeTextureData to fail
273
274 funcs->glBindFramebuffer(GL_FRAMEBUFFER, m_textureResource->m_fbo);
275
276 GLuint tmp_texture;
277 funcs->glGenTextures(1, &tmp_texture);
278 funcs->glBindTexture(GL_TEXTURE_2D, tmp_texture);
279 funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0,
280 GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
281 funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
282 funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
283 funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
284 funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
285 m_filterMode = Nearest;
286 funcs->glBindTexture(GL_TEXTURE_2D, 0);
287 funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
288 GL_TEXTURE_2D, tmp_texture, 0);
289
290 funcs->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
291 funcs->glBindTexture(GL_TEXTURE_2D, oldTexture);
292
293 if (pex != nullptr)
295
296 funcs->glDisable(GL_STENCIL_TEST);
297 funcs->glDisable(GL_DEPTH_TEST);
298 funcs->glDisable(GL_SCISSOR_TEST);
299 funcs->glDisable(GL_BLEND);
300
301 funcs->glViewport(0, 0, oldWidth, oldHeight);
302
303 QOpenGLShaderProgram *blitProgram = nullptr;
304 if (pex == nullptr) {
305 if (m_blitProgram == nullptr) {
306 m_blitProgram = new QOpenGLShaderProgram;
307 const bool isCoreProfile = ctx->format().profile() == QSurfaceFormat::CoreProfile;
308
309 {
311#ifdef Q_OS_WASM
312 source.append(QLatin1StringView(isCoreProfile ? qopenglslUntransformedPositionVertexShader_core : qopenglslUntransformedPositionVertexShader));
313 source.append(QLatin1StringView(isCoreProfile ? qopenglslMainWithTexCoordsVertexShader_core : qopenglslMainWithTexCoordsVertexShader));
314#else
315 source.append(QLatin1StringView(isCoreProfile ? qopenglslMainWithTexCoordsVertexShader_core : qopenglslMainWithTexCoordsVertexShader));
316 source.append(QLatin1StringView(isCoreProfile ? qopenglslUntransformedPositionVertexShader_core : qopenglslUntransformedPositionVertexShader));
317#endif
319 }
320
321 {
323#ifdef Q_OS_WASM
324 source.append(QLatin1StringView(isCoreProfile ? qopenglslImageSrcFragmentShader_core : qopenglslImageSrcFragmentShader));
325 source.append(QLatin1StringView(isCoreProfile ? qopenglslMainFragmentShader_core : qopenglslMainFragmentShader));
326#else
327 source.append(QLatin1StringView(isCoreProfile ? qopenglslMainFragmentShader_core : qopenglslMainFragmentShader));
328 source.append(QLatin1StringView(isCoreProfile ? qopenglslImageSrcFragmentShader_core : qopenglslImageSrcFragmentShader));
329#endif
331 }
332
333 m_blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR);
334 m_blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR);
335
336 m_blitProgram->link();
337
338 if (m_vao.isCreated()) {
339 m_vao.bind();
340 setupVertexAttribs();
341 }
342 }
343
344 if (m_vao.isCreated())
345 m_vao.bind();
346 else
347 setupVertexAttribs();
348
349 m_blitProgram->bind();
350 blitProgram = m_blitProgram;
351
352 } else {
353 pex->uploadData(QT_VERTEX_COORDS_ATTR, m_vertexCoordinateArray, 8);
354 pex->uploadData(QT_TEXTURE_COORDS_ATTR, m_textureCoordinateArray, 8);
355
357 blitProgram = pex->shaderManager->blitProgram();
358 }
359
360 blitProgram->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT);
361
362 funcs->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
363
364 funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
365
366 funcs->glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight);
367
368 funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
369 GL_RENDERBUFFER, 0);
370 funcs->glDeleteTextures(1, &tmp_texture);
371 funcs->glDeleteTextures(1, &oldTexture);
372
373 funcs->glBindFramebuffer(GL_FRAMEBUFFER, (GLuint)oldFbo);
374
375 if (pex != nullptr) {
376 funcs->glViewport(0, 0, pex->width, pex->height);
378 } else {
379 if (m_vao.isCreated()) {
380 m_vao.release();
381 } else {
382 m_blitProgram->disableAttributeArray(int(QT_VERTEX_COORDS_ATTR));
384 }
385 }
386}
387
389 glyph_t glyph,
390 const QFixedPoint &subPixelPosition)
391{
393 if (ctx == nullptr) {
394 qWarning("QOpenGLTextureGlyphCache::fillTexture: Called with no context");
395 return;
396 }
397
398 if (ctx->d_func()->workaround_brokenFBOReadBack) {
399 QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition);
400 load_glyph_image_region_to_texture(ctx, image(), c.x, c.y, c.w, c.h, m_textureResource->m_texture, c.x, c.y);
401 return;
402 }
403
404 QImage mask = textureMapForGlyph(glyph, subPixelPosition);
405 load_glyph_image_to_texture(ctx, mask, m_textureResource->m_texture, c.x, c.y);
406}
407
409{
411 return 8;
412 else
413 return 1;
414}
415
417{
419 if (ctx == nullptr)
421 else
422 return ctx->d_func()->maxTextureSize();
423}
424
426{
428 if (ctx == nullptr)
430
431 if (ctx->d_func()->workaround_brokenTexSubImage)
432 return qMin(1024, ctx->d_func()->maxTextureSize());
433 else
434 return ctx->d_func()->maxTextureSize();
435}
436
438{
439 if (m_textureResource)
440 m_textureResource->free();
441 m_textureResource = nullptr;
442
443 delete m_blitProgram;
444 m_blitProgram = nullptr;
445
446 m_w = 0;
447 m_h = 0;
448 m_cx = 0;
449 m_cy = 0;
451 coords.clear();
452}
453
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
QImage copy(const QRect &rect=QRect()) const
Returns a sub-area of the image as a new image.
@ 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
QOpenGLEngineShaderManager * shaderManager
void transferMode(EngineMode newMode)
void uploadData(unsigned int arrayIndex, const GLfloat *data, GLuint count)
The QOpenGLBuffer class provides functions for creating and managing OpenGL buffer objects.
bool bind()
Binds the buffer associated with this object to the current OpenGL context.
bool create()
Creates the buffer object in the OpenGL server.
bool isCreated() const
Returns true if this buffer has been created; false otherwise.
void allocate(const void *data, int count)
Allocates count bytes of space to the buffer, initialized to the contents of data.
void release()
Releases the buffer associated with this object from the current OpenGL context.
\inmodule QtGui
static QOpenGLContext * currentContext()
Returns the last context which called makeCurrent in the current thread, or \nullptr,...
The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
The QOpenGLShaderProgram class allows OpenGL shader programs to be linked and used.
void bindAttributeLocation(const char *name, int location)
Binds the attribute name to the specified location.
void enableAttributeArray(int location)
Enables the vertex array at location in this shader program so that the value set by setAttributeArra...
virtual bool link()
Links together the shaders that were added to this program with addShader().
void setUniformValue(int location, GLfloat value)
Sets the uniform variable at location in the current context to value.
void disableAttributeArray(int location)
Disables the vertex array at location in this shader program that was enabled by a previous call to e...
bool addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type, const char *source)
Registers the shader of the specified type and source to this program.
bool bind()
Binds this shader program to the active QOpenGLContext and makes it the current shader program.
void setAttributeBuffer(int location, GLenum type, int offset, int tupleSize, int stride=0)
Sets an array of vertex values on the attribute at location in this shader program,...
virtual int glyphPadding() const override
virtual int maxTextureWidth() const override
virtual void createTextureData(int width, int height) override
virtual int maxTextureHeight() const override
virtual void resizeTextureData(int width, int height) override
virtual void fillTexture(const Coord &c, glyph_t glyph, const QFixedPoint &subPixelPosition) override
QOpenGLTextureGlyphCache(QFontEngine::GlyphFormat glyphFormat, const QTransform &matrix, const QColor &color=QColor())
void release()
Unbinds this vertex array object by binding the default vertex array object (id = 0).
bool create()
Creates the underlying OpenGL vertex array object.
bool isCreated() const
Returns true is the underlying OpenGL vertex array object has been created.
void bind()
Binds this vertex array object to the OpenGL binding point.
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
virtual int maxTextureHeight() const
QImage textureMapForGlyph(glyph_t g, const QFixedPoint &subPixelPosition) const
virtual int maxTextureWidth() const
The QTransform class specifies 2D transformations of a coordinate system.
Definition qtransform.h:20
EGLContext ctx
static VulkanServerBufferGlFunctions * funcs
Combined button and popup list for selecting options.
Definition image.cpp:4
#define Q_BASIC_ATOMIC_INITIALIZER(a)
#define qDebug
[1]
Definition qlogging.h:164
#define qWarning
Definition qlogging.h:166
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
static const GLuint QT_TEXTURE_COORDS_ATTR
static QT_BEGIN_NAMESPACE const GLuint QT_VERTEX_COORDS_ATTR
static const char *const qopenglslImageSrcFragmentShader
static const char *const qopenglslUntransformedPositionVertexShader
static const char *const qopenglslMainFragmentShader
static const char *const qopenglslMainWithTexCoordsVertexShader
GLboolean GLboolean GLboolean b
typedef GLint(GL_APIENTRYP PFNGLGETPROGRAMRESOURCELOCATIONINDEXEXTPROC)(GLuint program
GLint GLint GLint GLint GLint x
[0]
typedef GLfloat(GL_APIENTRYP PFNGLGETPATHLENGTHNVPROC)(GLuint path
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLboolean r
[2]
GLsizei const GLubyte GLsizei GLenum const void * coords
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum src
GLint GLsizei width
GLuint color
[2]
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum GLuint texture
GLboolean GLboolean g
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLint y
GLsizei GLenum internalFormat
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
#define GL_TEXTURE0
Definition qopenglext.h:129
const GLubyte * c
#define GL_R8
GLint void * img
Definition qopenglext.h:233
#define GL_COLOR_ATTACHMENT0
#define GL_BGRA
Definition qopenglext.h:97
GLuint GLenum matrix
#define GL_RENDERBUFFER
#define GL_FRAMEBUFFER
#define GL_FRAMEBUFFER_BINDING
GLbyte ty
#define GL_CLAMP_TO_EDGE
Definition qopenglext.h:100
@ BrushDrawingMode
#define QT_IMAGE_TEXTURE_UNIT
static void load_glyph_image_region_to_texture(QOpenGLContext *ctx, const QImage &srcImg, int x, int y, int w, int h, GLuint texture, int tx, int ty)
static bool isCoreProfile()
static void load_glyph_image_to_texture(QOpenGLContext *ctx, QImage &img, GLuint texture, int tx, int ty)
static QT_BEGIN_NAMESPACE int next_qopengltextureglyphcache_serial_number()
static quint32 ARGB2RGBA(quint32 x)
#define Q_BIG_ENDIAN
#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
#define GL_RED
#define GLuint
#define GL_FLOAT
#define GL_UNSIGNED_BYTE
#define GL_RGBA
unsigned int glyph_t
QVideoFrameFormat::PixelFormat fmt
QObject::connect nullptr
AvgFunction avg