From b91888b0a3d0854935437c1cfd8cf5ca923c9746 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Mon, 6 May 2019 17:27:14 +0100 Subject: [PATCH] new backend: glx: trivial refactoring Signed-off-by: Yuxuan Shui --- src/backend/gl/gl_common.c | 37 +++++++++++++++++++++-------------- src/backend/gl/gl_common.h | 20 ++++++++++--------- src/backend/gl/glx.c | 40 +++++++++++++++++++------------------- 3 files changed, 53 insertions(+), 44 deletions(-) diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c index ae539bf..088513d 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -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; } diff --git a/src/backend/gl/gl_common.h b/src/backend/gl/gl_common.h index ebcc1ba..8cbdd78 100644 --- a/src/backend/gl/gl_common.h +++ b/src/backend/gl/gl_common.h @@ -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; diff --git a/src/backend/gl/glx.c b/src/backend/gl/glx.c index 91cc829..68db55b 100644 --- a/src/backend/gl/glx.c +++ b/src/backend/gl/glx.c @@ -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; }