commit 87e5e78
Michael Forney
·
2013-12-07 04:28:02 +0000 UTC
parent 75b42b7
compositor: Better support for multiple outputs Now, multiple outputs displaying the same region both get painted correctly because each output keeps track of it's damage since it's last refresh.
3 files changed,
+48,
-27
+46,
-26
1@@ -85,43 +85,49 @@ static void calculate_damage(struct swc_compositor * compositor)
2 }
3
4 static void repaint_output(struct swc_compositor * compositor,
5- struct swc_output * output)
6+ struct swc_output * output,
7+ pixman_region32_t * damage)
8 {
9- pixman_region32_t damage, previous_damage, base_damage;
10+ pixman_region32_t base_damage;
11
12- pixman_region32_init(&damage);
13- pixman_region32_init(&previous_damage);
14 pixman_region32_init(&base_damage);
15-
16- pixman_region32_intersect_rect
17- (&damage, &compositor->damage, output->geometry.x, output->geometry.y,
18- output->geometry.width, output->geometry.height);
19-
20- /* We must save the damage from the previous frame because the back buffer
21- * is also damaged in this region. */
22- pixman_region32_copy(&previous_damage, &output->previous_damage);
23- pixman_region32_copy(&output->previous_damage, &damage);
24-
25- /* The total damage is composed of the damage from the new frame, and the
26- * damage from the last frame. */
27- pixman_region32_union(&damage, &damage, &previous_damage);
28-
29- pixman_region32_subtract(&base_damage, &damage, &compositor->opaque);
30+ pixman_region32_subtract(&base_damage, damage, &compositor->opaque);
31
32 swc_renderer_set_target(&compositor->renderer, &output->framebuffer_plane);
33- swc_renderer_repaint(&compositor->renderer, &damage, &base_damage,
34+ swc_renderer_repaint(&compositor->renderer, damage, &base_damage,
35 &compositor->surfaces);
36
37- pixman_region32_subtract(&compositor->damage, &compositor->damage, &damage);
38-
39- pixman_region32_fini(&damage);
40- pixman_region32_fini(&previous_damage);
41 pixman_region32_fini(&base_damage);
42
43 if (!swc_plane_flip(&output->framebuffer_plane))
44 fprintf(stderr, "Plane flip failed\n");
45 }
46
47+static void update_output_damage(struct swc_output * output,
48+ pixman_region32_t * damage)
49+{
50+ pixman_region32_union
51+ (&output->current_damage, &output->current_damage, damage);
52+ pixman_region32_intersect_rect
53+ (&output->current_damage, &output->current_damage,
54+ output->geometry.x, output->geometry.y,
55+ output->geometry.width, output->geometry.height);
56+}
57+
58+static void flush_output_damage(struct swc_output * output,
59+ pixman_region32_t * damage)
60+{
61+ /* The total damage is composed of the damage from the new frame, and the
62+ * damage from the last frame. */
63+ pixman_region32_union(damage,
64+ &output->current_damage, &output->previous_damage);
65+
66+ /* We must save the damage from the previous frame because the back buffer
67+ * is also damaged in this region. */
68+ pixman_region32_copy(&output->previous_damage, &output->current_damage);
69+ pixman_region32_clear(&output->current_damage);
70+}
71+
72 static void perform_update(void * data)
73 {
74 struct swc_compositor * compositor = data;
75@@ -131,15 +137,29 @@ static void perform_update(void * data)
76
77 if (updates)
78 {
79+ pixman_region32_t damage;
80+
81 printf("performing update\n");
82 calculate_damage(compositor);
83+ pixman_region32_init(&damage);
84
85 wl_list_for_each(output, &compositor->outputs, link)
86 {
87- if (updates & SWC_OUTPUT_MASK(output))
88- repaint_output(compositor, output);
89+ if (compositor->scheduled_updates & SWC_OUTPUT_MASK(output))
90+ {
91+ update_output_damage(output, &compositor->damage);
92+
93+ if (!(compositor->pending_flips & SWC_OUTPUT_MASK(output)))
94+ {
95+ flush_output_damage(output, &damage);
96+ repaint_output(compositor, output, &damage);
97+ }
98+ }
99 }
100
101+ pixman_region32_fini(&damage);
102+ /* XXX: Should assert that all damage was covered by some output */
103+ pixman_region32_clear(&compositor->damage);
104 compositor->pending_flips |= updates;
105 compositor->scheduled_updates &= ~updates;
106 }
+1,
-0
1@@ -64,6 +64,7 @@ bool swc_output_initialize(struct swc_output * output, struct swc_drm * drm,
2
3 wl_list_init(&output->resources);
4 wl_array_init(&output->modes);
5+ pixman_region32_init(&output->current_damage);
6 pixman_region32_init(&output->previous_damage);
7
8 output->crtc_id = crtc_id;
+1,
-1
1@@ -29,7 +29,7 @@ struct swc_output
2 struct swc_plane framebuffer_plane;
3 struct swc_plane cursor_plane;
4
5- pixman_region32_t previous_damage;
6+ pixman_region32_t current_damage, previous_damage;
7
8 /* The CRTC and connector we are using to drive this output */
9 uint32_t crtc_id;