E_Client_Hook *client_del_hook;
+ struct wl_list frames;
+
struct wl_listener destroy;
struct wl_listener precommit_to_cache;
struct wl_listener precommit_from_cache;
EINTERN void
e_surface_frame_done_send(E_Surface *surface)
{
- struct wl_resource *resource;
- Eina_List *l, *ll;
+ struct wl_resource *resource, *tmp;
- EINA_LIST_FOREACH_SAFE(surface->base.frames, l, ll, resource)
+ wl_resource_for_each_safe(resource, tmp, &surface->frames)
{
wl_callback_send_done(resource, (unsigned int)(ecore_loop_time_get() * 1000));
wl_resource_destroy(resource);
wl_signal_init(&surface->base.apply_viewport_signal);
wl_signal_init(&surface->base.state_commit_signal);
+ wl_list_init(&surface->frames);
+
e_comp_wl_surface_state_init(&surface->base.pending, ec->w, ec->h);
/* set initial client data properties */
static void
_e_surface_destroy(E_Surface *surface)
{
- struct wl_resource *cb;
E_Comp_Wl_Data *comp_wl;
+ struct wl_resource *resource, *tmp;
ELOGF("COMPOSITOR", "Desroy E_Surface %p", surface->ec, surface);
e_comp_wl_buffer_reference(&surface->base.buffer_ref, NULL);
- EINA_LIST_FREE(surface->base.frames, cb)
- wl_resource_destroy(cb);
+ wl_resource_for_each_safe(resource, tmp, &surface->frames)
+ wl_resource_destroy(resource);
if (surface->base.aux_hint.hints)
{
}
static void
-_frame_callback_cb_destroy(struct wl_listener *listener, void *data)
-{
- struct wl_resource *resource = data;
- E_Frame_Callback *frame_callback;
- E_Surface *surface;
-
- frame_callback = wl_container_of(listener, frame_callback, destroy);
- surface = frame_callback->surface;
-
- if (surface->base.frames)
- surface->base.frames = eina_list_remove(surface->base.frames, resource);
-
- if (surface->base.pending.frames)
- surface->base.pending.frames = eina_list_remove(surface->base.pending.frames, resource);
-
- wl_list_remove(&frame_callback->destroy.link);
- free(frame_callback);
-}
-
-static Eina_Bool
-_e_surface_pending_frame_callback_add(E_Surface *surface, struct wl_resource *resource)
-{
- E_Frame_Callback *frame_callback;
-
- frame_callback = E_NEW(E_Frame_Callback, 1);
- if (!frame_callback)
- return EINA_FALSE;
-
- frame_callback->surface = surface;
-
- frame_callback->destroy.notify = _frame_callback_cb_destroy;
- wl_resource_add_destroy_listener(resource, &frame_callback->destroy);
-
- surface->base.pending.frames = eina_list_prepend(surface->base.pending.frames, resource);
-
- return EINA_TRUE;
-}
-
-static void
-_e_surface_pending_frame_callback_update(E_Surface *surface)
+_e_surface_frame_callback_list_update(E_Surface *surface)
{
struct ds_surface *ds_surface = surface->ds_surface;
- struct wl_resource *resource, *tmp;
- wl_resource_for_each_safe(resource, tmp, &ds_surface->current.frame_callback_list)
- {
- if (_e_surface_pending_frame_callback_add(surface, resource))
- {
- wl_list_remove(wl_resource_get_link(resource));
- wl_list_init(wl_resource_get_link(resource));
- }
- }
+ // FIXME
+ // flush frame callback events to fix the problem that some application
+ // historically had without this.
+ // If we remove it we can use ds_surface_send_frame_done() and remove
+ // frames field from E_Surface.
+ e_surface_frame_done_send(surface);
+
+ wl_list_insert_list(&surface->frames, &ds_surface->current.frame_callback_list);
+ wl_list_init(&ds_surface->current.frame_callback_list);
}
static void
_e_surface_pending_buffer_scale_update(surface);
if (ds_surface->current.committed & DS_SURFACE_STATE_FRAME_CALLBACK_LIST)
- _e_surface_pending_frame_callback_update(surface);
+ _e_surface_frame_callback_list_update(surface);
if (ds_surface->current.committed & DS_SURFACE_STATE_VIEWPORT)
_e_surface_pending_viewport_update(surface);