1 #include "e_compositor_intern.h"
2 #include "e_comp_wl_intern.h"
3 #include "e_comp_wl_buffer_intern.h"
4 #include "e_comp_wl_data_intern.h"
5 #include "e_comp_wl_rsm_intern.h"
6 #include "e_comp_wl_subsurface_intern.h"
7 #include "e_comp_intern.h"
8 #include "e_pixmap_intern.h"
9 #include "e_presentation_time_intern.h"
10 #include "e_client_video_intern.h"
11 #include "e_client_intern.h"
13 #include <libds/compositor.h>
14 #include <libds/subcompositor.h>
15 #include <libds/types/ds_surface.h>
16 #include <libds/types/ds_subsurface.h>
18 typedef struct _E_Compositor E_Compositor;
19 typedef struct _E_Subsurface E_Subsurface;
20 typedef struct _E_Frame_Callback E_Frame_Callback;
24 struct ds_compositor *ds_compositor;
25 struct ds_subcompositor *ds_subcompositor;
27 E_Client_Hook *new_client_hook;
29 struct wl_listener new_surface;
30 struct wl_listener display_destroy;
35 E_Comp_Wl_Client_Data base;
38 struct ds_surface *ds_surface;
39 struct ds_surface_viewport *surface_viewport;
41 E_Client_Hook *client_del_hook;
43 struct wl_listener destroy;
44 struct wl_listener commit;
45 struct wl_listener new_subsurface;
49 struct wl_signal destroy;
50 struct wl_signal parent_destroy;
56 E_Comp_Wl_Subsurf_Data base;
59 struct ds_subsurface *ds_subsurface;
61 struct wl_listener destroy;
62 struct wl_listener surface_destroy;
63 struct wl_listener parent_surface_destroy;
64 struct wl_listener cached;
65 struct wl_listener request_move;
68 struct _E_Frame_Callback
71 struct wl_listener destroy;
74 static void _e_compositor_cb_display_destroy(struct wl_listener *listener, void *data);
75 static void _e_compositor_cb_new_surface(struct wl_listener *listener, void *data);
76 static void _e_compositor_cb_new_client(void *data EINA_UNUSED, E_Client *ec);
78 static E_Surface *_e_surface_create(E_Client *ec);
79 static E_Surface *_e_surface_from_ds_surface(struct ds_surface *ds_surface);
80 static E_Surface *_e_surface_from_comp_data(E_Comp_Wl_Client_Data *comp_data);
81 static void _e_surface_destroy(E_Surface *surface);
82 static void _e_surface_ds_surface_set(E_Surface *surface, struct ds_surface *ds_surface);
83 static void _e_surface_cb_client_del(void *data, E_Client *ec);
84 static void _e_surface_cb_destroy(struct wl_listener *listener, void *data);
85 static void _e_surface_cb_commit(struct wl_listener *listener, void *data);
86 static void _e_surface_cb_new_subsurface(struct wl_listener *listener, void *data);
88 static E_Subsurface *_e_subsurface_create(struct ds_subsurface *ds_subsurface, E_Surface *parent_surface);
89 static E_Subsurface *_e_subsurface_from_surface(E_Surface *surface);
90 static E_Subsurface *_e_subsurface_from_resource(struct wl_resource *resource);
91 static E_Subsurface *_e_subsurface_from_ds_subsurface(struct ds_subsurface *ds_subsurface);
92 static void _e_subsurface_destroy(E_Subsurface *sub);
93 static void _e_subsurface_commit(E_Subsurface *sub);
94 static void _e_subsurface_place_below_parent(E_Subsurface *sub);
95 static void _e_subsurface_position_update(E_Subsurface *sub);
96 static void _e_subsurface_cb_destroy(struct wl_listener *listener, void *data);
97 static void _e_subsurface_cb_cached(struct wl_listener *listener, void *data);
98 static void _e_subsurface_cb_request_move(struct wl_listener *listener, void *data);
99 static void _e_subsurface_cb_surface_destroy(struct wl_listener *listener, void *data);
100 static void _e_subsurface_cb_parent_surface_destroy(struct wl_listener *listener, void *data);
102 static void _ds_surface_buffer_transform_set(struct ds_surface *ds_surface, enum wl_output_transform transform);
103 static void _ds_surface_viewport_source_box_set(struct ds_surface *ds_surface, Eina_Rectangle *box);
104 static void _ds_surface_viewport_destination_set(struct ds_surface *ds_surface, int32_t width, int32_t height);
105 static void _ds_surface_viewport_unset(struct ds_surface *ds_surface);
106 static void _ds_subsurface_position_set(struct ds_subsurface *ds_subsurface, int x, int y);
108 static const char *e_comp_wl_subsurface_role_name = "ds_subsurface";
109 static E_Compositor *_compositor;
112 e_compositor_init(struct wl_display *display)
119 comp = E_NEW(E_Compositor, 1);
123 comp->ds_compositor = ds_compositor_create(display);
124 if (!comp->ds_compositor)
126 ELOGF("COMPOSITOR", "Could not create ds_compositor", NULL);
131 comp->ds_subcompositor = ds_subcompositor_create(display);
132 if (!comp->ds_subcompositor)
134 ELOGF("COMPOSITOR", "Could not create ds_subcompositor", NULL);
139 comp->new_surface.notify = _e_compositor_cb_new_surface;
140 ds_compositor_add_new_surface_listener(comp->ds_compositor,
143 comp->new_client_hook = e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT,
144 _e_compositor_cb_new_client,
147 comp->display_destroy.notify = _e_compositor_cb_display_destroy;
148 wl_display_add_destroy_listener(display, &comp->display_destroy);
156 e_compositor_util_client_from_surface_resource(struct wl_resource *surface_resource)
159 struct ds_surface *ds_surface;
161 ds_surface = ds_surface_from_resource(surface_resource);
165 surface = _e_surface_from_ds_surface(ds_surface);
173 e_comp_wl_subsurface_add(struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource)
175 return !!ds_subsurface_create(resource,
176 ds_surface_from_resource(surface_resource),
177 ds_surface_from_resource(parent_resource),
182 e_comp_wl_subsurface_resource_stand_alone_mode_set(struct wl_resource *subsurface_resource)
186 sub = _e_subsurface_from_resource(subsurface_resource);
189 INF("The given subsurface resource(%p) seems inert.", subsurface_resource);
193 ELOGF("SUBSURFACE", "SUBSURF|STAND_ALONE", sub->surface->ec);
195 sub->base.stand_alone = EINA_TRUE;
199 e_comp_wl_subsurface_resource_place_below_parent(struct wl_resource *subsurface_resource)
202 E_Comp_Wl_Client_Data *epc_cdata;
204 sub = _e_subsurface_from_resource(subsurface_resource);
207 INF("The given subsurface resource(%p) seems inert.", subsurface_resource);
211 EINA_SAFETY_ON_NULL_RETURN(sub->base.parent);
212 epc_cdata = e_client_cdata_get(sub->base.parent);
213 EINA_SAFETY_ON_NULL_RETURN(epc_cdata);
215 ELOGF("SUBSURFACE", "SUBSURF|BELOW_PARENT", sub->surface->ec);
217 _e_subsurface_place_below_parent(sub);
219 epc_cdata->sub.list = eina_list_remove(epc_cdata->sub.list, sub->surface->ec);
220 epc_cdata->sub.list_pending = eina_list_remove(epc_cdata->sub.list_pending, sub->surface->ec);
221 epc_cdata->sub.below_list = eina_list_remove(epc_cdata->sub.below_list, sub->surface->ec);
222 epc_cdata->sub.below_list_pending = eina_list_remove(epc_cdata->sub.below_list_pending, sub->surface->ec);
224 epc_cdata->sub.below_list_pending = eina_list_append(epc_cdata->sub.below_list_pending, sub->surface->ec);
225 epc_cdata->sub.below_list = eina_list_append(epc_cdata->sub.below_list, sub->surface->ec);
226 epc_cdata->sub.list_changed = EINA_TRUE;
230 e_comp_wl_subsurface_commit(E_Client *ec)
235 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
237 if (e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) return EINA_FALSE;
239 surface = _e_surface_from_comp_data(ec->comp_data);
240 sub = _e_subsurface_from_surface(surface);
244 _e_subsurface_commit(sub);
250 e_surface_from_resource(struct wl_resource *surface_resource)
253 struct ds_surface *ds_surface;
255 ds_surface = ds_surface_from_resource(surface_resource);
259 surface = _e_surface_from_ds_surface(ds_surface);
267 e_surface_destroy_listener_add(E_Surface *surface, struct wl_listener *listener)
269 wl_signal_add(&surface->events.destroy, listener);
272 EINTERN struct wl_listener *
273 e_surface_destroy_listener_get(E_Surface *surface, wl_notify_func_t notify)
275 return wl_signal_get(&surface->events.destroy, notify);
279 e_surface_parent_destroy_listener_add(E_Surface *surface, struct wl_listener *listener)
281 wl_signal_add(&surface->events.parent_destroy, listener);
285 e_surface_viewporter_resource_set(E_Surface *surface, struct wl_resource *viewporter)
287 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
289 if (surface->base.scaler.viewport)
292 if (surface->surface_viewport)
295 surface->surface_viewport = ds_surface_take_viewport(surface->ds_surface);
296 if (!surface->surface_viewport)
299 surface->base.scaler.viewport = viewporter;
305 e_surface_viewporter_resource_unset(E_Surface *surface)
307 EINA_SAFETY_ON_NULL_RETURN(surface);
309 surface->base.scaler.viewport = NULL;
310 surface->base.scaler.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
311 surface->base.scaler.buffer_viewport.surface.width = -1;
312 surface->base.scaler.buffer_viewport.changed = 1;
313 surface->base.pending.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
314 surface->base.pending.buffer_viewport.surface.width = -1;
315 surface->base.pending.buffer_viewport.changed = 1;
317 if (surface->surface_viewport)
319 ds_surface_viewport_release(surface->surface_viewport);
320 surface->surface_viewport = NULL;
323 if (surface->ds_surface)
324 _ds_surface_viewport_unset(surface->ds_surface);
327 EINTERN enum wl_output_transform
328 e_surface_buffer_transform_get(E_Surface *surface)
330 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, WL_OUTPUT_TRANSFORM_NORMAL);
331 return surface->base.scaler.buffer_viewport.buffer.transform;
335 e_surface_buffer_transform_set(E_Surface *surface, enum wl_output_transform transform)
338 E_Comp_Wl_Buffer_Viewport *vp;
340 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
342 vp = &surface->base.scaler.buffer_viewport;
343 if (vp->buffer.transform == transform)
346 vp->buffer.transform = transform;
347 vp->changed = EINA_TRUE;
349 surface->base.pending.buffer_viewport = *vp;
351 sub = _e_subsurface_from_surface(surface);
353 sub->base.cached.buffer_viewport = *vp;
355 if (surface->ds_surface)
356 _ds_surface_buffer_transform_set(surface->ds_surface, transform);
362 e_surface_viewport_source_box_set(E_Surface *surface, Eina_Rectangle *box)
365 E_Comp_Wl_Buffer_Viewport *vp;
366 wl_fixed_t fx, fy, fw, fh;
368 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
370 fx = wl_fixed_from_int(box->x);
371 fy = wl_fixed_from_int(box->y);
372 fw = wl_fixed_from_int(box->w);
373 fh = wl_fixed_from_int(box->h);
375 vp = &surface->base.scaler.buffer_viewport;
376 if ((vp->buffer.src_x == fx) && (vp->buffer.src_y == fy) &&
377 (vp->buffer.src_width == fw) && (vp->buffer.src_height == fh))
380 vp->buffer.src_x = fx;
381 vp->buffer.src_y = fy;
382 vp->buffer.src_width = fw;
383 vp->buffer.src_height = fh;
384 vp->changed = EINA_TRUE;
386 surface->base.pending.buffer_viewport = *vp;
388 sub = _e_subsurface_from_surface(surface);
390 sub->base.cached.buffer_viewport = *vp;
392 if (surface->ds_surface)
393 _ds_surface_viewport_source_box_set(surface->ds_surface, box);
399 e_surface_viewport_destination_set(E_Surface *surface, int32_t width, int32_t height)
402 E_Comp_Wl_Buffer_Viewport *vp;
404 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
406 vp = &surface->base.scaler.buffer_viewport;
407 if ((vp->surface.width == width) && (vp->surface.height == height))
410 vp->surface.width = width;
411 vp->surface.height = height;
412 vp->changed = EINA_TRUE;
414 surface->base.pending.buffer_viewport = *vp;
416 sub = _e_subsurface_from_surface(surface);
418 sub->base.cached.buffer_viewport = *vp;
420 if (surface->ds_surface)
421 _ds_surface_viewport_destination_set(surface->ds_surface, width, height);
427 e_surface_viewport_changed_get(E_Surface *surface)
429 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
430 return surface->base.scaler.buffer_viewport.changed;
433 EINTERN E_Subsurface *
434 e_subsurface_from_surface(E_Surface *surface)
436 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, NULL);
437 return _e_subsurface_from_surface(surface);
441 e_subsurface_position_set(E_Subsurface *subsurface, int x, int y)
443 EINA_SAFETY_ON_NULL_RETURN_VAL(subsurface, EINA_FALSE);
445 if ((subsurface->base.position.x == x) && (subsurface->base.position.y == y))
448 subsurface->base.position.x = x;
449 subsurface->base.position.y = y;
450 subsurface->base.position.set = EINA_TRUE;
452 _ds_subsurface_position_set(subsurface->ds_subsurface, x, y);
458 _e_compositor_cb_display_destroy(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
460 wl_list_remove(&_compositor->display_destroy.link);
461 wl_list_remove(&_compositor->new_surface.link);
462 e_client_hook_del(_compositor->new_client_hook);
467 _e_comp_wl_client_usable_get(pid_t pid, E_Pixmap *ep)
469 /* NOTE: this will return usable E_Client for a surface of specified process
470 * by pid. it doesn't care whatever this surfaces is for but care only what
471 * is owner process of the surface.
474 E_Client *ec = NULL, *_ec = NULL;
477 /* find launchscreen client list */
478 if (e_comp->launchscrns)
480 EINA_LIST_FOREACH(e_comp->launchscrns, l, _ec)
482 if (_ec->netwm.pid == pid)
490 E_Pixmap *oldep = NULL;
494 /* do NOT replace with the client having comp data */
498 e_comp->launchscrns = eina_list_remove(e_comp->launchscrns, ec);
500 oldep = e_client_pixmap_change(ec, ep);
503 e_pixmap_win_id_del(oldep);
504 e_pixmap_free(oldep);
510 /* to set-up comp data */
511 _e_compositor_cb_new_client(NULL, ec);
513 if (!ec->comp_data) return NULL;
514 e_comp_wl_client_evas_init(ec);
516 ELOGF("COMP", "Reusable ec. new_pixmap:%p", ec, ec->pixmap);
517 e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_REUSE, ec);
525 _e_compositor_cb_new_surface(struct wl_listener *listener, void *data)
527 struct ds_surface *ds_surface = data;
530 struct wl_resource *surface_resource;
534 DBG("New ds_surface %p", ds_surface);
536 TRACE_DS_BEGIN(COMP_WL:NEW SURFACE CB);
538 surface_resource = ds_surface_get_wl_resource(ds_surface);
539 wl_client_get_credentials(wl_resource_get_client(surface_resource), &pid, NULL, NULL);
543 ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, (uintptr_t)wl_resource_get_id(surface_resource));
545 else if ((ep = e_pixmap_find(E_PIXMAP_TYPE_WL, (uintptr_t)surface_resource)))
547 ERR("There is e_pixmap already, Delete old e_pixmap %p", ep);
548 e_pixmap_win_id_del(ep);
553 /* try to create new pixmap */
554 if (!(ep = e_pixmap_new(E_PIXMAP_TYPE_WL, surface_resource)))
556 ERR("Could not create new pixmap");
561 E_Comp_Wl_Client_Data *cdata = e_pixmap_cdata_get(ep);
563 cdata->wl_surface = surface_resource;
565 DBG("\tUsing Pixmap: %p", ep);
567 if (!(ec = _e_comp_wl_client_usable_get(pid, ep)))
569 ec = e_client_new(ep, 0, internal);
577 e_comp->new_clients--;
579 if ((!ec->client.w) && (ec->client.h))
580 ec->client.w = ec->client.h = 1;
582 e_comp_wl_client_surface_set(ec, surface_resource);
583 ec->icccm.accepts_focus = 1;
584 wl_list_init(&ec->comp_data->pointer_constraints);
586 _e_surface_ds_surface_set(_e_surface_from_comp_data(ec->comp_data),
590 DBG("\tUsing Client: %p", ec);
596 _e_compositor_cb_new_client(void *data EINA_UNUSED, E_Client *ec)
601 /* make sure this is a wayland client */
602 if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
604 TRACE_DS_BEGIN(COMP_WL:CLIENT NEW HOOK);
606 /* get window id from pixmap */
607 win = e_pixmap_window_get(ec->pixmap);
609 /* ignore fake root windows */
610 if ((ec->override) && ((ec->x == -77) && (ec->y == -77)))
612 e_comp_ignore_win_add(E_PIXMAP_TYPE_WL, win);
613 e_object_del(E_OBJECT(ec));
618 surface = _e_surface_create(ec);
621 ERR("Could not create E_Surface");
626 ec->comp_data = &surface->base;
628 /* set initial client properties */
629 ec->argb = EINA_FALSE;
630 ELOGF("COMP", "Set argb:%d", ec, ec->argb);
631 ec->redirected = ec->ignored = 1;
634 /* NB: could not find a better place to do this, BUT for internal windows,
635 * we need to set delete_request else the close buttons on the frames do
636 * basically nothing */
638 ec->icccm.delete_request = EINA_TRUE;
640 E_Comp_Wl_Client_Data *p_cdata = e_pixmap_cdata_get(ec->pixmap);
641 EINA_SAFETY_ON_NULL_GOTO(p_cdata, end);
643 e_pixmap_cdata_set(ec->pixmap, &surface->base);
645 g_mutex_init(&ec->comp_data->surface_mutex);
652 _e_surface_create(E_Client *ec)
656 surface = E_NEW(E_Surface, 1);
660 e_object_ref(E_OBJECT(ec));
663 wl_signal_init(&surface->events.destroy);
664 wl_signal_init(&surface->events.parent_destroy);
665 wl_signal_init(&surface->base.destroy_signal);
666 wl_signal_init(&surface->base.apply_viewport_signal);
667 wl_signal_init(&surface->base.state_commit_signal);
669 e_comp_wl_surface_state_init(&surface->base.pending, ec->w, ec->h);
671 /* set initial client data properties */
672 surface->base.mapped = EINA_FALSE;
673 surface->base.first_damage = ec->internal;
674 surface->base.need_reparent = !ec->internal;
676 /* set initial value of scaler */
677 surface->base.scaler.buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
678 surface->base.scaler.buffer_viewport.buffer.scale = 1;
679 surface->base.scaler.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
680 surface->base.scaler.buffer_viewport.surface.width = -1;
682 e_presentation_time_container_init(&surface->base.presentation_container);
684 surface->client_del_hook = e_client_hook_add(E_CLIENT_HOOK_DEL,
685 _e_surface_cb_client_del,
692 _e_surface_destroy(E_Surface *surface)
694 struct wl_resource *cb;
696 g_mutex_lock(&surface->base.surface_mutex);
698 wl_signal_emit(&surface->base.destroy_signal, &surface->base.surface);
700 e_comp_wl_surface_state_finish(&surface->base.pending);
702 e_comp_wl_buffer_reference(&surface->base.buffer_ref, NULL);
704 EINA_LIST_FREE(surface->base.frames, cb)
705 wl_resource_destroy(cb);
707 EINA_LIST_FREE(surface->base.pending.frames, cb)
708 wl_resource_destroy(cb);
710 if (surface->base.aux_hint.hints)
712 E_Comp_Wl_Aux_Hint *hint;
713 EINA_LIST_FREE(surface->base.aux_hint.hints, hint)
715 eina_stringshare_del(hint->hint);
716 eina_stringshare_del(hint->val);
721 if (e_comp_wl->ptr.ec == surface->ec)
723 e_comp_wl->ptr.ec = NULL;
724 E_FREE_FUNC(e_comp_wl->ptr.hide_tmr, ecore_timer_del);
727 if (e_comp_wl->touch.faked_ec == surface->ec)
728 e_comp_wl->touch.faked_ec = NULL;
730 if (e_comp_wl->selection.cbhm == surface->base.surface)
731 e_comp_wl->selection.cbhm = NULL;
733 e_comp_wl_data_secondary_remove(surface->ec);
735 if (surface->base.viewport_transform)
737 e_client_transform_core_remove(surface->ec, surface->base.viewport_transform);
738 e_util_transform_del(surface->base.viewport_transform);
739 surface->base.viewport_transform = NULL;
742 e_presentation_time_container_finish(&surface->base.presentation_container);
744 E_FREE_FUNC(surface->base.on_focus_timer, ecore_timer_del);
746 e_client_hook_del(surface->client_del_hook);
748 g_mutex_unlock(&surface->base.surface_mutex);
750 g_mutex_clear(&surface->base.surface_mutex);
752 surface->ec->comp_data = NULL;
753 e_object_unref(E_OBJECT(surface->ec));
758 _e_surface_ds_surface_set(E_Surface *surface, struct ds_surface *ds_surface)
760 surface->ds_surface = ds_surface;
762 surface->destroy.notify = _e_surface_cb_destroy;
763 ds_surface_add_destroy_listener(ds_surface, &surface->destroy);
765 surface->commit.notify = _e_surface_cb_commit;
766 ds_surface_add_commit_listener(ds_surface, &surface->commit);
768 surface->new_subsurface.notify = _e_surface_cb_new_subsurface;
769 ds_surface_add_new_subsurface_listener(ds_surface, &surface->new_subsurface);
773 _e_surface_from_ds_surface(struct ds_surface *ds_surface)
775 E_Surface *surface = NULL;
776 struct wl_listener *listener;
778 listener = wl_signal_get(&ds_surface->events.destroy,
779 _e_surface_cb_destroy);
781 surface = wl_container_of(listener, surface, destroy);
787 _e_surface_from_comp_data(E_Comp_Wl_Client_Data *comp_data)
790 return wl_container_of(comp_data, surface, base);
794 _e_surface_root_surface_get(E_Surface *surface)
796 E_Surface *iter = surface;
799 while ((sub = _e_subsurface_from_surface(iter)))
800 iter = _e_surface_from_ds_surface(sub->ds_subsurface->parent);
806 _e_surface_buffer_video_content_type_check_and_set(E_Surface *surface, E_Comp_Wl_Buffer *buffer)
808 E_Client *ec = surface->ec;
810 if (ec->comp_data->video_client)
812 buffer->type = E_COMP_WL_BUFFER_TYPE_VIDEO;
813 buffer->w = buffer->h = 1;
816 else if (e_client_video_hw_composition_check(ec))
818 buffer->type = E_COMP_WL_BUFFER_TYPE_VIDEO;
823 _e_surface_pending_buffer_update(E_Surface *surface)
825 struct ds_surface *ds_surface = surface->ds_surface;
826 E_Client *ec = surface->ec;
827 E_Comp_Wl_Buffer *buffer = NULL;
829 if (ds_surface->buffer)
831 buffer = e_comp_wl_buffer_get(ds_surface->buffer);
833 _e_surface_buffer_video_content_type_check_and_set(surface, buffer);
836 e_comp_wl_client_surface_pending_buffer_set(ec, buffer,
837 ds_surface->current.dx,
838 ds_surface->current.dy);
842 _e_surface_pending_surface_damage_update(E_Surface *surface)
844 struct ds_surface *ds_surface = surface->ds_surface;
845 pixman_box32_t *rects;
850 rects = pixman_region32_rectangles(&ds_surface->current.surface_damage, &nrects);
851 for (i = 0; i < nrects; i++)
858 dmg = eina_rectangle_new(x, y, w, h);
861 surface->base.pending.damages =
862 eina_list_append(surface->base.pending.damages, dmg);
868 _e_surface_pending_buffer_damage_update(E_Surface *surface)
870 struct ds_surface *ds_surface = surface->ds_surface;
871 pixman_box32_t *rects;
876 rects = pixman_region32_rectangles(&ds_surface->current.buffer_damage, &nrects);
877 for (i = 0; i < nrects; i++)
884 dmg = eina_rectangle_new(x, y, w, h);
887 surface->base.pending.buffer_damages =
888 eina_list_append(surface->base.pending.buffer_damages, dmg);
894 _region_area_check(Eina_Tiler *tiler, int32_t x, int32_t y, int32_t w, int32_t h)
896 Eina_Bool need_set = EINA_FALSE;
900 eina_tiler_area_size_get(tiler, &area_w, &area_h);
904 need_set = EINA_TRUE;
910 need_set = EINA_TRUE;
915 INF("change region area. (%dx%d)", area_w, area_h);
916 eina_tiler_area_size_set(tiler, area_w, area_h);
921 _tiler_new_from_pixman_region(pixman_region32_t *pixman_region)
924 pixman_box32_t *rects;
928 tiler = eina_tiler_new(e_comp->w, e_comp->h);
932 eina_tiler_tile_size_set(tiler, 1, 1);
934 rects = pixman_region32_rectangles(pixman_region, &nrects);
935 for (i = 0; i < nrects; i++)
941 _region_area_check(tiler, x, y, w, h);
942 eina_tiler_rect_add(tiler, &(Eina_Rectangle){x, y, w, h});
949 _e_surface_pending_opaque_region_update(E_Surface *surface)
951 struct ds_surface *ds_surface = surface->ds_surface;
952 E_Client *ec = surface->ec;
955 if (pixman_region32_not_empty(&ds_surface->current.opaque))
957 region = _tiler_new_from_pixman_region(&ds_surface->current.opaque);
961 e_comp_wl_client_surface_pending_opaque_region_set(ec, region);
963 eina_tiler_free(region);
967 e_comp_wl_client_surface_pending_opaque_region_set(ec, NULL);
972 _e_surface_pending_input_region_update(E_Surface *surface)
974 struct ds_surface *ds_surface = surface->ds_surface;
975 E_Client *ec = surface->ec;
977 pixman_region32_t infinite_region;
979 pixman_region32_init_rect(&infinite_region, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
980 if (pixman_region32_equal(&ds_surface->current.input, &infinite_region))
982 e_comp_wl_client_surface_pending_input_region_set(ec, NULL);
986 region = _tiler_new_from_pixman_region(&ds_surface->current.input);
989 e_comp_wl_client_surface_pending_input_region_set(ec, region);
990 eina_tiler_free(region);
996 _e_surface_pending_buffer_transform_update(E_Surface *surface)
998 int32_t transform = surface->ds_surface->current.transform;
1000 surface->base.pending.buffer_viewport.buffer.transform = transform;
1001 surface->base.pending.buffer_viewport.changed = 1;
1005 _e_surface_pending_buffer_scale_update(E_Surface *surface)
1007 int32_t scale = surface->ds_surface->current.scale;
1009 surface->base.pending.buffer_viewport.buffer.scale = scale;
1010 surface->base.pending.buffer_viewport.changed = 1;
1014 _frame_callback_cb_destroy(struct wl_listener *listener, void *data)
1016 struct wl_resource *resource = data;
1017 E_Frame_Callback *frame_callback;
1019 frame_callback = wl_container_of(listener, frame_callback, destroy);
1020 e_comp_wl_client_surface_frame_callback_remove(frame_callback->ec, resource);
1021 e_object_unref(E_OBJECT(frame_callback->ec));
1022 free(frame_callback);
1026 _e_surface_pending_frame_callback_update(E_Surface *surface)
1028 struct ds_surface *ds_surface = surface->ds_surface;
1029 E_Client *ec = surface->ec;
1030 E_Frame_Callback *frame_callback;
1031 struct wl_resource *resource;
1033 wl_resource_for_each(resource, &ds_surface->current.frame_callback_list)
1035 frame_callback = E_NEW(E_Frame_Callback, 1);
1036 if (!frame_callback)
1039 e_object_ref(E_OBJECT(ec));
1040 frame_callback->ec = ec;
1042 frame_callback->destroy.notify = _frame_callback_cb_destroy;
1043 wl_resource_add_destroy_listener(resource, &frame_callback->destroy);
1045 e_comp_wl_client_surface_pending_frame_callback_add(ec, resource);
1048 wl_list_init(&ds_surface->current.frame_callback_list);
1052 _e_surface_pending_viewport_update(E_Surface *surface)
1054 struct ds_surface *ds_surface = surface->ds_surface;
1055 struct ds_surface_state *state = &ds_surface->current;
1056 E_Comp_Wl_Buffer_Viewport *vp = &surface->base.pending.buffer_viewport;
1058 if (state->viewport.has_src)
1060 vp->buffer.src_x = wl_fixed_from_double(state->viewport.src.x);
1061 vp->buffer.src_y = wl_fixed_from_double(state->viewport.src.y);
1062 vp->buffer.src_width = wl_fixed_from_double(state->viewport.src.width);
1063 vp->buffer.src_height = wl_fixed_from_double(state->viewport.src.height);
1064 vp->changed = EINA_TRUE;
1068 vp->buffer.src_width = wl_fixed_from_int(-1);
1069 vp->changed = EINA_TRUE;
1072 if (state->viewport.has_dst)
1074 vp->surface.width = state->viewport.dst_width;
1075 vp->surface.height = state->viewport.dst_height;
1076 vp->changed = EINA_TRUE;
1080 vp->surface.width = -1;
1081 vp->changed = EINA_TRUE;
1086 _e_surface_pending_subsurface_order_update(E_Surface *surface)
1088 struct ds_surface *ds_surface = surface->ds_surface;
1089 struct ds_subsurface *ds_subsurface;
1091 Eina_Bool reordered = EINA_FALSE;
1093 E_FREE_FUNC(surface->base.sub.list_pending, eina_list_free);
1094 E_FREE_FUNC(surface->base.sub.below_list_pending, eina_list_free);
1096 wl_list_for_each(ds_subsurface,
1097 &ds_surface->pending.subsurfaces_above,
1100 sub = _e_subsurface_from_ds_subsurface(ds_subsurface);
1101 surface->base.sub.list_pending =
1102 eina_list_append(surface->base.sub.list_pending, sub->surface->ec);
1104 reordered |= ds_subsurface->reordered;
1105 ds_subsurface->reordered = false;
1107 _e_surface_pending_subsurface_order_update(sub->surface);
1110 wl_list_for_each(ds_subsurface,
1111 &ds_surface->pending.subsurfaces_below,
1114 sub = _e_subsurface_from_ds_subsurface(ds_subsurface);
1115 surface->base.sub.below_list_pending =
1116 eina_list_append(surface->base.sub.below_list_pending, sub->surface->ec);
1118 reordered |= ds_subsurface->reordered;
1119 ds_subsurface->reordered = false;
1121 _e_surface_pending_subsurface_order_update(sub->surface);
1124 surface->base.sub.list_changed |= reordered;
1128 _e_surface_pending_update(E_Surface *surface)
1130 E_Surface *root_surface;
1131 struct ds_surface *ds_surface = surface->ds_surface;
1133 if (ds_surface->current.committed & DS_SURFACE_STATE_BUFFER)
1134 _e_surface_pending_buffer_update(surface);
1136 if (ds_surface->current.committed & DS_SURFACE_STATE_SURFACE_DAMAGE)
1137 _e_surface_pending_surface_damage_update(surface);
1139 if (ds_surface->current.committed & DS_SURFACE_STATE_BUFFER_DAMAGE)
1140 _e_surface_pending_buffer_damage_update(surface);
1142 if (ds_surface->current.committed & DS_SURFACE_STATE_OPAQUE_REGION)
1143 _e_surface_pending_opaque_region_update(surface);
1145 if (ds_surface->current.committed & DS_SURFACE_STATE_INPUT_REGION)
1146 _e_surface_pending_input_region_update(surface);
1148 if (ds_surface->current.committed & DS_SURFACE_STATE_TRANSFORM)
1149 _e_surface_pending_buffer_transform_update(surface);
1151 if (ds_surface->current.committed & DS_SURFACE_STATE_SCALE)
1152 _e_surface_pending_buffer_scale_update(surface);
1154 if (ds_surface->current.committed & DS_SURFACE_STATE_FRAME_CALLBACK_LIST)
1155 _e_surface_pending_frame_callback_update(surface);
1157 if (ds_surface->current.committed & DS_SURFACE_STATE_VIEWPORT)
1158 _e_surface_pending_viewport_update(surface);
1161 // It's not supposed to update subsurface order for entire surface tree.
1162 // This is for backward compatibility
1163 root_surface = _e_surface_root_surface_get(surface);
1164 _e_surface_pending_subsurface_order_update(root_surface);
1168 _e_surface_commit_pre(E_Surface *surface)
1170 E_Client *ec = surface->ec;
1171 E_Comp_Config *comp_conf = NULL;
1173 if (e_object_is_del(E_OBJECT(ec))) return;
1175 if (!surface->base.first_commit)
1176 surface->base.first_commit = EINA_TRUE;
1178 if (!surface->base.mapped)
1180 if (surface->base.shell.surface && surface->base.pending.new_attach &&
1181 !ec->internal && !e_comp_wl_subsurface_check(ec) && !ec->remote_surface.provider)
1183 ELOGF("COMP", "Current unmapped. COMMIT. pixmap_usable:%d", ec, e_pixmap_usable_get(ec->pixmap));
1185 // no canvas update before client's commit request, begin rendering after 1st commit
1186 comp_conf = e_comp_config_get();
1187 if (comp_conf && comp_conf->canvas_render_delay_after_boot && e_comp->canvas_render_delayed)
1189 ELOGF("COMP", "Begin canvas update for the first time after boot", ec);
1190 e_comp->canvas_render_delayed = EINA_FALSE;
1195 e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_BEFORE_SURFACE_COMMIT, ec);
1199 _e_surface_commit(E_Surface *surface)
1201 e_comp_wl_client_surface_pending_commit(surface->ec);
1205 _e_surface_cb_client_del(void *data, E_Client *ec)
1207 E_Surface *surface = data;
1209 if (surface->ec != ec)
1212 /* make sure this is a wayland client */
1213 if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
1215 TRACE_DS_BEGIN(COMP_WL:CLIENT DEL CB);
1217 e_comp_wl_hook_call(E_COMP_WL_HOOK_DEL, ec);
1219 e_comp_wl_client_evas_deinit(ec);
1221 e_pixmap_cdata_set(ec->pixmap, NULL);
1223 _e_surface_destroy(surface);
1229 _e_surface_cb_destroy(struct wl_listener *listener, void *data)
1233 surface = wl_container_of(listener, surface, destroy);
1235 wl_signal_emit(&surface->events.destroy, surface);
1237 wl_list_remove(&surface->destroy.link);
1238 wl_list_remove(&surface->commit.link);
1239 wl_list_remove(&surface->new_subsurface.link);
1240 surface->ds_surface = NULL;
1242 e_comp_wl_client_surface_finish(surface->ec);
1246 _e_surface_cb_commit(struct wl_listener *listener, void *data)
1251 surface = wl_container_of(listener, surface, commit);
1253 _e_surface_pending_update(surface);
1254 _e_surface_commit_pre(surface);
1256 if (e_comp_wl_remote_surface_commit(surface->ec)) return;
1258 sub = _e_subsurface_from_surface(surface);
1260 _e_subsurface_commit(sub);
1262 _e_surface_commit(surface);
1266 _e_surface_cb_new_subsurface(struct wl_listener *listener, void *data)
1268 struct ds_subsurface *ds_subsurface = data;
1271 surface = wl_container_of(listener, surface, new_subsurface);
1273 if (!_e_subsurface_create(ds_subsurface, surface))
1275 ELOGF("COMPOSITOR", "Could not create E_Subsurface", surface->ec);
1280 static E_Subsurface *
1281 _e_subsurface_create(struct ds_subsurface *ds_subsurface, E_Surface *parent_surface)
1285 E_Client *offscreen_parent = NULL, *epc = parent_surface->ec;
1287 sub = E_NEW(E_Subsurface, 1);
1291 surface = _e_surface_from_ds_surface(ds_subsurface->surface);
1293 if (parent_surface->base.remote_surface.onscreen_parent)
1295 offscreen_parent = epc;
1296 epc = parent_surface->base.remote_surface.onscreen_parent;
1299 if (e_comp_wl_client_subsurface_cyclic_reference_check(surface->ec, epc))
1301 ERR("Subsurface parent relationship is a cycle : "
1302 "[child win : %zx, %s], [parent win : %zx, %s]",
1303 e_client_util_win_get(surface->ec),
1304 e_client_util_name_get(surface->ec),
1305 e_client_util_win_get(epc),
1306 e_client_util_name_get(epc));
1311 if (!e_comp_wl_surface_role_set(surface->ec, e_comp_wl_subsurface_role_name,
1318 sub->ds_subsurface = ds_subsurface;
1319 sub->destroy.notify = _e_subsurface_cb_destroy;
1320 wl_signal_add(&ds_subsurface->events.destroy, &sub->destroy);
1322 sub->cached.notify = _e_subsurface_cb_cached;
1323 wl_signal_add(&ds_subsurface->events.cached, &sub->cached);
1325 sub->request_move.notify = _e_subsurface_cb_request_move;
1326 wl_signal_add(&ds_subsurface->events.request_move, &sub->request_move);
1328 sub->surface = surface;
1329 sub->surface_destroy.notify = _e_subsurface_cb_surface_destroy;
1330 wl_signal_add(&surface->base.destroy_signal, &sub->surface_destroy);
1332 sub->parent_surface_destroy.notify = _e_subsurface_cb_parent_surface_destroy;
1333 wl_signal_add(&parent_surface->base.destroy_signal, &sub->parent_surface_destroy);
1335 e_comp_wl_client_subsurface_init(surface->ec,
1336 ds_subsurface->resource,
1341 _e_subsurface_position_update(sub);
1343 ELOGF("SUBSURFACE", "Create: parent(%p)", surface->ec, epc);
1349 _e_subsurface_destroy(E_Subsurface *sub)
1351 ELOGF("SUBSURFACE", "Destroy", sub->surface->ec);
1352 e_comp_wl_client_subsurface_finish(sub->surface->ec);
1353 wl_list_remove(&sub->request_move.link);
1354 wl_list_remove(&sub->parent_surface_destroy.link);
1355 wl_list_remove(&sub->cached.link);
1356 wl_list_remove(&sub->surface_destroy.link);
1357 wl_list_remove(&sub->destroy.link);
1361 static E_Subsurface *
1362 _e_subsurface_from_ds_subsurface(struct ds_subsurface *ds_subsurface)
1364 struct wl_listener *listener;
1365 E_Subsurface *sub = NULL;
1367 listener = wl_signal_get(&ds_subsurface->events.destroy,
1368 _e_subsurface_cb_destroy);
1370 sub = wl_container_of(listener, sub, destroy);
1375 static E_Subsurface *
1376 _e_subsurface_from_surface(E_Surface *surface)
1378 struct ds_subsurface *ds_subsurface;
1380 if (!surface->ds_surface)
1383 ds_subsurface = ds_subsurface_from_surface(surface->ds_surface);
1387 return _e_subsurface_from_ds_subsurface(ds_subsurface);
1390 static E_Subsurface *
1391 _e_subsurface_from_resource(struct wl_resource *resource)
1393 struct ds_subsurface *ds_subsurface;
1395 ds_subsurface = ds_subsurface_from_resource(resource);
1399 return _e_subsurface_from_ds_subsurface(ds_subsurface);
1403 _e_subsurface_synchronized_check(E_Subsurface *sub)
1405 struct ds_subsurface *ds_subsurface = sub->ds_subsurface;
1409 if (ds_subsurface->synchronized)
1412 while ((ds_subsurface = ds_subsurface_from_surface(ds_subsurface->parent)));
1418 _e_subsurface_commit(E_Subsurface *sub)
1420 if (sub->base.cached.has_data)
1422 e_comp_wl_client_subsurface_commit_to_cache(sub->surface->ec);
1423 e_comp_wl_client_subsurface_commit_from_cache(sub->surface->ec);
1427 e_comp_wl_surface_commit(sub->surface->ec);
1430 if (_e_subsurface_synchronized_check(sub))
1432 e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_SYNCHRONIZED_COMMIT,
1438 _e_subsurface_position_update(E_Subsurface *sub)
1440 E_Client *ec = sub->surface->ec;
1443 if (e_comp_wl_subsurface_global_coord_get(ec, &x, &y))
1444 evas_object_move(ec->frame, x, y);
1448 _e_subsurface_place_below_parent(E_Subsurface *sub)
1450 struct ds_subsurface *ds_subsurface = sub->ds_subsurface;
1452 wl_list_remove(&ds_subsurface->pending.link);
1453 wl_list_insert(ds_subsurface->parent->pending.subsurfaces_below.prev,
1454 &ds_subsurface->pending.link);
1457 wl_list_remove(&ds_subsurface->current.link);
1458 wl_list_insert(ds_subsurface->parent->current.subsurfaces_below.prev,
1459 &ds_subsurface->current.link);
1461 ds_subsurface->reordered = true;
1465 _e_subsurface_cb_destroy(struct wl_listener *listener, void *data)
1469 sub = wl_container_of(listener, sub, destroy);
1470 _e_subsurface_destroy(sub);
1474 _e_subsurface_cb_cached(struct wl_listener *listener, void *data)
1478 sub = wl_container_of(listener, sub, cached);
1480 e_presentation_time_container_feedback_discard(&sub->base.cached.presentation_container);
1481 e_presentation_time_container_feedback_merge(&sub->base.cached.presentation_container,
1482 &sub->surface->base.pending.presentation_container);
1484 sub->base.cached.has_data = EINA_TRUE;
1486 e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_COMMIT_TO_CACHE, sub->surface->ec);
1490 _e_subsurface_cb_request_move(struct wl_listener *listener, void *data)
1493 struct ds_subsurface *ds_subsurface;
1495 sub = wl_container_of(listener, sub, request_move);
1496 ds_subsurface = sub->ds_subsurface;
1498 if ((sub->base.position.x == ds_subsurface->current.x) &&
1499 (sub->base.position.y == ds_subsurface->current.y))
1502 sub->base.position.x = ds_subsurface->current.x;
1503 sub->base.position.y = ds_subsurface->current.y;
1505 _e_subsurface_position_update(sub);
1509 _e_subsurface_cb_surface_destroy(struct wl_listener *listener, void *data)
1513 sub = wl_container_of(listener, sub, surface_destroy);
1514 _e_subsurface_destroy(sub);
1518 _e_subsurface_cb_parent_surface_destroy(struct wl_listener *listener, void *data)
1522 sub = wl_container_of(listener, sub, parent_surface_destroy);
1524 wl_signal_emit(&sub->surface->events.parent_destroy, sub->surface);
1526 wl_list_remove(&sub->parent_surface_destroy.link);
1527 wl_list_init(&sub->parent_surface_destroy.link);
1529 e_comp_wl_client_subsurface_parent_unset(sub->surface->ec);
1533 _ds_surface_buffer_transform_set(struct ds_surface *ds_surface, enum wl_output_transform transform)
1535 ds_surface->pending.transform = transform;
1536 ds_surface->current.transform = transform;
1540 _ds_surface_viewport_source_box_set(struct ds_surface *ds_surface, Eina_Rectangle *box)
1542 ds_surface->pending.viewport.has_src = true;
1543 ds_surface->pending.viewport.src.x = (double)box->x;
1544 ds_surface->pending.viewport.src.y = (double)box->y;
1545 ds_surface->pending.viewport.src.width = (double)box->w;
1546 ds_surface->pending.viewport.src.height = (double)box->h;
1547 ds_surface->current.viewport.has_src = true;
1548 ds_surface->current.viewport.src = ds_surface->pending.viewport.src;
1552 _ds_surface_viewport_destination_set(struct ds_surface *ds_surface, int32_t width, int32_t height)
1554 ds_surface->pending.viewport.has_dst = true;
1555 ds_surface->pending.viewport.dst_width = width;
1556 ds_surface->pending.viewport.dst_height = height;
1557 ds_surface->pending.width = width;
1558 ds_surface->pending.height = height;
1559 ds_surface->current.viewport.has_dst = true;
1560 ds_surface->current.viewport.dst_width = width;
1561 ds_surface->current.viewport.dst_height = height;
1562 ds_surface->current.width = width;
1563 ds_surface->current.height = height;
1567 _ds_surface_viewport_unset(struct ds_surface *ds_surface)
1569 ds_surface->pending.viewport.has_src = false;
1570 ds_surface->pending.viewport.has_dst = false;
1571 ds_surface->current.viewport.has_src = false;
1572 ds_surface->current.viewport.has_dst = false;
1576 _ds_subsurface_position_set(struct ds_subsurface *ds_subsurface, int x, int y)
1578 ds_subsurface->pending.x = x;
1579 ds_subsurface->pending.y = y;
1581 ds_subsurface->current.x = x;
1582 ds_subsurface->current.y = y;