mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-04 20:55:58 +01:00
wlr_scene: Handle fractional scaling better
Try to alleviate scaling inaccuracies by implementing a fudge factor.
This commit is contained in:
parent
6d90518c97
commit
c2d2773df5
1 changed files with 26 additions and 4 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue