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;