commit 4b382ea

Michael Forney  ·  2013-09-11 08:44:49 +0000 UTC
parent 47694ff
Introduce planes
6 files changed,  +330, -1
+1, -0
1@@ -10,6 +10,7 @@ libswc_la_SOURCES = \
2     util.c util.h \
3     output.c output.h \
4     buffer.c buffer.h \
5+    plane.c plane.h \
6     surface.c surface.h \
7     compositor_surface.c compositor_surface.h \
8     region.c region.h \
+10, -1
 1@@ -213,12 +213,18 @@ bool swc_drm_initialize(struct swc_drm * drm, struct udev * udev,
 2         printf("has blt: %u\n", ret);
 3     }
 4 
 5+    if (!(drm->context = wld_drm_create_context(drm->fd)))
 6+    {
 7+        fprintf(stderr, "Could not create WLD DRM context\n");
 8+        goto error_fd;
 9+    }
10+
11     drm->bufmgr = drm_intel_bufmgr_gem_init(drm->fd, INTEL_MAX_COMMANDS << 2);
12 
13     if (!drm->bufmgr)
14     {
15         printf("could not create bufmgr\n");
16-        goto error_fd;
17+        goto error_wld;
18     }
19 
20     //drm_intel_bufmgr_set_debug(drm->bufmgr, true);
21@@ -228,6 +234,8 @@ bool swc_drm_initialize(struct swc_drm * drm, struct udev * udev,
22 
23     return true;
24 
25+  error_wld:
26+    wld_drm_destroy_context(drm->context);
27   error_fd:
28     close(drm->fd);
29   error_device:
30@@ -238,6 +246,7 @@ bool swc_drm_initialize(struct swc_drm * drm, struct udev * udev,
31 
32 void swc_drm_finish(struct swc_drm * drm)
33 {
34+    wld_drm_destroy_context(drm->context);
35     drm_intel_bufmgr_destroy(drm->bufmgr);
36     close(drm->fd);
37 }
+3, -0
 1@@ -8,6 +8,8 @@
 2 #include <wayland-server.h>
 3 #include <libdrm/intel_bufmgr.h>
 4 
 5+struct wld_drm_context * context;
 6+
 7 enum swc_drm_event
 8 {
 9     SWC_DRM_PAGE_FLIP
10@@ -19,6 +21,7 @@ struct swc_drm
11     uint32_t id;
12 
13     drm_intel_bufmgr * bufmgr;
14+    struct wld_drm_context * context;
15 
16     uint32_t taken_output_ids;
17 
+225, -0
  1@@ -0,0 +1,225 @@
  2+/* swc: plane.c
  3+ *
  4+ * Copyright (c) 2013 Michael Forney
  5+ *
  6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
  7+ * of this software and associated documentation files (the "Software"), to deal
  8+ * in the Software without restriction, including without limitation the rights
  9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10+ * copies of the Software, and to permit persons to whom the Software is
 11+ * furnished to do so, subject to the following conditions:
 12+ *
 13+ * The above copyright notice and this permission notice shall be included in
 14+ * all copies or substantial portions of the Software.
 15+ *
 16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22+ * SOFTWARE.
 23+ */
 24+
 25+#include "plane.h"
 26+#include "output.h"
 27+#include "mode.h"
 28+
 29+#include <stdlib.h>
 30+#include <stdio.h>
 31+#include <libdrm/drm.h>
 32+#include <wld/wld.h>
 33+#include <wld/drm.h>
 34+
 35+struct framebuffer
 36+{
 37+    struct wld_drawable * drawable;
 38+    uint32_t fb_id;
 39+};
 40+
 41+static bool framebuffer_initialize(struct swc_plane * plane)
 42+{
 43+    struct framebuffer * buffer
 44+        = swc_double_buffer_front(&plane->double_buffer);
 45+
 46+    return drmModeSetCrtc(plane->output->drm->fd, plane->output->crtc_id,
 47+                          buffer->fb_id, 0, 0, &plane->output->connector_id, 1,
 48+                          &plane->output->current_mode->info) == 0;
 49+}
 50+
 51+static void * framebuffer_create_buffer(struct swc_plane * plane)
 52+{
 53+    struct wld_drawable * drawable;
 54+    struct swc_output * output = plane->output;
 55+    struct framebuffer * buffer;
 56+    uint32_t handle;
 57+
 58+    if (!(buffer = malloc(sizeof *buffer)))
 59+        goto error0;
 60+
 61+    drawable = wld_drm_create_drawable(output->drm->context,
 62+                                       output->geometry.width,
 63+                                       output->geometry.height,
 64+                                       WLD_FORMAT_XRGB8888);
 65+
 66+    if (!drawable)
 67+    {
 68+        fprintf(stderr, "Could not create DRM drawable for framebuffer\n");
 69+        goto error1;
 70+    }
 71+
 72+    handle = wld_drm_drawable_get_handle(drawable);
 73+
 74+    if (drmModeAddFB(plane->output->drm->fd, drawable->width, drawable->height,
 75+                     24, 32, drawable->pitch, handle, &buffer->fb_id) != 0)
 76+    {
 77+        fprintf(stderr, "drmModeAddFB failed\n");
 78+        goto error2;
 79+    }
 80+
 81+    buffer->drawable = drawable;
 82+
 83+    return buffer;
 84+
 85+  error2:
 86+    wld_destroy_drawable(drawable);
 87+  error1:
 88+    free(buffer);
 89+  error0:
 90+    return NULL;
 91+}
 92+
 93+static void framebuffer_destroy_buffer(struct swc_plane * plane, void * data)
 94+{
 95+    struct framebuffer * buffer = data;
 96+
 97+    drmModeRmFB(plane->output->drm->fd, buffer->fb_id);
 98+    wld_destroy_drawable(buffer->drawable);
 99+}
100+
101+static struct wld_drawable * framebuffer_get_buffer(void * data)
102+{
103+    struct framebuffer * buffer = data;
104+
105+    return buffer->drawable;
106+}
107+
108+static bool framebuffer_flip(struct swc_plane * plane)
109+{
110+    struct swc_output * output = plane->output;
111+    struct framebuffer * buffer = swc_double_buffer_back(&plane->double_buffer);
112+
113+    return drmModePageFlip(output->drm->fd, output->crtc_id, buffer->fb_id,
114+                           DRM_MODE_PAGE_FLIP_EVENT, output) == 0;
115+}
116+
117+const struct swc_plane_interface swc_framebuffer_plane = {
118+    .initialize = &framebuffer_initialize,
119+    .create_buffer = &framebuffer_create_buffer,
120+    .destroy_buffer = &framebuffer_destroy_buffer,
121+    .get_buffer = &framebuffer_get_buffer,
122+    .flip = &framebuffer_flip
123+};
124+
125+static bool cursor_initialize(struct swc_plane * plane)
126+{
127+    return true;
128+}
129+
130+static void * cursor_create_buffer(struct swc_plane * plane)
131+{
132+    return wld_drm_create_drawable(plane->output->drm->context, 64, 64,
133+                                   WLD_FORMAT_ARGB8888);
134+}
135+
136+static void cursor_destroy_buffer(struct swc_plane * plane, void * data)
137+{
138+    struct wld_drawable * drawable = data;
139+
140+    wld_destroy_drawable(drawable);
141+}
142+
143+static struct wld_drawable * cursor_get_buffer(void * data)
144+{
145+    return data;
146+}
147+
148+static bool cursor_flip(struct swc_plane * plane)
149+{
150+    struct swc_output * output = plane->output;
151+    struct wld_drawable * drawable
152+        = swc_double_buffer_back(&plane->double_buffer);
153+    int handle = wld_drm_drawable_get_handle(drawable);
154+
155+    return drmModeSetCursor(plane->output->drm->fd, plane->output->crtc_id,
156+                            handle, 64, 64) == 0;
157+}
158+
159+static bool cursor_move(struct swc_plane * plane, int32_t x, int32_t y)
160+{
161+    return drmModeMoveCursor(plane->output->drm->fd, plane->output->crtc_id,
162+                             x, y) == 0;
163+}
164+
165+const struct swc_plane_interface swc_cursor_plane = {
166+    .initialize = &cursor_initialize,
167+    .create_buffer = &cursor_create_buffer,
168+    .destroy_buffer = &cursor_destroy_buffer,
169+    .get_buffer = &cursor_get_buffer,
170+    .flip = &cursor_flip,
171+    .move = &cursor_move
172+};
173+
174+bool swc_plane_initialize(struct swc_plane * plane,
175+                          const struct swc_plane_interface * interface,
176+                          struct swc_output * output)
177+{
178+    plane->interface = interface;
179+    plane->output = output;
180+    plane->double_buffer.buffers[0] = interface->create_buffer(plane);
181+    plane->double_buffer.buffers[1] = interface->create_buffer(plane);
182+    plane->double_buffer.front = 0;
183+    plane->x = 0;
184+    plane->y = 0;
185+
186+    return plane->interface->initialize(plane);
187+}
188+
189+void swc_plane_finish(struct swc_plane * plane)
190+{
191+    plane->interface->destroy_buffer(plane, plane->double_buffer.buffers[0]);
192+    plane->interface->destroy_buffer(plane, plane->double_buffer.buffers[1]);
193+}
194+
195+bool swc_plane_flip(struct swc_plane * plane)
196+{
197+    if (plane->interface->flip(plane))
198+    {
199+        swc_double_buffer_swap(&plane->double_buffer);
200+
201+        return true;
202+    }
203+    else
204+        return false;
205+}
206+
207+bool swc_plane_move(struct swc_plane * plane, int32_t x, int32_t y)
208+{
209+    if (plane->interface->move(plane, x, y))
210+    {
211+        plane->x = x;
212+        plane->y = y;
213+
214+        return true;
215+    }
216+    else
217+        return false;
218+}
219+
220+struct wld_drawable * swc_plane_get_buffer(struct swc_plane * plane)
221+{
222+    void * back = swc_double_buffer_back(&plane->double_buffer);
223+
224+    return plane->interface->get_buffer(back);
225+}
226+
+66, -0
 1@@ -0,0 +1,66 @@
 2+/* swc: plane.h
 3+ *
 4+ * Copyright (c) 2013 Michael Forney
 5+ * 
 6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
 7+ * of this software and associated documentation files (the "Software"), to deal
 8+ * in the Software without restriction, including without limitation the rights
 9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ * 
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ * 
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+#ifndef SWC_PLANE_H
26+#define SWC_PLANE_H 1
27+
28+#include "util.h"
29+
30+struct swc_plane;
31+
32+struct swc_plane_interface
33+{
34+    bool (* initialize)(struct swc_plane * plane);
35+    void * (* create_buffer)(struct swc_plane * plane);
36+    void (* destroy_buffer)(struct swc_plane * plane, void * data);
37+    struct wld_drawable * (* get_buffer)(void * data);
38+    bool (* flip)(struct swc_plane * plane);
39+    bool (* move)(struct swc_plane * plane, int32_t x, int32_t y);
40+};
41+
42+struct swc_plane
43+{
44+    const struct swc_plane_interface * interface;
45+    struct swc_output * output;
46+
47+    struct swc_double_buffer double_buffer;
48+
49+    /* Relative to the output's origin. */
50+    int32_t x, y;
51+};
52+
53+bool swc_plane_initialize(struct swc_plane * plane,
54+                          const struct swc_plane_interface * interface,
55+                          struct swc_output * output);
56+
57+bool swc_plane_flip(struct swc_plane * plane);
58+
59+bool swc_plane_move(struct swc_plane * plane, int32_t x, int32_t y);
60+
61+struct wld_drawable * swc_plane_get_buffer(struct swc_plane * plane);
62+
63+extern const struct swc_plane_interface swc_framebuffer_plane;
64+extern const struct swc_plane_interface swc_cursor_plane;
65+
66+#endif
67+
+25, -0
 1@@ -29,5 +29,30 @@ static inline bool swc_rectangle_overlap
 2 int swc_launch_open_input_device(int socket, const char * path, int flags);
 3 bool swc_launch_drm_master(int socket, int fd, bool set);
 4 
 5+/* Double Buffers */
 6+struct swc_double_buffer
 7+{
 8+    void * buffers[2];
 9+    uint8_t front;
10+};
11+
12+static inline void * swc_double_buffer_front
13+    (struct swc_double_buffer * double_buffer)
14+{
15+    return double_buffer->buffers[double_buffer->front];
16+}
17+
18+static inline void * swc_double_buffer_back
19+    (struct swc_double_buffer * double_buffer)
20+{
21+    return double_buffer->buffers[double_buffer->front ^ 1];
22+}
23+
24+static inline void swc_double_buffer_swap
25+    (struct swc_double_buffer * double_buffer)
26+{
27+    double_buffer->front ^= 1;
28+}
29+
30 #endif
31