Package version up to 0.8.8
[platform/core/uifw/wayland-tbm.git] / test / tbm-client-queue-test.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5
6 #define WL_HIDE_DEPRECATED
7 #include <wayland-client.h>
8 #include <wayland-tbm-client.h>
9 #include <wayland-tbm-int.h>
10
11 #include <tbm_surface.h>
12 #include <tbm_surface_queue.h>
13 #include <tbm_surface_internal.h>
14
15 #include "wayland-tbm-test-client-protocol.h"
16
17 #define WL_APP_C_LOG(fmt, ...)   fprintf(stderr, "[CLIENT(%d):%s] " fmt, getpid(), __func__, ##__VA_ARGS__)
18
19 typedef struct {
20         struct wayland_tbm_client *tbm_client;
21         struct wl_tbm_test *wl_tbm_test;
22         struct wl_test_surface *surface;
23         tbm_surface_queue_h surface_queue;
24
25         int try_draw;
26         int exit;
27         int count;
28 } AppInfoClient;
29
30 typedef struct {
31         tbm_surface_h buffer;
32         tbm_surface_queue_h surface_queue;
33         struct wl_buffer *wl_buffer;
34 } AppBuffer;
35
36 AppInfoClient gApp;
37 static void _drawing_surface(AppInfoClient *app);
38
39 static void
40 _create_surface_and_queue(AppInfoClient *app)
41 {
42         app->surface = wl_tbm_test_create_surface(app->wl_tbm_test);
43         app->surface_queue = wayland_tbm_client_create_surface_queue(app->tbm_client,
44                              (struct wl_surface *)app->surface, 3, 100, 100,
45                              TBM_FORMAT_ABGR8888);
46         WL_APP_C_LOG("surface:%p, surface_queue:%p\n", app->surface,
47                      app->surface_queue);
48         return;
49 }
50
51 static void
52 _destroy_surface_and_queue(AppInfoClient *app)
53 {
54         tbm_surface_queue_destroy(app->surface_queue);
55         wl_test_surface_destroy(app->surface);
56
57         WL_APP_C_LOG("surface:%p, surface_queue:%p\n", app->surface,
58                      app->surface_queue);
59
60         return;
61 }
62
63 static const int key_app_buffer;
64
65 static struct wl_buffer *
66 _get_wl_buffer(tbm_surface_h buffer)
67 {
68         AppBuffer *app_buffer = NULL;
69
70         tbm_surface_internal_get_user_data(buffer,
71                                            (unsigned long)&key_app_buffer,
72                                            (void **)&app_buffer);
73
74         if (!app_buffer)
75                 return (struct wl_buffer *)NULL;
76
77         return app_buffer->wl_buffer;
78 }
79
80 static void
81 _set_wl_buffer(tbm_surface_h buffer, AppBuffer *app_buffer)
82 {
83         tbm_surface_internal_add_user_data(buffer,
84                                            (unsigned long)&key_app_buffer,
85                                            NULL);
86         tbm_surface_internal_set_user_data(buffer,
87                                            (unsigned long)&key_app_buffer,
88                                            (void *)app_buffer);
89 }
90
91 static void
92 _cb_wl_buffer_release_callback(void *data, struct wl_buffer *wl_buffer)
93 {
94         AppBuffer *app_buffer = data;
95
96         tbm_surface_queue_release(app_buffer->surface_queue, app_buffer->buffer);
97         WL_APP_C_LOG("RELEASE queue:%p, tbm_surface:%p\n", app_buffer->surface_queue,
98                      app_buffer->buffer);
99 }
100
101 static const struct wl_buffer_listener buffer_release_listener = {
102         _cb_wl_buffer_release_callback
103 };
104
105 static void
106 _cb_wl_callback_surface_frame_done(void *data,
107                                     struct wl_callback *wl_callback,
108                                     uint32_t callback_data)
109 {
110         AppInfoClient *app = data;
111
112         WL_APP_C_LOG("FRAME DONE\n");
113         _drawing_surface(app);
114         wl_callback_destroy(wl_callback);
115 }
116
117 static const struct wl_callback_listener surface_callback_listener = {
118         _cb_wl_callback_surface_frame_done
119 };
120
121 static void
122 _drawing_surface(AppInfoClient *app)
123 {
124         tbm_surface_queue_h surface_queue = app->surface_queue;
125         tbm_surface_h buffer = NULL;
126         tbm_surface_info_s info;
127         struct wl_buffer *wl_buffer;
128         struct wl_callback *wl_callback;
129
130         app->count++;
131         if (app->count == 10)
132                 app->exit = 1;
133
134         if (!tbm_surface_queue_can_dequeue(surface_queue, 0)) {
135                 WL_APP_C_LOG("Wait free_buffer\n");
136                 app->try_draw = 1;
137                 return;
138         } else {
139                 app->try_draw = 0;
140         }
141
142         tbm_surface_queue_dequeue(surface_queue, &buffer);
143         if (buffer == NULL) {
144                 WL_APP_C_LOG("Failed to dequeue_buffer\n");
145                 return;
146         }
147         //WL_APP_C_LOG("DEQUEUE queue:%p, tbm_surface:%p\n", app->surface_queue, buffer);
148
149         tbm_surface_map(buffer, TBM_OPTION_READ | TBM_OPTION_WRITE, &info);
150         WL_APP_C_LOG("\tDraw: buf:%p\n", buffer);
151         tbm_surface_unmap(buffer);
152         tbm_surface_queue_enqueue(app->surface_queue, buffer);
153         //WL_APP_C_LOG("ENQUEUE queue:%p, tbm_surface:%p\n", app->surface_queue, buffer);
154
155         tbm_surface_queue_acquire(app->surface_queue, &buffer);
156         //WL_APP_C_LOG("ACQUIRE queue:%p, tbm_surface:%p\n", app->surface_queue, buffer);
157         wl_buffer = _get_wl_buffer(buffer);
158         if (!wl_buffer) {
159                 AppBuffer *app_buffer = calloc(1, sizeof(AppBuffer));
160
161                 wl_buffer = wayland_tbm_client_create_buffer(app->tbm_client, buffer);
162                 wl_buffer_add_listener(wl_buffer, &buffer_release_listener, (void *)app_buffer);
163
164                 app_buffer->wl_buffer = wl_buffer;
165                 app_buffer->surface_queue = app->surface_queue;
166                 app_buffer->buffer = buffer;
167                 _set_wl_buffer(buffer, app_buffer);
168                 WL_APP_C_LOG("\tCreate NEW wl_buffer: buf:%p\n", buffer);
169         }
170
171         wl_callback = wl_test_surface_frame(app->surface);
172         wl_callback_add_listener(wl_callback, &surface_callback_listener, app);
173         wl_test_surface_attach(app->surface, wl_buffer);
174         //WL_APP_C_LOG("ATTACH wl_surface:%p, wl_buffer:%p\n", app->surface, wl_buffer);
175 }
176
177 static void
178 _wl_registry_global_cb(void *data,
179                        struct wl_registry *wl_registry,
180                        uint32_t name,
181                        const char *interface,
182                        uint32_t version)
183 {
184         AppInfoClient *app = (AppInfoClient *)data;
185
186         if (!strcmp(interface, "wl_tbm_test")) {
187                 WL_APP_C_LOG("bind %s", interface);
188                 app->wl_tbm_test = wl_registry_bind(wl_registry, name,
189                                                     &wl_tbm_test_interface, 1);
190         }
191 }
192
193 static void
194 _wl_registry_global_remove_cb(void *data,
195                               struct wl_registry *wl_registry,
196                               uint32_t name)
197 {
198 }
199
200 static const struct wl_registry_listener wl_registry_impl = {
201         _wl_registry_global_cb,
202         _wl_registry_global_remove_cb,
203 };
204
205 int
206 main(int argc, char *argv[])
207 {
208         struct wl_display *dpy = NULL;
209         struct wl_registry *registry;
210         const char *dpy_name = NULL;
211         const char *default_dpy_name = "queue";
212         int ret = 0;
213         tbm_bufmgr bufmgr = NULL;
214
215         if (argc > 1)
216                 dpy_name = argv[1];
217         else
218                 dpy_name = default_dpy_name;
219
220         dpy = wl_display_connect(dpy_name);
221         if (!dpy) {
222                 printf("[APP] failed to connect server\n");
223                 return -1;
224         }
225
226         registry = wl_display_get_registry(dpy);
227         wl_registry_add_listener(registry, &wl_registry_impl, &gApp);
228         wl_display_roundtrip(dpy);
229         if (gApp.wl_tbm_test == NULL) {
230                 WL_APP_C_LOG("fail to bind::wl_tbm_test");
231                 return 0;
232         }
233
234         gApp.tbm_client = wayland_tbm_client_init(dpy);
235         if (!gApp.tbm_client) {
236                 WL_APP_C_LOG("fail to wayland_tbm_client_init()\n");
237                 goto finish;
238         }
239         bufmgr = tbm_bufmgr_init(-1);
240         tbm_bufmgr_debug_show(bufmgr);
241
242         _create_surface_and_queue(&gApp);
243         _drawing_surface(&gApp);
244         while (ret >= 0 && gApp.exit == 0) {
245                 ret = wl_display_dispatch(dpy);
246                 if (gApp.try_draw)
247                         _drawing_surface(&gApp);
248         }
249
250         tbm_bufmgr_debug_show(bufmgr);
251 finish:
252         if (gApp.surface)
253                 _destroy_surface_and_queue(&gApp);
254         if (bufmgr)
255                 tbm_bufmgr_debug_show(bufmgr);
256         return 1;
257 }