new backend: glx: trivial refactoring
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
e894105e7b
commit
b91888b0a3
|
@ -160,7 +160,7 @@ static void gl_free_prog_main(gl_win_shader_t *pprogram) {
|
|||
void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
|
||||
const region_t *reg_tgt, const region_t *reg_visible) {
|
||||
|
||||
gl_texture_t *ptex = image_data;
|
||||
struct gl_image *ptex = image_data;
|
||||
struct gl_data *gd = (void *)base;
|
||||
|
||||
// Until we start to use glClipControl, reg_tgt, dst_x and dst_y and
|
||||
|
@ -169,7 +169,7 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
|
|||
// screen, with y axis pointing up; Xorg has the origin at the upper left of the
|
||||
// screen, with y axis pointing down. We have to do some coordinate conversion in
|
||||
// this function
|
||||
if (!ptex || !ptex->texture) {
|
||||
if (!ptex || !ptex->inner->texture) {
|
||||
log_error("Missing texture.");
|
||||
return;
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
|
|||
// dst_y is the top coordinate, in OpenGL, it is the upper bound of the y
|
||||
// coordinate.
|
||||
dst_y = gd->height - dst_y;
|
||||
auto dst_y2 = dst_y - ptex->height;
|
||||
auto dst_y2 = dst_y - ptex->inner->height;
|
||||
|
||||
bool dual_texture = false;
|
||||
|
||||
|
@ -209,10 +209,10 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
|
|||
// x, y, width, height, dx, dy, ptex->width, ptex->height, z);
|
||||
|
||||
// Bind texture
|
||||
glBindTexture(GL_TEXTURE_2D, ptex->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, ptex->inner->texture);
|
||||
if (dual_texture) {
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, ptex->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, ptex->inner->texture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
auto coord = ccalloc(nrects * 16, GLfloat);
|
||||
|
@ -232,17 +232,17 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
|
|||
auto texture_y2 = texture_y1 + (GLfloat)(crect.y1 - crect.y2);
|
||||
|
||||
// X pixmaps might be Y inverted, invert the texture coordinates
|
||||
if (ptex->y_inverted) {
|
||||
texture_y1 = (GLfloat)ptex->height - texture_y1;
|
||||
texture_y2 = (GLfloat)ptex->height - texture_y2;
|
||||
if (ptex->inner->y_inverted) {
|
||||
texture_y1 = (GLfloat)ptex->inner->height - texture_y1;
|
||||
texture_y2 = (GLfloat)ptex->inner->height - texture_y2;
|
||||
}
|
||||
|
||||
// GL_TEXTURE_2D coordinates are normalized
|
||||
// TODO use texelFetch
|
||||
texture_x1 /= (GLfloat)ptex->width;
|
||||
texture_y1 /= (GLfloat)ptex->height;
|
||||
texture_x2 /= (GLfloat)ptex->width;
|
||||
texture_y2 /= (GLfloat)ptex->height;
|
||||
texture_x1 /= (GLfloat)ptex->inner->width;
|
||||
texture_y1 /= (GLfloat)ptex->inner->height;
|
||||
texture_x2 /= (GLfloat)ptex->inner->width;
|
||||
texture_y2 /= (GLfloat)ptex->inner->height;
|
||||
|
||||
// Vertex coordinates
|
||||
auto vx1 = (GLfloat)crect.x1;
|
||||
|
@ -893,10 +893,17 @@ GLuint gl_new_texture(GLenum target) {
|
|||
return texture;
|
||||
}
|
||||
|
||||
/// Decouple `img` from the image it references, also applies all the lazy operations
|
||||
static inline void gl_image_decouple(struct gl_image *img) {
|
||||
if (img->inner->refcount == 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// stub for backend_operations::image_op
|
||||
bool gl_image_op(backend_t *base, enum image_operations op, void *image_data,
|
||||
const region_t *reg_op, const region_t *reg_visible, void *arg) {
|
||||
struct gl_texture *tex = image_data;
|
||||
struct gl_image *tex = image_data;
|
||||
int *iargs = arg;
|
||||
switch (op) {
|
||||
case IMAGE_OP_INVERT_COLOR_ALL: tex->color_inverted = true; break;
|
||||
|
@ -905,7 +912,7 @@ bool gl_image_op(backend_t *base, enum image_operations op, void *image_data,
|
|||
break;
|
||||
case IMAGE_OP_APPLY_ALPHA_ALL: tex->opacity *= *(double *)arg; break;
|
||||
case IMAGE_OP_APPLY_ALPHA:
|
||||
// TODO
|
||||
gl_image_decouple(tex);
|
||||
log_warn("IMAGE_OP_APPLY_ALPHA not implemented yet");
|
||||
break;
|
||||
case IMAGE_OP_RESIZE_TILE:
|
||||
|
@ -919,6 +926,6 @@ bool gl_image_op(backend_t *base, enum image_operations op, void *image_data,
|
|||
}
|
||||
|
||||
bool gl_is_image_transparent(backend_t *base, void *image_data) {
|
||||
gl_texture_t *img = image_data;
|
||||
struct gl_image *img = image_data;
|
||||
return img->has_alpha;
|
||||
}
|
||||
|
|
|
@ -42,21 +42,23 @@ typedef struct {
|
|||
GLint color_loc;
|
||||
} gl_fill_shader_t;
|
||||
|
||||
struct gl_texture {
|
||||
int refcount;
|
||||
GLuint texture;
|
||||
int width, height;
|
||||
bool y_inverted;
|
||||
unsigned depth;
|
||||
};
|
||||
|
||||
/// @brief Wrapper of a binded GLX texture.
|
||||
typedef struct gl_texture {
|
||||
typedef struct gl_image {
|
||||
struct gl_texture *inner;
|
||||
double opacity;
|
||||
double dim;
|
||||
int *refcount;
|
||||
GLuint texture;
|
||||
// The size of the backing texture
|
||||
int width, height;
|
||||
// The effective size of the texture
|
||||
int ewidth, eheight;
|
||||
unsigned depth;
|
||||
bool y_inverted;
|
||||
bool has_alpha;
|
||||
bool color_inverted;
|
||||
} gl_texture_t;
|
||||
} gl_image_t;
|
||||
|
||||
struct gl_data {
|
||||
backend_t base;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "x.h"
|
||||
|
||||
struct _glx_image_data {
|
||||
gl_texture_t texture;
|
||||
struct gl_image gl;
|
||||
GLXPixmap glpixmap;
|
||||
xcb_pixmap_t pixmap;
|
||||
bool owned;
|
||||
|
@ -163,14 +163,14 @@ struct glx_fbconfig_info *glx_find_fbconfig(Display *dpy, int screen, struct xvi
|
|||
void glx_release_image(backend_t *base, void *image_data) {
|
||||
struct _glx_image_data *wd = image_data;
|
||||
struct _glx_data *gd = (void *)base;
|
||||
(*wd->texture.refcount)--;
|
||||
if (*wd->texture.refcount != 0) {
|
||||
wd->gl.inner->refcount--;
|
||||
if (wd->gl.inner->refcount != 0) {
|
||||
free(wd);
|
||||
return;
|
||||
}
|
||||
// Release binding
|
||||
if (wd->glpixmap && wd->texture.texture) {
|
||||
glBindTexture(GL_TEXTURE_2D, wd->texture.texture);
|
||||
if (wd->glpixmap && wd->gl.inner->texture) {
|
||||
glBindTexture(GL_TEXTURE_2D, wd->gl.inner->texture);
|
||||
glXReleaseTexImageEXT(gd->display, wd->glpixmap, GLX_FRONT_LEFT_EXT);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
@ -186,8 +186,8 @@ void glx_release_image(backend_t *base, void *image_data) {
|
|||
wd->pixmap = XCB_NONE;
|
||||
}
|
||||
|
||||
glDeleteTextures(1, &wd->texture.texture);
|
||||
free(wd->texture.refcount);
|
||||
glDeleteTextures(1, &wd->gl.inner->texture);
|
||||
free(wd->gl.inner);
|
||||
|
||||
// Free structure itself
|
||||
free(wd);
|
||||
|
@ -364,8 +364,9 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
|
|||
log_trace("Binding pixmap %#010x", pixmap);
|
||||
auto wd = ccalloc(1, struct _glx_image_data);
|
||||
wd->pixmap = pixmap;
|
||||
wd->texture.width = wd->texture.ewidth = r->width;
|
||||
wd->texture.height = wd->texture.eheight = r->height;
|
||||
wd->gl.inner = ccalloc(1, struct gl_texture);
|
||||
wd->gl.inner->width = wd->gl.ewidth = r->width;
|
||||
wd->gl.inner->height = wd->gl.eheight = r->height;
|
||||
free(r);
|
||||
|
||||
auto fbcfg = glx_find_fbconfig(gd->display, gd->screen, fmt);
|
||||
|
@ -393,7 +394,7 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
|
|||
0,
|
||||
};
|
||||
|
||||
wd->texture.y_inverted = fbcfg->y_inverted;
|
||||
wd->gl.inner->y_inverted = fbcfg->y_inverted;
|
||||
|
||||
wd->glpixmap = glXCreatePixmap(gd->display, fbcfg->cfg, wd->pixmap, attrs);
|
||||
free(fbcfg);
|
||||
|
@ -406,16 +407,15 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b
|
|||
log_trace("GLXPixmap %#010lx", wd->glpixmap);
|
||||
|
||||
// Create texture
|
||||
wd->texture.texture = gl_new_texture(GL_TEXTURE_2D);
|
||||
wd->texture.opacity = 1;
|
||||
wd->texture.depth = (unsigned int)fmt.visual_depth;
|
||||
wd->texture.color_inverted = false;
|
||||
wd->texture.dim = 0;
|
||||
wd->texture.has_alpha = fmt.alpha_size != 0;
|
||||
wd->texture.refcount = ccalloc(1, int);
|
||||
*wd->texture.refcount = 1;
|
||||
wd->gl.inner->texture = gl_new_texture(GL_TEXTURE_2D);
|
||||
wd->gl.inner->depth = (unsigned int)fmt.visual_depth;
|
||||
wd->gl.opacity = 1;
|
||||
wd->gl.color_inverted = false;
|
||||
wd->gl.dim = 0;
|
||||
wd->gl.has_alpha = fmt.alpha_size != 0;
|
||||
wd->gl.inner->refcount = 1;
|
||||
wd->owned = owned;
|
||||
glBindTexture(GL_TEXTURE_2D, wd->texture.texture);
|
||||
glBindTexture(GL_TEXTURE_2D, wd->gl.inner->texture);
|
||||
glXBindTexImageEXT(gd->display, wd->glpixmap, GLX_FRONT_LEFT_EXT, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
|
@ -456,7 +456,7 @@ static void *glx_copy(backend_t *base, const void *image_data, const region_t *r
|
|||
const struct _glx_image_data *img = image_data;
|
||||
auto new_img = ccalloc(1, struct _glx_image_data);
|
||||
*new_img = *img;
|
||||
(*new_img->texture.refcount)++;
|
||||
new_img->gl.inner->refcount++;
|
||||
return new_img;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue