remove libds stuffs
[platform/core/uifw/libds-tizen.git] / src / tbm_server.c
1 #include <assert.h>
2 #include <stdbool.h>
3 #include <stdlib.h>
4
5 #include <tbm_bufmgr.h>
6
7 #include <libds/log.h>
8 #include "pixel_format.h"
9 #include "tbm_server.h"
10
11 static const struct ds_buffer_resource_interface tbm_buffer_resource_iface;
12 static const struct ds_buffer_interface tbm_client_buffer_iface;
13
14 static void tbm_server_handle_display_destroy(struct wl_listener *listener,
15         void *data);
16
17 WL_EXPORT struct ds_tbm_server *
18 ds_tbm_server_create(struct wl_display *display)
19 {
20     struct ds_tbm_server *tbm;
21     tbm_bufmgr bufmgr;
22
23     tbm = calloc(1, sizeof *tbm);
24     if (!tbm)
25         return NULL;
26
27     wl_signal_init(&tbm->events.destroy);
28
29     tbm->wl_tbm = wayland_tbm_server_init(display, NULL, -1, 0);
30     if (!tbm->wl_tbm) {
31         goto err_wl_tbm;
32     }
33
34     bufmgr = wayland_tbm_server_get_bufmgr(tbm->wl_tbm);
35     if (!bufmgr) {
36         goto err_bind;
37     }
38
39     if (!tbm_bufmgr_bind_native_display(bufmgr, (void *)display)) {
40         goto err_bind;
41     }
42
43     tbm->display_destroy.notify = tbm_server_handle_display_destroy;
44     wl_display_add_destroy_listener(display, &tbm->display_destroy);
45
46     ds_buffer_register_resource_interface(&tbm_buffer_resource_iface);
47
48     return tbm;
49
50 err_bind:
51     wayland_tbm_server_deinit(tbm->wl_tbm);
52 err_wl_tbm:
53     free(tbm);
54
55     return NULL;
56 }
57
58 WL_EXPORT void
59 ds_tbm_server_add_destroy_listener(struct ds_tbm_server *tbm,
60         struct wl_listener *listener)
61 {
62     wl_signal_add(&tbm->events.destroy, listener);
63 }
64
65 WL_EXPORT struct ds_tbm_client_buffer *
66 ds_tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer)
67 {
68     if (ds_buffer->iface != &tbm_client_buffer_iface)
69         return NULL;
70     return (struct ds_tbm_client_buffer *)ds_buffer;
71 }
72
73 WL_EXPORT tbm_surface_h
74 ds_tbm_client_buffer_get_tbm_surface(struct ds_tbm_client_buffer *buffer)
75 {
76     if (buffer->base.iface != &tbm_client_buffer_iface)
77         return NULL;
78     return buffer->surface;
79 }
80
81 static void
82 tbm_server_handle_display_destroy(struct wl_listener *listener, void *data)
83 {
84     struct ds_tbm_server *tbm;
85
86     tbm = wl_container_of(listener, tbm, display_destroy);
87
88     wl_signal_emit(&tbm->events.destroy, tbm);
89
90     wayland_tbm_server_deinit(tbm->wl_tbm);
91     free(tbm);
92 }
93
94 static void
95 tbm_client_buffer_handle_release(struct wl_listener *listener, void *data)
96 {
97     struct ds_tbm_client_buffer *buffer;
98
99     buffer = wl_container_of(listener, buffer, buffer_release);
100     if (buffer->resource)
101         wl_buffer_send_release(buffer->resource);
102 }
103
104 static void
105 tbm_client_buffer_handle_resource_destroy(struct wl_listener *listener,
106         void *data)
107 {
108     struct ds_tbm_client_buffer *buffer;
109
110     buffer = wl_container_of(listener, buffer, resource_destroy);
111
112     buffer->resource = NULL;
113     buffer->surface = NULL;
114     wl_list_remove(&buffer->resource_destroy.link);
115     wl_list_init(&buffer->resource_destroy.link);
116
117     ds_buffer_drop(&buffer->base);
118 }
119
120 static struct ds_tbm_client_buffer *
121 tbm_client_buffer_from_buffer(struct ds_buffer *ds_buffer)
122 {
123     assert(ds_buffer->iface == &tbm_client_buffer_iface);
124     return (struct ds_tbm_client_buffer *)ds_buffer;
125 }
126
127 static void
128 tbm_client_buffer_iface_destroy(struct ds_buffer *ds_buffer)
129 {
130     struct ds_tbm_client_buffer *buffer;
131
132     buffer = tbm_client_buffer_from_buffer(ds_buffer);
133
134     ds_inf("Destroy TBM client buffer(%p)", buffer);
135
136     wl_list_remove(&buffer->resource_destroy.link);
137     wl_list_remove(&buffer->buffer_release.link);
138     free(buffer);
139 }
140
141 static bool
142 tbm_client_buffer_iface_begin_data_ptr_access(struct ds_buffer *ds_buffer,
143         enum ds_buffer_data_ptr_access_flag flags, void **data,
144         uint32_t *format, size_t *stride)
145 {
146     struct ds_tbm_client_buffer *buffer;
147     tbm_surface_info_s info;
148     tbm_bo_access_option op = TBM_OPTION_NONE;
149     int err;
150
151     buffer = tbm_client_buffer_from_buffer(ds_buffer);
152
153     if (flags & DS_BUFFER_DATA_PTR_ACCESS_READ)
154         op |= TBM_OPTION_READ;
155
156     if (flags & DS_BUFFER_DATA_PTR_ACCESS_WRITE)
157         op |= TBM_OPTION_WRITE;
158
159     err = tbm_surface_map(buffer->surface, op, &info);
160     if (err != TBM_SURFACE_ERROR_NONE) {
161         ds_err("Failed tbm_surface_map()");
162         return false;
163     }
164
165     *format = convert_tbm_format_to_drm(buffer->format);
166     *stride = info.planes[0].stride;
167     *data = info.planes[0].ptr;
168
169     return true;
170 }
171
172 static void
173 tbm_client_buffer_iface_end_ptr_access(struct ds_buffer *ds_buffer)
174 {
175     struct ds_tbm_client_buffer *buffer;
176
177     buffer = tbm_client_buffer_from_buffer(ds_buffer);
178
179     tbm_surface_unmap(buffer->surface);
180 }
181
182 static const struct ds_buffer_interface tbm_client_buffer_iface = {
183     .destroy = tbm_client_buffer_iface_destroy,
184     .begin_data_ptr_access = tbm_client_buffer_iface_begin_data_ptr_access,
185     .end_data_ptr_access = tbm_client_buffer_iface_end_ptr_access,
186 };
187
188 static struct ds_tbm_client_buffer *
189 tbm_client_buffer_create(struct wl_resource *resource)
190 {
191     struct ds_tbm_client_buffer *buffer;
192     tbm_surface_h surface;
193     int32_t width, height;
194
195     surface = wayland_tbm_server_get_surface(NULL, resource);
196     if (!surface) {
197         ds_err("Could not get tbm_surface from wl_resource@%d",
198                 wl_resource_get_id(resource));
199         return NULL;
200     }
201
202     width = tbm_surface_get_width(surface);
203     height = tbm_surface_get_height(surface);
204
205     buffer = calloc(1, sizeof *buffer);
206     if (!buffer)
207         return NULL;
208
209     ds_buffer_init(&buffer->base, &tbm_client_buffer_iface, width, height);
210
211     buffer->resource = resource;
212     buffer->surface = surface;
213     buffer->format = tbm_surface_get_format(surface);
214
215     buffer->buffer_release.notify = tbm_client_buffer_handle_release;
216     ds_buffer_add_release_listener(&buffer->base, &buffer->buffer_release);
217
218     buffer->resource_destroy.notify =
219         tbm_client_buffer_handle_resource_destroy;
220     wl_resource_add_destroy_listener(resource, &buffer->resource_destroy);
221
222     ds_inf("TBM client buffer(%p) created", buffer);
223
224     return buffer;
225 }
226
227 static struct ds_tbm_client_buffer *
228 tbm_client_buffer_get_or_create(struct wl_resource *resource)
229 {
230     struct ds_tbm_client_buffer *buffer;
231     struct wl_listener *resource_destroy_listener;
232
233     resource_destroy_listener = wl_resource_get_destroy_listener(resource,
234             tbm_client_buffer_handle_resource_destroy);;
235     if (resource_destroy_listener) {
236         buffer = wl_container_of(resource_destroy_listener,
237                 buffer, resource_destroy);
238         return buffer;
239     }
240
241     return tbm_client_buffer_create(resource);
242 }
243
244 static bool
245 tbm_buffer_resource_iface_is_instance(struct wl_resource *resource)
246 {
247     return !!wayland_tbm_server_get_surface(NULL, resource);
248 }
249
250 static struct ds_buffer *
251 tbm_buffer_resource_iface_from_resource(struct wl_resource *resource)
252 {
253     struct ds_tbm_client_buffer *buffer;
254
255     buffer = tbm_client_buffer_get_or_create(resource);
256     if (!buffer) {
257         ds_err("Could not get or create ds_tbm_client_buffer");
258         return NULL;
259     }
260
261     return &buffer->base;
262 }
263
264 static const struct ds_buffer_resource_interface tbm_buffer_resource_iface = {
265     .name = "tbm",
266     .is_instance = tbm_buffer_resource_iface_is_instance,
267     .from_resource = tbm_buffer_resource_iface_from_resource,
268 };