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, 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) { 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; struct gl_data *gd = (void *)base;
// Until we start to use glClipControl, reg_tgt, dst_x and dst_y and // 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 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 // screen, with y axis pointing down. We have to do some coordinate conversion in
// this function // this function
if (!ptex || !ptex->texture) { if (!ptex || !ptex->inner->texture) {
log_error("Missing texture."); log_error("Missing texture.");
return; 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 // dst_y is the top coordinate, in OpenGL, it is the upper bound of the y
// coordinate. // coordinate.
dst_y = gd->height - dst_y; 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; 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); // x, y, width, height, dx, dy, ptex->width, ptex->height, z);
// Bind texture // Bind texture
glBindTexture(GL_TEXTURE_2D, ptex->texture); glBindTexture(GL_TEXTURE_2D, ptex->inner->texture);
if (dual_texture) { if (dual_texture) {
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, ptex->texture); glBindTexture(GL_TEXTURE_2D, ptex->inner->texture);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
} }
auto coord = ccalloc(nrects * 16, GLfloat); 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); auto texture_y2 = texture_y1 + (GLfloat)(crect.y1 - crect.y2);
// X pixmaps might be Y inverted, invert the texture coordinates // X pixmaps might be Y inverted, invert the texture coordinates
if (ptex->y_inverted) { if (ptex->inner->y_inverted) {
texture_y1 = (GLfloat)ptex->height - texture_y1; texture_y1 = (GLfloat)ptex->inner->height - texture_y1;
texture_y2 = (GLfloat)ptex->height - texture_y2; texture_y2 = (GLfloat)ptex->inner->height - texture_y2;
} }
// GL_TEXTURE_2D coordinates are normalized // GL_TEXTURE_2D coordinates are normalized
// TODO use texelFetch // TODO use texelFetch
texture_x1 /= (GLfloat)ptex->width; texture_x1 /= (GLfloat)ptex->inner->width;
texture_y1 /= (GLfloat)ptex->height; texture_y1 /= (GLfloat)ptex->inner->height;
texture_x2 /= (GLfloat)ptex->width; texture_x2 /= (GLfloat)ptex->inner->width;
texture_y2 /= (GLfloat)ptex->height; texture_y2 /= (GLfloat)ptex->inner->height;
// Vertex coordinates // Vertex coordinates
auto vx1 = (GLfloat)crect.x1; auto vx1 = (GLfloat)crect.x1;
@ -893,10 +893,17 @@ GLuint gl_new_texture(GLenum target) {
return texture; 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 /// stub for backend_operations::image_op
bool gl_image_op(backend_t *base, enum image_operations op, void *image_data, 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) { 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; int *iargs = arg;
switch (op) { switch (op) {
case IMAGE_OP_INVERT_COLOR_ALL: tex->color_inverted = true; break; 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; break;
case IMAGE_OP_APPLY_ALPHA_ALL: tex->opacity *= *(double *)arg; break; case IMAGE_OP_APPLY_ALPHA_ALL: tex->opacity *= *(double *)arg; break;
case IMAGE_OP_APPLY_ALPHA: case IMAGE_OP_APPLY_ALPHA:
// TODO gl_image_decouple(tex);
log_warn("IMAGE_OP_APPLY_ALPHA not implemented yet"); log_warn("IMAGE_OP_APPLY_ALPHA not implemented yet");
break; break;
case IMAGE_OP_RESIZE_TILE: 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) { 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; return img->has_alpha;
} }

View File

@ -42,21 +42,23 @@ typedef struct {
GLint color_loc; GLint color_loc;
} gl_fill_shader_t; } 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. /// @brief Wrapper of a binded GLX texture.
typedef struct gl_texture { typedef struct gl_image {
struct gl_texture *inner;
double opacity; double opacity;
double dim; double dim;
int *refcount;
GLuint texture;
// The size of the backing texture
int width, height;
// The effective size of the texture
int ewidth, eheight; int ewidth, eheight;
unsigned depth;
bool y_inverted;
bool has_alpha; bool has_alpha;
bool color_inverted; bool color_inverted;
} gl_texture_t; } gl_image_t;
struct gl_data { struct gl_data {
backend_t base; backend_t base;

View File

@ -34,7 +34,7 @@
#include "x.h" #include "x.h"
struct _glx_image_data { struct _glx_image_data {
gl_texture_t texture; struct gl_image gl;
GLXPixmap glpixmap; GLXPixmap glpixmap;
xcb_pixmap_t pixmap; xcb_pixmap_t pixmap;
bool owned; 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) { void glx_release_image(backend_t *base, void *image_data) {
struct _glx_image_data *wd = image_data; struct _glx_image_data *wd = image_data;
struct _glx_data *gd = (void *)base; struct _glx_data *gd = (void *)base;
(*wd->texture.refcount)--; wd->gl.inner->refcount--;
if (*wd->texture.refcount != 0) { if (wd->gl.inner->refcount != 0) {
free(wd); free(wd);
return; return;
} }
// Release binding // Release binding
if (wd->glpixmap && wd->texture.texture) { if (wd->glpixmap && wd->gl.inner->texture) {
glBindTexture(GL_TEXTURE_2D, wd->texture.texture); glBindTexture(GL_TEXTURE_2D, wd->gl.inner->texture);
glXReleaseTexImageEXT(gd->display, wd->glpixmap, GLX_FRONT_LEFT_EXT); glXReleaseTexImageEXT(gd->display, wd->glpixmap, GLX_FRONT_LEFT_EXT);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
@ -186,8 +186,8 @@ void glx_release_image(backend_t *base, void *image_data) {
wd->pixmap = XCB_NONE; wd->pixmap = XCB_NONE;
} }
glDeleteTextures(1, &wd->texture.texture); glDeleteTextures(1, &wd->gl.inner->texture);
free(wd->texture.refcount); free(wd->gl.inner);
// Free structure itself // Free structure itself
free(wd); 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); log_trace("Binding pixmap %#010x", pixmap);
auto wd = ccalloc(1, struct _glx_image_data); auto wd = ccalloc(1, struct _glx_image_data);
wd->pixmap = pixmap; wd->pixmap = pixmap;
wd->texture.width = wd->texture.ewidth = r->width; wd->gl.inner = ccalloc(1, struct gl_texture);
wd->texture.height = wd->texture.eheight = r->height; wd->gl.inner->width = wd->gl.ewidth = r->width;
wd->gl.inner->height = wd->gl.eheight = r->height;
free(r); free(r);
auto fbcfg = glx_find_fbconfig(gd->display, gd->screen, fmt); 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, 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); wd->glpixmap = glXCreatePixmap(gd->display, fbcfg->cfg, wd->pixmap, attrs);
free(fbcfg); 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); log_trace("GLXPixmap %#010lx", wd->glpixmap);
// Create texture // Create texture
wd->texture.texture = gl_new_texture(GL_TEXTURE_2D); wd->gl.inner->texture = gl_new_texture(GL_TEXTURE_2D);
wd->texture.opacity = 1; wd->gl.inner->depth = (unsigned int)fmt.visual_depth;
wd->texture.depth = (unsigned int)fmt.visual_depth; wd->gl.opacity = 1;
wd->texture.color_inverted = false; wd->gl.color_inverted = false;
wd->texture.dim = 0; wd->gl.dim = 0;
wd->texture.has_alpha = fmt.alpha_size != 0; wd->gl.has_alpha = fmt.alpha_size != 0;
wd->texture.refcount = ccalloc(1, int); wd->gl.inner->refcount = 1;
*wd->texture.refcount = 1;
wd->owned = owned; 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); glXBindTexImageEXT(gd->display, wd->glpixmap, GLX_FRONT_LEFT_EXT, NULL);
glBindTexture(GL_TEXTURE_2D, 0); 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; const struct _glx_image_data *img = image_data;
auto new_img = ccalloc(1, struct _glx_image_data); auto new_img = ccalloc(1, struct _glx_image_data);
*new_img = *img; *new_img = *img;
(*new_img->texture.refcount)++; new_img->gl.inner->refcount++;
return new_img; return new_img;
} }