Fix launching with depth 30 XOrg

Our fallback logic for inexact matches was not very good at accepting
better suggestions.

Change-Id: I40fb78bf583171105725156148e4a2245fb81354
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
This commit is contained in:
Allan Sandfeld Jensen 2018-04-13 11:44:41 +02:00
parent 1192c463db
commit 8ec98fc2dc
2 changed files with 40 additions and 7 deletions

View File

@ -91,21 +91,21 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay
int visualRedSize = qPopulationCount(chosenVisualInfo->red_mask);
int visualGreenSize = qPopulationCount(chosenVisualInfo->green_mask);
int visualBlueSize = qPopulationCount(chosenVisualInfo->blue_mask);
int visualAlphaSize = chosenVisualInfo->depth == 32 ? 8 : 0;
int visualAlphaSize = chosenVisualInfo->depth - visualRedSize - visualBlueSize - visualGreenSize;
const bool visualMatchesConfig = visualRedSize == configRedSize
&& visualGreenSize == configGreenSize
&& visualBlueSize == configBlueSize
&& visualAlphaSize == configAlphaSize;
const bool visualMatchesConfig = visualRedSize >= configRedSize
&& visualGreenSize >= configGreenSize
&& visualBlueSize >= configBlueSize
&& visualAlphaSize >= configAlphaSize;
// In some cases EGL tends to suggest a 24-bit visual for 8888
// configs. In such a case we have to fall back to XGetVisualInfo.
if (!visualMatchesConfig) {
visualId = 0;
qCDebug(lcXlibEglDebug,
"EGL suggested using X Visual ID %d (%d %d %d depth %d) for EGL config %d"
"EGL suggested using X Visual ID %d (%d %d %d %d depth %d) for EGL config %d"
"(%d %d %d %d), but this is incompatible",
(int)visualId, visualRedSize, visualGreenSize, visualBlueSize, chosenVisualInfo->depth,
(int)visualId, visualRedSize, visualGreenSize, visualBlueSize, visualAlphaSize, chosenVisualInfo->depth,
configId, configRedSize, configGreenSize, configBlueSize, configAlphaSize);
}
} else {

View File

@ -42,13 +42,18 @@
#include <QtCore/QByteArray>
#include <QtCore/QScopedPointer>
#include <QtCore/qmetatype.h>
#include <QtCore/qtextstream.h>
#include "qglxconvenience_p.h"
#include <QtCore/QLoggingCategory>
#include <QtCore/QVector>
#include <QtCore/QVarLengthArray>
#include <GL/glxext.h>
Q_LOGGING_CATEGORY(lcGlx, "qt.glx")
enum {
XFocusOut = FocusOut,
XFocusIn = FocusIn,
@ -207,6 +212,7 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format
const int requestedBlue = qMax(0, format.blueBufferSize());
const int requestedAlpha = qMax(0, format.alphaBufferSize());
GLXFBConfig compatibleCandidate = nullptr;
for (int i = 0; i < confcount; i++) {
GLXFBConfig candidate = configs[i];
@ -226,6 +232,16 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format
const int actualBlue = qPopulationCount(visual->blue_mask);
const int actualAlpha = visual->depth - actualRed - actualGreen - actualBlue;
if (requestedRed && actualRed < requestedRed)
continue;
if (requestedGreen && actualGreen < requestedGreen)
continue;
if (requestedBlue && actualBlue < requestedBlue)
continue;
if (requestedAlpha && actualAlpha < requestedAlpha)
continue;
compatibleCandidate = candidate;
if (requestedRed && actualRed != requestedRed)
continue;
if (requestedGreen && actualGreen != requestedGreen)
@ -237,6 +253,11 @@ GLXFBConfig qglx_findConfig(Display *display, int screen , QSurfaceFormat format
return candidate;
}
if (compatibleCandidate) {
qCDebug(lcGlx) << "qglx_findConfig: Found non-matching but compatible FBConfig";
return compatibleCandidate;
}
qCWarning(lcGlx, "qglx_findConfig: Failed to finding matching FBConfig (%d %d %d %d)", requestedRed, requestedGreen, requestedBlue, requestedAlpha);
} while (qglx_reduceFormat(&format));
return config;
@ -352,6 +373,18 @@ void qglx_surfaceFormatFromVisualInfo(QSurfaceFormat *format, Display *display,
bool qglx_reduceFormat(QSurfaceFormat *format)
{
Q_ASSERT(format);
if (std::max(std::max(format->redBufferSize(), format->greenBufferSize()), format->blueBufferSize()) > 8) {
if (format->alphaBufferSize() > 2) {
// First try to match 10 10 10 2
format->setAlphaBufferSize(2);
return true;
}
format->setRedBufferSize(std::min(format->redBufferSize(), 8));
format->setGreenBufferSize(std::min(format->greenBufferSize(), 8));
format->setBlueBufferSize(std::min(format->blueBufferSize(), 8));
return true;
}
if (format->redBufferSize() > 1) {
format->setRedBufferSize(1);