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,
|
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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user