support client API for wait_vblank
[platform/core/uifw/libtdm.git] / src / tdm_private.h
1 /**************************************************************************
2
3 libtdm
4
5 Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: Eunchul Kim <chulspro.kim@samsung.com>,
8          JinYoung Jeon <jy0.jeon@samsung.com>,
9          Taeheon Kim <th908.kim@samsung.com>,
10          YoungJun Cho <yj44.cho@samsung.com>,
11          SooChan Lim <sc1.lim@samsung.com>,
12          Boram Park <sc1.lim@samsung.com>
13
14 Permission is hereby granted, free of charge, to any person obtaining a
15 copy of this software and associated documentation files (the
16 "Software"), to deal in the Software without restriction, including
17 without limitation the rights to use, copy, modify, merge, publish,
18 distribute, sub license, and/or sell copies of the Software, and to
19 permit persons to whom the Software is furnished to do so, subject to
20 the following conditions:
21
22 The above copyright notice and this permission notice (including the
23 next paragraph) shall be included in all copies or substantial portions
24 of the Software.
25
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
27 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
29 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
30 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
31 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
32 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33
34 **************************************************************************/
35
36 #ifndef _TDM_PRIVATE_H_
37 #define _TDM_PRIVATE_H_
38
39 #include <stdio.h>
40 #include <string.h>
41 #include <stdlib.h>
42 #include <pthread.h>
43 #include <errno.h>
44 #include <unistd.h>
45 #include <limits.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <fcntl.h>
49 #include <dlfcn.h>
50 #include <dirent.h>
51 #include <poll.h>
52 #include <sys/syscall.h>
53 #include <sys/types.h>
54
55 #include <tbm_bufmgr.h>
56 #include <tbm_surface_queue.h>
57
58 #include "tdm_backend.h"
59 #include "tdm_log.h"
60 #include "tdm_list.h"
61 #include "tdm_macro.h"
62
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66
67 //#define INIT_BUFMGR
68
69 /**
70  * @file tdm_private.h
71  * @brief The private header file for a frontend library
72  */
73
74 extern int tdm_debug_buffer;
75 extern int tdm_debug_mutex;
76 extern int tdm_debug_thread;
77
78 #ifdef HAVE_TTRACE
79 #include <ttrace.h>
80 #define TDM_TRACE_BEGIN(NAME) traceBegin(TTRACE_TAG_GRAPHICS, "TDM:"#NAME)
81 #define TDM_TRACE_END() traceEnd(TTRACE_TAG_GRAPHICS)
82 #else
83 #define TDM_TRACE_BEGIN(NAME)
84 #define TDM_TRACE_END()
85 #endif
86
87 typedef enum {
88         TDM_CAPTURE_TARGET_OUTPUT,
89         TDM_CAPTURE_TARGET_LAYER,
90 } tdm_capture_target;
91
92 typedef struct _tdm_private_display tdm_private_display;
93 typedef struct _tdm_private_output tdm_private_output;
94 typedef struct _tdm_private_layer tdm_private_layer;
95 typedef struct _tdm_private_pp tdm_private_pp;
96 typedef struct _tdm_private_capture tdm_private_capture;
97 typedef struct _tdm_private_loop tdm_private_loop;
98 typedef struct _tdm_private_server tdm_private_server;
99 typedef struct _tdm_private_thread tdm_private_thread;
100 typedef struct _tdm_private_vblank_handler tdm_private_vblank_handler;
101 typedef struct _tdm_private_commit_handler tdm_private_commit_handler;
102 typedef struct _tdm_private_change_handler tdm_private_change_handler;
103
104 struct _tdm_private_display {
105         pthread_mutex_t lock;
106         unsigned int init_count;
107
108         /* backend module info */
109         void *module;
110         tdm_backend_module *module_data;
111         tdm_backend_data *bdata;
112
113 #ifdef INIT_BUFMGR
114         tbm_bufmgr bufmgr;
115 #endif
116
117         /* backend function */
118         tdm_display_capability capabilities;
119         tdm_func_display func_display;
120         tdm_func_output func_output;
121         tdm_func_layer func_layer;
122         tdm_func_pp func_pp;
123         tdm_func_capture func_capture;
124
125         /* backend capability */
126         tdm_caps_display caps_display;
127         tdm_caps_pp caps_pp;
128         tdm_caps_capture caps_capture;
129
130         /* output, pp list */
131         struct list_head output_list;
132         struct list_head pp_list;
133         struct list_head capture_list;
134
135         void **outputs_ptr;
136
137         /* for event handling */
138         tdm_private_loop *private_loop;
139 };
140
141 struct _tdm_private_output {
142         struct list_head link;
143
144         unsigned long stamp;
145
146         tdm_private_display *private_display;
147
148         tdm_caps_output caps;
149         tdm_output *output_backend;
150
151         unsigned int pipe;
152
153         int regist_vblank_cb;
154         int regist_commit_cb;
155         int regist_change_cb;
156
157         struct list_head layer_list;
158         struct list_head capture_list;
159         struct list_head vblank_handler_list;
160         struct list_head commit_handler_list;
161
162         /* seperate list for multi-thread*/
163         struct list_head change_handler_list_main;
164         struct list_head change_handler_list_sub;
165
166         void **layers_ptr;
167 };
168
169 struct _tdm_private_layer {
170         struct list_head link;
171
172         tdm_private_display *private_display;
173         tdm_private_output *private_output;
174
175         tdm_caps_layer caps;
176         tdm_layer *layer_backend;
177
178         tbm_surface_h pending_buffer;
179         tbm_surface_h waiting_buffer;
180         tbm_surface_h showing_buffer;
181         tbm_surface_queue_h buffer_queue;
182
183         struct list_head capture_list;
184
185         unsigned int usable;
186 };
187
188 struct _tdm_private_pp {
189         struct list_head link;
190
191         unsigned long stamp;
192
193         tdm_private_display *private_display;
194
195         tdm_pp *pp_backend;
196
197         struct list_head src_pending_buffer_list;
198         struct list_head dst_pending_buffer_list;
199         struct list_head src_buffer_list;
200         struct list_head dst_buffer_list;
201
202         pid_t owner_tid;
203 };
204
205 struct _tdm_private_capture {
206         struct list_head link;
207         struct list_head display_link;
208
209         unsigned long stamp;
210
211         tdm_capture_target target;
212
213         tdm_private_display *private_display;
214         tdm_private_output *private_output;
215         tdm_private_layer *private_layer;
216
217         tdm_capture *capture_backend;
218
219         struct list_head pending_buffer_list;
220         struct list_head buffer_list;
221
222         pid_t owner_tid;
223 };
224
225 /* CAUTION:
226  * Note that this structure is not thread-safe. If there is no TDM thread, all
227  * TDM resources are protected by private_display's lock. If there is a TDM
228  * thread, this struct will be used only in a TDM thread. So, we don't need to
229  * protect this structure.
230  */
231 struct _tdm_private_loop {
232         /* TDM uses wl_event_loop to handle various event sources including the TDM
233          * backend's fd.
234          */
235         struct wl_display *wl_display;
236         struct wl_event_loop *wl_loop;
237
238         int backend_fd;
239         tdm_event_loop_source *backend_source;
240
241         /* In event loop, all resources are accessed by this dpy.
242          * CAUTION:
243          * - DO NOT include other private structure in this structure because this
244          *   struct is not thread-safe.
245          */
246         tdm_display *dpy;
247
248         /* for handling TDM client requests */
249         tdm_private_server *private_server;
250
251         /* To have a TDM event thread. If TDM_THREAD enviroment variable is not set
252          * private_thread is NULL.
253          */
254         tdm_private_thread *private_thread;
255 };
256
257 struct _tdm_private_vblank_handler {
258         struct list_head link;
259
260         tdm_private_output *private_output;
261         tdm_output_vblank_handler func;
262         void *user_data;
263
264         pid_t owner_tid;
265 };
266
267 struct _tdm_private_commit_handler {
268         struct list_head link;
269
270         tdm_private_output *private_output;
271         tdm_output_commit_handler func;
272         void *user_data;
273
274         pid_t owner_tid;
275 };
276
277 struct _tdm_private_change_handler {
278         struct list_head link;
279
280         tdm_private_output *private_output;
281         tdm_output_change_handler func;
282         void *user_data;
283
284         pid_t owner_tid;
285 };
286
287 typedef struct _tdm_buffer_info {
288         tbm_surface_h buffer;
289
290         /* ref_count for backend */
291         int backend_ref_count;
292
293         struct list_head release_funcs;
294         struct list_head destroy_funcs;
295
296         struct list_head *list;
297         struct list_head link;
298 } tdm_buffer_info;
299
300 tdm_private_output *
301 tdm_display_find_output_stamp(tdm_private_display *private_display,
302                               unsigned long stamp);
303 tdm_private_pp *
304 tdm_pp_find_stamp(tdm_private_display *private_display, unsigned long stamp);
305 tdm_private_capture *
306 tdm_capture_find_stamp(tdm_private_display *private_display, unsigned long stamp);
307
308 void
309 tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence,
310                      unsigned int tv_sec, unsigned int tv_usec, void *user_data);
311 void
312 tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence,
313                      unsigned int tv_sec, unsigned int tv_usec, void *user_data);
314 void
315 tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status,
316                      void *user_data);
317 void
318 tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst,
319                void *user_data);
320 void
321 tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer,
322                     void *user_data);
323
324 void
325 tdm_output_call_change_handler_internal(tdm_private_output *private_output,
326                                         struct list_head *change_handler_list,
327                                         tdm_output_change_type type,
328                                         tdm_value value);
329
330 tdm_private_pp *
331 tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error);
332 void
333 tdm_pp_destroy_internal(tdm_private_pp *private_pp);
334
335 tdm_private_capture *
336 tdm_capture_create_output_internal(tdm_private_output *private_output,
337                                    tdm_error *error);
338 tdm_private_capture *
339 tdm_capture_create_layer_internal(tdm_private_layer *private_layer,
340                                   tdm_error *error);
341 void
342 tdm_capture_destroy_internal(tdm_private_capture *private_capture);
343
344 /* utility buffer functions for private */
345 tdm_buffer_info*
346 tdm_buffer_get_info(tbm_surface_h buffer);
347 tbm_surface_h
348 tdm_buffer_list_get_first_entry(struct list_head *list);
349 void
350 tdm_buffer_list_dump(struct list_head *list);
351
352 /* event functions for private */
353 tdm_error
354 tdm_event_loop_init(tdm_private_display *private_display);
355 void
356 tdm_event_loop_deinit(tdm_private_display *private_display);
357 void
358 tdm_event_loop_create_backend_source(tdm_private_display *private_display);
359 int
360 tdm_event_loop_get_fd(tdm_private_display *private_display);
361 tdm_error
362 tdm_event_loop_dispatch(tdm_private_display *private_display);
363 void
364 tdm_event_loop_flush(tdm_private_display *private_display);
365
366 typedef enum {
367         TDM_THREAD_CB_NONE,
368         TDM_THREAD_CB_OUTPUT_COMMIT,
369         TDM_THREAD_CB_OUTPUT_VBLANK,
370         TDM_THREAD_CB_OUTPUT_STATUS,
371         TDM_THREAD_CB_PP_DONE,
372         TDM_THREAD_CB_CAPTURE_DONE,
373 } tdm_thread_cb_type;
374
375 typedef struct _tdm_thread_cb_base tdm_thread_cb_base;
376 typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_commit;
377 typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_vblank;
378 typedef struct _tdm_thread_cb_output_status tdm_thread_cb_output_status;
379 typedef struct _tdm_thread_cb_pp_done tdm_thread_cb_pp_done;
380 typedef struct _tdm_thread_cb_capture_done tdm_thread_cb_capture_done;
381
382 struct _tdm_thread_cb_base {
383         tdm_thread_cb_type type;
384         unsigned int length;
385 };
386
387 struct _tdm_thread_cb_output_vblank {
388         tdm_thread_cb_base base;
389         unsigned long output_stamp;
390         unsigned int sequence;
391         unsigned int tv_sec;
392         unsigned int tv_usec;
393         void *user_data;
394 };
395
396 struct _tdm_thread_cb_output_status {
397         tdm_thread_cb_base base;
398         unsigned long output_stamp;
399         tdm_output_conn_status status;
400         void *user_data;
401 };
402
403 struct _tdm_thread_cb_pp_done {
404         tdm_thread_cb_base base;
405         unsigned long pp_stamp;
406         tbm_surface_h src;
407         tbm_surface_h dst;
408         void *user_data;
409 };
410
411 struct _tdm_thread_cb_capture_done {
412         tdm_thread_cb_base base;
413         unsigned long capture_stamp;
414         tbm_surface_h buffer;
415         void *user_data;
416 };
417
418 tdm_error
419 tdm_thread_init(tdm_private_loop *private_loop);
420 void
421 tdm_thread_deinit(tdm_private_loop *private_loop);
422 int
423 tdm_thread_get_fd(tdm_private_loop *private_loop);
424 tdm_error
425 tdm_thread_send_cb(tdm_private_loop *private_loop, tdm_thread_cb_base *base);
426 tdm_error
427 tdm_thread_handle_cb(tdm_private_loop *private_loop);
428 int
429 tdm_thread_in_display_thread(tdm_private_loop *private_loop, pid_t tid);
430
431 tdm_error
432 tdm_server_init(tdm_private_loop *private_loop);
433 void
434 tdm_server_deinit(tdm_private_loop *private_loop);
435
436 unsigned long
437 tdm_helper_get_time_in_millis(void);
438 int
439 tdm_helper_unlock_in_cb(tdm_private_display *private_display);
440 void
441 tdm_helper_lock_in_cb(tdm_private_display *private_display, int need_lock);
442
443 #define _pthread_mutex_lock(l) \
444     do {if (tdm_debug_mutex) TDM_INFO("mutex lock"); pthread_mutex_lock(l);} while (0)
445 #define _pthread_mutex_unlock(l) \
446     do {if (tdm_debug_mutex) TDM_INFO("mutex unlock"); pthread_mutex_unlock(l);} while (0)
447
448 #ifdef __cplusplus
449 }
450 #endif
451
452 #endif /* _TDM_PRIVATE_H_ */