{
E_Comp_Wl_Buffer base;
struct ds_buffer *ds_buffer;
+
+ void (*lock)(E_Buffer *buffer);
+ void (*release)(E_Buffer *buffer);
};
static void _e_comp_wl_buffer_ref(E_Comp_Wl_Buffer *buffer);
static void _e_comp_wl_buffer_unref(E_Comp_Wl_Buffer *buffer);
static void _e_comp_wl_buffer_reference_cb_destroy(struct wl_listener *listener, void *data);
-static E_Buffer *_e_buffer_create(struct ds_buffer *ds_buffer);
+static E_Buffer *_e_buffer_create_with_ds_buffer(struct ds_buffer *ds_buffer);
+static E_Buffer *_e_buffer_create_with_tbm_surface(tbm_surface_h tbm_surface);
static E_Buffer *_e_buffer_from_base(E_Comp_Wl_Buffer *base);
static E_Buffer *_e_buffer_from_buffer(struct ds_buffer *ds_buffer);
+static void _e_buffer_destroy(E_Buffer *buffer);
static void _e_buffer_cb_resource_destroy(struct wl_listener *listener, void *data);
static void _e_buffer_transform_update(E_Buffer *buffer);
+static void _e_buffer_tbm_surface_destroy(E_Buffer *buffer);
E_API void
e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer)
if (buffer)
goto done;
- buffer = _e_buffer_create(ds_buffer);
+ buffer = _e_buffer_create_with_ds_buffer(ds_buffer);
if (!buffer)
{
ERR("Failed to create E_Comp_Wl_Buffer");
return &buffer->base;
}
+EINTERN E_Comp_Wl_Buffer *
+e_comp_wl_buffer_create_with_tbm_surface(tbm_surface_h tbm_surface)
+{
+ E_Buffer *buffer;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(tbm_surface, NULL);
+
+ buffer = _e_buffer_create_with_tbm_surface(tbm_surface);
+ if (!buffer)
+ return NULL;
+
+ DBG("Create Buffer(%p) with tbm_surface(%p)", buffer, tbm_surface);
+
+ return &buffer->base;
+}
+
+EINTERN void
+e_comp_wl_buffer_destroy(E_Comp_Wl_Buffer *comp_buffer)
+{
+ E_Buffer *buffer;
+
+ EINA_SAFETY_ON_NULL_RETURN(comp_buffer);
+
+ buffer = _e_buffer_from_base(comp_buffer);
+ EINA_SAFETY_ON_NULL_RETURN(buffer);
+
+ if (buffer->ds_buffer)
+ {
+ ERR("Cannot destroy the buffer(%p) associated with ds_buffer", buffer);
+ return;
+ }
+
+ _e_buffer_tbm_surface_destroy(buffer);
+}
+
EINTERN void *
e_comp_wl_buffer_single_pixel_buffer_data_get(E_Comp_Wl_Buffer *comp_buffer)
{
if (base->busy == 1)
{
buffer = _e_buffer_from_base(base);
- if (buffer)
- ds_buffer_lock(buffer->ds_buffer);
+ if (buffer && buffer->lock)
+ buffer->lock(buffer);
}
}
buffer = _e_buffer_from_base(base);
if (buffer)
- ds_buffer_unlock(buffer->ds_buffer);
- else if (base->type == E_COMP_WL_BUFFER_TYPE_TBM)
- e_comp_wl_tbm_buffer_destroy(base);
+ buffer->release(buffer);
}
static void
return EINA_TRUE;
}
+static void
+_e_comp_wl_buffer_init(E_Comp_Wl_Buffer *base, int32_t width, int32_t height)
+{
+ base->w = width;
+ base->h = height;
+ wl_signal_init(&base->destroy_signal);
+ wl_list_init(&base->destroy_listener.link);
+}
+
static Eina_Bool
-_e_comp_wl_buffer_init(E_Comp_Wl_Buffer *base, struct ds_buffer *ds_buffer)
+_e_comp_wl_buffer_init_with_ds_buffer(E_Comp_Wl_Buffer *base, struct ds_buffer *ds_buffer)
{
struct wl_shm_buffer *shmbuff;
struct wl_resource *resource;
+ int32_t width, height;
+
+ ds_buffer_get_size(ds_buffer, &width, &height);
+ _e_comp_wl_buffer_init(base, width, height);
resource = ds_buffer_get_resource(ds_buffer);
if (!resource)
return EINA_FALSE;
}
- ds_buffer_get_size(ds_buffer, &base->w, &base->h);
base->resource = resource;
base->destroy_listener.notify = _e_buffer_cb_resource_destroy;
wl_resource_add_destroy_listener(resource, &base->destroy_listener);
- wl_signal_init(&base->destroy_signal);
-
- DBG("E_Comp_Wl_Buffer Create: b %p", base);
-
return EINA_TRUE;
}
static void
_e_comp_wl_buffer_finish(E_Comp_Wl_Buffer *base)
{
- DBG("Wl Buffer(%p) Destroy", base);
-
wl_signal_emit(&base->destroy_signal, base);
if (base->buffer_release)
wl_list_remove(&base->destroy_listener.link);
}
+static void
+_e_buffer_ds_buffer_lock(E_Buffer *buffer)
+{
+ ds_buffer_lock(buffer->ds_buffer);
+}
+
+static void
+_e_buffer_ds_buffer_unlock(E_Buffer *buffer)
+{
+ ds_buffer_unlock(buffer->ds_buffer);
+}
+
static E_Buffer *
-_e_buffer_create(struct ds_buffer *ds_buffer)
+_e_buffer_create_with_ds_buffer(struct ds_buffer *ds_buffer)
{
E_Buffer *buffer;
return NULL;
buffer->ds_buffer = ds_buffer;
+ buffer->lock = _e_buffer_ds_buffer_lock;
+ buffer->release = _e_buffer_ds_buffer_unlock;
- if (!_e_comp_wl_buffer_init(&buffer->base, ds_buffer))
+ if (!_e_comp_wl_buffer_init_with_ds_buffer(&buffer->base, ds_buffer))
{
free(buffer);
return NULL;
}
+ DBG("Create Buffer(%p) with ds_buffer(%p)", buffer, ds_buffer);
+
return buffer;
}
+static void
+_e_buffer_destroy(E_Buffer *buffer)
+{
+ DBG("Destroy Buffer(%p)", buffer);
+
+ _e_comp_wl_buffer_finish(&buffer->base);
+ free(buffer);
+}
+
static E_Buffer *
_e_buffer_from_base(E_Comp_Wl_Buffer *base)
{
if (buffer->base.busy > 0)
ds_buffer_unlock(buffer->ds_buffer);
- _e_comp_wl_buffer_finish(&buffer->base);
- free(buffer);
+
+ _e_buffer_destroy(buffer);
}
static E_Buffer *
if (buffer->base.tbm_surface)
buffer->base.transform = wayland_tbm_server_buffer_get_buffer_transform(NULL, buffer->base.resource);
}
+
+static void
+_e_buffer_tbm_surface_destroy(E_Buffer *buffer)
+{
+ tbm_surface_internal_unref(buffer->base.tbm_surface);
+ _e_buffer_destroy(buffer);
+}
+
+static void
+_e_comp_wl_buffer_init_with_tbm_surface(E_Comp_Wl_Buffer *base, tbm_surface_h tbm_surface)
+{
+ _e_comp_wl_buffer_init(base,
+ tbm_surface_get_width(tbm_surface),
+ tbm_surface_get_height(tbm_surface));
+
+ base->type = E_COMP_WL_BUFFER_TYPE_TBM;
+ base->tbm_surface = tbm_surface;
+ tbm_surface_internal_ref(tbm_surface);
+
+ // This is NOT to add a destroy listener, but to idendify the E_Buffer from
+ // E_Comp_Wl_Buffer.
+ base->destroy_listener.notify = _e_buffer_cb_resource_destroy;
+}
+
+static E_Buffer *
+_e_buffer_create_with_tbm_surface(tbm_surface_h tbm_surface)
+{
+ E_Buffer *buffer;
+
+ buffer = E_NEW(E_Buffer, 1);
+ if (!buffer)
+ return NULL;
+
+ buffer->release = _e_buffer_tbm_surface_destroy;
+
+ _e_comp_wl_buffer_init_with_tbm_surface(&buffer->base, tbm_surface);
+
+ return buffer;
+}