diff --git a/glxbackend.cpp b/glxbackend.cpp
index 426708ce5a..d7695760ee 100644
--- a/glxbackend.cpp
+++ b/glxbackend.cpp
@@ -43,6 +43,9 @@ along with this program. If not, see .
#include
#include
+#include
+#include
+
#ifndef XCB_GLX_BUFFER_SWAP_COMPLETE
#define XCB_GLX_BUFFER_SWAP_COMPLETE 1
typedef struct xcb_glx_buffer_swap_complete_event_t {
@@ -142,15 +145,20 @@ static bool gs_tripleBufferNeedsDetection = false;
void GlxBackend::init()
{
initGLX();
- // require at least GLX 1.3
+
+ // Require at least GLX 1.3
if (!hasGLXVersion(1, 3)) {
setFailed(QStringLiteral("Requires at least GLX 1.3"));
return;
}
+
+ initVisualDepthHashTable();
+
if (!initBuffer()) {
setFailed(QStringLiteral("Could not initialize the buffer"));
return;
}
+
if (!initRenderingContext()) {
setFailed(QStringLiteral("Could not initialize rendering context"));
return;
@@ -239,8 +247,6 @@ void GlxBackend::init()
setIsDirectRendering(bool(glXIsDirect(display(), ctx)));
qDebug() << "Direct rendering:" << isDirectRendering() << endl;
-
- initVisualDepthHashTable();
}
bool GlxBackend::initRenderingContext()
@@ -365,12 +371,40 @@ bool GlxBackend::initFbConfig()
int count = 0;
GLXFBConfig *configs = glXChooseFBConfig(display(), DefaultScreen(display()), attribs, &count);
- if (count > 0) {
- fbconfig = configs[0];
- XFree(configs);
+ struct FBConfig {
+ GLXFBConfig config;
+ int depth;
+ int stencil;
+ };
+
+ std::deque candidates;
+
+ for (int i = 0; i < count; i++) {
+ int depth, stencil;
+ glXGetFBConfigAttrib(display(), configs[i], GLX_DEPTH_SIZE, &depth);
+ glXGetFBConfigAttrib(display(), configs[i], GLX_STENCIL_SIZE, &stencil);
+
+ candidates.emplace_back(FBConfig{configs[i], depth, stencil});
}
- if (fbconfig == NULL) {
+ if (count > 0)
+ XFree(configs);
+
+ std::stable_sort(candidates.begin(), candidates.end(), [](const FBConfig &left, const FBConfig &right) {
+ if (left.depth < right.depth)
+ return true;
+
+ if (left.stencil < right.stencil)
+ return true;
+
+ return false;
+ });
+
+ if (candidates.size() > 0) {
+ fbconfig = candidates.front().config;
+ }
+
+ if (fbconfig == nullptr) {
qCCritical(KWIN_CORE) << "Failed to find a usable framebuffer configuration";
return false;
}
@@ -453,6 +487,15 @@ FBConfigInfo *GlxBackend::infoForVisual(xcb_visualid_t visual)
return info;
}
+ struct FBConfig {
+ GLXFBConfig config;
+ int depth;
+ int stencil;
+ int format;
+ };
+
+ std::deque candidates;
+
for (int i = 0; i < count; i++) {
int red, green, blue;
glXGetFBConfigAttrib(display(), configs[i], GLX_RED_SIZE, &red);
@@ -475,27 +518,46 @@ FBConfigInfo *GlxBackend::infoForVisual(xcb_visualid_t visual)
if (!bind_rgb && !bind_rgba)
continue;
+ int depth, stencil;
+ glXGetFBConfigAttrib(display(), configs[i], GLX_DEPTH_SIZE, &depth);
+ glXGetFBConfigAttrib(display(), configs[i], GLX_STENCIL_SIZE, &stencil);
+
int texture_format;
if (alpha_bits)
texture_format = bind_rgba ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT;
else
texture_format = bind_rgb ? GLX_TEXTURE_FORMAT_RGB_EXT : GLX_TEXTURE_FORMAT_RGBA_EXT;
- int y_inverted, texture_targets;
- glXGetFBConfigAttrib(display(), configs[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, &texture_targets);
- glXGetFBConfigAttrib(display(), configs[i], GLX_Y_INVERTED_EXT, &y_inverted);
-
- info->fbconfig = configs[i];
- info->bind_texture_format = texture_format;
- info->texture_targets = texture_targets;
- info->y_inverted = y_inverted;
- info->mipmap = 0;
- break;
+ candidates.emplace_back(FBConfig{configs[i], depth, stencil, texture_format});
}
if (count > 0)
XFree(configs);
+ std::stable_sort(candidates.begin(), candidates.end(), [](const FBConfig &left, const FBConfig &right) {
+ if (left.depth < right.depth)
+ return true;
+
+ if (left.stencil < right.stencil)
+ return true;
+
+ return false;
+ });
+
+ if (candidates.size() > 0) {
+ const FBConfig &candidate = candidates.front();
+
+ int y_inverted, texture_targets;
+ glXGetFBConfigAttrib(display(), candidate.config, GLX_BIND_TO_TEXTURE_TARGETS_EXT, &texture_targets);
+ glXGetFBConfigAttrib(display(), candidate.config, GLX_Y_INVERTED_EXT, &y_inverted);
+
+ info->fbconfig = candidate.config;
+ info->bind_texture_format = candidate.format;
+ info->texture_targets = texture_targets;
+ info->y_inverted = y_inverted;
+ info->mipmap = 0;
+ }
+
if (info->fbconfig) {
int fbc_id = 0;
int visual_id = 0;