summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorSeunghun Lee <beauty.positive3@gmail.com>2015-06-22 10:23:54 -0400
committerChris Michael <cp.michael@samsung.com>2015-06-22 10:31:42 -0400
commit8b621775619b9959fe952b095b3baaa7aaa99572 (patch)
tree99059a841a79729cac4687ea41f3abf672e6e455 /src/bin
parent3671506ad39d2a956e388e151bd20f1b9ffd62a5 (diff)
ecore-buffer: Add ecore_buffer library to EFL.
Summary: Ecore_Buffer is abstraction of graphic buffer. it supports backend of shm, x11_dri2 and x11_dri3 for now, and this library also provides method to share buffers between processes. Ecore_Buffer_Provider and Ecore_Buffer_Consumer is for this, sharing buffer. provider draws something in to Ecore_Buffer, and consumer receives and displays it. the binary, bq_mgr is a connection maker for buffer provider and consumer. it can be included Enlightenment as a deamon later. @feature Test Plan: 1. Configure with --enable-ecore-buffer and --enable-always-build-examples to build examples. 2. Run bq_mgr, it connects consumer and provider. 3. Run ecore_buffer_provider_example and ecore_buffer_consumer_example Reviewers: lsj119, gwanglim, cedric, zmike, jpeg, raster, devilhorns Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D2197
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/ecore_buffer/.gitignore1
-rw-r--r--src/bin/ecore_buffer/bq_mgr.c899
-rw-r--r--src/bin/ecore_buffer/bq_mgr_protocol.c131
-rw-r--r--src/bin/ecore_buffer/bq_mgr_protocol.h247
4 files changed, 1278 insertions, 0 deletions
diff --git a/src/bin/ecore_buffer/.gitignore b/src/bin/ecore_buffer/.gitignore
new file mode 100644
index 0000000000..846a9e2122
--- /dev/null
+++ b/src/bin/ecore_buffer/.gitignore
@@ -0,0 +1 @@
/bq_mgr
diff --git a/src/bin/ecore_buffer/bq_mgr.c b/src/bin/ecore_buffer/bq_mgr.c
new file mode 100644
index 0000000000..4cb3c1f759
--- /dev/null
+++ b/src/bin/ecore_buffer/bq_mgr.c
@@ -0,0 +1,899 @@
1#include <signal.h>
2#include <unistd.h>
3#include <sys/socket.h>
4#include <sys/types.h>
5#include <sys/xattr.h>
6
7#include <Eina.h>
8#include <Ecore_Getopt.h>
9#include <wayland-server.h>
10
11#include "bq_mgr_protocol.h"
12
13#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
14
15#define BQ_LOG(f, x...) printf("[ES|%30.30s|%04d] " f "\n", __func__, __LINE__, ##x)
16#define BQ_DEBUG(f, x...) if (debug) printf("[ES|%30.30s|%04d] " f "\n", __func__, __LINE__, ##x)
17#define BQ_OBJECT_NEW(x, f) bq_object_new(sizeof(x), ((Bq_Object_Free_Func)(f)))
18#define BQ_OBJECT(x) ((Bq_Object *)(x))
19#define BQ_OBJECT_RESOURCE(x) (((Bq_Object *)(x))->resource)
20
21typedef void (*Bq_Object_Free_Func) (void *obj);
22
23typedef struct _Bq_Object Bq_Object;
24typedef struct _Bq_Mgr Bq_Mgr;
25typedef struct _Bq_Buffer_Queue Bq_Buffer_Queue;
26typedef struct _Bq_Buffer_Consumer Bq_Buffer_Consumer;
27typedef struct _Bq_Buffer_Provider Bq_Buffer_Provider;
28typedef struct _Bq_Buffer Bq_Buffer;
29typedef enum _Bq_Buffer_Type Bq_Buffer_Type;
30
31struct _Bq_Object
32{
33 int ref;
34 Bq_Object_Free_Func free_fn;
35 Eina_Bool deleted;
36 struct wl_resource *resource;
37};
38
39struct _Bq_Mgr
40{
41 Bq_Object bq_obj;
42
43 struct wl_display *wdpy;
44 struct wl_event_source *signals[3];
45
46 /*BufferQueue manager*/
47 struct wl_global *bq_mgr;
48 Eina_Hash *buffer_queues;
49};
50
51
52struct _Bq_Buffer_Queue
53{
54 Bq_Object bq_obj;
55 Eina_Hash *link;
56
57 char *name;
58 struct wl_signal connect;
59
60 Bq_Buffer_Consumer *consumer;
61 Bq_Buffer_Provider *provider;
62 Eina_Inlist *buffers;
63};
64
65struct _Bq_Buffer_Consumer
66{
67 Bq_Object bq_obj;
68 Bq_Buffer_Queue *buffer_queue;
69
70 int32_t queue_size;
71 int32_t width;
72 int32_t height;
73};
74
75struct _Bq_Buffer_Provider
76{
77 Bq_Object bq_obj;
78 Bq_Buffer_Queue *buffer_queue;
79};
80
81enum _Bq_Buffer_Type
82{
83 bq_BUFFER_TYPE_ID,
84 bq_BUFFER_TYPE_FD,
85};
86
87struct _Bq_Buffer
88{
89 Bq_Object bq_obj; /*Dont use wl_resource in bq_obj*/
90 EINA_INLIST;
91
92 struct wl_resource *consumer;
93 struct wl_resource *provider;
94 uint32_t serial;
95
96 char *engine;
97 Bq_Buffer_Type type;
98 int32_t width;
99 int32_t height;
100 int32_t format;
101 uint32_t flags;
102
103 int32_t id;
104 int32_t offset0;
105 int32_t stride0;
106 int32_t offset1;
107 int32_t stride1;
108 int32_t offset2;
109 int32_t stride2;
110};
111
112static Eina_Bool debug;
113
114static void *
115bq_object_new(size_t size, Bq_Object_Free_Func fn)
116{
117 Bq_Object *o = calloc(1, size);
118
119 if ((!o)) return NULL;
120
121 o->ref = 1;
122 o->free_fn = fn;
123
124 return o;
125}
126
127static int
128bq_object_ref(Bq_Object *o)
129{
130 o->ref++;
131
132 return o->ref;
133}
134
135static int
136bq_object_unref(Bq_Object *o)
137{
138 o->ref--;
139
140 if (o->ref <= 0 || o->deleted)
141 {
142 if (o->free_fn)
143 o->free_fn(o);
144
145 free(o);
146 }
147
148 return o->ref;
149}
150
151static int
152bq_object_free(Bq_Object *o)
153{
154 if (!o) return 0;
155 if (o->deleted) return 0;
156
157 o->deleted = EINA_TRUE;
158
159 return bq_object_unref(o);
160}
161
162static void
163bq_mgr_buffer_queue_free(Bq_Buffer_Queue *bq)
164{
165 Bq_Buffer *buf;
166
167 if (!bq) return;
168
169 BQ_DEBUG("destroy buffer queue : %s\n", bq->name);
170
171 if (bq->consumer)
172 {
173 wl_resource_destroy(BQ_OBJECT_RESOURCE(bq->consumer));
174 bq->consumer = NULL;
175 }
176
177 if (bq->provider)
178 {
179 wl_resource_destroy(BQ_OBJECT_RESOURCE(bq->provider));
180 bq->provider = NULL;
181 }
182
183 while (bq->buffers)
184 {
185 buf = EINA_INLIST_CONTAINER_GET(bq->buffers,Bq_Buffer);
186 bq->buffers = eina_inlist_remove(bq->buffers, bq->buffers);
187 if (buf->consumer)
188 {
189 wl_resource_destroy(buf->consumer);
190 buf->consumer = NULL;
191 }
192
193 if (buf->provider)
194 {
195 wl_resource_destroy(buf->provider);
196 buf->provider = NULL;
197 }
198 }
199
200 if (bq->link)
201 {
202 eina_hash_del(bq->link, bq->name, bq);
203 bq->link = NULL;
204 }
205 if (bq->name)
206 {
207 free(bq->name);
208 bq->name = NULL;
209 }
210}
211
212static Bq_Buffer_Queue*
213bq_mgr_buffer_queue_new(Bq_Mgr *bq_mgr, const char *name)
214{
215 Bq_Buffer_Queue *bq;
216
217 bq = eina_hash_find(bq_mgr->buffer_queues, name);
218 if (bq)
219 {
220 bq_object_ref(BQ_OBJECT(bq));
221 return bq;
222 }
223
224 bq = BQ_OBJECT_NEW(Bq_Buffer_Queue, bq_mgr_buffer_queue_free);
225 EINA_SAFETY_ON_NULL_RETURN_VAL(bq, NULL);
226
227 bq->link = bq_mgr->buffer_queues;
228 bq->name = strdup(name);
229 if (!eina_hash_add(bq->link,bq->name,bq))
230 {
231 bq_object_free(BQ_OBJECT(bq));
232 return NULL;
233 }
234
235 wl_signal_init(&bq->connect);
236 bq->buffers = NULL;
237 return bq;
238}
239
240static void
241bq_mgr_buffer_consumer_release_buffer(struct wl_client *client EINA_UNUSED,
242 struct wl_resource *resource,
243 struct wl_resource *buffer)
244{
245 Bq_Buffer_Queue *bq;
246 Bq_Buffer_Consumer *bq_consumer;
247 Bq_Buffer_Provider *bq_provider;
248 Bq_Buffer *bq_buffer;
249
250 bq_consumer = (Bq_Buffer_Consumer*)wl_resource_get_user_data(resource);
251 bq_buffer = (Bq_Buffer*)wl_resource_get_user_data(buffer);
252 bq = bq_consumer->buffer_queue;
253 bq_provider = bq->provider;
254
255 if (bq_provider && bq_buffer->provider)
256 {
257 bq_provider_send_add_buffer(BQ_OBJECT_RESOURCE(bq_provider),
258 bq_buffer->provider, bq_buffer->serial);
259 }
260}
261
262static const struct bq_consumer_interface _bq_consumer_interface = {
263 bq_mgr_buffer_consumer_release_buffer
264};
265
266static void
267bq_mgr_buffer_consumer_destroy(struct wl_resource *resource)
268{
269 Bq_Buffer_Consumer *bq_consumer = wl_resource_get_user_data(resource);
270 Bq_Buffer_Provider *bq_provider;
271 Bq_Buffer_Queue *bq;
272 Bq_Buffer *buf;
273
274 if (!bq_consumer) return;
275
276 BQ_DEBUG("destroy buffer consumer : %s\n", bq_consumer->buffer_queue->name);
277
278 bq = bq_consumer->buffer_queue;
279 bq_provider = bq->provider;
280
281 bq->consumer = NULL;
282 BQ_OBJECT_RESOURCE(bq_consumer) = NULL;
283
284 if (bq_provider)
285 {
286 bq_provider_send_disconnected(BQ_OBJECT_RESOURCE(bq_provider));
287 }
288
289 while (bq->buffers)
290 {
291 buf = EINA_INLIST_CONTAINER_GET(bq->buffers,Bq_Buffer);
292 bq->buffers = eina_inlist_remove(bq->buffers,bq->buffers);
293
294 BQ_DEBUG("destroy BUFFER : %d\n", buf->type);
295 if (buf->consumer)
296 {
297 wl_resource_destroy(buf->consumer);
298 buf->consumer = NULL;
299 bq_object_unref(BQ_OBJECT(buf));
300 }
301
302 if (buf->provider)
303 {
304 wl_resource_destroy(buf->provider);
305 buf->provider = NULL;
306 bq_object_unref(BQ_OBJECT(buf));
307 }
308 }
309
310 bq_object_unref(BQ_OBJECT(bq_consumer));
311 bq_object_unref(BQ_OBJECT(bq));
312}
313
314static void
315bq_mgr_buffer_destroy(struct wl_resource *resource)
316{
317 Bq_Buffer *buf = wl_resource_get_user_data(resource);
318
319 if (resource == buf->consumer)
320 {
321 BQ_DEBUG("destroy buffer : consumer\n");
322 }
323 else if (resource == buf->provider)
324 {
325 BQ_DEBUG("destroy buffer : provider\n");
326 }
327}
328
329static void
330bq_buffer_create_consumer_side(Bq_Buffer_Consumer *bq_consumer, Bq_Buffer *bq_buffer)
331{
332 if (!bq_consumer) return;
333
334 bq_buffer->consumer = wl_resource_create(wl_resource_get_client(BQ_OBJECT_RESOURCE(bq_consumer)),
335 &bq_buffer_interface, 1, 0);
336 wl_resource_set_implementation(bq_buffer->consumer, NULL, bq_buffer, bq_mgr_buffer_destroy);
337 bq_object_ref(BQ_OBJECT(bq_buffer));
338
339 bq_consumer_send_buffer_attached(BQ_OBJECT_RESOURCE(bq_consumer),
340 bq_buffer->consumer,
341 bq_buffer->engine,
342 bq_buffer->width,
343 bq_buffer->height,
344 bq_buffer->format,
345 bq_buffer->flags);
346}
347
348static void
349bq_buffer_set_consumer_side(Bq_Buffer_Consumer *bq_consumer, Bq_Buffer *bq_buffer)
350{
351 if (!bq_consumer) return;
352 EINA_SAFETY_ON_NULL_RETURN(bq_buffer);
353 EINA_SAFETY_ON_NULL_RETURN(bq_buffer->consumer);
354
355 if (bq_buffer->type == bq_BUFFER_TYPE_ID)
356 bq_consumer_send_set_buffer_id(BQ_OBJECT_RESOURCE(bq_consumer),
357 bq_buffer->consumer,
358 bq_buffer->id,
359 bq_buffer->offset0,
360 bq_buffer->stride0,
361 bq_buffer->offset1,
362 bq_buffer->stride1,
363 bq_buffer->offset2,
364 bq_buffer->stride2);
365 else
366 {
367 bq_consumer_send_set_buffer_fd(BQ_OBJECT_RESOURCE(bq_consumer),
368 bq_buffer->consumer,
369 bq_buffer->id,
370 bq_buffer->offset0,
371 bq_buffer->stride0,
372 bq_buffer->offset1,
373 bq_buffer->stride1,
374 bq_buffer->offset2,
375 bq_buffer->stride2);
376 close(bq_buffer->id);
377 }
378}
379
380static void
381bq_mgr_buffer_queue_create_consumer(struct wl_client *client,
382 struct wl_resource *resource,
383 uint32_t id,
384 const char *name,
385 int32_t queue_size,
386 int32_t width,
387 int32_t height)
388{
389 Bq_Mgr *bq_mgr = (Bq_Mgr*)wl_resource_get_user_data(resource);
390 Bq_Buffer_Queue *bq;
391 Bq_Buffer_Consumer *bq_consumer;
392 Bq_Buffer_Provider *bq_provider;
393 Bq_Buffer *buf;
394
395 EINA_SAFETY_ON_NULL_RETURN(bq_mgr);
396
397 bq = bq_mgr_buffer_queue_new(bq_mgr,name);
398 EINA_SAFETY_ON_NULL_RETURN(bq);
399
400 if (bq->consumer)
401 {
402 bq_object_unref(BQ_OBJECT(bq));
403 wl_resource_post_error(resource,
404 BQ_MGR_ERROR_ALREADY_USED,
405 "%s consumer already used",name);
406 return;
407 }
408
409 bq_consumer = BQ_OBJECT_NEW(Bq_Buffer_Consumer, NULL);
410 EINA_SAFETY_ON_NULL_RETURN(bq_consumer);
411 BQ_OBJECT_RESOURCE(bq_consumer) = wl_resource_create(client,
412 &bq_consumer_interface,
413 1, id);
414 if (!BQ_OBJECT_RESOURCE(bq_consumer))
415 {
416 bq_object_unref(BQ_OBJECT(bq_consumer));
417 wl_client_post_no_memory(client);
418 return;
419 }
420
421 wl_resource_set_implementation(BQ_OBJECT_RESOURCE(bq_consumer),
422 &_bq_consumer_interface,
423 bq_consumer,
424 bq_mgr_buffer_consumer_destroy);
425
426 bq_consumer->buffer_queue = bq;
427 bq_consumer->queue_size = queue_size;
428 bq_consumer->width = width;
429 bq_consumer->height = height;
430
431 bq_provider = bq->provider;
432 bq->consumer = bq_consumer;
433 if (bq_provider)
434 {
435 bq_provider_send_connected(BQ_OBJECT_RESOURCE(bq_provider),
436 queue_size, width, height);
437 bq_consumer_send_connected(BQ_OBJECT_RESOURCE(bq_consumer));
438 }
439
440 EINA_INLIST_FOREACH(bq->buffers,buf)
441 {
442 bq_buffer_create_consumer_side(bq_consumer, buf);
443 bq_buffer_set_consumer_side(bq_consumer, buf);
444 }
445}
446
447static void
448bq_buffer_free(Bq_Buffer *buf)
449{
450 if (buf->engine)
451 free(buf->engine);
452}
453
454static void
455bq_mgr_buffer_provider_attatch_buffer(struct wl_client *client,
456 struct wl_resource *resource,
457 uint32_t buffer,
458 const char *engine,
459 int32_t width,
460 int32_t height,
461 int32_t format,
462 uint32_t flags)
463{
464 Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
465 Bq_Buffer_Consumer *bq_consumer;
466 Bq_Buffer_Queue *bq;
467 Bq_Buffer *bq_buffer;
468
469 EINA_SAFETY_ON_NULL_RETURN(bq_provider);
470 bq = bq_provider->buffer_queue;
471 bq_consumer = bq->consumer;
472
473 bq_buffer = BQ_OBJECT_NEW(Bq_Buffer, bq_buffer_free);
474 bq_buffer->provider = wl_resource_create(client, &bq_buffer_interface, 1, buffer);
475 wl_resource_set_implementation(bq_buffer->provider, NULL, bq_buffer, bq_mgr_buffer_destroy);
476
477 if (!bq_buffer->provider)
478 {
479 wl_client_post_no_memory(client);
480 bq_object_unref(BQ_OBJECT(bq_buffer));
481 return;
482 }
483
484 bq_buffer->engine = strdup(engine);
485 bq_buffer->width = width;
486 bq_buffer->height = height;
487 bq_buffer->format = format;
488 bq_buffer->flags = flags;
489
490 bq->buffers = eina_inlist_append(bq->buffers,EINA_INLIST_GET(bq_buffer));
491 BQ_DEBUG("add BUFFER : %d\n", bq_buffer->type);
492
493 bq_buffer_create_consumer_side(bq_consumer, bq_buffer);
494
495}
496
497static void
498bq_mgr_buffer_provider_set_buffer_id(struct wl_client *client EINA_UNUSED,
499 struct wl_resource *resource,
500 struct wl_resource *buffer,
501 int32_t id,
502 int32_t offset0,
503 int32_t stride0,
504 int32_t offset1,
505 int32_t stride1,
506 int32_t offset2,
507 int32_t stride2)
508{
509 Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
510 Bq_Buffer_Consumer *bq_consumer;
511 Bq_Buffer_Queue *bq;
512 Bq_Buffer *bq_buffer;
513
514 EINA_SAFETY_ON_NULL_RETURN(bq_provider);
515 bq = bq_provider->buffer_queue;
516 bq_consumer = bq->consumer;
517 bq_buffer = wl_resource_get_user_data(buffer);
518 EINA_SAFETY_ON_NULL_RETURN(bq_buffer);
519
520 bq_buffer->type = bq_BUFFER_TYPE_ID;
521 bq_buffer->id = id;
522 bq_buffer->offset0 = offset0;
523 bq_buffer->stride0 = stride0;
524 bq_buffer->offset1 = offset1;
525 bq_buffer->stride1 = stride1;
526 bq_buffer->offset2 = offset2;
527 bq_buffer->stride2 = stride2;
528
529 bq_buffer_set_consumer_side(bq_consumer, bq_buffer);
530}
531
532static void
533bq_mgr_buffer_provider_set_buffer_fd(struct wl_client *client EINA_UNUSED,
534 struct wl_resource *resource,
535 struct wl_resource *buffer,
536 int32_t fd,
537 int32_t offset0,
538 int32_t stride0,
539 int32_t offset1,
540 int32_t stride1,
541 int32_t offset2,
542 int32_t stride2)
543{
544 Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
545 Bq_Buffer_Consumer *bq_consumer;
546 Bq_Buffer_Queue *bq;
547 Bq_Buffer *bq_buffer;
548
549 EINA_SAFETY_ON_NULL_RETURN(bq_provider);
550 bq = bq_provider->buffer_queue;
551 bq_consumer = bq->consumer;
552 bq_buffer = wl_resource_get_user_data(buffer);
553 EINA_SAFETY_ON_NULL_RETURN(bq_buffer);
554
555 bq_buffer->type = bq_BUFFER_TYPE_FD;
556 bq_buffer->id = fd;
557 bq_buffer->offset0 = offset0;
558 bq_buffer->stride0 = stride0;
559 bq_buffer->offset1 = offset1;
560 bq_buffer->stride1 = stride1;
561 bq_buffer->offset2 = offset2;
562 bq_buffer->stride2 = stride2;
563
564 bq_buffer_set_consumer_side(bq_consumer, bq_buffer);
565}
566
567
568static void
569bq_mgr_buffer_provider_detach_buffer(struct wl_client *client EINA_UNUSED,
570 struct wl_resource *resource,
571 struct wl_resource *buffer)
572{
573 Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
574 Bq_Buffer_Consumer *bq_consumer;
575 Bq_Buffer_Queue *bq;
576 Bq_Buffer *bq_buffer;
577
578 EINA_SAFETY_ON_NULL_RETURN(bq_provider);
579 bq = bq_provider->buffer_queue;
580 bq_consumer = bq->consumer;
581 bq_buffer = wl_resource_get_user_data(buffer);
582
583 if (bq_consumer)
584 {
585 bq_consumer_send_buffer_detached(BQ_OBJECT_RESOURCE(bq_consumer),
586 bq_buffer->consumer);
587 wl_resource_destroy(bq_buffer->consumer);
588 bq_object_unref(BQ_OBJECT(bq_buffer));
589 }
590
591 wl_resource_destroy(bq_buffer->provider);
592 bq->buffers = eina_inlist_remove(bq->buffers,EINA_INLIST_GET(bq_buffer));
593 bq_object_unref(BQ_OBJECT(bq_buffer));
594}
595
596static void
597bq_mgr_buffer_provider_enqueue_buffer(struct wl_client *client EINA_UNUSED,
598 struct wl_resource *resource,
599 struct wl_resource *buffer,
600 uint32_t serial)
601{
602 Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
603 Bq_Buffer_Consumer *bq_consumer;
604 Bq_Buffer_Queue *bq;
605 Bq_Buffer *bq_buffer;
606
607 EINA_SAFETY_ON_NULL_RETURN(bq_provider);
608 bq = bq_provider->buffer_queue;
609 bq_consumer = bq->consumer;
610 if (!bq_consumer)
611 {
612 wl_resource_post_error(BQ_OBJECT_RESOURCE(bq_consumer),
613 BQ_PROVIDER_ERROR_CONNECTION,
614 "Not connected:%s", bq->name);
615 return;
616 }
617
618 bq_buffer = wl_resource_get_user_data(buffer);
619 EINA_SAFETY_ON_NULL_RETURN(bq_buffer);
620 bq_buffer->serial = serial;
621
622 bq_consumer_send_add_buffer(BQ_OBJECT_RESOURCE(bq_consumer),
623 bq_buffer->consumer,
624 bq_buffer->serial);
625}
626
627static const struct bq_provider_interface _bq_provider_interface = {
628 bq_mgr_buffer_provider_attatch_buffer,
629 bq_mgr_buffer_provider_set_buffer_id,
630 bq_mgr_buffer_provider_set_buffer_fd,
631 bq_mgr_buffer_provider_detach_buffer,
632 bq_mgr_buffer_provider_enqueue_buffer
633};
634
635static void
636bq_mgr_buffer_provider_destroy(struct wl_resource *resource)
637{
638 Bq_Buffer_Queue *bq;
639 Bq_Buffer_Provider *bq_provider = wl_resource_get_user_data(resource);
640 Bq_Buffer_Consumer *bq_consumer;
641 Bq_Buffer *buf;
642
643 EINA_SAFETY_ON_NULL_RETURN(bq_provider);
644 BQ_DEBUG("destroy buffer provider : %s\n", bq_provider->buffer_queue->name);
645 bq = bq_provider->buffer_queue;
646 bq_consumer = bq->consumer;
647
648 BQ_OBJECT_RESOURCE(bq_provider) = NULL;
649 bq->provider = NULL;
650
651 while (bq->buffers)
652 {
653 buf = EINA_INLIST_CONTAINER_GET(bq->buffers, Bq_Buffer);
654 bq->buffers = eina_inlist_remove(bq->buffers, bq->buffers);
655
656 if (buf->consumer)
657 {
658 bq_consumer_send_buffer_detached(BQ_OBJECT_RESOURCE(bq_consumer), buf->consumer);
659 wl_resource_destroy(buf->consumer);
660 buf->consumer = NULL;
661 bq_object_unref(BQ_OBJECT(buf));
662 }
663
664 if (buf->provider)
665 {
666 wl_resource_destroy(buf->provider);
667 buf->provider = NULL;
668 bq_object_unref(BQ_OBJECT(buf));
669 }
670 }
671
672 if (bq_consumer)
673 {
674 if (BQ_OBJECT_RESOURCE(bq_consumer))
675 bq_consumer_send_disconnected(BQ_OBJECT_RESOURCE(bq_consumer));
676 }
677
678 bq_object_unref(BQ_OBJECT(bq_provider));
679 bq_object_unref(BQ_OBJECT(bq));
680}
681
682static void
683bq_mgr_buffer_queue_create_provider(struct wl_client *client,
684 struct wl_resource *resource,
685 uint32_t id,
686 const char *name)
687{
688 Bq_Mgr *bq_mgr = (Bq_Mgr*)wl_resource_get_user_data(resource);
689 Bq_Buffer_Queue *bq;
690 Bq_Buffer_Provider *bq_provider;
691 Bq_Buffer_Consumer *bq_consumer;
692
693 EINA_SAFETY_ON_NULL_RETURN(bq_mgr);
694
695 bq = bq_mgr_buffer_queue_new(bq_mgr,name);
696 EINA_SAFETY_ON_NULL_RETURN(bq);
697
698 if (bq->provider)
699 {
700 bq_object_unref(BQ_OBJECT(bq));
701 wl_resource_post_error(resource,
702 BQ_MGR_ERROR_ALREADY_USED,
703 "%s rpovider already used",name);
704 return;
705 }
706
707 bq_provider = BQ_OBJECT_NEW(Bq_Buffer_Provider, NULL);
708 EINA_SAFETY_ON_NULL_GOTO(bq_provider, on_error);
709
710 BQ_OBJECT_RESOURCE(bq_provider)= wl_resource_create(client,
711 &bq_provider_interface,
712 1, id);
713 EINA_SAFETY_ON_NULL_GOTO(BQ_OBJECT_RESOURCE(bq_provider), on_error);
714
715 wl_resource_set_implementation(BQ_OBJECT_RESOURCE(bq_provider),
716 &_bq_provider_interface,
717 bq_provider,
718 bq_mgr_buffer_provider_destroy);
719
720 bq_provider->buffer_queue = bq;
721 bq->provider = bq_provider;
722 bq_consumer = bq->consumer;
723 if (bq_consumer)
724 {
725 /*Send connect*/
726 bq_consumer_send_connected(BQ_OBJECT_RESOURCE(bq_consumer));
727 bq_provider_send_connected(BQ_OBJECT_RESOURCE(bq_provider),
728 bq_consumer->queue_size,
729 bq_consumer->width, bq_consumer->height);
730 }
731
732 return;
733
734on_error:
735 if (bq) bq_object_unref(BQ_OBJECT(bq));
736 if (bq_provider) bq_object_unref(BQ_OBJECT(bq_provider));
737 wl_client_post_no_memory(client);
738}
739
740static const struct bq_mgr_interface _bq_mgr_interface =
741{
742 bq_mgr_buffer_queue_create_consumer,
743 bq_mgr_buffer_queue_create_provider
744};
745
746static void
747bq_mgr_buffer_queue_bind(struct wl_client *client, void *data,
748 uint32_t version EINA_UNUSED, uint32_t id)
749{
750 Bq_Mgr *bq_mgr = (Bq_Mgr*)data;
751 struct wl_resource *resource;
752
753 resource = wl_resource_create(client, &bq_mgr_interface,
754 1, id);
755 if (resource == NULL) {
756 wl_client_post_no_memory(client);
757 return;
758 }
759
760 wl_resource_set_implementation(resource,
761 &_bq_mgr_interface,
762 bq_mgr, NULL);
763}
764
765Eina_Bool
766bq_mgr_buffer_queue_manager_init(Bq_Mgr *bq_mgr)
767{
768 EINA_SAFETY_ON_NULL_RETURN_VAL(bq_mgr,EINA_FALSE);
769 bq_mgr->bq_mgr = wl_global_create(bq_mgr->wdpy
770 ,&bq_mgr_interface,1
771 ,bq_mgr
772 ,bq_mgr_buffer_queue_bind);
773
774 EINA_SAFETY_ON_NULL_RETURN_VAL(bq_mgr->bq_mgr,EINA_FALSE);
775
776 bq_mgr->buffer_queues = eina_hash_string_superfast_new(NULL);
777 EINA_SAFETY_ON_NULL_RETURN_VAL(bq_mgr->buffer_queues,EINA_FALSE);
778
779 return EINA_TRUE;
780}
781
782static const Ecore_Getopt optdesc =
783{
784 "tbm_daemon",
785 "%prog [options]",
786 "0.1.0",
787 "(C) Samsung",
788 "BSD 2-Clause",
789 "Tizen Buffer Manager Daemon",
790 EINA_FALSE,
791 {
792 ECORE_GETOPT_STORE_STR('s', "socket_name",
793 "socket name"),
794 ECORE_GETOPT_STORE_BOOL('d',"debug","enable debug log"),
795 ECORE_GETOPT_VERSION('v', "version"),
796 ECORE_GETOPT_HELP('h', "help"),
797 ECORE_GETOPT_SENTINEL
798 }
799};
800
801static int
802bq_mgr_on_term_signal(int signal_number, void *data)
803{
804 Bq_Mgr *bq_mgr = data;
805
806 BQ_LOG("caught signal %d\n", signal_number);
807 wl_display_terminate(bq_mgr->wdpy);
808
809 return 1;
810}
811
812static void
813bq_mgr_free(Bq_Mgr *bq_mgr)
814{
815 int i;
816
817 for (i = ARRAY_LENGTH(bq_mgr->signals) - 1; i >= 0; i--)
818 {
819 if (bq_mgr->signals[i])
820 wl_event_source_remove(bq_mgr->signals[i]);
821 }
822
823 if (bq_mgr->wdpy)
824 wl_display_destroy(bq_mgr->wdpy);
825}
826
827static Bq_Mgr*
828bq_mgr_new(char *sock_name)
829{
830 static char *default_sock_name = "bq_mgr_daemon";
831 Bq_Mgr *bq_mgr = BQ_OBJECT_NEW(Bq_Mgr, bq_mgr_free);
832 struct wl_event_loop *loop;
833
834 if (!bq_mgr) return NULL;
835
836 bq_mgr->wdpy = wl_display_create();
837 loop = wl_display_get_event_loop(bq_mgr->wdpy);
838 EINA_SAFETY_ON_NULL_GOTO(loop, on_err);
839
840 bq_mgr->signals[0] = wl_event_loop_add_signal(loop, SIGTERM, bq_mgr_on_term_signal, bq_mgr);
841 bq_mgr->signals[1] = wl_event_loop_add_signal(loop, SIGINT, bq_mgr_on_term_signal, bq_mgr);
842 bq_mgr->signals[2] = wl_event_loop_add_signal(loop, SIGQUIT, bq_mgr_on_term_signal, bq_mgr);
843
844 if (!sock_name)
845 sock_name = default_sock_name;
846 wl_display_add_socket(bq_mgr->wdpy, sock_name);
847
848 return bq_mgr;
849
850on_err:
851 bq_object_free(BQ_OBJECT(bq_mgr));
852 return NULL;
853}
854
855int
856main(int argc, char **argv)
857{
858 Bq_Mgr *bq_mgr = NULL;
859 int res, ret = EXIT_FAILURE;
860 char *opt_path = NULL;
861 Eina_Bool quit = EINA_FALSE;
862 Ecore_Getopt_Value values[] =
863 {
864 ECORE_GETOPT_VALUE_STR(opt_path),
865 ECORE_GETOPT_VALUE_BOOL(debug),
866 ECORE_GETOPT_VALUE_BOOL(quit),
867 ECORE_GETOPT_VALUE_BOOL(quit),
868 ECORE_GETOPT_VALUE_NONE
869 };
870
871 eina_init();
872
873 res = ecore_getopt_parse(&optdesc,
874 values,
875 argc, argv);
876
877 if ((res < 0) || (quit)) goto finish;
878
879 if (opt_path)
880 BQ_LOG("socket_name : %s\n", opt_path);
881
882 bq_mgr = bq_mgr_new(opt_path);
883 if (!bq_mgr) goto finish;
884
885 if (!bq_mgr_buffer_queue_manager_init(bq_mgr))
886 {
887 bq_mgr_free(bq_mgr);
888 goto finish;
889 }
890
891 wl_display_run(bq_mgr->wdpy);
892
893 ret = EXIT_SUCCESS;
894finish:
895 eina_shutdown();
896 bq_object_free(BQ_OBJECT(bq_mgr));
897
898 return ret;
899}
diff --git a/src/bin/ecore_buffer/bq_mgr_protocol.c b/src/bin/ecore_buffer/bq_mgr_protocol.c
new file mode 100644
index 0000000000..fe8b98c9bc
--- /dev/null
+++ b/src/bin/ecore_buffer/bq_mgr_protocol.c
@@ -0,0 +1,131 @@
1#include <stdlib.h>
2#include <stdint.h>
3#include "wayland-util.h"
4
5extern const struct wl_interface bq_buffer_interface;
6extern const struct wl_interface bq_consumer_interface;
7extern const struct wl_interface bq_provider_interface;
8
9static const struct wl_interface *types[] = {
10 NULL,
11 NULL,
12 NULL,
13 &bq_consumer_interface,
14 NULL,
15 NULL,
16 NULL,
17 NULL,
18 &bq_provider_interface,
19 NULL,
20 &bq_buffer_interface,
21 &bq_buffer_interface,
22 NULL,
23 NULL,
24 NULL,
25 NULL,
26 NULL,
27 &bq_buffer_interface,
28 NULL,
29 NULL,
30 NULL,
31 NULL,
32 NULL,
33 NULL,
34 NULL,
35 &bq_buffer_interface,
36 NULL,
37 NULL,
38 NULL,
39 NULL,
40 NULL,
41 NULL,
42 NULL,
43 &bq_buffer_interface,
44 &bq_buffer_interface,
45 NULL,
46 &bq_buffer_interface,
47 NULL,
48 NULL,
49 NULL,
50 NULL,
51 NULL,
52 &bq_buffer_interface,
53 NULL,
54 NULL,
55 NULL,
56 NULL,
57 NULL,
58 NULL,
59 NULL,
60 &bq_buffer_interface,
61 NULL,
62 NULL,
63 NULL,
64 NULL,
65 NULL,
66 NULL,
67 NULL,
68 &bq_buffer_interface,
69 &bq_buffer_interface,
70 NULL,
71 &bq_buffer_interface,
72 NULL,
73};
74
75static const struct wl_message bq_mgr_requests[] = {
76 { "create_consumer", "nsiii", types + 3 },
77 { "create_provider", "ns", types + 8 },
78};
79
80WL_EXPORT const struct wl_interface bq_mgr_interface = {
81 "bq_mgr", 1,
82 2, bq_mgr_requests,
83 0, NULL,
84};
85
86static const struct wl_message bq_consumer_requests[] = {
87 { "release_buffer", "o", types + 10 },
88};
89
90static const struct wl_message bq_consumer_events[] = {
91 { "connected", "", types + 0 },
92 { "disconnected", "", types + 0 },
93 { "buffer_attached", "nsiiiu", types + 11 },
94 { "set_buffer_id", "oiiiiiii", types + 17 },
95 { "set_buffer_fd", "ohiiiiii", types + 25 },
96 { "buffer_detached", "o", types + 33 },
97 { "add_buffer", "ou", types + 34 },
98};
99
100WL_EXPORT const struct wl_interface bq_consumer_interface = {
101 "bq_consumer", 1,
102 1, bq_consumer_requests,
103 7, bq_consumer_events,
104};
105
106static const struct wl_message bq_provider_requests[] = {
107 { "attach_buffer", "nsiiiu", types + 36 },
108 { "set_buffer_id", "oiiiiiii", types + 42 },
109 { "set_buffer_fd", "ohiiiiii", types + 50 },
110 { "detach_buffer", "o", types + 58 },
111 { "enqueue_buffer", "ou", types + 59 },
112};
113
114static const struct wl_message bq_provider_events[] = {
115 { "connected", "iii", types + 0 },
116 { "disconnected", "", types + 0 },
117 { "add_buffer", "ou", types + 61 },
118};
119
120WL_EXPORT const struct wl_interface bq_provider_interface = {
121 "bq_provider", 1,
122 5, bq_provider_requests,
123 3, bq_provider_events,
124};
125
126WL_EXPORT const struct wl_interface bq_buffer_interface = {
127 "bq_buffer", 1,
128 0, NULL,
129 0, NULL,
130};
131
diff --git a/src/bin/ecore_buffer/bq_mgr_protocol.h b/src/bin/ecore_buffer/bq_mgr_protocol.h
new file mode 100644
index 0000000000..b2d7bcc775
--- /dev/null
+++ b/src/bin/ecore_buffer/bq_mgr_protocol.h
@@ -0,0 +1,247 @@
1#ifndef BQ_MGR_SERVER_PROTOCOL_H
2#define BQ_MGR_SERVER_PROTOCOL_H
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#include <stdint.h>
9#include <stddef.h>
10#include "wayland-server.h"
11
12struct wl_client;
13struct wl_resource;
14
15struct bq_mgr;
16struct bq_consumer;
17struct bq_provider;
18struct bq_buffer;
19
20extern const struct wl_interface bq_mgr_interface;
21extern const struct wl_interface bq_consumer_interface;
22extern const struct wl_interface bq_provider_interface;
23extern const struct wl_interface bq_buffer_interface;
24
25#ifndef BQ_MGR_ERROR_ENUM
26#define BQ_MGR_ERROR_ENUM
27enum bq_mgr_error {
28 BQ_MGR_ERROR_INVALID_PERMISSION = 0,
29 BQ_MGR_ERROR_INVALID_NAME = 1,
30 BQ_MGR_ERROR_ALREADY_USED = 2,
31};
32#endif /* BQ_MGR_ERROR_ENUM */
33
34struct bq_mgr_interface {
35 /**
36 * create_consumer - (none)
37 * @id: (none)
38 * @name: (none)
39 * @queue_size: (none)
40 * @width: (none)
41 * @height: (none)
42 */
43 void (*create_consumer)(struct wl_client *client,
44 struct wl_resource *resource,
45 uint32_t id,
46 const char *name,
47 int32_t queue_size,
48 int32_t width,
49 int32_t height);
50 /**
51 * create_provider - (none)
52 * @id: (none)
53 * @name: (none)
54 */
55 void (*create_provider)(struct wl_client *client,
56 struct wl_resource *resource,
57 uint32_t id,
58 const char *name);
59};
60
61
62struct bq_consumer_interface {
63 /**
64 * release_buffer - (none)
65 * @buffer: (none)
66 */
67 void (*release_buffer)(struct wl_client *client,
68 struct wl_resource *resource,
69 struct wl_resource *buffer);
70};
71
72#define BQ_CONSUMER_CONNECTED 0
73#define BQ_CONSUMER_DISCONNECTED 1
74#define BQ_CONSUMER_BUFFER_ATTACHED 2
75#define BQ_CONSUMER_SET_BUFFER_ID 3
76#define BQ_CONSUMER_SET_BUFFER_FD 4
77#define BQ_CONSUMER_BUFFER_DETACHED 5
78#define BQ_CONSUMER_ADD_BUFFER 6
79
80#define BQ_CONSUMER_CONNECTED_SINCE_VERSION 1
81#define BQ_CONSUMER_DISCONNECTED_SINCE_VERSION 1
82#define BQ_CONSUMER_BUFFER_ATTACHED_SINCE_VERSION 1
83#define BQ_CONSUMER_SET_BUFFER_ID_SINCE_VERSION 1
84#define BQ_CONSUMER_SET_BUFFER_FD_SINCE_VERSION 1
85#define BQ_CONSUMER_BUFFER_DETACHED_SINCE_VERSION 1
86#define BQ_CONSUMER_ADD_BUFFER_SINCE_VERSION 1
87
88static inline void
89bq_consumer_send_connected(struct wl_resource *resource_)
90{
91 wl_resource_post_event(resource_, BQ_CONSUMER_CONNECTED);
92}
93
94static inline void
95bq_consumer_send_disconnected(struct wl_resource *resource_)
96{
97 wl_resource_post_event(resource_, BQ_CONSUMER_DISCONNECTED);
98}
99
100static inline void
101bq_consumer_send_buffer_attached(struct wl_resource *resource_, struct wl_resource *buffer, const char *engine, int32_t width, int32_t height, int32_t format, uint32_t flags)
102{
103 wl_resource_post_event(resource_, BQ_CONSUMER_BUFFER_ATTACHED, buffer, engine, width, height, format, flags);
104}
105
106static inline void
107bq_consumer_send_set_buffer_id(struct wl_resource *resource_, struct wl_resource *buffer, int32_t id, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
108{
109 wl_resource_post_event(resource_, BQ_CONSUMER_SET_BUFFER_ID, buffer, id, offset0, stride0, offset1, stride1, offset2, stride2);
110}
111
112static inline void
113bq_consumer_send_set_buffer_fd(struct wl_resource *resource_, struct wl_resource *buffer, int32_t fd, int32_t offset0, int32_t stride0, int32_t offset1, int32_t stride1, int32_t offset2, int32_t stride2)
114{
115 wl_resource_post_event(resource_, BQ_CONSUMER_SET_BUFFER_FD, buffer, fd, offset0, stride0, offset1, stride1, offset2, stride2);
116}
117
118static inline void
119bq_consumer_send_buffer_detached(struct wl_resource *resource_, struct wl_resource *buffer)
120{
121 wl_resource_post_event(resource_, BQ_CONSUMER_BUFFER_DETACHED, buffer);
122}
123
124static inline void
125bq_consumer_send_add_buffer(struct wl_resource *resource_, struct wl_resource *buffer, uint32_t serial)
126{
127 wl_resource_post_event(resource_, BQ_CONSUMER_ADD_BUFFER, buffer, serial);
128}
129
130#ifndef BQ_PROVIDER_ERROR_ENUM
131#define BQ_PROVIDER_ERROR_ENUM
132enum bq_provider_error {
133 BQ_PROVIDER_ERROR_OVERFLOW_QUEUE_SIZE = 0,
134 BQ_PROVIDER_ERROR_CONNECTION = 1,
135};
136#endif /* BQ_PROVIDER_ERROR_ENUM */
137
138struct bq_provider_interface {
139 /**
140 * attach_buffer - (none)
141 * @buffer: (none)
142 * @engine: (none)
143 * @width: (none)
144 * @height: (none)
145 * @format: (none)
146 * @flags: (none)
147 */
148 void (*attach_buffer)(struct wl_client *client,
149 struct wl_resource *resource,
150 uint32_t buffer,
151 const char *engine,
152 int32_t width,
153 int32_t height,
154 int32_t format,
155 uint32_t flags);
156 /**
157 * set_buffer_id - (none)
158 * @buffer: (none)
159 * @id: (none)
160 * @offset0: (none)
161 * @stride0: (none)
162 * @offset1: (none)
163 * @stride1: (none)
164 * @offset2: (none)
165 * @stride2: (none)
166 */
167 void (*set_buffer_id)(struct wl_client *client,
168 struct wl_resource *resource,
169 struct wl_resource *buffer,
170 int32_t id,
171 int32_t offset0,
172 int32_t stride0,
173 int32_t offset1,
174 int32_t stride1,
175 int32_t offset2,
176 int32_t stride2);
177 /**
178 * set_buffer_fd - (none)
179 * @buffer: (none)
180 * @fd: (none)
181 * @offset0: (none)
182 * @stride0: (none)
183 * @offset1: (none)
184 * @stride1: (none)
185 * @offset2: (none)
186 * @stride2: (none)
187 */
188 void (*set_buffer_fd)(struct wl_client *client,
189 struct wl_resource *resource,
190 struct wl_resource *buffer,
191 int32_t fd,
192 int32_t offset0,
193 int32_t stride0,
194 int32_t offset1,
195 int32_t stride1,
196 int32_t offset2,
197 int32_t stride2);
198 /**
199 * detach_buffer - (none)
200 * @buffer: (none)
201 */
202 void (*detach_buffer)(struct wl_client *client,
203 struct wl_resource *resource,
204 struct wl_resource *buffer);
205 /**
206 * enqueue_buffer - (none)
207 * @buffer: (none)
208 * @serial: (none)
209 */
210 void (*enqueue_buffer)(struct wl_client *client,
211 struct wl_resource *resource,
212 struct wl_resource *buffer,
213 uint32_t serial);
214};
215
216#define BQ_PROVIDER_CONNECTED 0
217#define BQ_PROVIDER_DISCONNECTED 1
218#define BQ_PROVIDER_ADD_BUFFER 2
219
220#define BQ_PROVIDER_CONNECTED_SINCE_VERSION 1
221#define BQ_PROVIDER_DISCONNECTED_SINCE_VERSION 1
222#define BQ_PROVIDER_ADD_BUFFER_SINCE_VERSION 1
223
224static inline void
225bq_provider_send_connected(struct wl_resource *resource_, int32_t queue_size, int32_t width, int32_t height)
226{
227 wl_resource_post_event(resource_, BQ_PROVIDER_CONNECTED, queue_size, width, height);
228}
229
230static inline void
231bq_provider_send_disconnected(struct wl_resource *resource_)
232{
233 wl_resource_post_event(resource_, BQ_PROVIDER_DISCONNECTED);
234}
235
236static inline void
237bq_provider_send_add_buffer(struct wl_resource *resource_, struct wl_resource *buffer, uint32_t serial)
238{
239 wl_resource_post_event(resource_, BQ_PROVIDER_ADD_BUFFER, buffer, serial);
240}
241
242
243#ifdef __cplusplus
244}
245#endif
246
247#endif