backend interface: add IMAGE_OP_RESIZE_TILE
We need this to paint the wallpaper with repeat to mimic the behavior of Xorg's background pixmap. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
fb155c9769
commit
c5d9f459dd
|
@ -32,6 +32,11 @@ enum image_operations {
|
||||||
// Same as APPLY_ALPHA, but `reg_op` is ignored and the operation applies to the
|
// Same as APPLY_ALPHA, but `reg_op` is ignored and the operation applies to the
|
||||||
// full image
|
// full image
|
||||||
IMAGE_OP_APPLY_ALPHA_ALL,
|
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 {
|
struct backend_operations {
|
||||||
|
|
|
@ -267,6 +267,7 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
|
||||||
|
|
||||||
// Painting
|
// Painting
|
||||||
int nrects;
|
int nrects;
|
||||||
|
|
||||||
const rect_t *rects;
|
const rect_t *rects;
|
||||||
rects = pixman_region32_rectangles((region_t *)reg_tgt, &nrects);
|
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) {
|
if (ptex->target == GL_TEXTURE_2D) {
|
||||||
// GL_TEXTURE_2D coordinates are 0-1
|
// GL_TEXTURE_2D coordinates are normalized
|
||||||
texture_x1 /= ptex->width;
|
texture_x1 /= ptex->width;
|
||||||
texture_y1 /= ptex->height;
|
texture_y1 /= ptex->height;
|
||||||
texture_x2 /= ptex->width;
|
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,
|
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_texture *tex = image_data;
|
||||||
|
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;
|
||||||
case IMAGE_OP_DIM_ALL: log_warn("IMAGE_OP_DIM_ALL not implemented yet"); 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:
|
case IMAGE_OP_APPLY_ALPHA:
|
||||||
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:
|
||||||
|
// texture is already set to repeat, so nothing else we need to do
|
||||||
|
tex->ewidth = iargs[0];
|
||||||
|
tex->eheight = iargs[1];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,9 @@ typedef struct gl_texture {
|
||||||
int *refcount;
|
int *refcount;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
GLenum target;
|
GLenum target;
|
||||||
unsigned width;
|
int width, height;
|
||||||
unsigned height;
|
// The effective size of the texture
|
||||||
|
int ewidth, eheight;
|
||||||
unsigned depth;
|
unsigned depth;
|
||||||
bool y_inverted;
|
bool y_inverted;
|
||||||
bool has_alpha;
|
bool has_alpha;
|
||||||
|
|
|
@ -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);
|
auto wd = ccalloc(1, struct _glx_image_data);
|
||||||
wd->pixmap = pixmap;
|
wd->pixmap = pixmap;
|
||||||
wd->texture.width = r->width;
|
wd->texture.width = wd->texture.ewidth = r->width;
|
||||||
wd->texture.height = r->height;
|
wd->texture.height = wd->texture.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);
|
||||||
|
|
|
@ -76,6 +76,8 @@ struct _xrender_image_data {
|
||||||
// A Picture links to the Pixmap
|
// A Picture links to the Pixmap
|
||||||
xcb_render_picture_t pict;
|
xcb_render_picture_t pict;
|
||||||
long width, height;
|
long width, height;
|
||||||
|
// The effective size of the image
|
||||||
|
long ewidth, eheight;
|
||||||
bool has_alpha;
|
bool has_alpha;
|
||||||
double opacity;
|
double opacity;
|
||||||
xcb_visualid_t visual;
|
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, ®);
|
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],
|
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(®);
|
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);
|
auto img = ccalloc(1, struct _xrender_image_data);
|
||||||
img->depth = fmt.visual_depth;
|
img->depth = fmt.visual_depth;
|
||||||
img->width = r->width;
|
img->width = img->ewidth = r->width;
|
||||||
img->height = r->height;
|
img->height = img->eheight = r->height;
|
||||||
img->pixmap = pixmap;
|
img->pixmap = pixmap;
|
||||||
img->opacity = 1;
|
img->opacity = 1;
|
||||||
img->has_alpha = fmt.alpha_size != 0;
|
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;
|
region_t reg;
|
||||||
double dim_opacity;
|
double dim_opacity;
|
||||||
double alpha_multiplier;
|
double alpha_multiplier;
|
||||||
|
int *iargs = arg;
|
||||||
if (op == IMAGE_OP_APPLY_ALPHA_ALL) {
|
if (op == IMAGE_OP_APPLY_ALPHA_ALL) {
|
||||||
alpha_multiplier = *(double *)arg;
|
alpha_multiplier = *(double *)arg;
|
||||||
img->opacity *= alpha_multiplier;
|
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);
|
alpha_pict, 0, 0, 0, 0, 0, 0, img->width, img->height);
|
||||||
img->has_alpha = true;
|
img->has_alpha = true;
|
||||||
break;
|
break;
|
||||||
|
case IMAGE_OP_RESIZE_TILE:
|
||||||
|
img->ewidth = iargs[0];
|
||||||
|
img->eheight = iargs[1];
|
||||||
|
break;
|
||||||
case IMAGE_OP_APPLY_ALPHA_ALL: assert(false);
|
case IMAGE_OP_APPLY_ALPHA_ALL: assert(false);
|
||||||
}
|
}
|
||||||
pixman_region32_fini(®);
|
pixman_region32_fini(®);
|
||||||
|
|
|
@ -951,6 +951,8 @@ root_damaged(session_t *ps) {
|
||||||
ps->root_image =
|
ps->root_image =
|
||||||
ps->backend_data->ops->bind_pixmap(ps->backend_data, pixmap,
|
ps->backend_data->ops->bind_pixmap(ps->backend_data, pixmap,
|
||||||
x_get_visual_info(ps->c, ps->vis), false);
|
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) {
|
if (ps->root_image) {
|
||||||
ps->backend_data->ops->release_image(ps->backend_data, ps->root_image);
|
ps->backend_data->ops->release_image(ps->backend_data, ps->root_image);
|
||||||
ps->root_image = NULL;
|
ps->root_image = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
free_paint(ps, &w->paint);
|
free_paint(ps, &w->paint);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue