diff --git a/src/backend/backend.h b/src/backend/backend.h index 104d6ca..c8151e1 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -32,6 +32,11 @@ enum image_operations { // Same as APPLY_ALPHA, but `reg_op` is ignored and the operation applies to the // full image IMAGE_OP_APPLY_ALPHA_ALL, + // Change the effective size of the image, without touching the backing image + // itself. When the image is used, the backing image should be tiled to fill its + // effective size. `reg_op` and `reg_visibile` is ignored. `arg` is two integers, + // width and height, in that order. + IMAGE_OP_RESIZE_TILE, }; struct backend_operations { diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c index ea32339..acf8a9e 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -267,6 +267,7 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y, // Painting int nrects; + const rect_t *rects; rects = pixman_region32_rectangles((region_t *)reg_tgt, &nrects); @@ -291,7 +292,7 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y, } if (ptex->target == GL_TEXTURE_2D) { - // GL_TEXTURE_2D coordinates are 0-1 + // GL_TEXTURE_2D coordinates are normalized texture_x1 /= ptex->width; texture_y1 /= ptex->height; texture_x2 /= ptex->width; @@ -899,6 +900,7 @@ GLuint gl_new_texture(GLenum target) { 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; + int *iargs = arg; switch (op) { case IMAGE_OP_INVERT_COLOR_ALL: tex->color_inverted = true; break; case IMAGE_OP_DIM_ALL: log_warn("IMAGE_OP_DIM_ALL not implemented yet"); break; @@ -906,7 +908,13 @@ bool gl_image_op(backend_t *base, enum image_operations op, void *image_data, case IMAGE_OP_APPLY_ALPHA: log_warn("IMAGE_OP_APPLY_ALPHA not implemented yet"); break; + case IMAGE_OP_RESIZE_TILE: + // texture is already set to repeat, so nothing else we need to do + tex->ewidth = iargs[0]; + tex->eheight = iargs[1]; + break; } + return true; } diff --git a/src/backend/gl/gl_common.h b/src/backend/gl/gl_common.h index 78a5309..ba080ac 100644 --- a/src/backend/gl/gl_common.h +++ b/src/backend/gl/gl_common.h @@ -46,8 +46,9 @@ typedef struct gl_texture { int *refcount; GLuint texture; GLenum target; - unsigned width; - unsigned height; + int width, height; + // The effective size of the texture + int ewidth, eheight; unsigned depth; bool y_inverted; bool has_alpha; diff --git a/src/backend/gl/glx.c b/src/backend/gl/glx.c index c98fc50..038ba07 100644 --- a/src/backend/gl/glx.c +++ b/src/backend/gl/glx.c @@ -355,8 +355,8 @@ glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, b auto wd = ccalloc(1, struct _glx_image_data); wd->pixmap = pixmap; - wd->texture.width = r->width; - wd->texture.height = r->height; + wd->texture.width = wd->texture.ewidth = r->width; + wd->texture.height = wd->texture.eheight = r->height; free(r); auto fbcfg = glx_find_fbconfig(gd->display, gd->screen, fmt); diff --git a/src/backend/xrender.c b/src/backend/xrender.c index cdd3878..b3337a6 100644 --- a/src/backend/xrender.c +++ b/src/backend/xrender.c @@ -76,6 +76,8 @@ struct _xrender_image_data { // A Picture links to the Pixmap xcb_render_picture_t pict; long width, height; + // The effective size of the image + long ewidth, eheight; bool has_alpha; double opacity; xcb_visualid_t visual; @@ -99,7 +101,7 @@ static void compose(backend_t *base, void *img_data, int dst_x, int dst_y, x_set_picture_clip_region(base->c, xd->back[xd->curr_back], 0, 0, ®); xcb_render_composite(base->c, op, img->pict, alpha_pict, xd->back[xd->curr_back], - 0, 0, 0, 0, dst_x, dst_y, img->width, img->height); + 0, 0, 0, 0, dst_x, dst_y, img->ewidth, img->eheight); pixman_region32_fini(®); } @@ -226,8 +228,8 @@ bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt, bool auto img = ccalloc(1, struct _xrender_image_data); img->depth = fmt.visual_depth; - img->width = r->width; - img->height = r->height; + img->width = img->ewidth = r->width; + img->height = img->eheight = r->height; img->pixmap = pixmap; img->opacity = 1; img->has_alpha = fmt.alpha_size != 0; @@ -343,6 +345,7 @@ static bool image_op(backend_t *base, enum image_operations op, void *image, region_t reg; double dim_opacity; double alpha_multiplier; + int *iargs = arg; if (op == IMAGE_OP_APPLY_ALPHA_ALL) { alpha_multiplier = *(double *)arg; img->opacity *= alpha_multiplier; @@ -414,6 +417,10 @@ static bool image_op(backend_t *base, enum image_operations op, void *image, alpha_pict, 0, 0, 0, 0, 0, 0, img->width, img->height); img->has_alpha = true; break; + case IMAGE_OP_RESIZE_TILE: + img->ewidth = iargs[0]; + img->eheight = iargs[1]; + break; case IMAGE_OP_APPLY_ALPHA_ALL: assert(false); } pixman_region32_fini(®); diff --git a/src/compton.c b/src/compton.c index 49a95e2..31d3f28 100644 --- a/src/compton.c +++ b/src/compton.c @@ -951,6 +951,8 @@ root_damaged(session_t *ps) { ps->root_image = ps->backend_data->ops->bind_pixmap(ps->backend_data, pixmap, x_get_visual_info(ps->c, ps->vis), false); + ps->backend_data->ops->image_op(ps->backend_data, IMAGE_OP_RESIZE_TILE, + ps->root_image, NULL, NULL, (int[]){ps->root_width, ps->root_height}); } } @@ -2088,7 +2090,7 @@ redir_stop(session_t *ps) { if (ps->root_image) { ps->backend_data->ops->release_image(ps->backend_data, ps->root_image); ps->root_image = NULL; - } + } } else { free_paint(ps, &w->paint); }