glx: Do additional sorting of fbconfigs
Prefer configurations with smaller depth/stencil sizes.
This commit is contained in:
parent
fb4e733bcc
commit
ca777f38f1
1 changed files with 79 additions and 17 deletions
|
@ -43,6 +43,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <xcb/glx.h>
|
#include <xcb/glx.h>
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#ifndef XCB_GLX_BUFFER_SWAP_COMPLETE
|
#ifndef XCB_GLX_BUFFER_SWAP_COMPLETE
|
||||||
#define XCB_GLX_BUFFER_SWAP_COMPLETE 1
|
#define XCB_GLX_BUFFER_SWAP_COMPLETE 1
|
||||||
typedef struct xcb_glx_buffer_swap_complete_event_t {
|
typedef struct xcb_glx_buffer_swap_complete_event_t {
|
||||||
|
@ -142,15 +145,20 @@ static bool gs_tripleBufferNeedsDetection = false;
|
||||||
void GlxBackend::init()
|
void GlxBackend::init()
|
||||||
{
|
{
|
||||||
initGLX();
|
initGLX();
|
||||||
// require at least GLX 1.3
|
|
||||||
|
// Require at least GLX 1.3
|
||||||
if (!hasGLXVersion(1, 3)) {
|
if (!hasGLXVersion(1, 3)) {
|
||||||
setFailed(QStringLiteral("Requires at least GLX 1.3"));
|
setFailed(QStringLiteral("Requires at least GLX 1.3"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initVisualDepthHashTable();
|
||||||
|
|
||||||
if (!initBuffer()) {
|
if (!initBuffer()) {
|
||||||
setFailed(QStringLiteral("Could not initialize the buffer"));
|
setFailed(QStringLiteral("Could not initialize the buffer"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!initRenderingContext()) {
|
if (!initRenderingContext()) {
|
||||||
setFailed(QStringLiteral("Could not initialize rendering context"));
|
setFailed(QStringLiteral("Could not initialize rendering context"));
|
||||||
return;
|
return;
|
||||||
|
@ -239,8 +247,6 @@ void GlxBackend::init()
|
||||||
setIsDirectRendering(bool(glXIsDirect(display(), ctx)));
|
setIsDirectRendering(bool(glXIsDirect(display(), ctx)));
|
||||||
|
|
||||||
qDebug() << "Direct rendering:" << isDirectRendering() << endl;
|
qDebug() << "Direct rendering:" << isDirectRendering() << endl;
|
||||||
|
|
||||||
initVisualDepthHashTable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GlxBackend::initRenderingContext()
|
bool GlxBackend::initRenderingContext()
|
||||||
|
@ -365,12 +371,40 @@ bool GlxBackend::initFbConfig()
|
||||||
int count = 0;
|
int count = 0;
|
||||||
GLXFBConfig *configs = glXChooseFBConfig(display(), DefaultScreen(display()), attribs, &count);
|
GLXFBConfig *configs = glXChooseFBConfig(display(), DefaultScreen(display()), attribs, &count);
|
||||||
|
|
||||||
if (count > 0) {
|
struct FBConfig {
|
||||||
fbconfig = configs[0];
|
GLXFBConfig config;
|
||||||
XFree(configs);
|
int depth;
|
||||||
|
int stencil;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::deque<FBConfig> 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";
|
qCCritical(KWIN_CORE) << "Failed to find a usable framebuffer configuration";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -453,6 +487,15 @@ FBConfigInfo *GlxBackend::infoForVisual(xcb_visualid_t visual)
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FBConfig {
|
||||||
|
GLXFBConfig config;
|
||||||
|
int depth;
|
||||||
|
int stencil;
|
||||||
|
int format;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::deque<FBConfig> candidates;
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
int red, green, blue;
|
int red, green, blue;
|
||||||
glXGetFBConfigAttrib(display(), configs[i], GLX_RED_SIZE, &red);
|
glXGetFBConfigAttrib(display(), configs[i], GLX_RED_SIZE, &red);
|
||||||
|
@ -475,27 +518,46 @@ FBConfigInfo *GlxBackend::infoForVisual(xcb_visualid_t visual)
|
||||||
if (!bind_rgb && !bind_rgba)
|
if (!bind_rgb && !bind_rgba)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
int depth, stencil;
|
||||||
|
glXGetFBConfigAttrib(display(), configs[i], GLX_DEPTH_SIZE, &depth);
|
||||||
|
glXGetFBConfigAttrib(display(), configs[i], GLX_STENCIL_SIZE, &stencil);
|
||||||
|
|
||||||
int texture_format;
|
int texture_format;
|
||||||
if (alpha_bits)
|
if (alpha_bits)
|
||||||
texture_format = bind_rgba ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT;
|
texture_format = bind_rgba ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT;
|
||||||
else
|
else
|
||||||
texture_format = bind_rgb ? GLX_TEXTURE_FORMAT_RGB_EXT : GLX_TEXTURE_FORMAT_RGBA_EXT;
|
texture_format = bind_rgb ? GLX_TEXTURE_FORMAT_RGB_EXT : GLX_TEXTURE_FORMAT_RGBA_EXT;
|
||||||
|
|
||||||
int y_inverted, texture_targets;
|
candidates.emplace_back(FBConfig{configs[i], depth, stencil, texture_format});
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
XFree(configs);
|
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) {
|
if (info->fbconfig) {
|
||||||
int fbc_id = 0;
|
int fbc_id = 0;
|
||||||
int visual_id = 0;
|
int visual_id = 0;
|
||||||
|
|
Loading…
Reference in a new issue