picom upto date sync with yshui, full anim support
This commit is contained in:
@@ -55,6 +55,58 @@ region_t get_damage(session_t *ps, bool all_damage) {
|
||||
return region;
|
||||
}
|
||||
|
||||
static void process_window_for_painting(session_t *ps, struct managed_win *w,
|
||||
void *win_image, double additional_alpha,
|
||||
region_t *reg_bound, region_t *reg_visible,
|
||||
region_t *reg_paint, region_t *reg_paint_in_bound) {
|
||||
// For window image processing, we don't have to limit the process
|
||||
// region to damage for correctness. (see <damager-note> for
|
||||
// details)
|
||||
|
||||
// The visible region, in window local coordinates Although we
|
||||
// don't limit process region to damage, we provide that info in
|
||||
// reg_visible as a hint. Since window image data outside of the
|
||||
// damage region won't be painted onto target
|
||||
coord_t window_coord = {.x = w->g.x, .y = w->g.y};
|
||||
coord_t dest_coord = {.x = w->g.x + w->widthb, .y = w->g.y + w->heightb};
|
||||
|
||||
region_t reg_visible_local;
|
||||
{
|
||||
// The bounding shape, in window local coordinates
|
||||
region_t reg_bound_local;
|
||||
pixman_region32_init(®_bound_local);
|
||||
pixman_region32_copy(®_bound_local, reg_bound);
|
||||
pixman_region32_translate(®_bound_local, -w->g.x, -w->g.y);
|
||||
|
||||
pixman_region32_init(®_visible_local);
|
||||
pixman_region32_intersect(®_visible_local, reg_visible, reg_paint);
|
||||
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.
|
||||
pixman_region32_intersect(®_visible_local, ®_visible_local,
|
||||
®_bound_local);
|
||||
pixman_region32_fini(®_bound_local);
|
||||
}
|
||||
|
||||
auto new_img = ps->backend_data->ops->clone_image(ps->backend_data, win_image,
|
||||
®_visible_local);
|
||||
auto reg_frame = win_get_region_frame_local_by_val(w);
|
||||
double alpha = additional_alpha * w->opacity;
|
||||
ps->backend_data->ops->set_image_property(
|
||||
ps->backend_data, IMAGE_PROPERTY_OPACITY, new_img, &alpha);
|
||||
ps->backend_data->ops->image_op(ps->backend_data, IMAGE_OP_APPLY_ALPHA, new_img,
|
||||
®_frame, ®_visible_local,
|
||||
(double[]){w->frame_opacity});
|
||||
pixman_region32_fini(®_frame);
|
||||
ps->backend_data->ops->compose(ps->backend_data, new_img,
|
||||
window_coord, NULL, dest_coord,
|
||||
reg_paint_in_bound, reg_visible);
|
||||
ps->backend_data->ops->release_image(ps->backend_data, new_img);
|
||||
pixman_region32_fini(®_visible_local);
|
||||
}
|
||||
|
||||
void handle_device_reset(session_t *ps) {
|
||||
log_error("Device reset detected");
|
||||
// Wait for reset to complete
|
||||
@@ -185,7 +237,7 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
||||
|
||||
if (ps->root_image) {
|
||||
ps->backend_data->ops->compose(ps->backend_data, ps->root_image,
|
||||
(coord_t){0}, NULL, (coord_t){0},
|
||||
(coord_t){0}, NULL, (coord_t){.x = ps->root_width, .y = ps->root_height},
|
||||
®_paint, ®_visible);
|
||||
} else {
|
||||
ps->backend_data->ops->fill(ps->backend_data, (struct color){0, 0, 0, 1},
|
||||
@@ -237,6 +289,7 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
||||
* option */
|
||||
auto real_win_mode = w->mode;
|
||||
coord_t window_coord = {.x = w->g.x, .y = w->g.y};
|
||||
coord_t dest_coord = {.x = w->g.x + w->widthb, .y = w->g.y + w->heightb};
|
||||
|
||||
if (w->blur_background &&
|
||||
(ps->o.force_win_blend || real_win_mode == WMODE_TRANS ||
|
||||
@@ -409,6 +462,17 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
||||
ps->backend_data->ops->set_image_property(
|
||||
ps->backend_data, IMAGE_PROPERTY_BORDER_WIDTH,
|
||||
w->win_image, &border_width);
|
||||
if (w->old_win_image) {
|
||||
// TODO(dccsillag): explain why the following is
|
||||
// "necessary"
|
||||
double zero = 0.0;
|
||||
ps->backend_data->ops->set_image_property(
|
||||
ps->backend_data, IMAGE_PROPERTY_BORDER_WIDTH,
|
||||
w->old_win_image, &zero);
|
||||
ps->backend_data->ops->set_image_property(
|
||||
ps->backend_data, IMAGE_PROPERTY_CORNER_RADIUS,
|
||||
w->old_win_image, &zero);
|
||||
}
|
||||
}
|
||||
|
||||
ps->backend_data->ops->set_image_property(
|
||||
@@ -431,53 +495,43 @@ void paint_all_new(session_t *ps, struct managed_win *t, bool ignore_damage) {
|
||||
}
|
||||
|
||||
// Draw window on target
|
||||
if (w->frame_opacity == 1) {
|
||||
bool is_animating = 0 <= w->animation_progress && w->animation_progress < 1.0;
|
||||
if (w->frame_opacity == 1 && !is_animating) {
|
||||
ps->backend_data->ops->compose(ps->backend_data, w->win_image,
|
||||
window_coord, NULL, window_coord,
|
||||
window_coord, NULL, dest_coord,
|
||||
®_paint_in_bound, ®_visible);
|
||||
} else {
|
||||
// For window image processing, we don't have to limit the process
|
||||
// region to damage for correctness. (see <damager-note> for
|
||||
// details)
|
||||
if (is_animating && w->old_win_image) {
|
||||
bool is_focused = win_is_focused_raw(ps, w);
|
||||
if (!is_focused && w->focused && w->opacity_is_set)
|
||||
is_focused = true;
|
||||
assert(w->old_win_image);
|
||||
|
||||
// The visible region, in window local coordinates Although we
|
||||
// don't limit process region to damage, we provide that info in
|
||||
// reg_visible as a hint. Since window image data outside of the
|
||||
// damage region won't be painted onto target
|
||||
region_t reg_visible_local;
|
||||
region_t reg_bound_local;
|
||||
{
|
||||
// The bounding shape, in window local coordinates
|
||||
pixman_region32_init(®_bound_local);
|
||||
pixman_region32_copy(®_bound_local, ®_bound);
|
||||
pixman_region32_translate(®_bound_local, -w->g.x, -w->g.y);
|
||||
bool resizing =
|
||||
w->g.width != w->pending_g.width ||
|
||||
w->g.height != w->pending_g.height;
|
||||
|
||||
pixman_region32_init(®_visible_local);
|
||||
pixman_region32_intersect(®_visible_local,
|
||||
®_visible, ®_paint);
|
||||
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.
|
||||
pixman_region32_intersect(
|
||||
®_visible_local, ®_visible_local, ®_bound_local);
|
||||
// Only animate opacity here if we are resizing
|
||||
// a transparent window
|
||||
process_window_for_painting(ps, w, w->win_image,
|
||||
is_focused ? 1.0 : w->opacity >= 1 ? 1.0 : w->animation_progress,
|
||||
®_bound, ®_visible,
|
||||
®_paint, ®_paint_in_bound);
|
||||
|
||||
// Only do this if size changes as otherwise moving
|
||||
// transparent windows will flicker and if you just
|
||||
// move so slightly they will keep flickering
|
||||
if (resizing && (!is_focused || !w->opacity_is_set)) {
|
||||
process_window_for_painting(ps, w, w->old_win_image,
|
||||
1.0 - w->animation_progress,
|
||||
®_bound, ®_visible,
|
||||
®_paint, ®_paint_in_bound);
|
||||
}
|
||||
} else {
|
||||
process_window_for_painting(
|
||||
ps, w, w->win_image, 1.0, ®_bound, ®_visible,
|
||||
®_paint, ®_paint_in_bound);
|
||||
}
|
||||
|
||||
auto new_img = ps->backend_data->ops->clone_image(
|
||||
ps->backend_data, w->win_image, ®_visible_local);
|
||||
auto reg_frame = win_get_region_frame_local_by_val(w);
|
||||
ps->backend_data->ops->image_op(
|
||||
ps->backend_data, IMAGE_OP_APPLY_ALPHA, new_img, ®_frame,
|
||||
®_visible_local, (double[]){w->frame_opacity});
|
||||
pixman_region32_fini(®_frame);
|
||||
ps->backend_data->ops->compose(ps->backend_data, new_img,
|
||||
window_coord, NULL, window_coord,
|
||||
®_paint_in_bound, ®_visible);
|
||||
ps->backend_data->ops->release_image(ps->backend_data, new_img);
|
||||
pixman_region32_fini(®_visible_local);
|
||||
pixman_region32_fini(®_bound_local);
|
||||
}
|
||||
skip:
|
||||
pixman_region32_fini(®_bound);
|
||||
|
||||
@@ -183,6 +183,11 @@ struct backend_operations {
|
||||
void *mask, coord_t mask_dst, const region_t *reg_paint,
|
||||
const region_t *reg_visible);
|
||||
|
||||
void (*_compose)(backend_t *backend_data, void *image_data,
|
||||
int dst_x1, int dst_y1, int dst_x2, int dst_y2,
|
||||
const region_t *reg_paint, const region_t *reg_visible);
|
||||
|
||||
|
||||
/// Fill rectangle of the rendering buffer, mostly for debug purposes, optional.
|
||||
void (*fill)(backend_t *backend_data, struct color, const region_t *clip);
|
||||
|
||||
|
||||
@@ -412,7 +412,7 @@ static void _gl_compose(backend_t *base, struct backend_image *img, GLuint targe
|
||||
}
|
||||
|
||||
glUniform1i(win_shader->uniform_mask_tex, 2);
|
||||
glUniform2f(win_shader->uniform_mask_offset, (float)mask_offset.x,
|
||||
glUniform2f(win_shader->uniform_mask_offset, (float)mask_offset.x ,
|
||||
(float)mask_offset.y);
|
||||
if (mask != NULL) {
|
||||
glUniform1i(win_shader->uniform_mask_inverted, mask->color_inverted);
|
||||
@@ -494,7 +494,8 @@ void x_rect_to_coords(int nrects, const rect_t *rects, coord_t image_dst,
|
||||
int extent_height, int texture_height, int root_height,
|
||||
bool y_inverted, GLint *coord, GLuint *indices) {
|
||||
image_dst.y = root_height - image_dst.y;
|
||||
image_dst.y -= extent_height;
|
||||
image_dst.y -= extent_height;
|
||||
|
||||
|
||||
for (int i = 0; i < nrects; i++) {
|
||||
// Y-flip. Note after this, crect.y1 > crect.y2
|
||||
@@ -573,6 +574,11 @@ void gl_compose(backend_t *base, void *image_data, coord_t image_dst, void *mask
|
||||
coord_t mask_offset = {.x = mask_dst.x - image_dst.x, .y = mask_dst.y - image_dst.y};
|
||||
x_rect_to_coords(nrects, rects, image_dst, inner->height, inner->height,
|
||||
gd->height, inner->y_inverted, coord, indices);
|
||||
for (unsigned int i = 2; i < 16; i+=4) {
|
||||
coord[i+0] = lerp_range(0, mask_offset.x, 0, inner->width, coord[i+0]);
|
||||
coord[i+1] = lerp_range(0, mask_offset.y, 0, inner->height, coord[i+1]);
|
||||
}
|
||||
|
||||
_gl_compose(base, img, gd->back_fbo, mask, mask_offset, coord, indices, nrects);
|
||||
|
||||
free(indices);
|
||||
|
||||
Reference in New Issue
Block a user