commit 627e642
Michael Forney
·
2014-01-18 03:22:23 +0000 UTC
parent fed8a9c
compositor: Add shm buffer support
1 files changed,
+55,
-1
+55,
-1
1@@ -9,6 +9,7 @@
2 #include "region.h"
3 #include "screen.h"
4 #include "seat.h"
5+#include "shm.h"
6 #include "surface.h"
7 #include "util.h"
8 #include "view.h"
9@@ -35,6 +36,7 @@ struct view
10 struct wl_listener event_listener;
11 struct swc_compositor * compositor;
12 struct swc_surface * surface;
13+ struct wld_buffer * wld;
14
15 /* The box that the surface covers (including it's border). */
16 pixman_box32_t extents;
17@@ -230,7 +232,7 @@ static void repaint_view(struct render_target * target, struct view * view,
18 if (pixman_region32_not_empty(&view_damage))
19 {
20 pixman_region32_translate(&view_damage, -geometry->x, -geometry->y);
21- wld_copy_region(swc.drm->renderer, view->base.buffer->wld,
22+ wld_copy_region(swc.drm->renderer, view->wld,
23 geometry->x - target->geometry->x,
24 geometry->y - target->geometry->y, &view_damage);
25 }
26@@ -282,11 +284,62 @@ static void renderer_repaint(struct render_target * target,
27
28 static bool renderer_attach(struct view * view, struct swc_buffer * buffer)
29 {
30+ struct wld_buffer * wld;
31+ bool was_proxy = view->base.buffer && view->wld != view->base.buffer->wld;
32+ bool needs_proxy = buffer
33+ && !(wld_capabilities(swc.drm->renderer,
34+ buffer->wld) & WLD_CAPABILITY_READ);
35+ bool resized = view->wld && buffer
36+ && (view->wld->width != buffer->wld->width
37+ || view->wld->height != buffer->wld->height);
38+
39+ if (buffer)
40+ {
41+ /* Create a proxy buffer if necessary (for example a hardware buffer
42+ * backing a SHM buffer). */
43+ if (needs_proxy)
44+ {
45+ if (!was_proxy || resized)
46+ {
47+ DEBUG("Creating a proxy buffer\n");
48+ wld = wld_create_buffer(swc.drm->context,
49+ buffer->wld->width, buffer->wld->height,
50+ buffer->wld->format);
51+
52+ if (!wld)
53+ return false;
54+ }
55+ else
56+ {
57+ /* Otherwise we can keep the original proxy buffer. */
58+ wld = view->wld;
59+ }
60+ }
61+ else
62+ wld = buffer->wld;
63+ }
64+ else
65+ wld = NULL;
66+
67+ /* If we no longer need a proxy buffer, or the original buffer is of a
68+ * different size, destroy the old proxy image. */
69+ if (view->wld && ((!needs_proxy && was_proxy) || (needs_proxy && resized)))
70+ wld_destroy_buffer(view->wld);
71+
72+ view->wld = wld;
73+
74 return true;
75 }
76
77 static void renderer_flush_view(struct view * view)
78 {
79+ if (view->wld == view->base.buffer->wld)
80+ return;
81+
82+ wld_set_target_buffer(swc.shm->renderer, view->wld);
83+ wld_copy_region(swc.shm->renderer, view->base.buffer->wld,
84+ 0, 0, &view->surface->state.damage);
85+ wld_flush(swc.shm->renderer);
86 }
87
88 /* }}} */
89@@ -447,6 +500,7 @@ bool swc_compositor_add_surface(struct swc_compositor * compositor,
90 wl_signal_add(&view->base.event_signal, &view->event_listener);
91 view->compositor = compositor;
92 view->surface = surface;
93+ view->wld = NULL;
94 view->extents.x1 = 0;
95 view->extents.y1 = 0;
96 view->extents.x2 = 0;