aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--types/scene/wlr_scene.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c
index c5c301a7..69d6f4a3 100644
--- a/types/scene/wlr_scene.c
+++ b/types/scene/wlr_scene.c
@@ -270,6 +270,14 @@ static uint32_t region_area(pixman_region32_t *region) {
return area;
}
+static void scale_output_damage(pixman_region32_t *damage, float scale) {
+ wlr_region_scale(damage, damage, scale);
+
+ if (floor(scale) != scale) {
+ wlr_region_expand(damage, damage, 1);
+ }
+}
+
static void scene_damage_outputs(struct wlr_scene *scene, pixman_region32_t *damage) {
if (!pixman_region32_not_empty(damage)) {
return;
@@ -282,8 +290,7 @@ static void scene_damage_outputs(struct wlr_scene *scene, pixman_region32_t *dam
pixman_region32_copy(&output_damage, damage);
pixman_region32_translate(&output_damage,
-scene_output->x, -scene_output->y);
- wlr_region_scale(&output_damage, &output_damage,
- scene_output->output->scale);
+ scale_output_damage(&output_damage, scene_output->output->scale);
if (wlr_damage_ring_add(&scene_output->damage_ring, &output_damage)) {
wlr_output_schedule_frame(scene_output->output);
}
@@ -649,6 +656,11 @@ void wlr_scene_buffer_set_buffer_with_damage(struct wlr_scene_buffer *scene_buff
pixman_region32_intersect(&output_damage, &output_damage, &cull_region);
pixman_region32_fini(&cull_region);
+ // if we are using fractional scaling add a 1px margin.
+ if (floor(output_scale) != output_scale) {
+ wlr_region_expand(&output_damage, &output_damage, 1);
+ }
+
pixman_region32_translate(&output_damage,
(lx - scene_output->x) * output_scale,
(ly - scene_output->y) * output_scale);
@@ -1055,7 +1067,7 @@ static void scene_node_render(struct wlr_scene_node *node,
pixman_region32_init(&render_region);
pixman_region32_copy(&render_region, &node->visible);
pixman_region32_translate(&render_region, -scene_output->x, -scene_output->y);
- wlr_region_scale(&render_region, &render_region, output->scale);
+ scale_output_damage(&render_region, output->scale);
pixman_region32_intersect(&render_region, &render_region, damage);
if (!pixman_region32_not_empty(&render_region)) {
pixman_region32_fini(&render_region);
@@ -1534,6 +1546,8 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
// scene nodes above. Those scene nodes will just render atop having us
// never see the background.
if (scene_output->scene->calculate_visibility) {
+ float output_scale = scene_output->output->scale;
+
for (int i = list_len - 1; i >= 0; i--) {
struct wlr_scene_node *node = list_data[i];
int x, y;
@@ -1550,10 +1564,18 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
pixman_region32_intersect(&opaque, &opaque, &node->visible);
pixman_region32_translate(&opaque, -scene_output->x, -scene_output->y);
- wlr_region_scale(&opaque, &opaque, scene_output->output->scale);
+ wlr_region_scale(&opaque, &opaque, output_scale);
pixman_region32_subtract(&background, &background, &opaque);
pixman_region32_fini(&opaque);
}
+
+ if (floor(output_scale) != output_scale) {
+ wlr_region_expand(&background, &background, 1);
+
+ // reintersect with the damage because we never want to render
+ // outside of the damage region
+ pixman_region32_intersect(&background, &background, &damage);
+ }
}
int nrects;