Implement monitor repaint in new xrender
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
c387a266dc
commit
eed5ea719e
|
@ -2,7 +2,7 @@
|
|||
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
#include "backend.h"
|
||||
#include "backend/backend.h"
|
||||
#include "common.h"
|
||||
#include "compiler.h"
|
||||
#include "config.h"
|
||||
|
@ -17,11 +17,18 @@ backend_init_fn backend_list[NUM_BKEND] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
region_t get_damage(session_t *ps) {
|
||||
/**
|
||||
* @param all_damage if true ignore damage and repaint the whole screen
|
||||
*/
|
||||
region_t get_damage(session_t *ps, bool all_damage) {
|
||||
region_t region;
|
||||
auto buffer_age_fn = ps->backend_data->ops->buffer_age;
|
||||
int buffer_age = buffer_age_fn ? buffer_age_fn(ps->backend_data) : -1;
|
||||
|
||||
if (all_damage) {
|
||||
buffer_age = -1;
|
||||
}
|
||||
|
||||
pixman_region32_init(®ion);
|
||||
if (buffer_age == -1 || buffer_age > ps->ndamage) {
|
||||
pixman_region32_copy(®ion, &ps->screen_reg);
|
||||
|
@ -42,7 +49,7 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) {
|
|||
// part of the image we want to reuse
|
||||
region_t reg_damage;
|
||||
if (!ignore_damage) {
|
||||
reg_damage = get_damage(ps);
|
||||
reg_damage = get_damage(ps, ps->o.monitor_repaint);
|
||||
} else {
|
||||
pixman_region32_init(®_damage);
|
||||
pixman_region32_copy(®_damage, &ps->screen_reg);
|
||||
|
@ -149,7 +156,8 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) {
|
|||
ps->backend_data->ops->blur(ps->backend_data, w->opacity,
|
||||
®_paint, ®_visible);
|
||||
} else if (frame_transparent && ps->o.blur_background_frame) {
|
||||
// Window itself is solid, we only need to blur the frame region
|
||||
// Window itself is solid, we only need to blur the frame
|
||||
// region
|
||||
auto reg_blur = win_get_region_frame_local_by_val(w);
|
||||
pixman_region32_translate(®_blur, w->g.x, w->g.y);
|
||||
// make sure reg_blur \in reg_damage
|
||||
|
@ -165,8 +173,8 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) {
|
|||
w->g.y, ®_paint, ®_visible);
|
||||
} else {
|
||||
// For window image processing, we don't need to limit the process
|
||||
// region to damage, since the window image data is independent from
|
||||
// the target image data, which we want to protect.
|
||||
// region to damage, since the window image data is independent
|
||||
// from the target image data, which we want to protect.
|
||||
|
||||
// The bounding shape, in window local coordinates
|
||||
region_t reg_bound_local;
|
||||
|
@ -183,8 +191,9 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) {
|
|||
pixman_region32_intersect(®_visible_local, ®_visible, ®_damage);
|
||||
pixman_region32_translate(®_visible_local, -w->g.x, -w->g.y);
|
||||
// Data outside of the bounding shape won't be visible, but it is
|
||||
// not necessary to limit the image operations to the bounding shape
|
||||
// yet. So pass that as the visible region, not the clip region.
|
||||
// not necessary to limit the image operations to the bounding
|
||||
// shape yet. So pass that as the visible region, not the clip
|
||||
// region.
|
||||
pixman_region32_intersect(®_visible_local, ®_visible_local,
|
||||
®_bound_local);
|
||||
|
||||
|
@ -231,6 +240,15 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) {
|
|||
}
|
||||
pixman_region32_fini(®_damage);
|
||||
|
||||
if (ps->o.monitor_repaint) {
|
||||
reg_damage = get_damage(ps, false);
|
||||
auto extent = pixman_region32_extents(®_damage);
|
||||
ps->backend_data->ops->fill_rectangle(
|
||||
ps->backend_data, 0.5, 0, 0, 0.5, extent->x1, extent->y1,
|
||||
extent->x2 - extent->x1, extent->y2 - extent->y1, ®_damage);
|
||||
pixman_region32_fini(®_damage);
|
||||
}
|
||||
|
||||
// Move the head of the damage ring
|
||||
ps->damage = ps->damage - 1;
|
||||
if (ps->damage < ps->damage_ring) {
|
||||
|
|
|
@ -83,6 +83,10 @@ struct backend_operations {
|
|||
void (*compose)(backend_t *backend_data, void *image_data, int dst_x, int dst_y,
|
||||
const region_t *reg_paint, const region_t *reg_visible);
|
||||
|
||||
/// Fill rectangle of target, mostly for debug purposes, optional.
|
||||
void (*fill_rectangle)(backend_t *backend_data, double r, double g, double b, double a,
|
||||
int x, int y, int width, int height, const region_t *clip);
|
||||
|
||||
/// Blur a given region on of the target.
|
||||
bool (*blur)(backend_t *backend_data, double opacity, const region_t *reg_blur,
|
||||
const region_t *reg_visible) attr_nonnull(1, 3, 4);
|
||||
|
|
|
@ -267,7 +267,8 @@ void *default_backend_render_shadow(backend_t *backend_data, int width, int heig
|
|||
shadow_pixel, &shadow, &pict);
|
||||
|
||||
auto visual = x_get_visual_for_standard(backend_data->c, XCB_PICT_STANDARD_ARGB_32);
|
||||
void *ret = backend_data->ops->bind_pixmap(backend_data, shadow, x_get_visual_info(backend_data->c, visual), true);
|
||||
void *ret = backend_data->ops->bind_pixmap(
|
||||
backend_data, shadow, x_get_visual_info(backend_data->c, visual), true);
|
||||
xcb_render_free_picture(backend_data->c, pict);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,18 @@ static void compose(backend_t *base, void *img_data, int dst_x, int dst_y,
|
|||
pixman_region32_fini(®);
|
||||
}
|
||||
|
||||
static void fill_rectangle(backend_t *base, double r, double g, double b, double a, int x,
|
||||
int y, int width, int height, const region_t *clip) {
|
||||
struct _xrender_data *xd = (void *)base;
|
||||
x_set_picture_clip_region(base->c, xd->back[xd->curr_back], 0, 0, clip);
|
||||
// color is in X fixed point representation
|
||||
xcb_render_fill_rectangles(
|
||||
base->c, XCB_RENDER_PICT_OP_OVER, xd->back[xd->curr_back],
|
||||
(xcb_render_color_t){
|
||||
.red = r * 0xffff, .green = g * 0xffff, .blue = b * 0xffff, .alpha = a * 0xffff},
|
||||
1, (xcb_rectangle_t[]){{.x = x, .y = y, .width = width, .height = height}});
|
||||
}
|
||||
|
||||
static bool blur(backend_t *backend_data, double opacity, const region_t *reg_blur,
|
||||
const region_t *reg_visible) {
|
||||
struct _xrender_data *xd = (void *)backend_data;
|
||||
|
@ -192,8 +204,8 @@ static bool blur(backend_t *backend_data, double opacity, const region_t *reg_bl
|
|||
// There is only 1 pass
|
||||
if (i == 1) {
|
||||
xcb_render_composite(c, XCB_RENDER_PICT_OP_OVER, src_pict, alpha_pict,
|
||||
xd->back[xd->curr_back], 0, 0, 0, 0, extent->x1, extent->y1,
|
||||
width, height);
|
||||
xd->back[xd->curr_back], 0, 0, 0, 0, extent->x1,
|
||||
extent->y1, width, height);
|
||||
}
|
||||
|
||||
xcb_render_free_picture(c, tmp_picture[0]);
|
||||
|
@ -446,6 +458,7 @@ static struct backend_operations xrender_ops = {
|
|||
.blur = blur,
|
||||
.present = present,
|
||||
.compose = compose,
|
||||
.fill_rectangle = fill_rectangle,
|
||||
.bind_pixmap = bind_pixmap,
|
||||
.release_image = release_image,
|
||||
.render_shadow = default_backend_render_shadow,
|
||||
|
|
Loading…
Reference in New Issue