blob: 0cd0d2ff833f093d7b6d74555a2c933a78251d0c [file] [log] [blame]
George Kiagiadakis53868982014-06-12 16:26:49 +02001/*
2 * Copyright © 2011 Benjamin Franzke
3 * Copyright © 2010 Intel Corporation
4 * Copyright © 2014 Collabora Ltd.
5 *
Yong Bakos53361532017-01-23 06:17:44 -08006 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
George Kiagiadakis53868982014-06-12 16:26:49 +020013 *
Yong Bakos53361532017-01-23 06:17:44 -080014 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
George Kiagiadakis53868982014-06-12 16:26:49 +020026 */
27
Bryce Harringtonb4dae9b2016-06-15 18:13:07 -070028#include "config.h"
George Kiagiadakis53868982014-06-12 16:26:49 +020029
Jussi Kukkonen649bbce2016-07-19 14:16:27 +030030#include <stdint.h>
George Kiagiadakis53868982014-06-12 16:26:49 +020031#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <stdbool.h>
35#include <assert.h>
36#include <unistd.h>
37#include <sys/mman.h>
38#include <signal.h>
39#include <fcntl.h>
40
41#include <xf86drm.h>
Emmanuel Gil Peyrot8ef29572016-01-11 19:04:37 +000042#include <i915_drm.h>
43#include <intel_bufmgr.h>
44#include <drm_fourcc.h>
George Kiagiadakis53868982014-06-12 16:26:49 +020045
46#include <wayland-client.h>
Bryce Harrington0d1a6222016-02-11 16:42:49 -080047#include "shared/zalloc.h"
Jonas Ådahl42682622016-08-11 23:44:41 +080048#include "xdg-shell-unstable-v6-client-protocol.h"
Jonas Ådahl496adb32015-11-17 16:00:27 +080049#include "fullscreen-shell-unstable-v1-client-protocol.h"
Jonas Ådahl57e48f02015-11-17 16:00:28 +080050#include "linux-dmabuf-unstable-v1-client-protocol.h"
George Kiagiadakis53868982014-06-12 16:26:49 +020051
52struct display {
53 struct wl_display *display;
54 struct wl_registry *registry;
55 struct wl_compositor *compositor;
Jonas Ådahl42682622016-08-11 23:44:41 +080056 struct zxdg_shell_v6 *shell;
Jonas Ådahl496adb32015-11-17 16:00:27 +080057 struct zwp_fullscreen_shell_v1 *fshell;
Jonas Ådahl57e48f02015-11-17 16:00:28 +080058 struct zwp_linux_dmabuf_v1 *dmabuf;
George Kiagiadakis53868982014-06-12 16:26:49 +020059 int xrgb8888_format_found;
Varad Gautam48be0be2017-04-26 19:16:00 +053060 int req_dmabuf_immediate;
George Kiagiadakis53868982014-06-12 16:26:49 +020061};
62
63struct buffer {
64 struct wl_buffer *buffer;
65 int busy;
66
67 int drm_fd;
68
69 drm_intel_bufmgr *bufmgr;
70 drm_intel_bo *bo;
71
72 uint32_t gem_handle;
73 int dmabuf_fd;
74 uint8_t *mmap;
75
76 int width;
77 int height;
78 int bpp;
79 unsigned long stride;
80};
81
Pekka Paalanend56b94a2016-06-10 13:13:01 +030082#define NUM_BUFFERS 3
83
George Kiagiadakis53868982014-06-12 16:26:49 +020084struct window {
85 struct display *display;
86 int width, height;
87 struct wl_surface *surface;
Jonas Ådahl42682622016-08-11 23:44:41 +080088 struct zxdg_surface_v6 *xdg_surface;
89 struct zxdg_toplevel_v6 *xdg_toplevel;
Pekka Paalanend56b94a2016-06-10 13:13:01 +030090 struct buffer buffers[NUM_BUFFERS];
George Kiagiadakis53868982014-06-12 16:26:49 +020091 struct buffer *prev_buffer;
92 struct wl_callback *callback;
Jonas Ådahl42682622016-08-11 23:44:41 +080093 bool initialized;
94 bool wait_for_configure;
George Kiagiadakis53868982014-06-12 16:26:49 +020095};
96
97static int running = 1;
98
99static void
Jonas Ådahl42682622016-08-11 23:44:41 +0800100redraw(void *data, struct wl_callback *callback, uint32_t time);
101
102static void
George Kiagiadakis53868982014-06-12 16:26:49 +0200103buffer_release(void *data, struct wl_buffer *buffer)
104{
105 struct buffer *mybuf = data;
106
107 mybuf->busy = 0;
108}
109
110static const struct wl_buffer_listener buffer_listener = {
111 buffer_release
112};
113
114static int
115drm_connect(struct buffer *my_buf)
116{
117 /* This won't work with card0 as we need to be authenticated; instead,
118 * boot with drm.rnodes=1 and use that. */
119 my_buf->drm_fd = open("/dev/dri/renderD128", O_RDWR);
120 if (my_buf->drm_fd < 0)
121 return 0;
122
123 my_buf->bufmgr = drm_intel_bufmgr_gem_init(my_buf->drm_fd, 32);
124 if (!my_buf->bufmgr)
125 return 0;
126
127 return 1;
128}
129
130static void
131drm_shutdown(struct buffer *my_buf)
132{
133 drm_intel_bufmgr_destroy(my_buf->bufmgr);
134 close(my_buf->drm_fd);
135}
136
137static int
138alloc_bo(struct buffer *my_buf)
139{
140 /* XXX: try different tiling modes for testing FB modifiers. */
141 uint32_t tiling = I915_TILING_NONE;
142
143 assert(my_buf->bufmgr);
144
145 my_buf->bo = drm_intel_bo_alloc_tiled(my_buf->bufmgr, "test",
146 my_buf->width, my_buf->height,
147 (my_buf->bpp / 8), &tiling,
148 &my_buf->stride, 0);
149
150 printf("buffer allocated w %d, h %d, stride %lu, size %lu\n",
151 my_buf->width, my_buf->height, my_buf->stride, my_buf->bo->size);
152
153 if (!my_buf->bo)
154 return 0;
155
156 if (tiling != I915_TILING_NONE)
157 return 0;
158
159 return 1;
160}
161
162static void
163free_bo(struct buffer *my_buf)
164{
165 drm_intel_bo_unreference(my_buf->bo);
166}
167
168static int
169map_bo(struct buffer *my_buf)
170{
171 if (drm_intel_gem_bo_map_gtt(my_buf->bo) != 0)
172 return 0;
173
174 my_buf->mmap = my_buf->bo->virtual;
175
176 return 1;
177}
178
179static void
180fill_content(struct buffer *my_buf)
181{
182 int x = 0, y = 0;
183 uint32_t *pix;
184
185 assert(my_buf->mmap);
186
187 for (y = 0; y < my_buf->height; y++) {
188 pix = (uint32_t *)(my_buf->mmap + y * my_buf->stride);
189 for (x = 0; x < my_buf->width; x++) {
190 *pix++ = (0xff << 24) | ((x % 256) << 16) |
191 ((y % 256) << 8) | 0xf0;
192 }
193 }
194}
195
196static void
197unmap_bo(struct buffer *my_buf)
198{
199 drm_intel_gem_bo_unmap_gtt(my_buf->bo);
200}
201
202static void
203create_succeeded(void *data,
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800204 struct zwp_linux_buffer_params_v1 *params,
George Kiagiadakis53868982014-06-12 16:26:49 +0200205 struct wl_buffer *new_buffer)
206{
207 struct buffer *buffer = data;
208
209 buffer->buffer = new_buffer;
210 wl_buffer_add_listener(buffer->buffer, &buffer_listener, buffer);
211
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800212 zwp_linux_buffer_params_v1_destroy(params);
George Kiagiadakis53868982014-06-12 16:26:49 +0200213}
214
215static void
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800216create_failed(void *data, struct zwp_linux_buffer_params_v1 *params)
George Kiagiadakis53868982014-06-12 16:26:49 +0200217{
218 struct buffer *buffer = data;
219
220 buffer->buffer = NULL;
Emmanuel Gil Peyrot8ef29572016-01-11 19:04:37 +0000221 running = 0;
George Kiagiadakis53868982014-06-12 16:26:49 +0200222
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800223 zwp_linux_buffer_params_v1_destroy(params);
George Kiagiadakis53868982014-06-12 16:26:49 +0200224
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800225 fprintf(stderr, "Error: zwp_linux_buffer_params.create failed.\n");
George Kiagiadakis53868982014-06-12 16:26:49 +0200226}
227
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800228static const struct zwp_linux_buffer_params_v1_listener params_listener = {
George Kiagiadakis53868982014-06-12 16:26:49 +0200229 create_succeeded,
230 create_failed
231};
232
233static int
234create_dmabuf_buffer(struct display *display, struct buffer *buffer,
235 int width, int height)
236{
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800237 struct zwp_linux_buffer_params_v1 *params;
George Kiagiadakis53868982014-06-12 16:26:49 +0200238 uint64_t modifier;
239 uint32_t flags;
240
241 if (!drm_connect(buffer)) {
242 fprintf(stderr, "drm_connect failed\n");
243 goto error;
244 }
245
246 buffer->width = width;
247 buffer->height = height;
248 buffer->bpp = 32; /* hardcoded XRGB8888 format */
249
250 if (!alloc_bo(buffer)) {
251 fprintf(stderr, "alloc_bo failed\n");
252 goto error1;
253 }
254
255 if (!map_bo(buffer)) {
256 fprintf(stderr, "map_bo failed\n");
257 goto error2;
258 }
259 fill_content(buffer);
260 unmap_bo(buffer);
261
262 if (drm_intel_bo_gem_export_to_prime(buffer->bo, &buffer->dmabuf_fd) != 0) {
263 fprintf(stderr, "drm_intel_bo_gem_export_to_prime failed\n");
264 goto error2;
265 }
266 if (buffer->dmabuf_fd < 0) {
267 fprintf(stderr, "error: dmabuf_fd < 0\n");
268 goto error2;
269 }
270
271 /* We now have a dmabuf! It should contain 2x2 tiles (i.e. each tile
272 * is 256x256) of misc colours, and be mappable, either as ARGB8888, or
273 * XRGB8888. */
274 modifier = 0;
275 flags = 0;
276
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800277 params = zwp_linux_dmabuf_v1_create_params(display->dmabuf);
278 zwp_linux_buffer_params_v1_add(params,
279 buffer->dmabuf_fd,
280 0, /* plane_idx */
281 0, /* offset */
282 buffer->stride,
283 modifier >> 32,
284 modifier & 0xffffffff);
285 zwp_linux_buffer_params_v1_add_listener(params, &params_listener, buffer);
Varad Gautam48be0be2017-04-26 19:16:00 +0530286 if (display->req_dmabuf_immediate) {
287 buffer->buffer = zwp_linux_buffer_params_v1_create_immed(params,
288 buffer->width,
289 buffer->height,
290 DRM_FORMAT_XRGB8888,
291 flags);
292 wl_buffer_add_listener(buffer->buffer, &buffer_listener, buffer);
293 }
294 else
295 zwp_linux_buffer_params_v1_create(params,
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800296 buffer->width,
297 buffer->height,
298 DRM_FORMAT_XRGB8888,
299 flags);
George Kiagiadakis53868982014-06-12 16:26:49 +0200300
George Kiagiadakis53868982014-06-12 16:26:49 +0200301 return 0;
302
303error2:
304 free_bo(buffer);
305error1:
306 drm_shutdown(buffer);
307error:
308 return -1;
309}
310
311static void
Jonas Ådahl42682622016-08-11 23:44:41 +0800312xdg_surface_handle_configure(void *data, struct zxdg_surface_v6 *surface,
313 uint32_t serial)
314{
315 struct window *window = data;
316
317 zxdg_surface_v6_ack_configure(surface, serial);
318
319 if (window->initialized && window->wait_for_configure)
320 redraw(window, NULL, 0);
321 window->wait_for_configure = false;
322}
323
324static const struct zxdg_surface_v6_listener xdg_surface_listener = {
325 xdg_surface_handle_configure,
326};
327
328static void
329xdg_toplevel_handle_configure(void *data, struct zxdg_toplevel_v6 *toplevel,
330 int32_t width, int32_t height,
331 struct wl_array *states)
George Kiagiadakis53868982014-06-12 16:26:49 +0200332{
333}
334
335static void
Jonas Ådahl42682622016-08-11 23:44:41 +0800336xdg_toplevel_handle_close(void *data, struct zxdg_toplevel_v6 *xdg_toplevel)
George Kiagiadakis53868982014-06-12 16:26:49 +0200337{
338 running = 0;
339}
340
Jonas Ådahl42682622016-08-11 23:44:41 +0800341static const struct zxdg_toplevel_v6_listener xdg_toplevel_listener = {
342 xdg_toplevel_handle_configure,
343 xdg_toplevel_handle_close,
George Kiagiadakis53868982014-06-12 16:26:49 +0200344};
345
346static struct window *
347create_window(struct display *display, int width, int height)
348{
349 struct window *window;
Emmanuel Gil Peyrot8ef29572016-01-11 19:04:37 +0000350 int i;
351 int ret;
George Kiagiadakis53868982014-06-12 16:26:49 +0200352
Bryce Harrington0d1a6222016-02-11 16:42:49 -0800353 window = zalloc(sizeof *window);
George Kiagiadakis53868982014-06-12 16:26:49 +0200354 if (!window)
355 return NULL;
356
357 window->callback = NULL;
358 window->display = display;
359 window->width = width;
360 window->height = height;
361 window->surface = wl_compositor_create_surface(display->compositor);
362
363 if (display->shell) {
364 window->xdg_surface =
Jonas Ådahl42682622016-08-11 23:44:41 +0800365 zxdg_shell_v6_get_xdg_surface(display->shell,
366 window->surface);
George Kiagiadakis53868982014-06-12 16:26:49 +0200367
368 assert(window->xdg_surface);
369
Jonas Ådahl42682622016-08-11 23:44:41 +0800370 zxdg_surface_v6_add_listener(window->xdg_surface,
371 &xdg_surface_listener, window);
George Kiagiadakis53868982014-06-12 16:26:49 +0200372
Jonas Ådahl42682622016-08-11 23:44:41 +0800373 window->xdg_toplevel =
374 zxdg_surface_v6_get_toplevel(window->xdg_surface);
375
376 assert(window->xdg_toplevel);
377
378 zxdg_toplevel_v6_add_listener(window->xdg_toplevel,
379 &xdg_toplevel_listener, window);
380
381 zxdg_toplevel_v6_set_title(window->xdg_toplevel, "simple-dmabuf");
382
383 window->wait_for_configure = true;
384 wl_surface_commit(window->surface);
George Kiagiadakis53868982014-06-12 16:26:49 +0200385 } else if (display->fshell) {
Jonas Ådahl496adb32015-11-17 16:00:27 +0800386 zwp_fullscreen_shell_v1_present_surface(display->fshell,
387 window->surface,
388 ZWP_FULLSCREEN_SHELL_V1_PRESENT_METHOD_DEFAULT,
389 NULL);
George Kiagiadakis53868982014-06-12 16:26:49 +0200390 } else {
391 assert(0);
392 }
393
Pekka Paalanend56b94a2016-06-10 13:13:01 +0300394 for (i = 0; i < NUM_BUFFERS; ++i) {
Emmanuel Gil Peyrot8ef29572016-01-11 19:04:37 +0000395 ret = create_dmabuf_buffer(display, &window->buffers[i],
396 width, height);
397
398 if (ret < 0)
399 return NULL;
400 }
401
George Kiagiadakis53868982014-06-12 16:26:49 +0200402 return window;
403}
404
405static void
406destroy_window(struct window *window)
407{
408 int i;
409
410 if (window->callback)
411 wl_callback_destroy(window->callback);
412
Pekka Paalanend56b94a2016-06-10 13:13:01 +0300413 for (i = 0; i < NUM_BUFFERS; i++) {
George Kiagiadakis53868982014-06-12 16:26:49 +0200414 if (!window->buffers[i].buffer)
415 continue;
416
417 wl_buffer_destroy(window->buffers[i].buffer);
418 free_bo(&window->buffers[i]);
419 close(window->buffers[i].dmabuf_fd);
420 drm_shutdown(&window->buffers[i]);
421 }
422
Jonas Ådahl42682622016-08-11 23:44:41 +0800423 if (window->xdg_toplevel)
424 zxdg_toplevel_v6_destroy(window->xdg_toplevel);
George Kiagiadakis53868982014-06-12 16:26:49 +0200425 if (window->xdg_surface)
Jonas Ådahl42682622016-08-11 23:44:41 +0800426 zxdg_surface_v6_destroy(window->xdg_surface);
George Kiagiadakis53868982014-06-12 16:26:49 +0200427 wl_surface_destroy(window->surface);
428 free(window);
429}
430
431static struct buffer *
432window_next_buffer(struct window *window)
433{
Pekka Paalanend56b94a2016-06-10 13:13:01 +0300434 int i;
George Kiagiadakis53868982014-06-12 16:26:49 +0200435
Pekka Paalanend56b94a2016-06-10 13:13:01 +0300436 for (i = 0; i < NUM_BUFFERS; i++)
437 if (!window->buffers[i].busy)
438 return &window->buffers[i];
George Kiagiadakis53868982014-06-12 16:26:49 +0200439
Pekka Paalanend56b94a2016-06-10 13:13:01 +0300440 return NULL;
George Kiagiadakis53868982014-06-12 16:26:49 +0200441}
442
443static const struct wl_callback_listener frame_listener;
444
445static void
446redraw(void *data, struct wl_callback *callback, uint32_t time)
447{
448 struct window *window = data;
449 struct buffer *buffer;
450
451 buffer = window_next_buffer(window);
452 if (!buffer) {
453 fprintf(stderr,
454 !callback ? "Failed to create the first buffer.\n" :
Pekka Paalanend56b94a2016-06-10 13:13:01 +0300455 "All buffers busy at redraw(). Server bug?\n");
George Kiagiadakis53868982014-06-12 16:26:49 +0200456 abort();
457 }
458
459 /* XXX: would be nice to draw something that changes here... */
460
461 wl_surface_attach(window->surface, buffer->buffer, 0, 0);
462 wl_surface_damage(window->surface, 0, 0, window->width, window->height);
463
464 if (callback)
465 wl_callback_destroy(callback);
466
467 window->callback = wl_surface_frame(window->surface);
468 wl_callback_add_listener(window->callback, &frame_listener, window);
469 wl_surface_commit(window->surface);
470 buffer->busy = 1;
471}
472
473static const struct wl_callback_listener frame_listener = {
474 redraw
475};
476
477static void
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800478dmabuf_format(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format)
George Kiagiadakis53868982014-06-12 16:26:49 +0200479{
480 struct display *d = data;
481
482 if (format == DRM_FORMAT_XRGB8888)
483 d->xrgb8888_format_found = 1;
484}
485
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800486static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
George Kiagiadakis53868982014-06-12 16:26:49 +0200487 dmabuf_format
488};
489
490static void
Jonas Ådahl42682622016-08-11 23:44:41 +0800491xdg_shell_ping(void *data, struct zxdg_shell_v6 *shell, uint32_t serial)
George Kiagiadakis53868982014-06-12 16:26:49 +0200492{
Jonas Ådahl42682622016-08-11 23:44:41 +0800493 zxdg_shell_v6_pong(shell, serial);
George Kiagiadakis53868982014-06-12 16:26:49 +0200494}
495
Jonas Ådahl42682622016-08-11 23:44:41 +0800496static const struct zxdg_shell_v6_listener xdg_shell_listener = {
George Kiagiadakis53868982014-06-12 16:26:49 +0200497 xdg_shell_ping,
498};
499
George Kiagiadakis53868982014-06-12 16:26:49 +0200500static void
501registry_handle_global(void *data, struct wl_registry *registry,
502 uint32_t id, const char *interface, uint32_t version)
503{
504 struct display *d = data;
505
506 if (strcmp(interface, "wl_compositor") == 0) {
507 d->compositor =
508 wl_registry_bind(registry,
509 id, &wl_compositor_interface, 1);
Jonas Ådahl42682622016-08-11 23:44:41 +0800510 } else if (strcmp(interface, "zxdg_shell_v6") == 0) {
George Kiagiadakis53868982014-06-12 16:26:49 +0200511 d->shell = wl_registry_bind(registry,
Jonas Ådahl42682622016-08-11 23:44:41 +0800512 id, &zxdg_shell_v6_interface, 1);
513 zxdg_shell_v6_add_listener(d->shell, &xdg_shell_listener, d);
Jonas Ådahl496adb32015-11-17 16:00:27 +0800514 } else if (strcmp(interface, "zwp_fullscreen_shell_v1") == 0) {
George Kiagiadakis53868982014-06-12 16:26:49 +0200515 d->fshell = wl_registry_bind(registry,
Jonas Ådahl496adb32015-11-17 16:00:27 +0800516 id, &zwp_fullscreen_shell_v1_interface, 1);
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800517 } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) {
George Kiagiadakis53868982014-06-12 16:26:49 +0200518 d->dmabuf = wl_registry_bind(registry,
Varad Gautam48be0be2017-04-26 19:16:00 +0530519 id, &zwp_linux_dmabuf_v1_interface,
520 d->req_dmabuf_immediate ? 2 : 1);
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800521 zwp_linux_dmabuf_v1_add_listener(d->dmabuf, &dmabuf_listener, d);
George Kiagiadakis53868982014-06-12 16:26:49 +0200522 }
523}
524
525static void
526registry_handle_global_remove(void *data, struct wl_registry *registry,
527 uint32_t name)
528{
529}
530
531static const struct wl_registry_listener registry_listener = {
532 registry_handle_global,
533 registry_handle_global_remove
534};
535
536static struct display *
Varad Gautam48be0be2017-04-26 19:16:00 +0530537create_display(int is_immediate)
George Kiagiadakis53868982014-06-12 16:26:49 +0200538{
539 struct display *display;
540
541 display = malloc(sizeof *display);
542 if (display == NULL) {
543 fprintf(stderr, "out of memory\n");
544 exit(1);
545 }
546 display->display = wl_display_connect(NULL);
547 assert(display->display);
548
549 /* XXX: fake, because the compositor does not yet advertise anything */
550 display->xrgb8888_format_found = 1;
Varad Gautam48be0be2017-04-26 19:16:00 +0530551 display->req_dmabuf_immediate = is_immediate;
George Kiagiadakis53868982014-06-12 16:26:49 +0200552
553 display->registry = wl_display_get_registry(display->display);
554 wl_registry_add_listener(display->registry,
555 &registry_listener, display);
556 wl_display_roundtrip(display->display);
557 if (display->dmabuf == NULL) {
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800558 fprintf(stderr, "No zwp_linux_dmabuf global\n");
George Kiagiadakis53868982014-06-12 16:26:49 +0200559 exit(1);
560 }
561
562 wl_display_roundtrip(display->display);
563
564 if (!display->xrgb8888_format_found) {
565 fprintf(stderr, "DRM_FORMAT_XRGB8888 not available\n");
566 exit(1);
567 }
568
569 return display;
570}
571
572static void
573destroy_display(struct display *display)
574{
575 if (display->dmabuf)
Jonas Ådahl57e48f02015-11-17 16:00:28 +0800576 zwp_linux_dmabuf_v1_destroy(display->dmabuf);
George Kiagiadakis53868982014-06-12 16:26:49 +0200577
578 if (display->shell)
Jonas Ådahl42682622016-08-11 23:44:41 +0800579 zxdg_shell_v6_destroy(display->shell);
George Kiagiadakis53868982014-06-12 16:26:49 +0200580
581 if (display->fshell)
Jonas Ådahl496adb32015-11-17 16:00:27 +0800582 zwp_fullscreen_shell_v1_release(display->fshell);
George Kiagiadakis53868982014-06-12 16:26:49 +0200583
584 if (display->compositor)
585 wl_compositor_destroy(display->compositor);
586
587 wl_registry_destroy(display->registry);
588 wl_display_flush(display->display);
589 wl_display_disconnect(display->display);
590 free(display);
591}
592
593static void
594signal_int(int signum)
595{
596 running = 0;
597}
598
599int
600main(int argc, char **argv)
601{
602 struct sigaction sigint;
603 struct display *display;
604 struct window *window;
Varad Gautam48be0be2017-04-26 19:16:00 +0530605 int is_immediate = 0;
George Kiagiadakis53868982014-06-12 16:26:49 +0200606 int ret = 0;
607
Varad Gautam48be0be2017-04-26 19:16:00 +0530608 if (argc > 1) {
609 if (!strcmp(argv[1], "immed")) {
610 is_immediate = 1;
611 }
612 else {
613 fprintf(stderr, "usage:\n\tsimple-dmabuf-intel [options]\n"
614 "available options:\n\timmed: avoid dmabuf "
615 "creation roundtrip and import immediately\n");
616 return 1;
617 }
618 }
619
620 display = create_display(is_immediate);
George Kiagiadakis53868982014-06-12 16:26:49 +0200621 window = create_window(display, 250, 250);
622 if (!window)
623 return 1;
624
625 sigint.sa_handler = signal_int;
626 sigemptyset(&sigint.sa_mask);
627 sigint.sa_flags = SA_RESETHAND;
628 sigaction(SIGINT, &sigint, NULL);
629
Varad Gautam48be0be2017-04-26 19:16:00 +0530630 /* Here we retrieve the linux-dmabuf objects if executed without immed,
631 * or error */
Emmanuel Gil Peyrot8ef29572016-01-11 19:04:37 +0000632 wl_display_roundtrip(display->display);
633
634 if (!running)
635 return 1;
George Kiagiadakis53868982014-06-12 16:26:49 +0200636
Jonas Ådahl42682622016-08-11 23:44:41 +0800637 window->initialized = true;
638
639 if (!window->wait_for_configure)
640 redraw(window, NULL, 0);
George Kiagiadakis53868982014-06-12 16:26:49 +0200641
642 while (running && ret != -1)
643 ret = wl_display_dispatch(display->display);
644
645 fprintf(stderr, "simple-dmabuf exiting\n");
646 destroy_window(window);
647 destroy_display(display);
648
649 return 0;
650}