2 #include "e_comp_wl_buffer_intern.h"
3 #include "e_tbm_gbm_server_intern.h"
4 #include "e_linux_dmabuf_intern.h"
5 #include "e_explicit_sync_intern.h"
7 #include <libds/single_pixel_buffer_v1.h>
9 #include <wayland-tbm-server.h>
11 typedef struct _E_Buffer E_Buffer;
15 E_Comp_Wl_Buffer base;
16 struct ds_buffer *ds_buffer;
18 void (*lock)(E_Buffer *buffer);
19 void (*release)(E_Buffer *buffer);
22 static void _e_comp_wl_buffer_ref(E_Comp_Wl_Buffer *buffer);
23 static void _e_comp_wl_buffer_unref(E_Comp_Wl_Buffer *buffer);
24 static void _e_comp_wl_buffer_reference_cb_destroy(struct wl_listener *listener, void *data);
26 static E_Buffer *_e_buffer_create_with_ds_buffer(struct ds_buffer *ds_buffer);
27 static E_Buffer *_e_buffer_create_with_tbm_surface(tbm_surface_h tbm_surface);
28 static E_Buffer *_e_buffer_from_base(E_Comp_Wl_Buffer *base);
29 static E_Buffer *_e_buffer_from_buffer(struct ds_buffer *ds_buffer);
30 static void _e_buffer_destroy(E_Buffer *buffer);
31 static void _e_buffer_cb_resource_destroy(struct wl_listener *listener, void *data);
32 static void _e_buffer_transform_update(E_Buffer *buffer);
33 static void _e_buffer_tbm_surface_destroy(E_Buffer *buffer);
36 e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer)
38 if (ref->buffer == buffer)
43 wl_list_remove(&ref->destroy_listener.link);
44 _e_comp_wl_buffer_unref(ref->buffer);
49 _e_comp_wl_buffer_ref(buffer);
51 ref->destroy_listener.notify = _e_comp_wl_buffer_reference_cb_destroy;
52 wl_signal_add(&buffer->destroy_signal, &ref->destroy_listener);
58 EINTERN E_Comp_Wl_Buffer *
59 e_comp_wl_buffer_get(struct ds_buffer *ds_buffer)
63 buffer = _e_buffer_from_buffer(ds_buffer);
67 buffer = _e_buffer_create_with_ds_buffer(ds_buffer);
70 ERR("Failed to create E_Comp_Wl_Buffer");
75 _e_buffer_transform_update(buffer);
80 EINTERN E_Comp_Wl_Buffer *
81 e_comp_wl_buffer_create_with_tbm_surface(tbm_surface_h tbm_surface)
85 EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surface, NULL);
87 buffer = _e_buffer_create_with_tbm_surface(tbm_surface);
91 DBG("Create Buffer(%p) with tbm_surface(%p)", buffer, tbm_surface);
97 e_comp_wl_buffer_destroy(E_Comp_Wl_Buffer *comp_buffer)
101 EINA_SAFETY_ON_NULL_RETURN(comp_buffer);
103 buffer = _e_buffer_from_base(comp_buffer);
104 EINA_SAFETY_ON_NULL_RETURN(buffer);
106 if (buffer->ds_buffer)
108 ERR("Cannot destroy the buffer(%p) associated with ds_buffer", buffer);
112 _e_buffer_tbm_surface_destroy(buffer);
116 e_comp_wl_buffer_single_pixel_buffer_data_get(E_Comp_Wl_Buffer *comp_buffer)
123 EINA_SAFETY_ON_NULL_RETURN_VAL(comp_buffer, NULL);
124 EINA_SAFETY_ON_FALSE_RETURN_VAL(comp_buffer->type == E_COMP_WL_BUFFER_TYPE_SINGLE_PIXEL, NULL);
126 buffer = _e_buffer_from_base(comp_buffer);
127 EINA_SAFETY_ON_NULL_RETURN_VAL(buffer, NULL);
129 if (!ds_buffer_begin_data_ptr_access(buffer->ds_buffer,
130 DS_BUFFER_DATA_PTR_ACCESS_READ,
131 &data, &format, &stride))
133 ERR("Could not access data of buffer(%p)", buffer);
137 ds_buffer_end_data_ptr_access(buffer->ds_buffer);
143 _e_comp_wl_buffer_ref(E_Comp_Wl_Buffer *base)
150 buffer = _e_buffer_from_base(base);
151 if (buffer && buffer->lock)
152 buffer->lock(buffer);
157 _e_comp_wl_buffer_release(E_Comp_Wl_Buffer *base)
161 if (base->buffer_release)
163 e_explicit_sync_buffer_release_destroy(base->buffer_release);
164 base->buffer_release = NULL;
167 buffer = _e_buffer_from_base(base);
169 buffer->release(buffer);
173 _e_comp_wl_buffer_unref(E_Comp_Wl_Buffer *base)
179 _e_comp_wl_buffer_release(base);
183 _e_comp_wl_buffer_reference_cb_destroy(struct wl_listener *listener, void *data)
185 E_Comp_Wl_Buffer_Ref *ref;
187 ref = container_of(listener, E_Comp_Wl_Buffer_Ref, destroy_listener);
188 wl_list_remove(&ref->destroy_listener.link);
193 _e_comp_wl_buffer_tbm_type_get(E_Comp_Wl_Buffer *base, struct ds_buffer *ds_buffer)
195 tbm_surface_h tsurface;
197 tsurface = e_tbm_gbm_server_tbm_surface_get_from_buffer(ds_buffer);
200 tsurface = e_linux_dmabuf_tbm_surface_get_from_buffer(ds_buffer);
205 base->type = E_COMP_WL_BUFFER_TYPE_TBM;
206 base->format = tbm_surface_get_format(tsurface);
207 base->tbm_surface = tsurface;
213 _e_comp_wl_buffer_init(E_Comp_Wl_Buffer *base, int32_t width, int32_t height)
217 wl_signal_init(&base->destroy_signal);
218 wl_list_init(&base->destroy_listener.link);
222 _e_comp_wl_buffer_init_with_ds_buffer(E_Comp_Wl_Buffer *base, struct ds_buffer *ds_buffer)
224 struct wl_shm_buffer *shmbuff;
225 struct wl_resource *resource;
226 int32_t width, height;
228 ds_buffer_get_size(ds_buffer, &width, &height);
229 _e_comp_wl_buffer_init(base, width, height);
231 resource = ds_buffer_get_resource(ds_buffer);
235 shmbuff = wl_shm_buffer_get(resource);
238 base->type = E_COMP_WL_BUFFER_TYPE_SHM;
239 base->format = wl_shm_buffer_get_format(shmbuff);
240 base->shm_buffer = shmbuff;
242 else if (ds_single_pixel_buffer_v1_from_buffer(ds_buffer))
244 base->type = E_COMP_WL_BUFFER_TYPE_SINGLE_PIXEL;
245 base->format = WL_SHM_FORMAT_ARGB8888;
247 else if (!_e_comp_wl_buffer_tbm_type_get(base, ds_buffer))
249 ERR("Invalid resource:%u", wl_resource_get_id(resource));
253 base->resource = resource;
255 base->destroy_listener.notify = _e_buffer_cb_resource_destroy;
256 wl_resource_add_destroy_listener(resource, &base->destroy_listener);
262 _e_comp_wl_buffer_finish(E_Comp_Wl_Buffer *base)
264 wl_signal_emit(&base->destroy_signal, base);
266 if (base->buffer_release)
267 e_explicit_sync_buffer_release_destroy(base->buffer_release);
269 wl_list_remove(&base->destroy_listener.link);
273 _e_buffer_ds_buffer_lock(E_Buffer *buffer)
275 ds_buffer_lock(buffer->ds_buffer);
279 _e_buffer_ds_buffer_unlock(E_Buffer *buffer)
281 ds_buffer_unlock(buffer->ds_buffer);
285 _e_buffer_create_with_ds_buffer(struct ds_buffer *ds_buffer)
289 buffer = E_NEW(E_Buffer, 1);
293 buffer->ds_buffer = ds_buffer;
294 buffer->lock = _e_buffer_ds_buffer_lock;
295 buffer->release = _e_buffer_ds_buffer_unlock;
297 if (!_e_comp_wl_buffer_init_with_ds_buffer(&buffer->base, ds_buffer))
303 DBG("Create Buffer(%p) with ds_buffer(%p)", buffer, ds_buffer);
309 _e_buffer_destroy(E_Buffer *buffer)
311 DBG("Destroy Buffer(%p)", buffer);
313 _e_comp_wl_buffer_finish(&buffer->base);
318 _e_buffer_from_base(E_Comp_Wl_Buffer *base)
322 if (base->destroy_listener.notify == _e_buffer_cb_resource_destroy)
323 return wl_container_of(base, buffer, base);
328 _e_buffer_cb_resource_destroy(struct wl_listener *listener, void *data)
332 buffer = wl_container_of(listener, buffer, base.destroy_listener);
334 if (buffer->base.busy > 0)
335 ds_buffer_unlock(buffer->ds_buffer);
337 _e_buffer_destroy(buffer);
341 _e_buffer_from_buffer(struct ds_buffer *ds_buffer)
344 struct wl_resource *resource;
345 struct wl_listener *listener;
347 resource = ds_buffer_get_resource(ds_buffer);
351 listener = wl_resource_get_destroy_listener(resource, _e_buffer_cb_resource_destroy);
353 return wl_container_of(listener, buffer, base.destroy_listener);
358 _e_buffer_transform_update(E_Buffer *buffer)
360 if (buffer->base.tbm_surface)
361 buffer->base.transform = wayland_tbm_server_buffer_get_buffer_transform(NULL, buffer->base.resource);
365 _e_buffer_tbm_surface_destroy(E_Buffer *buffer)
367 tbm_surface_internal_unref(buffer->base.tbm_surface);
368 _e_buffer_destroy(buffer);
372 _e_comp_wl_buffer_init_with_tbm_surface(E_Comp_Wl_Buffer *base, tbm_surface_h tbm_surface)
374 _e_comp_wl_buffer_init(base,
375 tbm_surface_get_width(tbm_surface),
376 tbm_surface_get_height(tbm_surface));
378 base->type = E_COMP_WL_BUFFER_TYPE_TBM;
379 base->tbm_surface = tbm_surface;
380 tbm_surface_internal_ref(tbm_surface);
382 // This is NOT to add a destroy listener, but to idendify the E_Buffer from
384 base->destroy_listener.notify = _e_buffer_cb_resource_destroy;
388 _e_buffer_create_with_tbm_surface(tbm_surface_h tbm_surface)
392 buffer = E_NEW(E_Buffer, 1);
396 buffer->release = _e_buffer_tbm_surface_destroy;
398 _e_comp_wl_buffer_init_with_tbm_surface(&buffer->base, tbm_surface);