Improve the interface of glx_find_fbconfig
Remove the dependence of xcb_render types in glx.h Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
@ -10,10 +10,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <GL/glx.h>
|
||||
#include <X11/Xlib-xcb.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <pixman.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
@ -53,20 +53,9 @@ struct _glx_data {
|
||||
};
|
||||
|
||||
struct glx_fbconfig_info *
|
||||
glx_find_fbconfig(Display *dpy, int screen, xcb_render_pictforminfo_t *pictfmt, int depth) {
|
||||
assert(pictfmt);
|
||||
|
||||
if (pictfmt->type != XCB_RENDER_PICT_TYPE_DIRECT) {
|
||||
log_error("compton cannot handle non-DirectColor visuals. Report an "
|
||||
"issue if you see this error message.");
|
||||
return NULL;
|
||||
}
|
||||
int red_size = popcountl(pictfmt->direct.red_mask),
|
||||
blue_size = popcountl(pictfmt->direct.blue_mask),
|
||||
green_size = popcountl(pictfmt->direct.green_mask),
|
||||
alpha_size = popcountl(pictfmt->direct.alpha_mask);
|
||||
log_debug("Looking for FBConfig for RGBA%d%d%d%d, depth %d", red_size, blue_size,
|
||||
green_size, alpha_size, depth);
|
||||
glx_find_fbconfig(Display *dpy, int screen, struct glx_fbconfig_criteria m) {
|
||||
log_debug("Looking for FBConfig for RGBA%d%d%d%d, depth %d", m.red_size, m.blue_size,
|
||||
m.green_size, m.alpha_size, m.visual_depth);
|
||||
|
||||
int ncfg;
|
||||
// clang-format off
|
||||
@ -77,11 +66,12 @@ glx_find_fbconfig(Display *dpy, int screen, xcb_render_pictforminfo_t *pictfmt,
|
||||
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
|
||||
GLX_X_RENDERABLE, true,
|
||||
GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, GLX_DONT_CARE,
|
||||
GLX_BUFFER_SIZE, red_size + green_size + blue_size + alpha_size,
|
||||
GLX_RED_SIZE, red_size,
|
||||
GLX_BLUE_SIZE, blue_size,
|
||||
GLX_GREEN_SIZE, green_size,
|
||||
GLX_ALPHA_SIZE, alpha_size,
|
||||
GLX_BUFFER_SIZE, m.red_size + m.green_size +
|
||||
m.blue_size + m.alpha_size,
|
||||
GLX_RED_SIZE, m.red_size,
|
||||
GLX_BLUE_SIZE, m.blue_size,
|
||||
GLX_GREEN_SIZE, m.green_size,
|
||||
GLX_ALPHA_SIZE, m.alpha_size,
|
||||
GLX_STENCIL_SIZE, 0,
|
||||
GLX_DEPTH_SIZE, 0,
|
||||
0
|
||||
@ -112,7 +102,7 @@ glx_find_fbconfig(Display *dpy, int screen, xcb_render_pictforminfo_t *pictfmt,
|
||||
glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_RED_SIZE, &red);
|
||||
glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_BLUE_SIZE, &blue);
|
||||
glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_GREEN_SIZE, &green);
|
||||
if (red != red_size || green != green_size || blue != blue_size) {
|
||||
if (red != m.red_size || green != m.green_size || blue != m.blue_size) {
|
||||
// Color size doesn't match, this cannot work
|
||||
continue;
|
||||
}
|
||||
@ -128,7 +118,8 @@ glx_find_fbconfig(Display *dpy, int screen, xcb_render_pictforminfo_t *pictfmt,
|
||||
|
||||
int visual;
|
||||
glXGetFBConfigAttribChecked(dpy, cfg[i], GLX_VISUAL_ID, &visual);
|
||||
if (depth != -1 && x_get_visual_depth(XGetXCBConnection(dpy), visual) != depth) {
|
||||
if (m.visual_depth != -1 &&
|
||||
x_get_visual_depth(XGetXCBConnection(dpy), visual) != m.visual_depth) {
|
||||
// Some driver might attach fbconfig to a GLX visual with a
|
||||
// different depth.
|
||||
//
|
||||
@ -144,7 +135,7 @@ glx_find_fbconfig(Display *dpy, int screen, xcb_render_pictforminfo_t *pictfmt,
|
||||
|
||||
// Prefer the texture format with matching alpha, with the other one as
|
||||
// fallback
|
||||
if (alpha_size) {
|
||||
if (m.alpha_size) {
|
||||
texture_fmt = rgba ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT;
|
||||
} else {
|
||||
texture_fmt = rgb ? GLX_TEXTURE_FORMAT_RGB_EXT : GLX_TEXTURE_FORMAT_RGBA_EXT;
|
||||
@ -421,13 +412,8 @@ static void *glx_prepare_win(void *backend_data, session_t *ps, win *w) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
auto pictfmt = x_get_pictform_for_visual(ps->c, w->a.visual);
|
||||
if (!pictfmt) {
|
||||
log_error("Window %#010x has invalid visual %#x", w->id, w->a.visual);
|
||||
goto err;
|
||||
}
|
||||
int depth = x_get_visual_depth(ps->c, w->a.visual);
|
||||
auto fbcfg = glx_find_fbconfig(ps->dpy, ps->scr, pictfmt, depth);
|
||||
auto criteria = x_visual_to_fbconfig_criteria(ps->c, w->a.visual);
|
||||
auto fbcfg = glx_find_fbconfig(ps->dpy, ps->scr, criteria);
|
||||
if (!fbcfg) {
|
||||
log_error("Couldn't find FBConfig with requested visual %x", w->a.visual);
|
||||
goto err;
|
||||
|
@ -3,8 +3,9 @@
|
||||
#pragma once
|
||||
#include <GL/glx.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <xcb/render.h>
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "x.h"
|
||||
|
||||
struct glx_fbconfig_info {
|
||||
GLXFBConfig cfg;
|
||||
@ -13,5 +14,48 @@ struct glx_fbconfig_info {
|
||||
int y_inverted;
|
||||
};
|
||||
|
||||
struct glx_fbconfig_info *
|
||||
glx_find_fbconfig(Display *, int screen, xcb_render_pictforminfo_t *, int depth);
|
||||
/// The search criteria for glx_find_fbconfig
|
||||
struct glx_fbconfig_criteria {
|
||||
/// Bit width of the red component
|
||||
int red_size;
|
||||
/// Bit width of the green component
|
||||
int green_size;
|
||||
/// Bit width of the blue component
|
||||
int blue_size;
|
||||
/// Bit width of the alpha component
|
||||
int alpha_size;
|
||||
/// The depth of X visual
|
||||
int visual_depth;
|
||||
};
|
||||
|
||||
struct glx_fbconfig_info *glx_find_fbconfig(Display *, int screen, struct glx_fbconfig_criteria);
|
||||
|
||||
/// Generate a search criteria for fbconfig from a X visual.
|
||||
/// Returns {-1, -1, -1, -1, -1} on failure
|
||||
static inline struct glx_fbconfig_criteria
|
||||
x_visual_to_fbconfig_criteria(xcb_connection_t *c, xcb_visualid_t visual) {
|
||||
auto pictfmt = x_get_pictform_for_visual(c, visual);
|
||||
auto depth = x_get_visual_depth(c, visual);
|
||||
if (!pictfmt || depth == -1) {
|
||||
log_error("Invalid visual %#03x", visual);
|
||||
return (struct glx_fbconfig_criteria){-1, -1, -1, -1, -1};
|
||||
}
|
||||
if (pictfmt->type != XCB_RENDER_PICT_TYPE_DIRECT) {
|
||||
log_error("compton cannot handle non-DirectColor visuals. Report an "
|
||||
"issue if you see this error message.");
|
||||
return (struct glx_fbconfig_criteria){-1, -1, -1, -1, -1};
|
||||
}
|
||||
|
||||
int red_size = popcountl(pictfmt->direct.red_mask),
|
||||
blue_size = popcountl(pictfmt->direct.blue_mask),
|
||||
green_size = popcountl(pictfmt->direct.green_mask),
|
||||
alpha_size = popcountl(pictfmt->direct.alpha_mask);
|
||||
|
||||
return (struct glx_fbconfig_criteria){
|
||||
.red_size = red_size,
|
||||
.green_size = green_size,
|
||||
.blue_size = blue_size,
|
||||
.alpha_size = alpha_size,
|
||||
.visual_depth = depth,
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user