new backend: glx: trivial refactoring

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-05-06 17:27:14 +01:00
parent e894105e7b
commit b91888b0a3
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
3 changed files with 53 additions and 44 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}