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