commit 255b466
Michael Forney
·
2013-12-21 08:22:15 +0000 UTC
parent 828f469
Move rendering code to compositor.c
9 files changed,
+251,
-288
+240,
-4
1@@ -4,6 +4,7 @@
2 #include "cursor_surface.h"
3 #include "data_device_manager.h"
4 #include "drm.h"
5+#include "drm_buffer.h"
6 #include "internal.h"
7 #include "output.h"
8 #include "pointer.h"
9@@ -14,8 +15,235 @@
10
11 #include <stdlib.h>
12 #include <stdio.h>
13+#include <assert.h>
14+#include <wld/wld.h>
15+#include <wld/drm.h>
16 #include <xkbcommon/xkbcommon-keysyms.h>
17
18+/* Rendering {{{ */
19+
20+struct buffer_state
21+{
22+ struct wld_drawable * drawable;
23+ /* Only used for SHM buffers */
24+ pixman_image_t * dst, * src;
25+ struct wl_listener destroy_listener;
26+};
27+
28+struct render_target
29+{
30+ struct wld_drawable * drawable;
31+ pixman_rectangle32_t geometry;
32+};
33+
34+static inline uint32_t pixman_format(uint32_t format)
35+{
36+ switch (format)
37+ {
38+ case WL_SHM_FORMAT_XRGB8888:
39+ return PIXMAN_x8r8g8b8;
40+ case WL_SHM_FORMAT_ARGB8888:
41+ return PIXMAN_a8r8g8b8;
42+ }
43+
44+ return 0;
45+}
46+
47+static inline uint32_t wld_format(uint32_t format)
48+{
49+ switch (format)
50+ {
51+ case WL_SHM_FORMAT_XRGB8888:
52+ return WLD_FORMAT_XRGB8888;
53+ case WL_SHM_FORMAT_ARGB8888:
54+ return WLD_FORMAT_ARGB8888;
55+ }
56+
57+ return 0;
58+}
59+
60+static void handle_buffer_destroy(struct wl_listener * listener, void * data)
61+{
62+ struct buffer_state * state
63+ = CONTAINER_OF(listener, typeof(*state), destroy_listener);
64+
65+ if (state->dst)
66+ pixman_image_unref(state->dst);
67+ if (state->src)
68+ pixman_image_unref(state->src);
69+ wld_destroy_drawable(state->drawable);
70+ free(state);
71+}
72+
73+static inline struct buffer_state * buffer_state(struct wl_resource * resource)
74+{
75+ struct wl_listener * listener
76+ = wl_resource_get_destroy_listener(resource, &handle_buffer_destroy);
77+
78+ return listener ? CONTAINER_OF(listener, struct buffer_state,
79+ destroy_listener)
80+ : NULL;
81+}
82+
83+static void repaint_surface(struct render_target * target,
84+ struct swc_surface * surface,
85+ pixman_region32_t * damage)
86+{
87+ pixman_region32_t surface_damage;
88+ pixman_region32_t border_damage;
89+ pixman_region32_t surface_region;
90+ struct buffer_state * state;
91+ struct swc_compositor_surface_state * surface_state = surface->view_state;
92+
93+ if (!surface->state.buffer)
94+ return;
95+
96+ state = buffer_state(surface->state.buffer);
97+ assert(state);
98+
99+ pixman_region32_init_with_extents(&surface_damage, &surface_state->extents);
100+ pixman_region32_init(&border_damage);
101+ pixman_region32_init_rect
102+ (&surface_region, surface->geometry.x, surface->geometry.y,
103+ surface->geometry.width, surface->geometry.height);
104+
105+ pixman_region32_intersect(&surface_damage, &surface_damage, damage);
106+ pixman_region32_subtract(&surface_damage, &surface_damage,
107+ &surface_state->clip);
108+ pixman_region32_subtract(&border_damage, &surface_damage, &surface_region);
109+ pixman_region32_intersect(&surface_damage, &surface_damage,
110+ &surface_region);
111+
112+ pixman_region32_fini(&surface_region);
113+
114+ if (pixman_region32_not_empty(&surface_damage))
115+ {
116+ DEBUG("\tDRM surface %u { x: %d, y: %d, w: %u, h: %u }\n",
117+ wl_resource_get_id(surface->resource),
118+ surface->geometry.x, surface->geometry.y,
119+ surface->geometry.width, surface->geometry.height);
120+
121+ pixman_region32_translate(&surface_damage,
122+ -surface->geometry.x, -surface->geometry.y);
123+ wld_copy_region(state->drawable, target->drawable, &surface_damage,
124+ surface->geometry.x - target->geometry.x,
125+ surface->geometry.y - target->geometry.y);
126+ }
127+
128+ pixman_region32_fini(&surface_damage);
129+
130+ /* Draw border */
131+ if (pixman_region32_not_empty(&border_damage))
132+ {
133+ DEBUG("\t\tRedrawing border\n");
134+
135+ pixman_region32_translate(&border_damage,
136+ -target->geometry.x, -target->geometry.y);
137+ wld_fill_region(target->drawable, surface_state->border.color,
138+ &border_damage);
139+ }
140+
141+ pixman_region32_fini(&border_damage);
142+}
143+
144+static void renderer_repaint(struct render_target * target,
145+ pixman_region32_t * damage,
146+ pixman_region32_t * base_damage,
147+ struct wl_list * surfaces)
148+{
149+ struct swc_surface * surface;
150+
151+ DEBUG("Rendering to target { x: %d, y: %d, w: %u, h: %u }\n",
152+ target->geometry.x, target->geometry.y,
153+ target->geometry.width, target->geometry.height);
154+
155+ /* Paint base damage black. */
156+ if (pixman_region32_not_empty(base_damage))
157+ {
158+ pixman_region32_translate(base_damage,
159+ -target->geometry.x, -target->geometry.y);
160+ wld_fill_region(target->drawable, 0xff000000, base_damage);
161+ }
162+
163+ wl_list_for_each_reverse(surface, surfaces, link)
164+ {
165+ if (swc_rectangle_overlap(&target->geometry, &surface->geometry))
166+ repaint_surface(target, surface, damage);
167+ }
168+
169+ wld_flush(target->drawable);
170+}
171+
172+void swc_compositor_attach(struct swc_surface * surface,
173+ struct wl_resource * resource)
174+{
175+ struct buffer_state * state;
176+ struct wl_shm_buffer * shm_buffer;
177+ struct swc_drm_buffer * drm_buffer;
178+
179+ if (!resource)
180+ return;
181+
182+ /* Check if we have already seen this buffer. */
183+ if ((state = buffer_state(resource)))
184+ return;
185+
186+ if (!(state = malloc(sizeof *state)))
187+ return;
188+
189+ if ((shm_buffer = wl_shm_buffer_get(resource)))
190+ {
191+ uint32_t width = wl_shm_buffer_get_width(shm_buffer),
192+ height = wl_shm_buffer_get_height(shm_buffer),
193+ format = wl_shm_buffer_get_format(shm_buffer),
194+ pitch = wl_shm_buffer_get_stride(shm_buffer);
195+ void * data = wl_shm_buffer_get_data(shm_buffer);
196+
197+ state->drawable = wld_drm_create_drawable(swc.drm->context,
198+ width, height,
199+ wld_format(format));
200+ state->src = pixman_image_create_bits_no_clear(pixman_format(format),
201+ width, height,
202+ data, pitch);
203+ state->dst = wld_map(state->drawable);
204+ }
205+ else if ((drm_buffer = swc_drm_buffer_get(resource)))
206+ {
207+ if (!(state = malloc(sizeof *state)))
208+ return;
209+
210+ state->drawable = drm_buffer->drawable;
211+ state->src = NULL;
212+ state->dst = NULL;
213+ }
214+ else
215+ {
216+ ERROR("Unsupported buffer type\n");
217+ return;
218+ }
219+
220+ state->destroy_listener.notify = &handle_buffer_destroy;
221+ wl_resource_add_destroy_listener(resource, &state->destroy_listener);
222+}
223+
224+static void renderer_flush_surface(struct swc_surface * surface)
225+{
226+ struct buffer_state * state;
227+
228+ state = buffer_state(surface->state.buffer);
229+ assert(state);
230+
231+ if (!state->src || !state->dst)
232+ return;
233+
234+ pixman_image_set_clip_region32(state->src, &surface->state.damage);
235+ pixman_image_composite32(PIXMAN_OP_SRC, state->src, NULL, state->dst,
236+ 0, 0, 0, 0, 0, 0,
237+ state->drawable->width, state->drawable->height);
238+}
239+
240+/* }}} */
241+
242 static void calculate_damage(struct swc_compositor * compositor)
243 {
244 struct swc_surface * surface;
245@@ -45,7 +273,7 @@ static void calculate_damage(struct swc_compositor * compositor)
246
247 if (pixman_region32_not_empty(&surface->state.damage))
248 {
249- swc_renderer_flush(&compositor->renderer, surface);
250+ renderer_flush_surface(surface);
251
252 /* Translate surface damage to global coordinates. */
253 pixman_region32_translate(&surface->state.damage,
254@@ -88,13 +316,21 @@ static void repaint_output(struct swc_compositor * compositor,
255 pixman_region32_t * damage)
256 {
257 pixman_region32_t base_damage;
258+ struct render_target target;
259
260 pixman_region32_init(&base_damage);
261 pixman_region32_subtract(&base_damage, damage, &compositor->opaque);
262
263- swc_renderer_set_target(&compositor->renderer, &output->framebuffer_plane);
264- swc_renderer_repaint(&compositor->renderer, damage, &base_damage,
265- &compositor->surfaces);
266+ target.drawable = swc_plane_get_buffer(&output->framebuffer_plane);
267+ target.geometry.x = output->framebuffer_plane.output->geometry.x
268+ + output->framebuffer_plane.x;
269+ target.geometry.y = output->framebuffer_plane.output->geometry.y
270+ + output->framebuffer_plane.y;
271+ target.geometry.width = target.drawable->width;
272+ target.geometry.height = target.drawable->height;
273+
274+ renderer_repaint(&target, damage, &base_damage,
275+ &compositor->surfaces);
276
277 pixman_region32_fini(&base_damage);
278
+5,
-3
1@@ -2,17 +2,16 @@
2 #define SWC_COMPOSITOR_H
3
4 #include "pointer.h"
5-#include "renderer.h"
6 #include "view.h"
7
8 #include <wayland-server.h>
9
10+struct swc_output;
11+
12 struct swc_compositor
13 {
14 struct wl_display * display;
15
16- struct swc_renderer renderer;
17-
18 struct wl_list outputs;
19 struct wl_list surfaces;
20
21@@ -52,5 +51,8 @@ void swc_compositor_add_globals(struct swc_compositor * compositor,
22 void swc_compositor_schedule_update(struct swc_compositor * compositor,
23 struct swc_output * output);
24
25+void swc_compositor_attach(struct swc_surface * surface,
26+ struct wl_resource * resource);
27+
28 #endif
29
+2,
-4
1@@ -24,6 +24,7 @@
2 #include "compositor_surface.h"
3 #include "compositor.h"
4 #include "event.h"
5+#include "output.h"
6 #include "util.h"
7
8 #include <stdio.h>
9@@ -207,10 +208,7 @@ void remove_(struct swc_surface * surface)
10
11 void attach(struct swc_surface * surface, struct wl_resource * resource)
12 {
13- struct swc_compositor * compositor = CONTAINER_OF
14- (surface->view, typeof(*compositor), compositor_view);
15-
16- swc_renderer_attach(&compositor->renderer, surface, resource);
17+ swc_compositor_attach(surface, resource);
18 }
19
20 void update(struct swc_surface * surface)
+2,
-0
1@@ -23,6 +23,8 @@
2
3 #include "cursor_surface.h"
4 #include "compositor.h"
5+#include "output.h"
6+#include "plane.h"
7
8 #include <string.h>
9 #include <wld/wld.h>
+0,
-1
1@@ -37,7 +37,6 @@ SWC_SOURCES = \
2 libswc/compositor_surface.c \
3 libswc/cursor_surface.c \
4 libswc/region.c \
5- libswc/renderer.c \
6 libswc/input_focus.c \
7 libswc/keyboard.c \
8 libswc/pointer.c \
+0,
-242
1@@ -1,242 +0,0 @@
2-#include "renderer.h"
3-#include "compositor_surface.h"
4-#include "drm.h"
5-#include "drm_buffer.h"
6-#include "internal.h"
7-
8-#include <assert.h>
9-#include <stdio.h>
10-#include <stdlib.h>
11-#include <wld/wld.h>
12-#include <wld/drm.h>
13-
14-struct buffer_state
15-{
16- struct wld_drawable * drawable;
17- /* Only used for SHM buffers */
18- pixman_image_t * dst, * src;
19- struct wl_listener destroy_listener;
20-};
21-
22-static inline uint32_t pixman_format(uint32_t format)
23-{
24- switch (format)
25- {
26- case WL_SHM_FORMAT_XRGB8888:
27- return PIXMAN_x8r8g8b8;
28- case WL_SHM_FORMAT_ARGB8888:
29- return PIXMAN_a8r8g8b8;
30- }
31-
32- return 0;
33-}
34-
35-static inline uint32_t wld_format(uint32_t format)
36-{
37- switch (format)
38- {
39- case WL_SHM_FORMAT_XRGB8888:
40- return WLD_FORMAT_XRGB8888;
41- case WL_SHM_FORMAT_ARGB8888:
42- return WLD_FORMAT_ARGB8888;
43- }
44-
45- return 0;
46-}
47-
48-static void handle_buffer_destroy(struct wl_listener * listener, void * data)
49-{
50- struct buffer_state * state
51- = CONTAINER_OF(listener, typeof(*state), destroy_listener);
52-
53- if (state->dst)
54- pixman_image_unref(state->dst);
55- if (state->src)
56- pixman_image_unref(state->src);
57- wld_destroy_drawable(state->drawable);
58- free(state);
59-}
60-
61-static inline struct buffer_state * buffer_state(struct wl_resource * resource)
62-{
63- struct wl_listener * listener
64- = wl_resource_get_destroy_listener(resource, &handle_buffer_destroy);
65-
66- return listener ? CONTAINER_OF(listener, struct buffer_state,
67- destroy_listener)
68- : NULL;
69-}
70-
71-static void repaint_surface(struct swc_renderer * renderer,
72- struct swc_surface * surface,
73- pixman_region32_t * damage)
74-{
75- struct swc_render_target * target = &renderer->target;
76- pixman_region32_t surface_damage;
77- pixman_region32_t border_damage;
78- pixman_region32_t surface_region;
79- struct buffer_state * state;
80- struct swc_compositor_surface_state * surface_state = surface->view_state;
81-
82- if (!surface->state.buffer)
83- return;
84-
85- state = buffer_state(surface->state.buffer);
86- assert(state);
87-
88- pixman_region32_init_with_extents(&surface_damage, &surface_state->extents);
89- pixman_region32_init(&border_damage);
90- pixman_region32_init_rect
91- (&surface_region, surface->geometry.x, surface->geometry.y,
92- surface->geometry.width, surface->geometry.height);
93-
94- pixman_region32_intersect(&surface_damage, &surface_damage, damage);
95- pixman_region32_subtract(&surface_damage, &surface_damage,
96- &surface_state->clip);
97- pixman_region32_subtract(&border_damage, &surface_damage, &surface_region);
98- pixman_region32_intersect(&surface_damage, &surface_damage,
99- &surface_region);
100-
101- pixman_region32_fini(&surface_region);
102-
103- if (pixman_region32_not_empty(&surface_damage))
104- {
105- DEBUG("\tDRM surface %u { x: %d, y: %d, w: %u, h: %u }\n",
106- wl_resource_get_id(surface->resource),
107- surface->geometry.x, surface->geometry.y,
108- surface->geometry.width, surface->geometry.height);
109-
110- pixman_region32_translate(&surface_damage,
111- -surface->geometry.x, -surface->geometry.y);
112- wld_copy_region(state->drawable, target->drawable, &surface_damage,
113- surface->geometry.x - target->geometry.x,
114- surface->geometry.y - target->geometry.y);
115- }
116-
117- pixman_region32_fini(&surface_damage);
118-
119- /* Draw border */
120- if (pixman_region32_not_empty(&border_damage))
121- {
122- DEBUG("\t\tRedrawing border\n");
123-
124- pixman_region32_translate(&border_damage,
125- -target->geometry.x, -target->geometry.y);
126- wld_fill_region(target->drawable, surface_state->border.color,
127- &border_damage);
128- }
129-
130- pixman_region32_fini(&border_damage);
131-}
132-
133-void swc_renderer_set_target(struct swc_renderer * renderer,
134- struct swc_plane * plane)
135-{
136- struct wld_drawable * drawable = swc_plane_get_buffer(plane);
137-
138- renderer->target.drawable = drawable;
139- renderer->target.geometry.x = plane->output->geometry.x + plane->x;
140- renderer->target.geometry.y = plane->output->geometry.y + plane->y;
141- renderer->target.geometry.width = drawable->width;
142- renderer->target.geometry.height = drawable->height;
143-}
144-
145-void swc_renderer_repaint(struct swc_renderer * renderer,
146- pixman_region32_t * damage,
147- pixman_region32_t * base_damage,
148- struct wl_list * surfaces)
149-{
150- struct swc_render_target * target = &renderer->target;
151- struct swc_surface * surface;
152-
153- DEBUG("Rendering to target { x: %d, y: %d, w: %u, h: %u }\n",
154- target->geometry.x, target->geometry.y,
155- target->geometry.width, target->geometry.height);
156-
157- /* Paint base damage black. */
158- if (pixman_region32_not_empty(base_damage))
159- {
160- pixman_region32_translate(base_damage,
161- -target->geometry.x, -target->geometry.y);
162- wld_fill_region(target->drawable, 0xff000000, base_damage);
163- }
164-
165- wl_list_for_each_reverse(surface, surfaces, link)
166- {
167- if (swc_rectangle_overlap(&target->geometry, &surface->geometry))
168- repaint_surface(renderer, surface, damage);
169- }
170-
171- wld_flush(target->drawable);
172-}
173-
174-void swc_renderer_attach(struct swc_renderer * renderer,
175- struct swc_surface * surface,
176- struct wl_resource * resource)
177-{
178- struct buffer_state * state;
179- struct wl_shm_buffer * shm_buffer;
180- struct swc_drm_buffer * drm_buffer;
181-
182- if (!resource)
183- return;
184-
185- /* Check if we have already seen this buffer. */
186- if ((state = buffer_state(resource)))
187- return;
188-
189- if (!(state = malloc(sizeof *state)))
190- return;
191-
192- if ((shm_buffer = wl_shm_buffer_get(resource)))
193- {
194- uint32_t width = wl_shm_buffer_get_width(shm_buffer),
195- height = wl_shm_buffer_get_height(shm_buffer),
196- format = wl_shm_buffer_get_format(shm_buffer),
197- pitch = wl_shm_buffer_get_stride(shm_buffer);
198- void * data = wl_shm_buffer_get_data(shm_buffer);
199-
200- state->drawable = wld_drm_create_drawable(swc.drm->context,
201- width, height,
202- wld_format(format));
203- state->src = pixman_image_create_bits_no_clear(pixman_format(format),
204- width, height,
205- data, pitch);
206- state->dst = wld_map(state->drawable);
207- }
208- else if ((drm_buffer = swc_drm_buffer_get(resource)))
209- {
210- if (!(state = malloc(sizeof *state)))
211- return;
212-
213- state->drawable = drm_buffer->drawable;
214- state->src = NULL;
215- state->dst = NULL;
216- }
217- else
218- {
219- ERROR("Unsupported buffer type\n");
220- return;
221- }
222-
223- state->destroy_listener.notify = &handle_buffer_destroy;
224- wl_resource_add_destroy_listener(resource, &state->destroy_listener);
225-}
226-
227-void swc_renderer_flush(struct swc_renderer * renderer,
228- struct swc_surface * surface)
229-{
230- struct buffer_state * state;
231-
232- state = buffer_state(surface->state.buffer);
233- assert(state);
234-
235- if (!state->src || !state->dst)
236- return;
237-
238- pixman_image_set_clip_region32(state->src, &surface->state.damage);
239- pixman_image_composite32(PIXMAN_OP_SRC, state->src, NULL, state->dst,
240- 0, 0, 0, 0, 0, 0,
241- state->drawable->width, state->drawable->height);
242-}
243-
+0,
-34
1@@ -1,34 +0,0 @@
2-#ifndef SWC_RENDERER_H
3-#define SWC_RENDERER_H
4-
5-#include "output.h"
6-#include "surface.h"
7-
8-struct swc_render_target
9-{
10- struct wld_drawable * drawable;
11- pixman_rectangle32_t geometry;
12-};
13-
14-struct swc_renderer
15-{
16- struct swc_render_target target;
17-};
18-
19-void swc_renderer_set_target(struct swc_renderer * renderer,
20- struct swc_plane * plane);
21-
22-void swc_renderer_repaint(struct swc_renderer * renderer,
23- pixman_region32_t * damage,
24- pixman_region32_t * base_damage,
25- struct wl_list * surfaces);
26-
27-void swc_renderer_attach(struct swc_renderer * renderer,
28- struct swc_surface * surface,
29- struct wl_resource * resource);
30-
31-void swc_renderer_flush(struct swc_renderer * renderer,
32- struct swc_surface * surface);
33-
34-#endif
35-
+1,
-0
1@@ -28,6 +28,7 @@
2 #include "drm.h"
3 #include "internal.h"
4 #include "keyboard.h"
5+#include "output.h"
6 #include "pointer.h"
7 #include "seat.h"
8 #include "shell.h"
+1,
-0
1@@ -29,6 +29,7 @@
2 #include "keyboard.h"
3 #include "seat.h"
4 #include "swc.h"
5+#include "util.h"
6
7 #include <stdlib.h>
8 #include <string.h>