Implement monitor repaint in new xrender

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-03-05 20:27:04 +00:00
parent c387a266dc
commit eed5ea719e
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
4 changed files with 47 additions and 11 deletions

View File

@ -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(&region);
if (buffer_age == -1 || buffer_age > ps->ndamage) {
pixman_region32_copy(&region, &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(&reg_damage);
pixman_region32_copy(&reg_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,
&reg_paint, &reg_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(&reg_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, &reg_paint, &reg_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(&reg_visible_local, &reg_visible, &reg_damage);
pixman_region32_translate(&reg_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(&reg_visible_local, &reg_visible_local,
&reg_bound_local);
@ -231,6 +240,15 @@ void paint_all_new(session_t *ps, win *const t, bool ignore_damage) {
}
pixman_region32_fini(&reg_damage);
if (ps->o.monitor_repaint) {
reg_damage = get_damage(ps, false);
auto extent = pixman_region32_extents(&reg_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, &reg_damage);
pixman_region32_fini(&reg_damage);
}
// Move the head of the damage ring
ps->damage = ps->damage - 1;
if (ps->damage < ps->damage_ring) {

View File

@ -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);

View File

@ -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;
}

View File

@ -103,6 +103,18 @@ static void compose(backend_t *base, void *img_data, int dst_x, int dst_y,
pixman_region32_fini(&reg);
}
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,