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 parent_destroy;
55 E_Comp_Wl_Subsurf_Data base;
58 struct ds_subsurface *ds_subsurface;
60 struct wl_listener destroy;
61 struct wl_listener surface_destroy;
62 struct wl_listener parent_surface_destroy;
63 struct wl_listener cached;
64 struct wl_listener request_move;
67 struct _E_Frame_Callback
70 struct wl_listener destroy;
73 static void _e_compositor_cb_display_destroy(struct wl_listener *listener, void *data);
74 static void _e_compositor_cb_new_surface(struct wl_listener *listener, void *data);
75 static void _e_compositor_cb_new_client(void *data EINA_UNUSED, E_Client *ec);
77 static E_Surface *_e_surface_create(E_Client *ec);
78 static E_Surface *_e_surface_from_ds_surface(struct ds_surface *ds_surface);
79 static E_Surface *_e_surface_from_comp_data(E_Comp_Wl_Client_Data *comp_data);
80 static void _e_surface_destroy(E_Surface *surface);
81 static void _e_surface_ds_surface_set(E_Surface *surface, struct ds_surface *ds_surface);
82 static void _e_surface_cb_client_del(void *data, E_Client *ec);
83 static void _e_surface_cb_destroy(struct wl_listener *listener, void *data);
84 static void _e_surface_cb_commit(struct wl_listener *listener, void *data);
85 static void _e_surface_cb_new_subsurface(struct wl_listener *listener, void *data);
87 static E_Subsurface *_e_subsurface_create(struct ds_subsurface *ds_subsurface, E_Surface *parent_surface);
88 static E_Subsurface *_e_subsurface_from_surface(E_Surface *surface);
89 static E_Subsurface *_e_subsurface_from_resource(struct wl_resource *resource);
90 static E_Subsurface *_e_subsurface_from_ds_subsurface(struct ds_subsurface *ds_subsurface);
91 static void _e_subsurface_destroy(E_Subsurface *sub);
92 static void _e_subsurface_commit(E_Subsurface *sub);
93 static void _e_subsurface_place_below_parent(E_Subsurface *sub);
94 static void _e_subsurface_position_update(E_Subsurface *sub);
95 static void _e_subsurface_cb_destroy(struct wl_listener *listener, void *data);
96 static void _e_subsurface_cb_cached(struct wl_listener *listener, void *data);
97 static void _e_subsurface_cb_request_move(struct wl_listener *listener, void *data);
98 static void _e_subsurface_cb_surface_destroy(struct wl_listener *listener, void *data);
99 static void _e_subsurface_cb_parent_surface_destroy(struct wl_listener *listener, void *data);
101 static void _ds_surface_buffer_transform_set(struct ds_surface *ds_surface, enum wl_output_transform transform);
102 static void _ds_surface_viewport_source_box_set(struct ds_surface *ds_surface, Eina_Rectangle *box);
103 static void _ds_surface_viewport_destination_set(struct ds_surface *ds_surface, int32_t width, int32_t height);
104 static void _ds_surface_viewport_unset(struct ds_surface *ds_surface);
105 static void _ds_subsurface_position_set(struct ds_subsurface *ds_subsurface, int x, int y);
107 static const char *e_comp_wl_subsurface_role_name = "ds_subsurface";
108 static E_Compositor *_compositor;
111 e_compositor_init(struct wl_display *display)
118 comp = E_NEW(E_Compositor, 1);
122 comp->ds_compositor = ds_compositor_create(display);
123 if (!comp->ds_compositor)
125 ELOGF("COMPOSITOR", "Could not create ds_compositor", NULL);
130 comp->ds_subcompositor = ds_subcompositor_create(display);
131 if (!comp->ds_subcompositor)
133 ELOGF("COMPOSITOR", "Could not create ds_subcompositor", NULL);
138 comp->new_surface.notify = _e_compositor_cb_new_surface;
139 ds_compositor_add_new_surface_listener(comp->ds_compositor,
142 comp->new_client_hook = e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT,
143 _e_compositor_cb_new_client,
146 comp->display_destroy.notify = _e_compositor_cb_display_destroy;
147 wl_display_add_destroy_listener(display, &comp->display_destroy);
155 e_compositor_util_client_from_surface_resource(struct wl_resource *surface_resource)
158 struct ds_surface *ds_surface;
160 ds_surface = ds_surface_from_resource(surface_resource);
164 surface = _e_surface_from_ds_surface(ds_surface);
172 e_comp_wl_subsurface_add(struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource)
174 return !!ds_subsurface_create(resource,
175 ds_surface_from_resource(surface_resource),
176 ds_surface_from_resource(parent_resource),
181 e_comp_wl_subsurface_resource_stand_alone_mode_set(struct wl_resource *subsurface_resource)
185 sub = _e_subsurface_from_resource(subsurface_resource);
188 INF("The given subsurface resource(%p) seems inert.", subsurface_resource);
192 ELOGF("SUBSURFACE", "SUBSURF|STAND_ALONE", sub->surface->ec);
194 sub->base.stand_alone = EINA_TRUE;
198 e_comp_wl_subsurface_resource_place_below_parent(struct wl_resource *subsurface_resource)
201 E_Comp_Wl_Client_Data *epc_cdata;
203 sub = _e_subsurface_from_resource(subsurface_resource);
206 INF("The given subsurface resource(%p) seems inert.", subsurface_resource);
210 EINA_SAFETY_ON_NULL_RETURN(sub->base.parent);
211 epc_cdata = e_client_cdata_get(sub->base.parent);
212 EINA_SAFETY_ON_NULL_RETURN(epc_cdata);
214 ELOGF("SUBSURFACE", "SUBSURF|BELOW_PARENT", sub->surface->ec);
216 _e_subsurface_place_below_parent(sub);
218 epc_cdata->sub.list = eina_list_remove(epc_cdata->sub.list, sub->surface->ec);
219 epc_cdata->sub.list_pending = eina_list_remove(epc_cdata->sub.list_pending, sub->surface->ec);
220 epc_cdata->sub.below_list = eina_list_remove(epc_cdata->sub.below_list, sub->surface->ec);
221 epc_cdata->sub.below_list_pending = eina_list_remove(epc_cdata->sub.below_list_pending, sub->surface->ec);
223 epc_cdata->sub.below_list_pending = eina_list_append(epc_cdata->sub.below_list_pending, sub->surface->ec);
224 epc_cdata->sub.below_list = eina_list_append(epc_cdata->sub.below_list, sub->surface->ec);
225 epc_cdata->sub.list_changed = EINA_TRUE;
229 e_comp_wl_subsurface_commit(E_Client *ec)
234 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
236 if (e_object_is_del(E_OBJECT(ec)) || !ec->comp_data) return EINA_FALSE;
238 surface = _e_surface_from_comp_data(ec->comp_data);
239 sub = _e_subsurface_from_surface(surface);
243 _e_subsurface_commit(sub);
249 e_surface_from_resource(struct wl_resource *surface_resource)
252 struct ds_surface *ds_surface;
254 ds_surface = ds_surface_from_resource(surface_resource);
258 surface = _e_surface_from_ds_surface(ds_surface);
266 e_surface_destroy_listener_add(E_Surface *surface, struct wl_listener *listener)
268 wl_signal_add(&surface->base.destroy_signal, listener);
271 EINTERN struct wl_listener *
272 e_surface_destroy_listener_get(E_Surface *surface, wl_notify_func_t notify)
274 return wl_signal_get(&surface->base.destroy_signal, notify);
278 e_surface_parent_destroy_listener_add(E_Surface *surface, struct wl_listener *listener)
280 wl_signal_add(&surface->events.parent_destroy, listener);
284 e_surface_viewporter_resource_set(E_Surface *surface, struct wl_resource *viewporter)
286 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
288 if (surface->base.scaler.viewport)
291 if (surface->surface_viewport)
294 surface->surface_viewport = ds_surface_take_viewport(surface->ds_surface);
295 if (!surface->surface_viewport)
298 surface->base.scaler.viewport = viewporter;
304 e_surface_viewporter_resource_unset(E_Surface *surface)
306 EINA_SAFETY_ON_NULL_RETURN(surface);
308 surface->base.scaler.viewport = NULL;
309 surface->base.scaler.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
310 surface->base.scaler.buffer_viewport.surface.width = -1;
311 surface->base.scaler.buffer_viewport.changed = 1;
312 surface->base.pending.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
313 surface->base.pending.buffer_viewport.surface.width = -1;
314 surface->base.pending.buffer_viewport.changed = 1;
316 if (surface->surface_viewport)
318 ds_surface_viewport_release(surface->surface_viewport);
319 surface->surface_viewport = NULL;
322 if (surface->ds_surface)
323 _ds_surface_viewport_unset(surface->ds_surface);
326 EINTERN enum wl_output_transform
327 e_surface_buffer_transform_get(E_Surface *surface)
329 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, WL_OUTPUT_TRANSFORM_NORMAL);
330 return surface->base.scaler.buffer_viewport.buffer.transform;
334 e_surface_buffer_transform_set(E_Surface *surface, enum wl_output_transform transform)
337 E_Comp_Wl_Buffer_Viewport *vp;
339 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
341 vp = &surface->base.scaler.buffer_viewport;
342 if (vp->buffer.transform == transform)
345 vp->buffer.transform = transform;
346 vp->changed = EINA_TRUE;
348 surface->base.pending.buffer_viewport = *vp;
350 sub = _e_subsurface_from_surface(surface);
352 sub->base.cached.buffer_viewport = *vp;
354 if (surface->ds_surface)
355 _ds_surface_buffer_transform_set(surface->ds_surface, transform);
361 e_surface_viewport_source_box_set(E_Surface *surface, Eina_Rectangle *box)
364 E_Comp_Wl_Buffer_Viewport *vp;
365 wl_fixed_t fx, fy, fw, fh;
367 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
369 fx = wl_fixed_from_int(box->x);
370 fy = wl_fixed_from_int(box->y);
371 fw = wl_fixed_from_int(box->w);
372 fh = wl_fixed_from_int(box->h);
374 vp = &surface->base.scaler.buffer_viewport;
375 if ((vp->buffer.src_x == fx) && (vp->buffer.src_y == fy) &&
376 (vp->buffer.src_width == fw) && (vp->buffer.src_height == fh))
379 vp->buffer.src_x = fx;
380 vp->buffer.src_y = fy;
381 vp->buffer.src_width = fw;
382 vp->buffer.src_height = fh;
383 vp->changed = EINA_TRUE;
385 surface->base.pending.buffer_viewport = *vp;
387 sub = _e_subsurface_from_surface(surface);
389 sub->base.cached.buffer_viewport = *vp;
391 if (surface->ds_surface)
392 _ds_surface_viewport_source_box_set(surface->ds_surface, box);
398 e_surface_viewport_destination_set(E_Surface *surface, int32_t width, int32_t height)
401 E_Comp_Wl_Buffer_Viewport *vp;
403 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
405 vp = &surface->base.scaler.buffer_viewport;
406 if ((vp->surface.width == width) && (vp->surface.height == height))
409 vp->surface.width = width;
410 vp->surface.height = height;
411 vp->changed = EINA_TRUE;
413 surface->base.pending.buffer_viewport = *vp;
415 sub = _e_subsurface_from_surface(surface);
417 sub->base.cached.buffer_viewport = *vp;
419 if (surface->ds_surface)
420 _ds_surface_viewport_destination_set(surface->ds_surface, width, height);
426 e_surface_viewport_changed_get(E_Surface *surface)
428 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
429 return surface->base.scaler.buffer_viewport.changed;
432 EINTERN E_Subsurface *
433 e_subsurface_from_surface(E_Surface *surface)
435 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, NULL);
436 return _e_subsurface_from_surface(surface);
440 e_subsurface_position_set(E_Subsurface *subsurface, int x, int y)
442 EINA_SAFETY_ON_NULL_RETURN_VAL(subsurface, EINA_FALSE);
444 if ((subsurface->base.position.x == x) && (subsurface->base.position.y == y))
447 subsurface->base.position.x = x;
448 subsurface->base.position.y = y;
449 subsurface->base.position.set = EINA_TRUE;
451 _ds_subsurface_position_set(subsurface->ds_subsurface, x, y);
457 _e_compositor_cb_display_destroy(struct wl_listener *listener EINA_UNUSED, void *data EINA_UNUSED)
459 wl_list_remove(&_compositor->display_destroy.link);
460 wl_list_remove(&_compositor->new_surface.link);
461 e_client_hook_del(_compositor->new_client_hook);
466 _e_comp_wl_client_usable_get(pid_t pid, E_Pixmap *ep)
468 /* NOTE: this will return usable E_Client for a surface of specified process
469 * by pid. it doesn't care whatever this surfaces is for but care only what
470 * is owner process of the surface.
473 E_Client *ec = NULL, *_ec = NULL;
476 /* find launchscreen client list */
477 if (e_comp->launchscrns)
479 EINA_LIST_FOREACH(e_comp->launchscrns, l, _ec)
481 if (_ec->netwm.pid == pid)
489 E_Pixmap *oldep = NULL;
493 /* do NOT replace with the client having comp data */
497 e_comp->launchscrns = eina_list_remove(e_comp->launchscrns, ec);
499 oldep = e_client_pixmap_change(ec, ep);
502 e_pixmap_win_id_del(oldep);
503 e_pixmap_free(oldep);
509 /* to set-up comp data */
510 _e_compositor_cb_new_client(NULL, ec);
512 if (!ec->comp_data) return NULL;
513 e_comp_wl_client_evas_init(ec);
515 ELOGF("COMP", "Reusable ec. new_pixmap:%p", ec, ec->pixmap);
516 e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_REUSE, ec);
524 _e_compositor_cb_new_surface(struct wl_listener *listener, void *data)
526 struct ds_surface *ds_surface = data;
529 struct wl_resource *surface_resource;
533 DBG("New ds_surface %p", ds_surface);
535 TRACE_DS_BEGIN(COMP_WL:NEW SURFACE CB);
537 surface_resource = ds_surface_get_wl_resource(ds_surface);
538 wl_client_get_credentials(wl_resource_get_client(surface_resource), &pid, NULL, NULL);
542 ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, (uintptr_t)wl_resource_get_id(surface_resource));
544 else if ((ep = e_pixmap_find(E_PIXMAP_TYPE_WL, (uintptr_t)surface_resource)))
546 ERR("There is e_pixmap already, Delete old e_pixmap %p", ep);
547 e_pixmap_win_id_del(ep);
552 /* try to create new pixmap */
553 if (!(ep = e_pixmap_new(E_PIXMAP_TYPE_WL, surface_resource)))
555 ERR("Could not create new pixmap");
560 E_Comp_Wl_Client_Data *cdata = e_pixmap_cdata_get(ep);
562 cdata->wl_surface = surface_resource;
564 DBG("\tUsing Pixmap: %p", ep);
566 if (!(ec = _e_comp_wl_client_usable_get(pid, ep)))
568 ec = e_client_new(ep, 0, internal);
576 e_comp->new_clients--;
578 if ((!ec->client.w) && (ec->client.h))
579 ec->client.w = ec->client.h = 1;
581 e_comp_wl_client_surface_set(ec, surface_resource);
582 ec->icccm.accepts_focus = 1;
583 wl_list_init(&ec->comp_data->pointer_constraints);
585 _e_surface_ds_surface_set(_e_surface_from_comp_data(ec->comp_data),
589 DBG("\tUsing Client: %p", ec);
595 _e_compositor_cb_new_client(void *data EINA_UNUSED, E_Client *ec)
600 /* make sure this is a wayland client */
601 if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
603 TRACE_DS_BEGIN(COMP_WL:CLIENT NEW HOOK);
605 /* get window id from pixmap */
606 win = e_pixmap_window_get(ec->pixmap);
608 /* ignore fake root windows */
609 if ((ec->override) && ((ec->x == -77) && (ec->y == -77)))
611 e_comp_ignore_win_add(E_PIXMAP_TYPE_WL, win);
612 e_object_del(E_OBJECT(ec));
617 surface = _e_surface_create(ec);
620 ERR("Could not create E_Surface");
625 ec->comp_data = &surface->base;
627 /* set initial client properties */
628 ec->argb = EINA_FALSE;
629 ELOGF("COMP", "Set argb:%d", ec, ec->argb);
630 ec->redirected = ec->ignored = 1;
633 /* NB: could not find a better place to do this, BUT for internal windows,
634 * we need to set delete_request else the close buttons on the frames do
635 * basically nothing */
637 ec->icccm.delete_request = EINA_TRUE;
639 E_Comp_Wl_Client_Data *p_cdata = e_pixmap_cdata_get(ec->pixmap);
640 EINA_SAFETY_ON_NULL_GOTO(p_cdata, end);
642 e_pixmap_cdata_set(ec->pixmap, &surface->base);
644 g_mutex_init(&ec->comp_data->surface_mutex);
651 _e_surface_create(E_Client *ec)
655 surface = E_NEW(E_Surface, 1);
659 e_object_ref(E_OBJECT(ec));
662 wl_signal_init(&surface->events.parent_destroy);
663 wl_signal_init(&surface->base.destroy_signal);
664 wl_signal_init(&surface->base.apply_viewport_signal);
665 wl_signal_init(&surface->base.state_commit_signal);
667 e_comp_wl_surface_state_init(&surface->base.pending, ec->w, ec->h);
669 /* set initial client data properties */
670 surface->base.mapped = EINA_FALSE;
671 surface->base.first_damage = ec->internal;
672 surface->base.need_reparent = !ec->internal;
674 /* set initial value of scaler */
675 surface->base.scaler.buffer_viewport.buffer.transform = WL_OUTPUT_TRANSFORM_NORMAL;
676 surface->base.scaler.buffer_viewport.buffer.scale = 1;
677 surface->base.scaler.buffer_viewport.buffer.src_width = wl_fixed_from_int(-1);
678 surface->base.scaler.buffer_viewport.surface.width = -1;
680 e_presentation_time_container_init(&surface->base.presentation_container);
682 surface->client_del_hook = e_client_hook_add(E_CLIENT_HOOK_DEL,
683 _e_surface_cb_client_del,
690 _e_surface_destroy(E_Surface *surface)
692 struct wl_resource *cb;
694 g_mutex_lock(&surface->base.surface_mutex);
696 wl_signal_emit(&surface->base.destroy_signal, &surface->base.surface);
698 e_comp_wl_surface_state_finish(&surface->base.pending);
700 e_comp_wl_buffer_reference(&surface->base.buffer_ref, NULL);
702 EINA_LIST_FREE(surface->base.frames, cb)
703 wl_resource_destroy(cb);
705 EINA_LIST_FREE(surface->base.pending.frames, cb)
706 wl_resource_destroy(cb);
708 if (surface->base.aux_hint.hints)
710 E_Comp_Wl_Aux_Hint *hint;
711 EINA_LIST_FREE(surface->base.aux_hint.hints, hint)
713 eina_stringshare_del(hint->hint);
714 eina_stringshare_del(hint->val);
719 if (e_comp_wl->ptr.ec == surface->ec)
721 e_comp_wl->ptr.ec = NULL;
722 E_FREE_FUNC(e_comp_wl->ptr.hide_tmr, ecore_timer_del);
725 if (e_comp_wl->touch.faked_ec == surface->ec)
726 e_comp_wl->touch.faked_ec = NULL;
728 if (e_comp_wl->selection.cbhm == surface->base.surface)
729 e_comp_wl->selection.cbhm = NULL;
731 e_comp_wl_data_secondary_remove(surface->ec);
733 if (surface->base.viewport_transform)
735 e_client_transform_core_remove(surface->ec, surface->base.viewport_transform);
736 e_util_transform_del(surface->base.viewport_transform);
737 surface->base.viewport_transform = NULL;
740 e_presentation_time_container_finish(&surface->base.presentation_container);
742 E_FREE_FUNC(surface->base.on_focus_timer, ecore_timer_del);
744 e_client_hook_del(surface->client_del_hook);
746 g_mutex_unlock(&surface->base.surface_mutex);
748 g_mutex_clear(&surface->base.surface_mutex);
750 surface->ec->comp_data = NULL;
751 e_object_unref(E_OBJECT(surface->ec));
756 _e_surface_ds_surface_set(E_Surface *surface, struct ds_surface *ds_surface)
758 surface->ds_surface = ds_surface;
760 surface->destroy.notify = _e_surface_cb_destroy;
761 ds_surface_add_destroy_listener(ds_surface, &surface->destroy);
763 surface->commit.notify = _e_surface_cb_commit;
764 ds_surface_add_commit_listener(ds_surface, &surface->commit);
766 surface->new_subsurface.notify = _e_surface_cb_new_subsurface;
767 ds_surface_add_new_subsurface_listener(ds_surface, &surface->new_subsurface);
771 _e_surface_from_ds_surface(struct ds_surface *ds_surface)
773 E_Surface *surface = NULL;
774 struct wl_listener *listener;
776 listener = wl_signal_get(&ds_surface->events.destroy,
777 _e_surface_cb_destroy);
779 surface = wl_container_of(listener, surface, destroy);
785 _e_surface_from_comp_data(E_Comp_Wl_Client_Data *comp_data)
788 return wl_container_of(comp_data, surface, base);
792 _e_surface_root_surface_get(E_Surface *surface)
794 E_Surface *iter = surface;
797 while ((sub = _e_subsurface_from_surface(iter)))
798 iter = _e_surface_from_ds_surface(sub->ds_subsurface->parent);
804 _e_surface_buffer_video_content_type_check_and_set(E_Surface *surface, E_Comp_Wl_Buffer *buffer)
806 E_Client *ec = surface->ec;
808 if (ec->comp_data->video_client)
810 buffer->type = E_COMP_WL_BUFFER_TYPE_VIDEO;
811 buffer->w = buffer->h = 1;
814 else if (e_client_video_hw_composition_check(ec))
816 buffer->type = E_COMP_WL_BUFFER_TYPE_VIDEO;
821 _e_surface_pending_buffer_update(E_Surface *surface)
823 struct ds_surface *ds_surface = surface->ds_surface;
824 E_Client *ec = surface->ec;
825 E_Comp_Wl_Buffer *buffer = NULL;
827 if (ds_surface->buffer)
829 buffer = e_comp_wl_buffer_get(ds_surface->buffer);
831 _e_surface_buffer_video_content_type_check_and_set(surface, buffer);
834 e_comp_wl_client_surface_pending_buffer_set(ec, buffer,
835 ds_surface->current.dx,
836 ds_surface->current.dy);
840 _e_surface_pending_surface_damage_update(E_Surface *surface)
842 struct ds_surface *ds_surface = surface->ds_surface;
843 pixman_box32_t *rects;
848 rects = pixman_region32_rectangles(&ds_surface->current.surface_damage, &nrects);
849 for (i = 0; i < nrects; i++)
856 dmg = eina_rectangle_new(x, y, w, h);
859 surface->base.pending.damages =
860 eina_list_append(surface->base.pending.damages, dmg);
866 _e_surface_pending_buffer_damage_update(E_Surface *surface)
868 struct ds_surface *ds_surface = surface->ds_surface;
869 pixman_box32_t *rects;
874 rects = pixman_region32_rectangles(&ds_surface->current.buffer_damage, &nrects);
875 for (i = 0; i < nrects; i++)
882 dmg = eina_rectangle_new(x, y, w, h);
885 surface->base.pending.buffer_damages =
886 eina_list_append(surface->base.pending.buffer_damages, dmg);
892 _region_area_check(Eina_Tiler *tiler, int32_t x, int32_t y, int32_t w, int32_t h)
894 Eina_Bool need_set = EINA_FALSE;
898 eina_tiler_area_size_get(tiler, &area_w, &area_h);
902 need_set = EINA_TRUE;
908 need_set = EINA_TRUE;
913 INF("change region area. (%dx%d)", area_w, area_h);
914 eina_tiler_area_size_set(tiler, area_w, area_h);
919 _tiler_new_from_pixman_region(pixman_region32_t *pixman_region)
922 pixman_box32_t *rects;
926 tiler = eina_tiler_new(e_comp->w, e_comp->h);
930 eina_tiler_tile_size_set(tiler, 1, 1);
932 rects = pixman_region32_rectangles(pixman_region, &nrects);
933 for (i = 0; i < nrects; i++)
939 _region_area_check(tiler, x, y, w, h);
940 eina_tiler_rect_add(tiler, &(Eina_Rectangle){x, y, w, h});
947 _e_surface_pending_opaque_region_update(E_Surface *surface)
949 struct ds_surface *ds_surface = surface->ds_surface;
950 E_Client *ec = surface->ec;
953 if (pixman_region32_not_empty(&ds_surface->current.opaque))
955 region = _tiler_new_from_pixman_region(&ds_surface->current.opaque);
959 e_comp_wl_client_surface_pending_opaque_region_set(ec, region);
961 eina_tiler_free(region);
965 e_comp_wl_client_surface_pending_opaque_region_set(ec, NULL);
970 _e_surface_pending_input_region_update(E_Surface *surface)
972 struct ds_surface *ds_surface = surface->ds_surface;
973 E_Client *ec = surface->ec;
975 pixman_region32_t infinite_region;
977 pixman_region32_init_rect(&infinite_region, INT32_MIN, INT32_MIN, UINT32_MAX, UINT32_MAX);
978 if (pixman_region32_equal(&ds_surface->current.input, &infinite_region))
980 e_comp_wl_client_surface_pending_input_region_set(ec, NULL);
984 region = _tiler_new_from_pixman_region(&ds_surface->current.input);
987 e_comp_wl_client_surface_pending_input_region_set(ec, region);
988 eina_tiler_free(region);
994 _e_surface_pending_buffer_transform_update(E_Surface *surface)
996 int32_t transform = surface->ds_surface->current.transform;
998 surface->base.pending.buffer_viewport.buffer.transform = transform;
999 surface->base.pending.buffer_viewport.changed = 1;
1003 _e_surface_pending_buffer_scale_update(E_Surface *surface)
1005 int32_t scale = surface->ds_surface->current.scale;
1007 surface->base.pending.buffer_viewport.buffer.scale = scale;
1008 surface->base.pending.buffer_viewport.changed = 1;
1012 _frame_callback_cb_destroy(struct wl_listener *listener, void *data)
1014 struct wl_resource *resource = data;
1015 E_Frame_Callback *frame_callback;
1017 frame_callback = wl_container_of(listener, frame_callback, destroy);
1018 e_comp_wl_client_surface_frame_callback_remove(frame_callback->ec, resource);
1019 e_object_unref(E_OBJECT(frame_callback->ec));
1020 free(frame_callback);
1024 _e_surface_pending_frame_callback_update(E_Surface *surface)
1026 struct ds_surface *ds_surface = surface->ds_surface;
1027 E_Client *ec = surface->ec;
1028 E_Frame_Callback *frame_callback;
1029 struct wl_resource *resource;
1031 wl_resource_for_each(resource, &ds_surface->current.frame_callback_list)
1033 frame_callback = E_NEW(E_Frame_Callback, 1);
1034 if (!frame_callback)
1037 e_object_ref(E_OBJECT(ec));
1038 frame_callback->ec = ec;
1040 frame_callback->destroy.notify = _frame_callback_cb_destroy;
1041 wl_resource_add_destroy_listener(resource, &frame_callback->destroy);
1043 e_comp_wl_client_surface_pending_frame_callback_add(ec, resource);
1046 wl_list_init(&ds_surface->current.frame_callback_list);
1050 _e_surface_pending_viewport_update(E_Surface *surface)
1052 struct ds_surface *ds_surface = surface->ds_surface;
1053 struct ds_surface_state *state = &ds_surface->current;
1054 E_Comp_Wl_Buffer_Viewport *vp = &surface->base.pending.buffer_viewport;
1056 if (state->viewport.has_src)
1058 vp->buffer.src_x = wl_fixed_from_double(state->viewport.src.x);
1059 vp->buffer.src_y = wl_fixed_from_double(state->viewport.src.y);
1060 vp->buffer.src_width = wl_fixed_from_double(state->viewport.src.width);
1061 vp->buffer.src_height = wl_fixed_from_double(state->viewport.src.height);
1062 vp->changed = EINA_TRUE;
1066 vp->buffer.src_width = wl_fixed_from_int(-1);
1067 vp->changed = EINA_TRUE;
1070 if (state->viewport.has_dst)
1072 vp->surface.width = state->viewport.dst_width;
1073 vp->surface.height = state->viewport.dst_height;
1074 vp->changed = EINA_TRUE;
1078 vp->surface.width = -1;
1079 vp->changed = EINA_TRUE;
1084 _e_surface_pending_subsurface_order_update(E_Surface *surface)
1086 struct ds_surface *ds_surface = surface->ds_surface;
1087 struct ds_subsurface *ds_subsurface;
1089 Eina_Bool reordered = EINA_FALSE;
1091 E_FREE_FUNC(surface->base.sub.list_pending, eina_list_free);
1092 E_FREE_FUNC(surface->base.sub.below_list_pending, eina_list_free);
1094 wl_list_for_each(ds_subsurface,
1095 &ds_surface->pending.subsurfaces_above,
1098 sub = _e_subsurface_from_ds_subsurface(ds_subsurface);
1099 surface->base.sub.list_pending =
1100 eina_list_append(surface->base.sub.list_pending, sub->surface->ec);
1102 reordered |= ds_subsurface->reordered;
1103 ds_subsurface->reordered = false;
1105 _e_surface_pending_subsurface_order_update(sub->surface);
1108 wl_list_for_each(ds_subsurface,
1109 &ds_surface->pending.subsurfaces_below,
1112 sub = _e_subsurface_from_ds_subsurface(ds_subsurface);
1113 surface->base.sub.below_list_pending =
1114 eina_list_append(surface->base.sub.below_list_pending, sub->surface->ec);
1116 reordered |= ds_subsurface->reordered;
1117 ds_subsurface->reordered = false;
1119 _e_surface_pending_subsurface_order_update(sub->surface);
1122 surface->base.sub.list_changed |= reordered;
1126 _e_surface_pending_update(E_Surface *surface)
1128 E_Surface *root_surface;
1129 struct ds_surface *ds_surface = surface->ds_surface;
1131 if (ds_surface->current.committed & DS_SURFACE_STATE_BUFFER)
1132 _e_surface_pending_buffer_update(surface);
1134 if (ds_surface->current.committed & DS_SURFACE_STATE_SURFACE_DAMAGE)
1135 _e_surface_pending_surface_damage_update(surface);
1137 if (ds_surface->current.committed & DS_SURFACE_STATE_BUFFER_DAMAGE)
1138 _e_surface_pending_buffer_damage_update(surface);
1140 if (ds_surface->current.committed & DS_SURFACE_STATE_OPAQUE_REGION)
1141 _e_surface_pending_opaque_region_update(surface);
1143 if (ds_surface->current.committed & DS_SURFACE_STATE_INPUT_REGION)
1144 _e_surface_pending_input_region_update(surface);
1146 if (ds_surface->current.committed & DS_SURFACE_STATE_TRANSFORM)
1147 _e_surface_pending_buffer_transform_update(surface);
1149 if (ds_surface->current.committed & DS_SURFACE_STATE_SCALE)
1150 _e_surface_pending_buffer_scale_update(surface);
1152 if (ds_surface->current.committed & DS_SURFACE_STATE_FRAME_CALLBACK_LIST)
1153 _e_surface_pending_frame_callback_update(surface);
1155 if (ds_surface->current.committed & DS_SURFACE_STATE_VIEWPORT)
1156 _e_surface_pending_viewport_update(surface);
1159 // It's not supposed to update subsurface order for entire surface tree.
1160 // This is for backward compatibility
1161 root_surface = _e_surface_root_surface_get(surface);
1162 _e_surface_pending_subsurface_order_update(root_surface);
1166 _e_surface_commit_pre(E_Surface *surface)
1168 E_Client *ec = surface->ec;
1169 E_Comp_Config *comp_conf = NULL;
1171 if (e_object_is_del(E_OBJECT(ec))) return;
1173 if (!surface->base.first_commit)
1174 surface->base.first_commit = EINA_TRUE;
1176 if (!surface->base.mapped)
1178 if (surface->base.shell.surface && surface->base.pending.new_attach &&
1179 !ec->internal && !e_comp_wl_subsurface_check(ec) && !ec->remote_surface.provider)
1181 ELOGF("COMP", "Current unmapped. COMMIT. pixmap_usable:%d", ec, e_pixmap_usable_get(ec->pixmap));
1183 // no canvas update before client's commit request, begin rendering after 1st commit
1184 comp_conf = e_comp_config_get();
1185 if (comp_conf && comp_conf->canvas_render_delay_after_boot && e_comp->canvas_render_delayed)
1187 ELOGF("COMP", "Begin canvas update for the first time after boot", ec);
1188 e_comp->canvas_render_delayed = EINA_FALSE;
1193 e_comp_wl_hook_call(E_COMP_WL_HOOK_CLIENT_BEFORE_SURFACE_COMMIT, ec);
1197 _e_surface_commit(E_Surface *surface)
1199 e_comp_wl_client_surface_pending_commit(surface->ec);
1203 _e_surface_cb_client_del(void *data, E_Client *ec)
1205 E_Surface *surface = data;
1207 if (surface->ec != ec)
1210 /* make sure this is a wayland client */
1211 if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
1213 TRACE_DS_BEGIN(COMP_WL:CLIENT DEL CB);
1215 e_comp_wl_hook_call(E_COMP_WL_HOOK_DEL, ec);
1217 e_comp_wl_client_evas_deinit(ec);
1219 e_pixmap_cdata_set(ec->pixmap, NULL);
1221 _e_surface_destroy(surface);
1227 _e_surface_cb_destroy(struct wl_listener *listener, void *data)
1231 surface = wl_container_of(listener, surface, destroy);
1233 if (surface->surface_viewport)
1235 ds_surface_viewport_release(surface->surface_viewport);
1236 surface->surface_viewport = NULL;
1239 wl_list_remove(&surface->destroy.link);
1240 wl_list_remove(&surface->commit.link);
1241 wl_list_remove(&surface->new_subsurface.link);
1242 surface->ds_surface = NULL;
1244 e_comp_wl_client_surface_finish(surface->ec);
1248 _e_surface_cb_commit(struct wl_listener *listener, void *data)
1253 surface = wl_container_of(listener, surface, commit);
1255 _e_surface_pending_update(surface);
1256 _e_surface_commit_pre(surface);
1258 if (e_comp_wl_remote_surface_commit(surface->ec)) return;
1260 sub = _e_subsurface_from_surface(surface);
1262 _e_subsurface_commit(sub);
1264 _e_surface_commit(surface);
1268 _e_surface_cb_new_subsurface(struct wl_listener *listener, void *data)
1270 struct ds_subsurface *ds_subsurface = data;
1273 surface = wl_container_of(listener, surface, new_subsurface);
1275 if (!_e_subsurface_create(ds_subsurface, surface))
1277 ELOGF("COMPOSITOR", "Could not create E_Subsurface", surface->ec);
1282 static E_Subsurface *
1283 _e_subsurface_create(struct ds_subsurface *ds_subsurface, E_Surface *parent_surface)
1287 E_Client *offscreen_parent = NULL, *epc = parent_surface->ec;
1289 sub = E_NEW(E_Subsurface, 1);
1293 surface = _e_surface_from_ds_surface(ds_subsurface->surface);
1295 if (parent_surface->base.remote_surface.onscreen_parent)
1297 offscreen_parent = epc;
1298 epc = parent_surface->base.remote_surface.onscreen_parent;
1301 if (e_comp_wl_client_subsurface_cyclic_reference_check(surface->ec, epc))
1303 ERR("Subsurface parent relationship is a cycle : "
1304 "[child win : %zx, %s], [parent win : %zx, %s]",
1305 e_client_util_win_get(surface->ec),
1306 e_client_util_name_get(surface->ec),
1307 e_client_util_win_get(epc),
1308 e_client_util_name_get(epc));
1313 if (!e_comp_wl_surface_role_set(surface->ec, e_comp_wl_subsurface_role_name,
1320 sub->ds_subsurface = ds_subsurface;
1321 sub->destroy.notify = _e_subsurface_cb_destroy;
1322 wl_signal_add(&ds_subsurface->events.destroy, &sub->destroy);
1324 sub->cached.notify = _e_subsurface_cb_cached;
1325 wl_signal_add(&ds_subsurface->events.cached, &sub->cached);
1327 sub->request_move.notify = _e_subsurface_cb_request_move;
1328 wl_signal_add(&ds_subsurface->events.request_move, &sub->request_move);
1330 sub->surface = surface;
1331 sub->surface_destroy.notify = _e_subsurface_cb_surface_destroy;
1332 wl_signal_add(&surface->base.destroy_signal, &sub->surface_destroy);
1334 sub->parent_surface_destroy.notify = _e_subsurface_cb_parent_surface_destroy;
1335 wl_signal_add(&parent_surface->base.destroy_signal, &sub->parent_surface_destroy);
1337 e_comp_wl_client_subsurface_init(surface->ec,
1338 ds_subsurface->resource,
1343 _e_subsurface_position_update(sub);
1345 ELOGF("SUBSURFACE", "Create: parent(%p)", surface->ec, epc);
1351 _e_subsurface_destroy(E_Subsurface *sub)
1353 ELOGF("SUBSURFACE", "Destroy", sub->surface->ec);
1354 e_comp_wl_client_subsurface_finish(sub->surface->ec);
1355 wl_list_remove(&sub->request_move.link);
1356 wl_list_remove(&sub->parent_surface_destroy.link);
1357 wl_list_remove(&sub->cached.link);
1358 wl_list_remove(&sub->surface_destroy.link);
1359 wl_list_remove(&sub->destroy.link);
1363 static E_Subsurface *
1364 _e_subsurface_from_ds_subsurface(struct ds_subsurface *ds_subsurface)
1366 struct wl_listener *listener;
1367 E_Subsurface *sub = NULL;
1369 listener = wl_signal_get(&ds_subsurface->events.destroy,
1370 _e_subsurface_cb_destroy);
1372 sub = wl_container_of(listener, sub, destroy);
1377 static E_Subsurface *
1378 _e_subsurface_from_surface(E_Surface *surface)
1380 struct ds_subsurface *ds_subsurface;
1382 if (!surface->ds_surface)
1385 ds_subsurface = ds_subsurface_from_surface(surface->ds_surface);
1389 return _e_subsurface_from_ds_subsurface(ds_subsurface);
1392 static E_Subsurface *
1393 _e_subsurface_from_resource(struct wl_resource *resource)
1395 struct ds_subsurface *ds_subsurface;
1397 ds_subsurface = ds_subsurface_from_resource(resource);
1401 return _e_subsurface_from_ds_subsurface(ds_subsurface);
1405 _e_subsurface_synchronized_check(E_Subsurface *sub)
1407 struct ds_subsurface *ds_subsurface = sub->ds_subsurface;
1411 if (ds_subsurface->synchronized)
1414 while ((ds_subsurface = ds_subsurface_from_surface(ds_subsurface->parent)));
1420 _e_subsurface_commit(E_Subsurface *sub)
1422 if (sub->base.cached.has_data)
1424 e_comp_wl_client_subsurface_commit_to_cache(sub->surface->ec);
1425 e_comp_wl_client_subsurface_commit_from_cache(sub->surface->ec);
1429 e_comp_wl_surface_commit(sub->surface->ec);
1432 if (_e_subsurface_synchronized_check(sub))
1434 e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_SYNCHRONIZED_COMMIT,
1440 _e_subsurface_position_update(E_Subsurface *sub)
1442 E_Client *ec = sub->surface->ec;
1445 if (e_comp_wl_subsurface_global_coord_get(ec, &x, &y))
1446 evas_object_move(ec->frame, x, y);
1450 _e_subsurface_place_below_parent(E_Subsurface *sub)
1452 struct ds_subsurface *ds_subsurface = sub->ds_subsurface;
1454 wl_list_remove(&ds_subsurface->pending.link);
1455 wl_list_insert(ds_subsurface->parent->pending.subsurfaces_below.prev,
1456 &ds_subsurface->pending.link);
1459 wl_list_remove(&ds_subsurface->current.link);
1460 wl_list_insert(ds_subsurface->parent->current.subsurfaces_below.prev,
1461 &ds_subsurface->current.link);
1463 ds_subsurface->reordered = true;
1467 _e_subsurface_cb_destroy(struct wl_listener *listener, void *data)
1471 sub = wl_container_of(listener, sub, destroy);
1472 _e_subsurface_destroy(sub);
1476 _e_subsurface_cb_cached(struct wl_listener *listener, void *data)
1480 sub = wl_container_of(listener, sub, cached);
1482 e_presentation_time_container_feedback_discard(&sub->base.cached.presentation_container);
1483 e_presentation_time_container_feedback_merge(&sub->base.cached.presentation_container,
1484 &sub->surface->base.pending.presentation_container);
1486 sub->base.cached.has_data = EINA_TRUE;
1488 e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_COMMIT_TO_CACHE, sub->surface->ec);
1492 _e_subsurface_cb_request_move(struct wl_listener *listener, void *data)
1495 struct ds_subsurface *ds_subsurface;
1497 sub = wl_container_of(listener, sub, request_move);
1498 ds_subsurface = sub->ds_subsurface;
1500 if ((sub->base.position.x == ds_subsurface->current.x) &&
1501 (sub->base.position.y == ds_subsurface->current.y))
1504 sub->base.position.x = ds_subsurface->current.x;
1505 sub->base.position.y = ds_subsurface->current.y;
1507 _e_subsurface_position_update(sub);
1511 _e_subsurface_cb_surface_destroy(struct wl_listener *listener, void *data)
1515 sub = wl_container_of(listener, sub, surface_destroy);
1516 _e_subsurface_destroy(sub);
1520 _e_subsurface_cb_parent_surface_destroy(struct wl_listener *listener, void *data)
1524 sub = wl_container_of(listener, sub, parent_surface_destroy);
1526 wl_signal_emit(&sub->surface->events.parent_destroy, sub->surface);
1528 wl_list_remove(&sub->parent_surface_destroy.link);
1529 wl_list_init(&sub->parent_surface_destroy.link);
1531 e_comp_wl_client_subsurface_parent_unset(sub->surface->ec);
1535 _ds_surface_buffer_transform_set(struct ds_surface *ds_surface, enum wl_output_transform transform)
1537 ds_surface->pending.transform = transform;
1538 ds_surface->current.transform = transform;
1542 _ds_surface_viewport_source_box_set(struct ds_surface *ds_surface, Eina_Rectangle *box)
1544 ds_surface->pending.viewport.has_src = true;
1545 ds_surface->pending.viewport.src.x = (double)box->x;
1546 ds_surface->pending.viewport.src.y = (double)box->y;
1547 ds_surface->pending.viewport.src.width = (double)box->w;
1548 ds_surface->pending.viewport.src.height = (double)box->h;
1549 ds_surface->current.viewport.has_src = true;
1550 ds_surface->current.viewport.src = ds_surface->pending.viewport.src;
1554 _ds_surface_viewport_destination_set(struct ds_surface *ds_surface, int32_t width, int32_t height)
1556 ds_surface->pending.viewport.has_dst = true;
1557 ds_surface->pending.viewport.dst_width = width;
1558 ds_surface->pending.viewport.dst_height = height;
1559 ds_surface->pending.width = width;
1560 ds_surface->pending.height = height;
1561 ds_surface->current.viewport.has_dst = true;
1562 ds_surface->current.viewport.dst_width = width;
1563 ds_surface->current.viewport.dst_height = height;
1564 ds_surface->current.width = width;
1565 ds_surface->current.height = height;
1569 _ds_surface_viewport_unset(struct ds_surface *ds_surface)
1571 ds_surface->pending.viewport.has_src = false;
1572 ds_surface->pending.viewport.has_dst = false;
1573 ds_surface->current.viewport.has_src = false;
1574 ds_surface->current.viewport.has_dst = false;
1578 _ds_subsurface_position_set(struct ds_subsurface *ds_subsurface, int x, int y)
1580 ds_subsurface->pending.x = x;
1581 ds_subsurface->pending.y = y;
1583 ds_subsurface->current.x = x;
1584 ds_subsurface->current.y = y;