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>