5#include <QtCore/qbytearray.h>
6#include <QtGui/qopenglcontext.h>
12#include <QtGui/private/qmath_p.h>
16#ifndef EGL_OPENGL_ES3_BIT_KHR
17#define EGL_OPENGL_ES3_BIT_KHR 0x0040
22QList<EGLint> q_createConfigAttributesFromFormat(
const QSurfaceFormat &format)
24 int redSize = format.redBufferSize();
25 int greenSize = format.greenBufferSize();
26 int blueSize = format.blueBufferSize();
27 int alphaSize = format.alphaBufferSize();
28 int depthSize = format.depthBufferSize();
29 int stencilSize = format.stencilBufferSize();
30 int sampleCount = format.samples();
32 QList<EGLint> configAttributes;
56 configAttributes.append(EGL_RED_SIZE);
57 configAttributes.append(redSize > 0 ? redSize : 0);
59 configAttributes.append(EGL_GREEN_SIZE);
60 configAttributes.append(greenSize > 0 ? greenSize : 0);
62 configAttributes.append(EGL_BLUE_SIZE);
63 configAttributes.append(blueSize > 0 ? blueSize : 0);
65 configAttributes.append(EGL_ALPHA_SIZE);
66 configAttributes.append(alphaSize > 0 ? alphaSize : 0);
68 configAttributes.append(EGL_SAMPLES);
69 configAttributes.append(sampleCount > 0 ? sampleCount : 0);
71 configAttributes.append(EGL_SAMPLE_BUFFERS);
72 configAttributes.append(sampleCount > 0);
74 if (format.renderableType() != QSurfaceFormat::OpenVG) {
75 configAttributes.append(EGL_DEPTH_SIZE);
76 configAttributes.append(depthSize > 0 ? depthSize : 0);
78 configAttributes.append(EGL_STENCIL_SIZE);
79 configAttributes.append(stencilSize > 0 ? stencilSize : 0);
82 configAttributes.append(EGL_ALPHA_MASK_SIZE);
83 configAttributes.append(8);
86 return configAttributes;
96 qsizetype i = configAttributes->indexOf(EGL_SWAP_BEHAVIOR);
98 configAttributes->remove(i,2);
101#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
105 i = configAttributes->indexOf(EGL_SURFACE_TYPE);
107 EGLint surfaceType = configAttributes->at(i +1);
108 if (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) {
109 surfaceType ^= EGL_VG_ALPHA_FORMAT_PRE_BIT;
110 configAttributes->replace(i+1,surfaceType);
121 i = configAttributes->indexOf(EGL_BUFFER_SIZE);
123 if (configAttributes->at(i+1) == 16) {
124 configAttributes->remove(i,2);
129 i = configAttributes->indexOf(EGL_SAMPLES);
131 EGLint value = configAttributes->value(i+1, 0);
133 configAttributes->replace(i+1, qMin(EGLint(16), value / 2));
135 configAttributes->remove(i, 2);
139 i = configAttributes->indexOf(EGL_SAMPLE_BUFFERS);
141 configAttributes->remove(i,2);
145 i = configAttributes->indexOf(EGL_DEPTH_SIZE);
147 if (configAttributes->at(i + 1) >= 32)
148 configAttributes->replace(i + 1, 24);
149 else if (configAttributes->at(i + 1) > 1)
150 configAttributes->replace(i + 1, 1);
152 configAttributes->remove(i, 2);
156 i = configAttributes->indexOf(EGL_ALPHA_SIZE);
158 configAttributes->remove(i,2);
159#if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB)
160 i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGBA);
162 configAttributes->replace(i,EGL_BIND_TO_TEXTURE_RGB);
163 configAttributes->replace(i+1,
true);
170 i = configAttributes->indexOf(EGL_STENCIL_SIZE);
172 if (configAttributes->at(i + 1) > 1)
173 configAttributes->replace(i + 1, 1);
175 configAttributes->remove(i, 2);
179#ifdef EGL_BIND_TO_TEXTURE_RGB
180 i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGB);
182 configAttributes->remove(i,2);
190QEglConfigChooser::QEglConfigChooser(EGLDisplay display)
192 , m_surfaceType(EGL_WINDOW_BIT)
201QEglConfigChooser::~QEglConfigChooser()
205EGLConfig QEglConfigChooser::chooseConfig()
207 QList<EGLint> configureAttributes = q_createConfigAttributesFromFormat(m_format);
208 configureAttributes.append(EGL_SURFACE_TYPE);
209 configureAttributes.append(surfaceType());
211 configureAttributes.append(EGL_RENDERABLE_TYPE);
212 bool needsES2Plus =
false;
213 switch (m_format.renderableType()) {
214 case QSurfaceFormat::OpenVG:
215 configureAttributes.append(EGL_OPENVG_BIT);
217#ifdef EGL_VERSION_1_4
218 case QSurfaceFormat::DefaultRenderableType: {
221 const char *vendor = eglQueryString(display(), EGL_VENDOR);
222 if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL && (!vendor || !strstr(vendor,
"NVIDIA")))
223 configureAttributes.append(EGL_OPENGL_BIT);
229 case QSurfaceFormat::OpenGL:
230 configureAttributes.append(EGL_OPENGL_BIT);
233 case QSurfaceFormat::OpenGLES:
234 if (m_format.majorVersion() == 1) {
235 configureAttributes.append(EGL_OPENGL_ES_BIT);
244 if (m_format.majorVersion() >= 3 && q_hasEglExtension(display(),
"EGL_KHR_create_context"))
247 configureAttributes.append(EGL_OPENGL_ES2_BIT);
249 configureAttributes.append(EGL_NONE);
251 EGLConfig cfg =
nullptr;
255 if (!eglChooseConfig(display(), configureAttributes.constData(),
nullptr, 0, &matching) || !matching)
260 qsizetype i = configureAttributes.indexOf(EGL_RED_SIZE);
261 m_confAttrRed = configureAttributes.at(i+1);
262 i = configureAttributes.indexOf(EGL_GREEN_SIZE);
263 m_confAttrGreen = configureAttributes.at(i+1);
264 i = configureAttributes.indexOf(EGL_BLUE_SIZE);
265 m_confAttrBlue = configureAttributes.at(i+1);
266 i = configureAttributes.indexOf(EGL_ALPHA_SIZE);
267 m_confAttrAlpha = i == -1 ? 0 : configureAttributes.at(i+1);
269 QList<EGLConfig> configs(matching);
270 eglChooseConfig(display(), configureAttributes.constData(), configs.data(),
271 EGLint(configs.size()), &matching);
272 if (!cfg && matching > 0)
273 cfg = configs.first();
282 for (
int i = 0; i < configs.size(); ++i) {
283 if (filterConfig(configs[i]))
284 return configs.at(i);
286 }
while (q_reduceConfigAttributes(&configureAttributes));
289 qWarning(
"Cannot find EGLConfig, returning null config");
293bool QEglConfigChooser::filterConfig(EGLConfig config)
const
307 eglGetConfigAttrib(display(), config, EGL_RED_SIZE, &red);
309 eglGetConfigAttrib(display(), config, EGL_GREEN_SIZE, &green);
311 eglGetConfigAttrib(display(), config, EGL_BLUE_SIZE, &blue);
313 eglGetConfigAttrib(display(), config, EGL_ALPHA_SIZE, &alpha);
315 return red == m_confAttrRed && green == m_confAttrGreen
316 && blue == m_confAttrBlue && alpha == m_confAttrAlpha;
322 chooser.setSurfaceFormat(format);
323 chooser.setSurfaceType(surfaceType);
324 chooser.setIgnoreColorChannels(highestPixelFormat);
326 return chooser.chooseConfig();
333 EGLint greenSize = 0;
335 EGLint alphaSize = 0;
336 EGLint depthSize = 0;
337 EGLint stencilSize = 0;
338 EGLint sampleCount = 0;
339 EGLint renderableType = 0;
341 eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize);
342 eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize);
343 eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize);
344 eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize);
345 eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize);
346 eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
347 eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount);
348 eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);
350 if (referenceFormat.renderableType() == QSurfaceFormat::OpenVG && (renderableType & EGL_OPENVG_BIT))
351 format.setRenderableType(QSurfaceFormat::OpenVG);
352#ifdef EGL_VERSION_1_4
353 else if (referenceFormat.renderableType() == QSurfaceFormat::OpenGL
354 && (renderableType & EGL_OPENGL_BIT))
355 format.setRenderableType(QSurfaceFormat::OpenGL);
356 else if (referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType
358 && QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL
359 && !strstr(eglQueryString(display, EGL_VENDOR),
"NVIDIA")
361 && (renderableType & EGL_OPENGL_BIT))
362 format.setRenderableType(QSurfaceFormat::OpenGL);
365 format.setRenderableType(QSurfaceFormat::OpenGLES);
367 format.setRedBufferSize(redSize);
368 format.setGreenBufferSize(greenSize);
369 format.setBlueBufferSize(blueSize);
370 format.setAlphaBufferSize(alphaSize);
371 format.setDepthBufferSize(depthSize);
372 format.setStencilBufferSize(stencilSize);
373 format.setSamples(sampleCount);
374 format.setStereo(
false);
375 format.setSwapInterval(referenceFormat.swapInterval());
387 QList<QByteArray> extensions =
388 QByteArray(
reinterpret_cast<
const char *>
389 (eglQueryString(display, EGL_EXTENSIONS))).split(
' ');
390 return extensions.contains(extensionName);
395 {EGL_BUFFER_SIZE,
"EGL_BUFFER_SIZE"},
396 {EGL_ALPHA_SIZE,
"EGL_ALPHA_SIZE"},
397 {EGL_BLUE_SIZE,
"EGL_BLUE_SIZE"},
398 {EGL_GREEN_SIZE,
"EGL_GREEN_SIZE"},
399 {EGL_RED_SIZE,
"EGL_RED_SIZE"},
400 {EGL_DEPTH_SIZE,
"EGL_DEPTH_SIZE"},
401 {EGL_STENCIL_SIZE,
"EGL_STENCIL_SIZE"},
402 {EGL_CONFIG_CAVEAT,
"EGL_CONFIG_CAVEAT"},
403 {EGL_CONFIG_ID,
"EGL_CONFIG_ID"},
404 {EGL_LEVEL,
"EGL_LEVEL"},
405 {EGL_MAX_PBUFFER_HEIGHT,
"EGL_MAX_PBUFFER_HEIGHT"},
406 {EGL_MAX_PBUFFER_PIXELS,
"EGL_MAX_PBUFFER_PIXELS"},
407 {EGL_MAX_PBUFFER_WIDTH,
"EGL_MAX_PBUFFER_WIDTH"},
408 {EGL_NATIVE_RENDERABLE,
"EGL_NATIVE_RENDERABLE"},
409 {EGL_NATIVE_VISUAL_ID,
"EGL_NATIVE_VISUAL_ID"},
410 {EGL_NATIVE_VISUAL_TYPE,
"EGL_NATIVE_VISUAL_TYPE"},
411 {EGL_SAMPLES,
"EGL_SAMPLES"},
412 {EGL_SAMPLE_BUFFERS,
"EGL_SAMPLE_BUFFERS"},
413 {EGL_SURFACE_TYPE,
"EGL_SURFACE_TYPE"},
414 {EGL_TRANSPARENT_TYPE,
"EGL_TRANSPARENT_TYPE"},
415 {EGL_TRANSPARENT_BLUE_VALUE,
"EGL_TRANSPARENT_BLUE_VALUE"},
416 {EGL_TRANSPARENT_GREEN_VALUE,
"EGL_TRANSPARENT_GREEN_VALUE"},
417 {EGL_TRANSPARENT_RED_VALUE,
"EGL_TRANSPARENT_RED_VALUE"},
418 {EGL_BIND_TO_TEXTURE_RGB,
"EGL_BIND_TO_TEXTURE_RGB"},
419 {EGL_BIND_TO_TEXTURE_RGBA,
"EGL_BIND_TO_TEXTURE_RGBA"},
420 {EGL_MIN_SWAP_INTERVAL,
"EGL_MIN_SWAP_INTERVAL"},
421 {EGL_MAX_SWAP_INTERVAL,
"EGL_MAX_SWAP_INTERVAL"},
427 for (index = 0;
attrs[index].attr != -1; ++index) {
429 if (eglGetConfigAttrib(display, config,
attrs[index].attr, &value)) {
430 qDebug(
"\t%s: %d",
attrs[index].name, (
int)value);
437QSizeF q_physicalScreenSizeFromFb(
int framebufferDevice,
const QSize &screenSize)
440 Q_UNUSED(framebufferDevice);
442 const int defaultPhysicalDpi = 100;
445 if (size.isEmpty()) {
447 int width = qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_PHYSICAL_WIDTH");
448 int height = qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_PHYSICAL_HEIGHT");
450 if (width && height) {
451 size.setWidth(width);
452 size.setHeight(height);
458 QSize screenResolution;
460 struct fb_var_screeninfo vinfo;
462 if (framebufferDevice != -1) {
463 if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) {
464 qWarning(
"eglconvenience: Could not query screen info");
468 screenResolution = QSize(vinfo.xres, vinfo.yres);
475 screenResolution = screenSize.isEmpty() ? q_screenSizeFromFb(framebufferDevice) : screenSize;
478 size.setWidth(w <= 0 ? screenResolution.width() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(w));
479 size.setHeight(h <= 0 ? screenResolution.height() * Q_MM_PER_INCH / defaultPhysicalDpi : qreal(h));
481 if (w <= 0 || h <= 0)
482 qWarning(
"Unable to query physical screen size, defaulting to %d dpi.\n"
483 "To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH "
484 "and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).", defaultPhysicalDpi);
490QSize q_screenSizeFromFb(
int framebufferDevice)
493 Q_UNUSED(framebufferDevice);
495 const int defaultWidth = 800;
496 const int defaultHeight = 600;
499 if (size.isEmpty()) {
500 int width = qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_WIDTH");
501 int height = qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_HEIGHT");
503 if (width && height) {
504 size.setWidth(width);
505 size.setHeight(height);
510 struct fb_var_screeninfo vinfo;
514 if (framebufferDevice != -1) {
515 if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1) {
516 qWarning(
"eglconvenience: Could not read screen info");
523 size.setWidth(xres <= 0 ? defaultWidth : xres);
524 size.setHeight(yres <= 0 ? defaultHeight : yres);
526 size.setWidth(defaultWidth);
527 size.setHeight(defaultHeight);
534int q_screenDepthFromFb(
int framebufferDevice)
537 Q_UNUSED(framebufferDevice);
539 const int defaultDepth = 32;
540 static int depth = qEnvironmentVariableIntValue(
"QT_QPA_EGLFS_DEPTH");
544 struct fb_var_screeninfo vinfo;
546 if (framebufferDevice != -1) {
547 if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) == -1)
548 qWarning(
"eglconvenience: Could not query screen info");
550 depth = vinfo.bits_per_pixel;
554 depth = defaultDepth;
556 depth = defaultDepth;
563qreal q_refreshRateFromFb(
int framebufferDevice)
566 Q_UNUSED(framebufferDevice);
569 static qreal rate = 0;
573 if (framebufferDevice != -1) {
574 struct fb_var_screeninfo vinfo;
575 if (ioctl(framebufferDevice, FBIOGET_VSCREENINFO, &vinfo) != -1) {
576 const quint64 quot = quint64(vinfo.left_margin + vinfo.right_margin + vinfo.xres + vinfo.hsync_len)
577 * quint64(vinfo.upper_margin + vinfo.lower_margin + vinfo.yres + vinfo.vsync_len)
580 rate = 1000000000000LLU / quot;
582 qWarning(
"eglconvenience: Could not query screen info");
Combined button and popup list for selecting options.
EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format, bool highestPixelFormat, int surfaceType)
QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, const QSurfaceFormat &referenceFormat)
bool q_hasEglExtension(EGLDisplay display, const char *extensionName)
void q_printEglConfig(EGLDisplay display, EGLConfig config)
bool q_reduceConfigAttributes(QList< EGLint > *configAttributes)
#define EGL_OPENGL_ES3_BIT_KHR
static struct AttrInfo attrs[]