utils: Add missing vk_container_of macro
[platform/core/uifw/vulkan-wsi-tizen.git] / src / utils / utils.h
1 /*
2  * Copyright © 2016 S-Core Corporation
3  * Copyright © 2016-2017 Samsung Electronics co., Ltd. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * 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
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 #ifndef UTILS_H
26 #define UTILS_H
27
28 #include <config.h>
29 #include <assert.h>
30 #include <vulkan/vulkan.h>
31
32 #if defined(__GNUC__) && __GNUC__ >= 4
33 #define VK_EXPORT __attribute__((visibility("default")))
34 #else
35 #define VK_EXPORT
36 #endif
37
38 #ifndef MAX
39 #define MAX(a, b)       ((a) > (b) ? (a) : (b))
40 #endif
41
42 #ifndef MIN
43 #define MIN(a, b)       ((a) < (b) ? (a) : (b))
44 #endif
45
46 #ifndef ARRAY_LENGTH
47 #define ARRAY_LENGTH(a) (sizeof(a) / sizeof((a)[0]))
48 #endif
49
50 #define VK_ERROR(fmt, ...)                                                                                      \
51         do {                                                                                                                    \
52                 vk_log("ERROR", __FILE__, __LINE__, fmt, ##__VA_ARGS__);        \
53         } while (0)
54
55 #define VK_DEBUG(fmt, ...)                                                                                      \
56         do {                                                                                                                    \
57                 vk_log("DEBUG", __FILE__, __LINE__, fmt, ##__VA_ARGS__);        \
58         } while (0)
59
60 #define VK_CHECK(exp, action, fmt, ...)                                                         \
61         do {                                                                                                                    \
62                 if (!(exp))                                                                                                     \
63                 {                                                                                                                       \
64                         VK_ERROR(fmt, ##__VA_ARGS__);                                                   \
65                         action;                                                                                                 \
66                 }                                                                                                                       \
67         } while (0)
68
69 #define VK_ASSERT(exp)  assert(exp)
70
71 #define vk_container_of(ptr, sample, member)                                                                    \
72         (__typeof__(sample))((char *)(ptr) - offsetof(__typeof__(*sample), member))
73
74 typedef VkBool32        vk_bool_t;
75
76 void
77 vk_log(const char *domain, const char *file, int line, const char *format, ...);
78
79 /* Linked list. */
80 typedef struct vk_list vk_list_t;
81
82 #define vk_list_for_each_list(pos, head)                                                        \
83         for (pos = (head)->next;                                                                                \
84                  pos != (head);                                                                                         \
85                  pos = pos->next)
86
87 #define vk_list_for_each_list_safe(pos, tmp, head)                                      \
88         for (pos = (head)->next, tmp = pos->next;                                               \
89                  pos != (head);                                                                                         \
90                  pos = tmp, tmp = pos->next)
91
92 #define vk_list_for_each_list_reverse(pos, head)                                        \
93         for (pos = (head)->prev;                                                                                \
94                  pos != (head);                                                                                         \
95                  pos = pos->prev)
96
97 #define vk_list_for_each_list_reverse_safe(pos, tmp, head)                      \
98         for (pos = (head)->prev, tmp = pos->prev;                                               \
99                  pos != (head);                                                                                         \
100                  pos = tmp, tmp = pos->prev)
101
102 #define vk_list_for_each(pos, head, member)                                                     \
103         for (pos = vk_container_of((head)->next, pos, member);                  \
104                  &pos->member != (head);                                                                        \
105                  pos = vk_container_of(pos->member.next, pos, member))
106
107 #define vk_list_for_each_safe(pos, tmp, head, member)                           \
108         for (pos = vk_container_of((head)->next, pos, member),                  \
109                  tmp = vk_container_of((pos)->member.next, tmp, member);        \
110                  &pos->member != (head);                                                                        \
111                  pos = tmp,                                                                                                     \
112                  tmp = vk_container_of(pos->member.next, tmp, member))
113
114 #define vk_list_for_each_reverse(pos, head, member)                                     \
115         for (pos = vk_container_of((head)->prev, pos, member);                  \
116                  &pos->member != (head);                                                                        \
117                  pos = vk_container_of(pos->member.prev, pos, member))
118
119 #define vk_list_for_each_reverse_safe(pos, tmp, head, member)           \
120         for (pos = vk_container_of((head)->prev, pos, member),                  \
121                  tmp = vk_container_of((pos)->member.prev, tmp, member);        \
122                  &pos->member != (head);                                                                        \
123                  pos = tmp,                                                                                                     \
124                  tmp = vk_container_of(pos->member.prev, tmp, member))
125
126 struct vk_list
127 {
128         vk_list_t *prev;
129         vk_list_t *next;
130         void      *item;
131 };
132
133 static inline void
134 vk_list_init(vk_list_t *list)
135 {
136         list->prev = list;
137         list->next = list;
138         list->item = NULL;
139 }
140
141 static inline void
142 vk_list_insert(vk_list_t *list, vk_list_t *elm)
143 {
144         elm->prev = list;
145         elm->next = list->next;
146         list->next = elm;
147         elm->next->prev = elm;
148 }
149
150 static inline void
151 vk_list_remove(vk_list_t *list)
152 {
153         list->prev->next = list->next;
154         list->next->prev = list->prev;
155         list->prev = NULL;
156         list->next = NULL;
157 }
158
159 static inline vk_bool_t
160 vk_list_empty(const vk_list_t *list)
161 {
162         return list->next == list;
163 }
164
165 static inline void
166 vk_list_insert_list(vk_list_t *list, vk_list_t *other)
167 {
168         if (vk_list_empty(other))
169                 return;
170
171         other->next->prev = list;
172         other->prev->next = list->next;
173         list->next->prev = other->prev;
174         list->next = other->next;
175 }
176
177 /* Hash table. */
178 typedef struct vk_map           vk_map_t;
179 typedef struct vk_map_entry     vk_map_entry_t;
180
181 typedef void (*vk_free_func_t)(void *);
182 typedef int  (*vk_hash_func_t)(const void *key, int key_length);
183 typedef int  (*vk_key_length_func_t)(const void *key);
184 typedef int  (*vk_key_compare_func_t)(const void *key0, int len0, const void *key1, int len1);
185
186 struct vk_map
187 {
188         vk_hash_func_t                    hash_func;
189         vk_key_length_func_t      key_length_func;
190         vk_key_compare_func_t     key_compare_func;
191
192         int                                               bucket_bits;
193         int                                               bucket_size;
194         int                                               bucket_mask;
195         vk_map_entry_t                  **buckets;
196 };
197
198 void
199 vk_map_init(vk_map_t                            *map,
200                         int                                              bucket_bits,
201                         vk_hash_func_t                   hash_func,
202                         vk_key_length_func_t     key_length_func,
203                         vk_key_compare_func_t    key_compare_func,
204                         void                                    *buckets);
205
206 void
207 vk_map_int32_init(vk_map_t *map, int bucket_bits, void *buckets);
208
209 void
210 vk_map_int64_init(vk_map_t *map, int bucket_bits, void *buckets);
211
212 void
213 vk_map_string_init(vk_map_t *map, int bucket_bits, void *buckets);
214
215 void
216 vk_map_fini(vk_map_t *map);
217
218 vk_map_t *
219 vk_map_create(int                                       bucket_bits,
220                           vk_hash_func_t                hash_func,
221                           vk_key_length_func_t  key_length_func,
222                           vk_key_compare_func_t key_compare_func);
223
224 vk_map_t *
225 vk_map_int32_create(int bucket_bits);
226
227 vk_map_t *
228 vk_map_int64_create(int bucket_bits);
229
230 vk_map_t *
231 vk_map_string_create(int bucket_bits);
232
233 void
234 vk_map_destroy(vk_map_t *map);
235
236 void
237 vk_map_clear(vk_map_t *map);
238
239 void *
240 vk_map_get(vk_map_t *map, const void *key);
241
242 void
243 vk_map_set(vk_map_t *map, const void *key, void *data, vk_free_func_t free_func);
244
245 #endif  /* UTILS_H */