1 #include "e_hwc_window_intern.h"
2 #include "e_hwc_windows_intern.h"
3 #include "e_hwc_intern.h"
4 #include "e_hwc_window_queue_intern.h"
5 #include "e_comp_wl_buffer_intern.h"
6 #include "e_comp_wl_intern.h"
7 #include "e_comp_wl_subsurface_intern.h"
8 #include "e_comp_wl_tbm_intern.h"
9 #include "e_pointer_intern.h"
10 #include "e_pixmap_intern.h"
11 #include "e_presentation_time_intern.h"
12 #include "services/e_service_quickpanel_intern.h"
13 #include "e_policy_private_data.h"
14 #include "e_policy_visibility_intern.h"
15 #include "e_client_video_intern.h"
16 #include "e_client_intern.h"
17 #include "e_comp_object_intern.h"
18 #include "e_utils_intern.h"
21 #include <wayland-tbm-server.h>
22 #include <presentation-time-server-protocol.h>
25 #define CLEAR(x) memset(&(x), 0, sizeof (x))
28 #define EHWERR(f, ec, hwc, ehw, x...) \
32 ELOGFE("HWC-WIN", "%2d|"f, \
33 (ec), (e_hwc_output_index_get(hwc)), ##x); \
35 ELOGFE("HWC-WIN", "%2d|ehw:%8p|"f, \
36 (ec), (e_hwc_output_index_get(hwc)), (ehw), ##x); \
40 #define EHWINF(f, ec, hwc, ehw, x...) \
44 ELOGF("HWC-WIN", "%2d|"f, \
45 (ec), (e_hwc_output_index_get(hwc)), ##x); \
47 ELOGF("HWC-WIN", "%2d|ehw:%8p|"f, \
48 (ec), (e_hwc_output_index_get(hwc)), (ehw), ##x); \
52 #define EHWTRACE(f, ec, hwc, ehw, x... )\
58 ELOGF("HWC-WIN", "%2d|"f, \
59 (ec), (e_hwc_output_index_get(hwc)), ##x); \
61 ELOGF("HWC-WIN", "%2d|ehw:%8p|"f, \
62 (ec), (e_hwc_output_index_get(hwc)), (ehw), ##x); \
67 typedef enum _E_Hwc_Window_Restriction
69 E_HWC_WINDOW_RESTRICTION_NONE,
70 E_HWC_WINDOW_RESTRICTION_DELETED,
71 E_HWC_WINDOW_RESTRICTION_OVERRIDE,
72 E_HWC_WINDOW_RESTRICTION_ANIMATING,
73 E_HWC_WINDOW_RESTRICTION_BUFFER,
74 E_HWC_WINDOW_RESTRICTION_VIEWPORT,
75 E_HWC_WINDOW_RESTRICTION_NEVER_HWC,
76 E_HWC_WINDOW_RESTRICTION_TRANSFORM,
77 E_HWC_WINDOW_RESTRICTION_BUFFER_TYPE,
78 E_HWC_WINDOW_RESTRICTION_OUTPUT,
79 E_HWC_WINDOW_RESTRICTION_MIN_WIDTH,
80 E_HWC_WINDOW_RESTRICTION_MIN_HEIGHT,
81 E_HWC_WINDOW_RESTRICTION_TOUCH_PRESS,
82 E_HWC_WINDOW_RESTRICTION_OUTPUT_TRANSFORM,
83 E_HWC_WINDOW_RESTRICTION_CONTENT_IMAGE,
84 E_HWC_WINDOW_RESTRICTION_QUICKPANEL_OPEN,
85 E_HWC_WINDOW_RESTRICTION_PIXMAP_RESOURCE,
86 E_HWC_WINDOW_RESTRICTION_OBSCURED_BY_TARGET,
87 E_HWC_WINDOW_RESTRICTION_IMAGE_FILTER,
88 E_HWC_WINDOW_RESTRICTION_DESK_GEOMETRY,
89 E_HWC_WINDOW_RESTRICTION_EFFECT_RUNNING,
90 E_HWC_WINDOW_RESTRICTION_RENDER_UPDATE_LOCK,
91 E_HWC_WINDOW_RESTRICTION_DESK_ZOOM,
92 E_HWC_WINDOW_RESTRICTION_BLEND_ALPHA,
93 E_HWC_WINDOW_RESTRICTION_BLEND_EQUATION,
94 E_HWC_WINDOW_RESTRICTION_ZONE,
95 E_HWC_WINDOW_RESTRICTION_QUEUE_UNSET_WAITING,
96 } E_Hwc_Window_Restriction;
98 static Eina_Bool ehw_trace = EINA_FALSE;
99 static Eina_List *hwc_window_client_hooks = NULL;
100 static Eina_List *hwc_window_comp_wl_hooks = NULL;
101 static Eina_List *hwc_window_event_hdlrs = NULL;
102 static Eina_List *hwc_window_comp_object_hooks = NULL;
104 static int _e_hwc_window_hooks_delete = 0;
105 static int _e_hwc_window_hooks_walking = 0;
107 typedef struct _Hwc_Window_Prop
110 char name[TDM_NAME_LEN];
114 static Eina_Inlist *_e_hwc_window_hooks[] =
116 [E_HWC_WINDOW_HOOK_ACCEPTED_STATE_SET] = NULL,
120 _e_hwc_window_hooks_clean(void)
123 E_Hwc_Window_Hook *ch;
125 for (x = 0; x < E_HWC_WINDOW_HOOK_LAST; x++)
126 EINA_INLIST_FOREACH_SAFE(_e_hwc_window_hooks[x], l, ch)
128 if (!ch->delete_me) continue;
129 _e_hwc_window_hooks[x] = eina_inlist_remove(_e_hwc_window_hooks[x], EINA_INLIST_GET(ch));
135 _e_hwc_window_hook_call(E_Hwc_Window_Hook_Point hookpoint, E_Hwc_Window *hwc_window)
137 E_Hwc_Window_Hook *ch;
139 _e_hwc_window_hooks_walking++;
140 EINA_INLIST_FOREACH(_e_hwc_window_hooks[hookpoint], ch)
142 if (ch->delete_me) continue;
143 ch->func(ch->data, hwc_window);
145 _e_hwc_window_hooks_walking--;
146 if ((_e_hwc_window_hooks_walking == 0) && (_e_hwc_window_hooks_delete > 0))
147 _e_hwc_window_hooks_clean();
150 static E_Comp_Wl_Buffer *
151 _e_hwc_window_comp_wl_buffer_get(E_Hwc_Window *hwc_window)
153 E_Client *ec = hwc_window->ec;
154 E_Comp_Wl_Client_Data *cdata;
156 if (!ec) return NULL;
158 cdata = e_client_cdata_get(ec);
159 if (!cdata) return NULL;
161 return cdata->buffer_ref.buffer;
164 static tdm_hwc_window_composition
165 _get_composition_type(E_Hwc_Window_State state)
167 tdm_hwc_window_composition composition_type = TDM_HWC_WIN_COMPOSITION_NONE;
171 case E_HWC_WINDOW_STATE_NONE:
172 composition_type = TDM_HWC_WIN_COMPOSITION_NONE;
174 case E_HWC_WINDOW_STATE_CLIENT:
175 composition_type = TDM_HWC_WIN_COMPOSITION_CLIENT;
177 case E_HWC_WINDOW_STATE_DEVICE:
178 composition_type = TDM_HWC_WIN_COMPOSITION_DEVICE;
180 case E_HWC_WINDOW_STATE_CURSOR:
181 composition_type = TDM_HWC_WIN_COMPOSITION_CURSOR;
183 case E_HWC_WINDOW_STATE_VIDEO:
184 composition_type = TDM_HWC_WIN_COMPOSITION_VIDEO;
187 composition_type = TDM_HWC_WIN_COMPOSITION_NONE;
188 EHWERR("unknown state of hwc_window", NULL, NULL, NULL);
191 return composition_type;
195 _e_hwc_window_buffer_cb_queue_destroy(struct wl_listener *listener, void *data)
197 E_Hwc_Window_Buffer *window_buffer;
199 window_buffer = container_of(listener, E_Hwc_Window_Buffer, queue_destroy_listener);
200 EINA_SAFETY_ON_NULL_RETURN(window_buffer);
202 if ((E_Hwc_Window_Queue *)data != window_buffer->queue) return;
204 if (window_buffer->queue_destroy_listener.notify)
206 wl_list_remove(&window_buffer->queue_destroy_listener.link);
207 window_buffer->queue_destroy_listener.notify = NULL;
210 window_buffer->queue = NULL;
214 e_hwc_window_buffer_set(E_Hwc_Window_Buffer *window_buffer,
215 tbm_surface_h tsurface,
216 E_Hwc_Window_Queue *queue,
219 EINA_SAFETY_ON_NULL_RETURN(window_buffer);
221 if (window_buffer->queue != queue)
223 if (window_buffer->queue_destroy_listener.notify)
225 wl_list_remove(&window_buffer->queue_destroy_listener.link);
226 window_buffer->queue_destroy_listener.notify = NULL;
231 wl_signal_add(&queue->destroy_signal, &window_buffer->queue_destroy_listener);
232 window_buffer->queue_destroy_listener.notify = _e_hwc_window_buffer_cb_queue_destroy;
237 window_buffer->from_queue = EINA_TRUE;
239 window_buffer->from_queue = EINA_FALSE;
241 window_buffer->queue = queue;
242 window_buffer->transform = transform;
244 if (window_buffer->tsurface)
245 tbm_surface_internal_unref(window_buffer->tsurface);
247 window_buffer->tsurface = tsurface;
249 tbm_surface_internal_ref(tsurface);
253 _e_hwc_window_cb_queue_destroy(struct wl_listener *listener, void *data)
255 E_Hwc_Window *hwc_window;
257 hwc_window = container_of(listener, E_Hwc_Window, queue_destroy_listener);
258 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
260 if ((E_Hwc_Window_Queue *)data != hwc_window->queue) return;
262 if (hwc_window->queue_destroy_listener.notify)
264 wl_list_remove(&hwc_window->queue_destroy_listener.link);
265 hwc_window->queue_destroy_listener.notify = NULL;
268 hwc_window->queue = NULL;
269 hwc_window->constraints &= ~TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE;
273 _e_hwc_window_buffer_queue_set(E_Hwc_Window *hwc_window)
275 E_Hwc_Window_Queue *queue;
277 queue = e_hwc_window_queue_user_set(hwc_window);
280 EHWERR("fail to e_hwc_window_queue_user_set", hwc_window->ec, hwc_window->hwc, hwc_window);
281 hwc_window->queue = NULL;
285 if (hwc_window->queue_destroy_listener.notify)
287 wl_list_remove(&hwc_window->queue_destroy_listener.link);
288 hwc_window->queue_destroy_listener.notify = NULL;
291 wl_signal_add(&queue->destroy_signal, &hwc_window->queue_destroy_listener);
292 hwc_window->queue_destroy_listener.notify = _e_hwc_window_cb_queue_destroy;
293 hwc_window->queue = queue;
295 EHWTRACE("Set constranints BUFFER_QUEUE -- {%s}",
296 hwc_window->ec, hwc_window->hwc, hwc_window, e_client_util_name_get(hwc_window->ec));
302 _e_hwc_window_buffer_queue_unset(E_Hwc_Window *hwc_window)
304 /* reset the TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE */
305 if (hwc_window->queue)
307 e_hwc_window_queue_user_unset(hwc_window->queue, hwc_window);
309 if (hwc_window->queue_destroy_listener.notify)
311 wl_list_remove(&hwc_window->queue_destroy_listener.link);
312 hwc_window->queue_destroy_listener.notify = NULL;
315 hwc_window->queue = NULL;
318 EHWTRACE("Unset constraints BUFFER_QUEUE - {%s}",
319 hwc_window->ec, hwc_window->hwc, hwc_window, e_client_util_name_get(hwc_window->ec));
323 e_hwc_window_constraints_reset(E_Hwc_Window *hwc_window)
325 if (hwc_window->is_target) return;
327 _e_hwc_window_buffer_queue_unset(hwc_window);
329 hwc_window->constraints = TDM_HWC_WIN_CONSTRAINT_NONE;
331 EHWTRACE("Reset constraints - {%s}",
332 hwc_window->ec, hwc_window->hwc, hwc_window, e_client_util_name_get(hwc_window->ec));
336 _e_hwc_window_client_surface_acquire(E_Hwc_Window *hwc_window)
338 E_Comp_Wl_Buffer *buffer = _e_hwc_window_comp_wl_buffer_get(hwc_window);
339 E_Comp_Wl_Data *wl_comp_data = (E_Comp_Wl_Data *)e_comp->wl_comp_data;
340 tbm_surface_h tsurface = NULL;
342 if (!buffer) return NULL;
344 switch (buffer->type)
346 case E_COMP_WL_BUFFER_TYPE_SHM:
347 case E_COMP_WL_BUFFER_TYPE_SINGLE_PIXEL:
349 case E_COMP_WL_BUFFER_TYPE_NATIVE:
350 case E_COMP_WL_BUFFER_TYPE_VIDEO:
351 tsurface = wayland_tbm_server_get_surface(wl_comp_data->tbm.server, buffer->resource);
353 case E_COMP_WL_BUFFER_TYPE_TBM:
354 tsurface = buffer->tbm_surface;
357 EHWERR("not supported buffer type:%d", hwc_window->ec, hwc_window->hwc, hwc_window, buffer->type);
365 _e_hwc_window_cb_cursor_buffer_destroy(struct wl_listener *listener, void *data)
367 E_Hwc_Window *hwc_window;
369 hwc_window = container_of(listener, E_Hwc_Window, cursor_buffer_destroy_listener);
370 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
372 if ((E_Comp_Wl_Buffer *)data != hwc_window->cursor.buffer) return;
374 if (hwc_window->cursor_buffer_destroy_listener.notify)
376 wl_list_remove(&hwc_window->cursor_buffer_destroy_listener.link);
377 hwc_window->cursor_buffer_destroy_listener.notify = NULL;
380 hwc_window->cursor.buffer = NULL;
384 _e_hwc_window_cursor_image_update(E_Hwc_Window *hwc_window)
386 E_Client *ec = hwc_window->ec;
387 E_Comp_Wl_Buffer *buffer;
389 int img_w, img_h, img_stride;
390 void *img_ptr = NULL;
393 pointer = e_pointer_get(ec);
394 buffer = _e_hwc_window_comp_wl_buffer_get(hwc_window);
395 if (!buffer || !pointer)
397 if (hwc_window->cursor.img_ptr)
399 if (hwc_window->cursor_buffer_destroy_listener.notify)
401 wl_list_remove(&hwc_window->cursor_buffer_destroy_listener.link);
402 hwc_window->cursor_buffer_destroy_listener.notify = NULL;
405 hwc_window->cursor.buffer = NULL;
406 hwc_window->cursor.rotation = 0;
407 hwc_window->cursor.img_ptr = NULL;
408 hwc_window->cursor.img_w = 0;
409 hwc_window->cursor.img_h = 0;
410 hwc_window->cursor.img_stride = 0;
412 error = tdm_hwc_window_set_cursor_image(hwc_window->thwc_window, 0, 0, 0, NULL);
413 if (error != TDM_ERROR_NONE)
415 EHWERR("fail to set cursor image to thwc(%p)", hwc_window->ec, hwc_window->hwc, hwc_window, hwc_window->thwc_window);
425 /* cursor image is the shm image from the wl_clients */
426 if (buffer->type == E_COMP_WL_BUFFER_TYPE_SHM)
428 img_ptr = wl_shm_buffer_get_data(buffer->shm_buffer);
431 EHWERR("Failed get data shm buffer", hwc_window->ec, hwc_window->hwc, hwc_window);
434 img_w = wl_shm_buffer_get_width(buffer->shm_buffer);
435 img_h = wl_shm_buffer_get_height(buffer->shm_buffer);
436 img_stride = wl_shm_buffer_get_stride(buffer->shm_buffer);
440 E_Comp_Wl_Client_Data *cdata = e_client_cdata_get(ec);
441 EHWERR("unkown buffer type:%d", NULL, hwc_window->hwc, hwc_window, cdata->buffer_ref.buffer->type);
445 /* no changes, no need to update the cursor image */
446 if ((hwc_window->cursor.buffer == buffer) &&
447 (hwc_window->cursor.rotation == pointer->rotation))
450 error = tdm_hwc_window_set_cursor_image(hwc_window->thwc_window, img_w, img_h, img_stride, img_ptr);
451 if (error != TDM_ERROR_NONE)
453 EHWERR("fail to set cursor image to thwc(%p)", hwc_window->ec, hwc_window->hwc, hwc_window, hwc_window->thwc_window);
457 if (hwc_window->cursor_buffer_destroy_listener.notify)
459 wl_list_remove(&hwc_window->cursor_buffer_destroy_listener.link);
460 hwc_window->cursor_buffer_destroy_listener.notify = NULL;
463 hwc_window->cursor.buffer = buffer;
464 wl_signal_add(&buffer->destroy_signal, &hwc_window->cursor_buffer_destroy_listener);
465 hwc_window->cursor_buffer_destroy_listener.notify = _e_hwc_window_cb_cursor_buffer_destroy;
466 hwc_window->cursor.rotation = pointer->rotation;
467 hwc_window->cursor.img_ptr = img_ptr;
468 hwc_window->cursor.img_w = img_w;
469 hwc_window->cursor.img_h = img_h;
470 hwc_window->cursor.img_stride = img_stride;
476 _e_hwc_window_cursor_position_get(E_Pointer *ptr, E_Output *output, int width, int height, unsigned int *x, unsigned int *y)
480 float ratio_w, ratio_h;
482 rotation = ptr->rotation;
487 if (e_config->cursor_configured_output_resolution.use)
489 ratio_w = (float)output->config.geom.w / (float)e_config->cursor_configured_output_resolution.w;
490 ratio_h = (float)output->config.geom.h / (float)e_config->cursor_configured_output_resolution.h;
492 if ((ratio_w > 1.0) && (ratio_h > 1.0))
494 hot_x = (int)((float)hot_x * (float)ratio_w);
495 hot_y = (int)((float)hot_y * (float)ratio_h);
507 *y = ptr->y + hot_x - width;
510 *x = ptr->x + hot_x - width;
511 *y = ptr->y + hot_y - height;
514 *x = ptr->x + hot_y - height;
525 _e_hwc_window_update_fps(E_Hwc_Window *hwc_window)
527 if (e_comp->calc_fps)
530 double tim = ecore_time_get();
532 dt = tim - hwc_window->fps.frametimes[0];
533 hwc_window->fps.frametimes[0] = tim;
535 hwc_window->fps.time += dt;
536 hwc_window->fps.cframes++;
538 if (hwc_window->fps.lapse == 0.0)
540 hwc_window->fps.lapse = tim;
541 hwc_window->fps.flapse = hwc_window->fps.cframes;
543 else if ((tim - hwc_window->fps.lapse) >= 0.5)
545 hwc_window->fps.fps = (hwc_window->fps.cframes - hwc_window->fps.flapse) /
546 (tim - hwc_window->fps.lapse);
547 hwc_window->fps.lapse = tim;
548 hwc_window->fps.flapse = hwc_window->fps.cframes;
549 hwc_window->fps.time = 0.0;
555 _e_hwc_window_cb_zone_del(void *data, void *obj)
557 E_Hwc_Window *hwc_window = (E_Hwc_Window *)data;
559 hwc_window->zone_delfn = NULL;
560 hwc_window->zone = NULL;
564 _e_hwc_window_zone_set(E_Hwc_Window *hwc_window, E_Zone *zone)
566 if (hwc_window->zone == zone) return;
568 if (hwc_window->zone)
570 if (hwc_window->zone_delfn)
572 e_object_delfn_del(E_OBJECT(hwc_window->zone), hwc_window->zone_delfn);
573 hwc_window->zone_delfn = NULL;
576 hwc_window->zone = NULL;
581 hwc_window->zone_delfn = e_object_delfn_add(E_OBJECT(zone),
582 _e_hwc_window_cb_zone_del,
584 hwc_window->zone = zone;
589 _e_hwc_window_free(E_Hwc_Window *hwc_window)
592 Hwc_Window_Prop *prop;
594 EHWINF("Free", NULL, hwc_window->hwc, hwc_window);
596 hwc = hwc_window->hwc;
598 hwc->hwc_windows = eina_list_remove(hwc->hwc_windows, hwc_window);
600 e_presentation_time_container_finish(&hwc_window->presentation_container);
601 e_hwc_presentation_callback_list_finish(&hwc_window->pending_presentation_callbacks);
602 e_hwc_presentation_callback_list_finish(&hwc_window->presentation_callbacks);
604 if(hwc_window->prop_list)
606 EINA_LIST_FREE(hwc_window->prop_list, prop)
612 if (hwc_window->thwc_window)
613 tdm_hwc_window_destroy(hwc_window->thwc_window);
615 if (hwc_window->cqueue)
616 wayland_tbm_server_client_queue_set_destroy_cb(hwc_window->cqueue,
620 _e_hwc_window_zone_set(hwc_window, NULL);
622 if (hwc_window->cursor_buffer_destroy_listener.notify)
624 wl_list_remove(&hwc_window->cursor_buffer_destroy_listener.link);
625 hwc_window->cursor_buffer_destroy_listener.notify = NULL;
628 if (hwc_window->queue_destroy_listener.notify)
630 wl_list_remove(&hwc_window->queue_destroy_listener.link);
631 hwc_window->queue_destroy_listener.notify = NULL;
634 e_comp_wl_buffer_reference(&hwc_window->current.buffer_ref, NULL);
635 e_comp_wl_buffer_reference(&hwc_window->commit.buffer_ref, NULL);
636 e_comp_wl_buffer_reference(&hwc_window->display.buffer_ref, NULL);
638 e_hwc_window_queue_buffer_reference(&hwc_window->current.queue_buffer_ref, NULL);
639 e_hwc_window_queue_buffer_reference(&hwc_window->commit.queue_buffer_ref, NULL);
640 e_hwc_window_queue_buffer_reference(&hwc_window->display.queue_buffer_ref, NULL);
642 e_hwc_window_buffer_set(&hwc_window->current.buffer, NULL, NULL, 0);
643 e_hwc_window_buffer_set(&hwc_window->commit.buffer, NULL, NULL, 0);
644 e_hwc_window_buffer_set(&hwc_window->display.buffer, NULL, NULL, 0);
650 _e_hwc_window_del(E_Hwc_Window *hwc_window)
654 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
656 EHWINF("Del", hwc_window->ec, hwc_window->hwc, hwc_window);
659 EINA_SAFETY_ON_NULL_RETURN(ec);
661 ec->hwc_window = NULL;
662 hwc_window->ec = NULL;
663 hwc_window->is_deleted = EINA_TRUE;
665 /* if delfn is called, ec_delfn should be set null
666 * before we get here */
667 if (hwc_window->ec_delfn)
669 e_object_delfn_del(E_OBJECT(ec), hwc_window->ec_delfn);
670 hwc_window->ec_delfn = NULL;
673 if (hwc_window->queue)
675 e_hwc_window_queue_user_unset(hwc_window->queue, hwc_window);
677 if (hwc_window->queue_destroy_listener.notify)
679 wl_list_remove(&hwc_window->queue_destroy_listener.link);
680 hwc_window->queue_destroy_listener.notify = NULL;
683 hwc_window->queue = NULL;
686 e_hwc_window_below_transparent_obj_set(hwc_window, EINA_FALSE);
687 e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE, EINA_TRUE);
689 e_object_del(E_OBJECT(hwc_window));
693 _e_hwc_window_cb_ec_free(void *data, void *obj)
695 E_Client *ec = (E_Client *)obj;
697 EINA_SAFETY_ON_NULL_RETURN(ec);
701 /* if delfn is called, ec_delfn should be set null */
702 ec->hwc_window->ec_delfn = NULL;
703 _e_hwc_window_del(ec->hwc_window);
707 static E_Hwc_Window *
708 _e_hwc_window_new(E_Hwc *hwc, E_Client *ec, E_Hwc_Window_State state)
710 E_Hwc_Window *hwc_window;
714 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
715 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
716 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), NULL);
718 if (ec->hwc_window) goto end;
721 EINA_SAFETY_ON_NULL_RETURN_VAL(thwc, EINA_FALSE);
723 hwc_window = E_OBJECT_ALLOC(E_Hwc_Window, E_HWC_WINDOW_TYPE, _e_hwc_window_free);
724 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, NULL);
726 hwc_window->hwc = hwc;
727 hwc_window->zpos = E_HWC_WINDOW_ZPOS_NONE;
728 hwc_window->render_target = EINA_TRUE;
729 hwc_window->device_state_available = EINA_TRUE;
731 hwc_window->thwc_window = tdm_hwc_create_window(thwc, &error);
732 if (error != TDM_ERROR_NONE)
734 EHWERR("cannot create tdm_hwc_window for thwc(%p)", hwc_window->ec, hwc_window->hwc, hwc_window, thwc);
740 if (e_policy_client_is_cursor(ec))
741 hwc_window->is_cursor = EINA_TRUE;
743 /* set the hwc window to the e client */
745 hwc_window->ec_delfn = e_object_delfn_add(E_OBJECT(ec),
746 _e_hwc_window_cb_ec_free,
748 ec->hwc_window = hwc_window;
750 hwc->hwc_windows = eina_list_append(hwc->hwc_windows, hwc_window);
752 e_presentation_time_container_init(&hwc_window->presentation_container);
753 e_hwc_presentation_callback_list_init(&hwc_window->pending_presentation_callbacks);
754 e_hwc_presentation_callback_list_init(&hwc_window->presentation_callbacks);
756 EHWINF("is created on eout:%p, video:%d cursor:%d",
757 hwc_window->ec, hwc_window->hwc, hwc_window, hwc->output,
758 hwc_window->is_video, hwc_window->is_cursor);
762 if (state == E_HWC_WINDOW_STATE_VIDEO)
763 ec->hwc_window->is_video = EINA_TRUE;
765 e_hwc_window_state_set(ec->hwc_window, state, EINA_TRUE);
767 return ec->hwc_window;
771 _e_hwc_window_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
773 E_Hwc_Window *hwc_window;
777 EINA_SAFETY_ON_NULL_RETURN(ec);
779 if (!(hwc_window = ec->hwc_window)) return;
781 zone = hwc_window->zone;
782 EINA_SAFETY_ON_NULL_RETURN(zone);
783 EINA_SAFETY_ON_NULL_RETURN(zone->output_id);
785 output = e_output_find(zone->output_id);
786 EINA_SAFETY_ON_NULL_RETURN(output);
788 /* If an e_client belongs to the e_output managed by hwc_plane policy,
789 * there's no need to deal with hwc_windows. */
790 if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
793 if (e_hwc_window_is_video(hwc_window)) return;
795 e_hwc_window_client_type_override(hwc_window);
799 _e_hwc_window_client_subsurface_present_sync(E_Client *ec)
801 E_Hwc_Window_State state;
805 if (!ec->hwc_window) return;
807 state = e_hwc_window_accepted_state_get(ec->hwc_window);
808 if ((state == E_HWC_WINDOW_STATE_DEVICE) || (state == E_HWC_WINDOW_STATE_VIDEO))
809 e_hwc_window_present_sync(ec->hwc_window);
811 EINA_LIST_FOREACH(ec->comp_data->sub.below_list_pending, l, subc)
813 if (!subc->hwc_window) continue;
814 _e_hwc_window_client_subsurface_present_sync(subc);
817 EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
819 if (!subc->hwc_window) continue;
820 _e_hwc_window_client_subsurface_present_sync(subc);
825 _e_hwc_window_client_cb_transform_change(void *data EINA_UNUSED, E_Client *ec)
832 E_Hwc_Window_State state;
833 E_Hwc_Window *hwc_window;
835 EINA_SAFETY_ON_NULL_RETURN(ec);
837 if (!(hwc_window = ec->hwc_window)) return;
839 zone = hwc_window->zone;
840 EINA_SAFETY_ON_NULL_RETURN(zone);
841 EINA_SAFETY_ON_NULL_RETURN(zone->output_id);
843 output = e_output_find(zone->output_id);
844 EINA_SAFETY_ON_NULL_RETURN(output);
846 /* If an e_client belongs to the e_output managed by hwc_plane policy,
847 * there's no need to deal with hwc_windows. */
848 if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES) return;
850 if (!e_comp_wl_video_subsurface_has(ec) && !e_comp_wl_normal_subsurface_has(ec))
853 topmost = e_comp_wl_topmost_parent_get(ec);
854 if (topmost != ec) return;
856 /* if window is device state, sync is not needed */
857 state = e_hwc_window_accepted_state_get(ec->hwc_window);
858 if (state != E_HWC_WINDOW_STATE_CLIENT) return;
860 EINA_LIST_FOREACH(ec->comp_data->sub.below_list_pending, l, subc)
862 if (!subc->hwc_window) continue;
863 _e_hwc_window_client_subsurface_present_sync(subc);
866 EINA_LIST_FOREACH(ec->comp_data->sub.below_list, l, subc)
868 if (!subc->hwc_window) continue;
869 _e_hwc_window_client_subsurface_present_sync(subc);
874 _e_hwc_window_client_cb_zone_set(void *data, int type, void *event)
876 E_Event_Client_Zone_Set *ev;
880 E_Hwc_Window *hwc_window;
881 Eina_Bool is_video = EINA_FALSE;
884 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
887 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_PASS_ON);
890 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, ECORE_CALLBACK_PASS_ON);
891 EINA_SAFETY_ON_NULL_RETURN_VAL(zone->output_id, ECORE_CALLBACK_PASS_ON);
893 output = e_output_find(zone->output_id);
894 EINA_SAFETY_ON_NULL_RETURN_VAL(output, ECORE_CALLBACK_PASS_ON);
896 /* If an e_client belongs to the e_output managed by hwc_plane policy,
897 * there's no need to deal with hwc_windows. */
898 if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
899 return ECORE_CALLBACK_PASS_ON;
901 if (e_object_is_del(E_OBJECT(ec)))
902 return ECORE_CALLBACK_PASS_ON;
904 hwc_window = ec->hwc_window;
907 if (hwc_window->hwc == output->hwc) goto done;
909 is_video = e_hwc_window_is_video(hwc_window);
910 _e_hwc_window_del(hwc_window);
913 hwc_window = _e_hwc_window_new(output->hwc, ec, E_HWC_WINDOW_STATE_NONE);
914 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, ECORE_CALLBACK_PASS_ON);
916 if (is_video) e_hwc_window_video_set(hwc_window, is_video);
918 EHWINF("set on eout:%p, zone_id:%d",
919 ec, hwc_window->hwc, hwc_window, output, zone->id);
922 _e_hwc_window_zone_set(hwc_window, zone);
924 return ECORE_CALLBACK_PASS_ON;
928 _e_hwc_window_cb_subsurface_synchronized_commit(void *data, E_Client *ec)
931 E_Hwc_Window_State state;
932 Eina_Bool need_sync = EINA_FALSE;
934 EINA_SAFETY_ON_NULL_RETURN(ec);
935 if ((!ec->hwc_window) || (!e_comp_wl_subsurface_check(ec))) return;
937 state = e_hwc_window_accepted_state_get(ec->hwc_window);
938 if ((state != E_HWC_WINDOW_STATE_DEVICE) && (state != E_HWC_WINDOW_STATE_VIDEO))
941 parent = e_comp_wl_subsurface_parent_get(ec);
944 state = e_hwc_window_accepted_state_get(parent->hwc_window);
945 if (state == E_HWC_WINDOW_STATE_CLIENT)
947 need_sync = EINA_TRUE;
951 if (!e_comp_wl_subsurface_check(parent))
954 parent = e_comp_wl_subsurface_parent_get(parent);
958 e_hwc_window_present_sync(ec->hwc_window);
962 _e_hwc_window_cb_update_lock_set(void *data, E_Client *ec)
964 E_Hwc_Window *hwc_window;
966 if (e_object_is_del(E_OBJECT(ec))) return EINA_TRUE;
968 hwc_window = ec->hwc_window;
969 if (!hwc_window) return EINA_TRUE;
971 e_hwc_window_client_type_override(hwc_window);
977 e_hwc_window_init(void)
979 E_LIST_HOOK_APPEND(hwc_window_client_hooks, E_CLIENT_HOOK_DEL,
980 _e_hwc_window_client_cb_del, NULL);
981 E_LIST_HOOK_APPEND(hwc_window_client_hooks, E_CLIENT_HOOK_TRANSFORM_CHANGE,
982 _e_hwc_window_client_cb_transform_change, NULL);
983 E_LIST_HANDLER_APPEND(hwc_window_event_hdlrs, E_EVENT_CLIENT_ZONE_SET,
984 _e_hwc_window_client_cb_zone_set, NULL);
985 E_COMP_WL_HOOK_APPEND(hwc_window_comp_wl_hooks, E_COMP_WL_HOOK_SUBSURFACE_SYNCHRONIZED_COMMIT,
986 _e_hwc_window_cb_subsurface_synchronized_commit, NULL);
987 E_COMP_COMP_HOOK_APPEND(hwc_window_comp_object_hooks, E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET,
988 _e_hwc_window_cb_update_lock_set, NULL);
994 e_hwc_window_deinit(void)
996 E_FREE_LIST(hwc_window_client_hooks, e_client_hook_del);
997 E_FREE_LIST(hwc_window_event_hdlrs, ecore_event_handler_del);
998 E_FREE_LIST(hwc_window_comp_wl_hooks, e_comp_wl_hook_del);
999 E_FREE_LIST(hwc_window_comp_object_hooks, e_comp_object_hook_del);
1002 EINTERN E_Hwc_Window *
1003 e_hwc_window_get(E_Hwc *hwc, E_Client *ec)
1005 E_Hwc_Window *hwc_window;
1007 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
1008 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1011 return ec->hwc_window;
1013 hwc_window = _e_hwc_window_new(hwc, ec, E_HWC_WINDOW_STATE_NONE);
1016 EHWERR("failed to e_hwc_window_new", ec, hwc, NULL);
1024 e_hwc_window_zpos_set(E_Hwc_Window *hwc_window, int zpos)
1026 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1028 if (hwc_window->zpos != zpos) hwc_window->zpos = zpos;
1034 e_hwc_window_zpos_get(E_Hwc_Window *hwc_window)
1036 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1038 if (hwc_window->state == E_HWC_WINDOW_STATE_NONE) return -999;
1040 return hwc_window->zpos;
1044 e_hwc_window_composition_update(E_Hwc_Window *hwc_window)
1046 tdm_hwc_window *thwc_window;
1047 tdm_hwc_window_composition composition_type;
1050 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1052 if (e_hwc_window_is_target(hwc_window))
1054 EHWERR("target window cannot update at e_hwc_window_composition_update", hwc_window->ec, hwc_window->hwc, hwc_window);
1058 thwc_window = hwc_window->thwc_window;
1059 EINA_SAFETY_ON_NULL_RETURN_VAL(thwc_window, EINA_FALSE);
1061 /* set composition type */
1062 composition_type = _get_composition_type(hwc_window->state);
1063 error = tdm_hwc_window_set_composition_type(hwc_window->thwc_window, composition_type);
1064 EINA_SAFETY_ON_TRUE_RETURN_VAL(error != TDM_ERROR_NONE, EINA_FALSE);
1070 e_hwc_window_is_target(E_Hwc_Window *hwc_window)
1072 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1074 return hwc_window->is_target;
1078 e_hwc_window_is_video(E_Hwc_Window *hwc_window)
1080 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1082 return hwc_window->is_video;
1086 e_hwc_window_is_cursor(E_Hwc_Window *hwc_window)
1088 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1090 return hwc_window->is_cursor;
1094 e_hwc_window_video_set(E_Hwc_Window *hwc_window, Eina_Bool set)
1096 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1098 hwc_window->is_video = set;
1104 _e_hwc_window_cursor_info_get(E_Hwc_Window *hwc_window, tdm_hwc_window_info *hwc_win_info)
1113 if (!e_hwc_window_is_cursor(hwc_window)) return EINA_FALSE;
1115 hwc = hwc_window->hwc;
1116 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
1118 output = hwc->output;
1119 EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
1121 ec = hwc_window->ec;
1122 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1123 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
1125 zone = hwc_window->zone;
1126 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
1128 pointer = e_pointer_get(ec);
1129 if (!pointer) return EINA_TRUE;
1131 hwc_win_info->src_config.format = TBM_FORMAT_ARGB8888;
1132 hwc_win_info->src_config.pos.x = 0;
1133 hwc_win_info->src_config.pos.y = 0;
1134 hwc_win_info->src_config.pos.w = hwc_window->cursor.img_w;
1135 hwc_win_info->src_config.pos.h = hwc_window->cursor.img_h;
1137 hwc_win_info->src_config.size.h = hwc_window->cursor.img_stride >> 2;
1138 EINA_SAFETY_ON_TRUE_RETURN_VAL(hwc_win_info->src_config.size.h == 0, EINA_FALSE);
1139 hwc_win_info->src_config.size.v = hwc_window->cursor.img_h;
1141 _e_hwc_window_cursor_position_get(pointer, output,
1142 hwc_win_info->src_config.pos.w,
1143 hwc_win_info->src_config.pos.h,
1144 &hwc_win_info->dst_pos.x,
1145 &hwc_win_info->dst_pos.y);
1147 if (output->config.rotation > 0)
1152 e_pixmap_size_get(ec->pixmap, &bw, &bh);
1153 e_comp_wl_rect_convert(zone->w, zone->h,
1154 output->config.rotation / 90, 1,
1155 hwc_win_info->dst_pos.x, hwc_win_info->dst_pos.y,
1160 hwc_win_info->dst_pos.x = dst_x;
1161 hwc_win_info->dst_pos.y = dst_y;
1164 hwc_win_info->dst_pos.x -= zone->x;
1165 hwc_win_info->dst_pos.y -= zone->y;
1167 hwc_win_info->dst_pos.w = hwc_window->cursor.img_w;
1168 hwc_win_info->dst_pos.h = hwc_window->cursor.img_h;
1170 rotation = (hwc_window->cursor.rotation + output->config.rotation) % 360;
1174 hwc_win_info->transform = TDM_TRANSFORM_NORMAL;
1177 hwc_win_info->transform = TDM_TRANSFORM_90;
1180 hwc_win_info->transform = TDM_TRANSFORM_180;
1183 hwc_win_info->transform = TDM_TRANSFORM_270;
1186 hwc_win_info->transform = TDM_TRANSFORM_NORMAL;
1194 _e_hwc_window_info_get(E_Hwc_Window *hwc_window, tdm_hwc_window_info *hwc_win_info)
1199 tbm_surface_h tsurface;
1200 tbm_surface_info_s surf_info = {0};
1205 ec = hwc_window->ec;
1206 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1207 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
1209 hwc = hwc_window->hwc;
1210 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
1212 zone = hwc_window->zone;
1213 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
1215 output = hwc->output;
1216 EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
1218 tsurface = hwc_window->current.buffer.tsurface;
1219 if (!tsurface) return EINA_TRUE;
1221 tbm_surface_get_info(tsurface, &surf_info);
1223 hwc_win_info->src_config.format = surf_info.format;
1224 hwc_win_info->src_config.pos.x = 0;
1225 hwc_win_info->src_config.pos.y = 0;
1226 hwc_win_info->src_config.pos.w = surf_info.width;
1227 hwc_win_info->src_config.pos.h = surf_info.height;
1229 hwc_win_info->src_config.size.h = e_comp_wl_tbm_aligned_width_get(tsurface);
1230 EINA_SAFETY_ON_TRUE_RETURN_VAL(hwc_win_info->src_config.size.h == 0, EINA_FALSE);
1231 hwc_win_info->src_config.size.v = surf_info.height;
1233 e_client_geometry_get(ec, &x, &y, &w, &h);
1235 hwc_win_info->dst_pos.x = x - zone->x;
1236 hwc_win_info->dst_pos.y = y - zone->y;
1238 if (output->config.rotation > 0)
1243 e_pixmap_size_get(ec->pixmap, &bw, &bh);
1244 e_comp_wl_rect_convert(zone->w, zone->h,
1245 output->config.rotation / 90, 1,
1246 hwc_win_info->dst_pos.x, hwc_win_info->dst_pos.y,
1251 hwc_win_info->dst_pos.x = dst_x;
1252 hwc_win_info->dst_pos.y = dst_y;
1255 transform = e_comp_wl_output_buffer_transform_get(ec);
1258 case WL_OUTPUT_TRANSFORM_90:
1259 case WL_OUTPUT_TRANSFORM_FLIPPED_90:
1260 case WL_OUTPUT_TRANSFORM_270:
1261 case WL_OUTPUT_TRANSFORM_FLIPPED_270:
1262 hwc_win_info->dst_pos.w = h;
1263 hwc_win_info->dst_pos.h = w;
1266 hwc_win_info->dst_pos.w = w;
1267 hwc_win_info->dst_pos.h = h;
1271 hwc_win_info->transform = TDM_TRANSFORM_NORMAL;
1277 _e_hwc_window_target_info_get(E_Hwc_Window *hwc_window, tdm_hwc_window_info *hwc_win_info)
1280 tbm_surface_h tsurface;
1281 tbm_surface_info_s surf_info = {0};
1283 if (!e_hwc_window_is_target(hwc_window)) return EINA_FALSE;
1285 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->hwc, EINA_FALSE);
1287 output = hwc_window->hwc->output;
1288 EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
1290 tsurface = hwc_window->current.buffer.tsurface;
1291 if (!tsurface) return EINA_TRUE;
1293 tbm_surface_get_info(tsurface, &surf_info);
1295 hwc_win_info->src_config.size.h = e_comp_wl_tbm_aligned_width_get(tsurface);
1296 EINA_SAFETY_ON_TRUE_RETURN_VAL(hwc_win_info->src_config.size.h == 0, EINA_FALSE);
1297 hwc_win_info->src_config.size.v = surf_info.height;
1298 hwc_win_info->src_config.format = surf_info.format;
1300 if ((hwc_window->hwc->pp_queue) && (output->display_mode == E_OUTPUT_DISPLAY_MODE_MIRROR))
1302 hwc_win_info->src_config.pos.x = 0;
1303 hwc_win_info->src_config.pos.y = 0;
1304 hwc_win_info->src_config.pos.w = surf_info.width;
1305 hwc_win_info->src_config.pos.h = surf_info.height;
1306 hwc_win_info->dst_pos.x = 0;
1307 hwc_win_info->dst_pos.y = 0;
1308 hwc_win_info->dst_pos.w = surf_info.width;
1309 hwc_win_info->dst_pos.h = surf_info.height;
1313 hwc_win_info->src_config.pos.x = output->config.geom.x;
1314 hwc_win_info->src_config.pos.y = output->config.geom.y;
1315 hwc_win_info->src_config.pos.w = output->config.geom.w;
1316 hwc_win_info->src_config.pos.h = output->config.geom.h;
1317 hwc_win_info->dst_pos.x = 0;
1318 hwc_win_info->dst_pos.y = 0;
1319 hwc_win_info->dst_pos.w = output->config.geom.w;
1320 hwc_win_info->dst_pos.h = output->config.geom.h;
1323 // TODO: need to calculation with ec(window) rotation and output->config.rotation?
1324 hwc_win_info->transform = TDM_TRANSFORM_NORMAL;
1330 _e_hwc_window_video_info_get(E_Hwc_Window *hwc_window, tdm_hwc_window_info *hwc_win_info)
1333 E_Client_Video_Info vinfo;
1337 if (!e_hwc_window_is_video(hwc_window)) return EINA_FALSE;
1339 ec = hwc_window->ec;
1340 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1341 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
1343 hwc = hwc_window->hwc;
1344 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
1346 zone = hwc_window->zone;
1347 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
1349 if (!e_client_video_info_get(ec, &vinfo))
1351 EHWERR("Video window does not get the video info", hwc_window->ec, hwc_window->hwc, hwc_window);
1355 vinfo.dst_pos.x -= zone->x;
1356 vinfo.dst_pos.y -= zone->y;
1358 memcpy(&hwc_win_info->src_config, &vinfo.src_config, sizeof(tdm_info_config));
1359 memcpy(&hwc_win_info->dst_pos, &vinfo.dst_pos, sizeof(tdm_pos));
1360 hwc_win_info->transform = vinfo.transform;
1366 _e_hwc_window_info_set(E_Hwc_Window *hwc_window, tdm_hwc_window_info *hwc_win_info)
1370 if (!memcmp(&hwc_window->current.info, hwc_win_info, sizeof(tdm_hwc_window_info)))
1373 memcpy(&hwc_window->current.info, hwc_win_info, sizeof(tdm_hwc_window_info));
1375 if (e_hwc_window_is_target(hwc_window))
1377 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->hwc, EINA_FALSE);
1379 error = tdm_hwc_set_client_target_buffer_info(hwc_window->hwc->thwc, &hwc_window->current.info);
1380 if (error == TDM_ERROR_NOT_IMPLEMENTED)
1382 EHWINF("tdm_hwc_set_client_target_buffer_info not implement",
1383 hwc_window->ec, hwc_window->hwc, hwc_window);
1387 EINA_SAFETY_ON_TRUE_RETURN_VAL(error != TDM_ERROR_NONE, EINA_FALSE);
1391 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->thwc_window, EINA_FALSE);
1393 error = tdm_hwc_window_set_info(hwc_window->thwc_window, &hwc_window->current.info);
1394 EINA_SAFETY_ON_TRUE_RETURN_VAL(error != TDM_ERROR_NONE, EINA_FALSE);
1397 EHWTRACE("INF src(%dx%d+%d+%d size:%dx%d fmt:%c%c%c%c) dst(%dx%d+%d+%d) trans(%d)",
1398 hwc_window->ec, hwc_window->hwc, hwc_window,
1399 hwc_window->current.info.src_config.pos.w, hwc_window->current.info.src_config.pos.h,
1400 hwc_window->current.info.src_config.pos.x, hwc_window->current.info.src_config.pos.y,
1401 hwc_window->current.info.src_config.size.h, hwc_window->current.info.src_config.size.v,
1402 EHW_FOURCC_STR(hwc_window->current.info.src_config.format),
1403 hwc_window->current.info.dst_pos.w, hwc_window->current.info.dst_pos.h,
1404 hwc_window->current.info.dst_pos.x, hwc_window->current.info.dst_pos.y,
1405 hwc_window->current.info.transform);
1411 e_hwc_window_info_update(E_Hwc_Window *hwc_window)
1413 tdm_hwc_window_info hwc_win_info = {0};
1416 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1418 if (hwc_window->is_deleted) return EINA_FALSE;
1420 if (hwc_window->is_target)
1422 if (!_e_hwc_window_target_info_get(hwc_window, &hwc_win_info))
1424 EHWERR("fail to _e_hwc_window_target_info_get",
1425 hwc_window->ec, hwc_window->hwc, hwc_window);
1431 ec = hwc_window->ec;
1432 if (!ec) return EINA_FALSE;
1434 if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
1436 if ((hwc_window->present_sync) || (eina_list_count(hwc_window->pending_update_list)))
1439 if (e_hwc_window_is_cursor(hwc_window))
1441 if (!_e_hwc_window_cursor_info_get(hwc_window, &hwc_win_info))
1443 EHWERR("fail to _e_hwc_window_cursor_info_get",
1444 hwc_window->ec, hwc_window->hwc, hwc_window);
1448 else if (e_hwc_window_is_video(hwc_window))
1450 if (!_e_hwc_window_video_info_get(hwc_window, &hwc_win_info))
1452 EHWERR("fail to _e_hwc_window_video_info_get",
1453 hwc_window->ec, hwc_window->hwc, hwc_window);
1459 if (!_e_hwc_window_info_get(hwc_window, &hwc_win_info))
1461 EHWERR("fail to _e_hwc_window_info_get",
1462 hwc_window->ec, hwc_window->hwc, hwc_window);
1468 return _e_hwc_window_info_set(hwc_window, &hwc_win_info);
1472 e_hwc_window_display_or_commit_buffer_check(E_Hwc_Window *hwc_window, tbm_surface_h tsurface)
1475 E_Hwc_Window_Commit_Data *commit_data;
1478 hwc = hwc_window->hwc;
1479 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
1480 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1481 EINA_SAFETY_ON_NULL_RETURN_VAL(tsurface, EINA_FALSE);
1483 if (hwc_window->display.buffer.tsurface == tsurface) return EINA_TRUE;
1485 EINA_LIST_FOREACH(hwc_window->commit_data_list, l, commit_data)
1487 if (commit_data->buffer.tsurface == tsurface)
1491 if (hwc->pp_update.buffer.tsurface == tsurface)
1498 _e_hwc_window_buffer_set(E_Hwc_Window *hwc_window, tbm_surface_h tsurface,
1499 E_Comp_Wl_Buffer *comp_buffer, E_Hwc_Window_Queue *queue)
1501 E_Hwc_Window_Queue_Buffer *queue_buffer = NULL, *queue_buffer2 = NULL;
1502 tdm_error error = TDM_ERROR_NONE;
1503 int acquire_fence_fd;
1505 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->thwc_window, EINA_FALSE);
1507 if (hwc_window->current.buffer.tsurface == tsurface) return EINA_FALSE;
1509 if (tsurface && queue)
1511 queue_buffer = e_hwc_window_queue_buffer_find(queue, tsurface);
1514 e_hwc_window_queue_buffer_enqueue(queue, queue_buffer);
1515 queue_buffer2 = e_hwc_window_queue_buffer_acquire(queue);
1516 while (queue_buffer != queue_buffer2)
1518 e_hwc_window_queue_buffer_release(queue, queue_buffer2);
1519 queue_buffer2 = e_hwc_window_queue_buffer_acquire(queue);
1522 EHWERR("fail to acquire buffer:%p tsurface:%p",
1523 hwc_window->ec, hwc_window->hwc, hwc_window,
1524 queue_buffer, queue_buffer->tsurface);
1531 EHWTRACE("FET ts:%10p - {%s} state:%s zpos:%d deleted:%s cursor:%d video:%d",
1532 hwc_window->ec, hwc_window->hwc, hwc_window,
1533 tsurface, e_hwc_window_name_get(hwc_window),
1534 e_hwc_window_state_string_get(hwc_window->state),
1535 hwc_window->zpos, (hwc_window->is_deleted ? "yes" : "no"),
1536 e_hwc_window_is_cursor(hwc_window), e_hwc_window_is_video(hwc_window));
1540 e_hwc_window_queue_buffer_reference(&hwc_window->current.queue_buffer_ref, queue_buffer);
1541 e_hwc_window_buffer_set(&hwc_window->current.buffer, tsurface, queue,
1542 comp_buffer ? comp_buffer->transform : 0);
1546 e_hwc_window_queue_buffer_reference(&hwc_window->current.queue_buffer_ref, NULL);
1547 e_hwc_window_buffer_set(&hwc_window->current.buffer, NULL, NULL, 0);
1550 error = tdm_hwc_window_set_buffer(hwc_window->thwc_window, hwc_window->current.buffer.tsurface);
1551 EINA_SAFETY_ON_TRUE_RETURN_VAL(error != TDM_ERROR_NONE, EINA_FALSE);
1553 if ((hwc_window->ec) && e_hwc_windows_fence_enabled_get(hwc_window->hwc))
1555 acquire_fence_fd = e_client_explicit_sync_acquire_fence_fd_get(hwc_window->ec);
1556 error = tdm_hwc_window_set_acquire_fence(hwc_window->thwc_window, acquire_fence_fd);
1557 EINA_SAFETY_ON_TRUE_RETURN_VAL(error != TDM_ERROR_NONE, EINA_FALSE);
1564 e_hwc_window_buffer_fetch(E_Hwc_Window *hwc_window)
1566 tbm_surface_h tsurface;
1568 E_Comp_Wl_Buffer *comp_buffer;
1570 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1571 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->hwc, EINA_FALSE);
1573 if (e_hwc_window_is_cursor(hwc_window))
1575 if (!_e_hwc_window_cursor_image_update(hwc_window))
1578 EHWTRACE("FET img_ptr:%p - {%s} state:%s zpos:%d deleted:%s",
1579 hwc_window->ec, hwc_window->hwc, hwc_window,
1580 hwc_window->cursor.img_ptr, e_hwc_window_name_get(hwc_window),
1581 e_hwc_window_state_string_get(hwc_window->state),
1582 hwc_window->zpos, (hwc_window->is_deleted ? "yes" : "no"));
1587 if ((hwc_window->present_sync) || (eina_list_count(hwc_window->pending_update_list)))
1590 ec = hwc_window->ec;
1592 if ((hwc_window->is_deleted) || (!ec) || e_object_is_del(E_OBJECT(ec)))
1596 /* for video we set buffer in the video module */
1597 else if (e_hwc_window_is_video(hwc_window))
1599 tsurface = e_client_video_tbm_surface_get(hwc_window->ec);
1603 /* acquire the surface */
1604 tsurface = _e_hwc_window_client_surface_acquire(hwc_window);
1607 comp_buffer = _e_hwc_window_comp_wl_buffer_get(hwc_window);
1609 return _e_hwc_window_buffer_set(hwc_window, tsurface, comp_buffer, hwc_window->queue);
1613 e_hwc_window_prop_update(E_Hwc_Window *hwc_window)
1615 Hwc_Window_Prop *prop;
1616 Eina_Bool ret = EINA_FALSE;
1618 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1620 EINA_LIST_FREE(hwc_window->prop_list, prop)
1622 if (!e_hwc_window_set_property(hwc_window, prop->id, prop->name, prop->value, EINA_TRUE))
1623 EHWERR("cannot update prop", hwc_window->ec, hwc_window->hwc, hwc_window);
1631 EINTERN E_Hwc_Window_Commit_Data *
1632 e_hwc_window_commit_data_acquire(E_Hwc_Window *hwc_window)
1634 E_Hwc_Window_Commit_Data *commit_data;
1635 E_Comp_Wl_Buffer *comp_buffer;
1637 if (hwc_window->accepted_state == E_HWC_WINDOW_STATE_CURSOR)
1639 if (!hwc_window->cursor.buffer) return NULL;
1640 if ((hwc_window->cursor.buffer == hwc_window->commit.buffer_ref.buffer) &&
1641 (!memcmp(&hwc_window->current.info, &hwc_window->commit.info, sizeof(tdm_hwc_window_info))))
1644 commit_data = E_NEW(E_Hwc_Window_Commit_Data, 1);
1645 EINA_SAFETY_ON_NULL_RETURN_VAL(commit_data, EINA_FALSE);
1647 memcpy(&commit_data->info, &hwc_window->current.info, sizeof(tdm_hwc_window_info));
1648 e_comp_wl_buffer_reference(&commit_data->buffer_ref,
1649 _e_hwc_window_comp_wl_buffer_get(hwc_window));
1651 _e_hwc_window_update_fps(hwc_window);
1653 else if ((hwc_window->accepted_state == E_HWC_WINDOW_STATE_DEVICE) ||
1654 (hwc_window->accepted_state == E_HWC_WINDOW_STATE_VIDEO))
1656 if (!hwc_window->current.buffer.tsurface) return EINA_FALSE;
1657 if ((hwc_window->current.buffer.tsurface == hwc_window->commit.buffer.tsurface) &&
1658 (!memcmp(&hwc_window->current.info, &hwc_window->commit.info, sizeof(tdm_hwc_window_info))))
1661 commit_data = E_NEW(E_Hwc_Window_Commit_Data, 1);
1662 EINA_SAFETY_ON_NULL_RETURN_VAL(commit_data, NULL);
1664 memcpy(&commit_data->info, &hwc_window->current.info, sizeof(tdm_hwc_window_info));
1666 e_hwc_window_queue_buffer_reference(&commit_data->queue_buffer_ref, hwc_window->current.queue_buffer_ref.buffer);
1668 if (e_hwc_window_is_video(hwc_window))
1670 comp_buffer = _e_hwc_window_comp_wl_buffer_get(hwc_window);
1671 if ((comp_buffer) &&
1672 (comp_buffer->tbm_surface == hwc_window->current.buffer.tsurface))
1673 e_comp_wl_buffer_reference(&commit_data->buffer_ref, comp_buffer);
1675 else if (!e_hwc_window_is_target(hwc_window))
1677 e_comp_wl_buffer_reference(&commit_data->buffer_ref,
1678 _e_hwc_window_comp_wl_buffer_get(hwc_window));
1681 e_hwc_window_buffer_set(&commit_data->buffer, hwc_window->current.buffer.tsurface,
1682 hwc_window->current.buffer.queue, hwc_window->current.buffer.transform);
1684 _e_hwc_window_update_fps(hwc_window);
1688 if (e_hwc_window_is_cursor(hwc_window))
1690 tdm_hwc_window_info info;
1694 if (!memcmp(&hwc_window->commit.info, &info, sizeof(tdm_hwc_window_info)))
1699 if (!hwc_window->commit.buffer.tsurface)
1703 commit_data = E_NEW(E_Hwc_Window_Commit_Data, 1);
1704 EINA_SAFETY_ON_NULL_RETURN_VAL(commit_data, NULL);
1706 e_hwc_window_buffer_set(&commit_data->buffer, NULL, NULL, 0);
1709 EHWTRACE("COM data:%p ts:%p - {%s} state:%s zpos:%d",
1710 hwc_window->ec, hwc_window->hwc, hwc_window,
1711 commit_data, commit_data->buffer.tsurface,
1712 e_hwc_window_name_get(hwc_window),
1713 e_hwc_window_state_string_get(hwc_window->state),
1716 commit_data->hwc_window = hwc_window;
1717 e_hwc_window_ref(hwc_window);
1719 /* set latest commit_data */
1720 memcpy(&hwc_window->commit.info, &commit_data->info, sizeof(tdm_hwc_window_info));
1722 e_hwc_window_queue_buffer_reference(&hwc_window->commit.queue_buffer_ref, commit_data->queue_buffer_ref.buffer);
1723 e_comp_wl_buffer_reference(&hwc_window->commit.buffer_ref, commit_data->buffer_ref.buffer);
1724 e_hwc_window_buffer_set(&hwc_window->commit.buffer, commit_data->buffer.tsurface,
1725 commit_data->buffer.queue, commit_data->buffer.transform);
1727 hwc_window->commit_data_list = eina_list_append(hwc_window->commit_data_list, commit_data);
1733 e_hwc_window_presentation_time_feedback_take(E_Hwc_Window *hwc_window,
1734 E_Presentation_Time_Container *container)
1736 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
1737 EINA_SAFETY_ON_NULL_RETURN(container);
1739 e_presentation_time_container_feedback_merge(&hwc_window->presentation_container,
1744 e_hwc_window_presentation_time_feedback_present(E_Hwc_Window *hwc_window,
1750 unsigned int flags =
1751 WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION;
1753 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
1755 if (!eina_list_count(hwc_window->presentation_container.presentation_feedbacks))
1758 EINA_SAFETY_ON_NULL_GOTO(hwc_window->hwc, discard);
1760 output = hwc_window->hwc->output;
1761 EINA_SAFETY_ON_NULL_GOTO(output, discard);
1763 if ((sequence) || (tv_sec) || (tv_usec))
1764 flags |= WP_PRESENTATION_FEEDBACK_KIND_HW_CLOCK;
1766 if (!hwc_window->is_target)
1767 flags |= WP_PRESENTATION_FEEDBACK_KIND_ZERO_COPY;
1769 e_presentation_time_container_feedback_present(&hwc_window->presentation_container,
1778 e_presentation_time_container_feedback_discard(&hwc_window->presentation_container);
1782 e_hwc_window_presentation_time_feedback_discard(E_Hwc_Window *hwc_window)
1784 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
1786 e_presentation_time_container_feedback_discard(&hwc_window->presentation_container);
1790 e_hwc_window_commit_data_release(E_Hwc_Window *hwc_window, E_Hwc_Window_Commit_Data *commit_data)
1792 tbm_surface_h tsurface;
1793 E_Hwc_Window_Queue *queue;
1794 E_Hwc_Window_Queue_Buffer *queue_buffer;
1796 /* we don't have data to release */
1797 if (!commit_data) return EINA_FALSE;
1799 if (!eina_list_data_find(hwc_window->commit_data_list, commit_data))
1801 EHWERR("failed to find commit_data:%p in commit_data_list",
1802 hwc_window->ec, hwc_window->hwc, hwc_window, commit_data);
1806 tsurface = commit_data->buffer.tsurface;
1807 queue = commit_data->buffer.queue;
1808 queue_buffer = commit_data->queue_buffer_ref.buffer;
1810 EHWTRACE("DON data:%p ts:%p - {%s} state:%s zpos:%d",
1811 hwc_window->ec, hwc_window->hwc, hwc_window,
1812 commit_data, tsurface, e_hwc_window_name_get(hwc_window),
1813 e_hwc_window_state_string_get(hwc_window->state),
1816 if (e_hwc_window_is_cursor(hwc_window))
1818 tdm_hwc_window_info info;
1822 if (memcmp(&commit_data->info, &info, sizeof(tdm_hwc_window_info)))
1824 e_comp_wl_buffer_reference(&hwc_window->display.buffer_ref,
1825 commit_data->buffer_ref.buffer);
1827 if (!memcmp(&hwc_window->display.info, &info, sizeof(tdm_hwc_window_info)))
1828 e_hwc_window_ref(hwc_window);
1830 memcpy(&hwc_window->display.info, &commit_data->info, sizeof(tdm_hwc_window_info));
1834 e_comp_wl_buffer_reference(&hwc_window->display.buffer_ref, NULL);
1836 if (memcmp(&hwc_window->display.info, &info, sizeof(tdm_hwc_window_info)))
1837 e_hwc_window_unref(hwc_window);
1839 CLEAR(hwc_window->display.info);
1842 e_comp_wl_buffer_reference(&commit_data->buffer_ref, NULL);
1843 hwc_window->commit_data_list = eina_list_remove(hwc_window->commit_data_list, commit_data);
1845 e_hwc_window_unref(hwc_window);
1852 if (hwc_window->display.buffer.tsurface)
1853 e_hwc_window_unref(hwc_window);
1855 e_hwc_window_queue_buffer_reference(&hwc_window->display.queue_buffer_ref, NULL);
1856 e_comp_wl_buffer_reference(&hwc_window->display.buffer_ref, NULL);
1857 e_hwc_window_buffer_set(&hwc_window->display.buffer, NULL, NULL, 0);
1859 CLEAR(hwc_window->display.info);
1863 if (hwc_window->display.buffer.tsurface)
1864 e_hwc_window_unref(hwc_window);
1866 e_hwc_window_queue_buffer_reference(&hwc_window->display.queue_buffer_ref, queue_buffer);
1867 e_comp_wl_buffer_reference(&hwc_window->display.buffer_ref, commit_data->buffer_ref.buffer);
1868 e_hwc_window_buffer_set(&hwc_window->display.buffer, tsurface, queue, commit_data->buffer.transform);
1870 memcpy(&hwc_window->display.info, &commit_data->info, sizeof(tdm_hwc_window_info));
1872 e_hwc_window_ref(hwc_window);
1875 e_hwc_window_queue_buffer_reference(&commit_data->queue_buffer_ref, NULL);
1876 e_comp_wl_buffer_reference(&commit_data->buffer_ref, NULL);
1877 e_hwc_window_buffer_set(&commit_data->buffer, NULL, NULL, 0);
1879 hwc_window->commit_data_list = eina_list_remove(hwc_window->commit_data_list, commit_data);
1881 e_hwc_window_unref(hwc_window);
1887 _e_hwc_window_cqueue_destroy_cb(struct wayland_tbm_client_queue *cqueue, void *data)
1889 E_Hwc_Window *hwc_window = (E_Hwc_Window *)data;
1891 hwc_window->cqueue = NULL;
1895 e_hwc_window_activate(E_Hwc_Window *hwc_window, E_Hwc_Window_Queue *queue)
1897 struct wayland_tbm_client_queue *cqueue;
1899 int queue_size = 0, queue_width = 0, queue_height = 0;
1901 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1902 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->ec, EINA_FALSE);
1904 if (hwc_window->activation_state == E_HWC_WINDOW_ACTIVATION_STATE_ACTIVATED)
1907 if (e_hwc_window_is_cursor(hwc_window)) return EINA_TRUE;
1912 queue_size = tbm_surface_queue_get_size(queue->tqueue);
1913 queue_width = tbm_surface_queue_get_width(queue->tqueue);
1914 queue_height = tbm_surface_queue_get_height(queue->tqueue);
1917 cqueue = e_comp_wl_tbm_client_queue_get(hwc_window->ec);
1920 wayland_tbm_server_client_queue_activate(cqueue, 0, queue_size,
1921 queue_width, queue_height, flush);
1922 wayland_tbm_server_client_queue_set_destroy_cb(cqueue,
1923 _e_hwc_window_cqueue_destroy_cb,
1925 hwc_window->cqueue = cqueue;
1928 EHWINF("Activate -- ehwq:%p {%s}",
1929 hwc_window->ec, hwc_window->hwc, hwc_window, queue,
1930 e_hwc_window_name_get(hwc_window));
1932 hwc_window->activation_state = E_HWC_WINDOW_ACTIVATION_STATE_ACTIVATED;
1938 e_hwc_window_deactivate(E_Hwc_Window *hwc_window)
1940 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1941 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->ec, EINA_FALSE);
1943 if (hwc_window->activation_state == E_HWC_WINDOW_ACTIVATION_STATE_DEACTIVATED)
1946 if (e_hwc_window_is_cursor(hwc_window)) return EINA_TRUE;
1948 if (hwc_window->cqueue)
1950 wayland_tbm_server_client_queue_deactivate(hwc_window->cqueue);
1951 wayland_tbm_server_client_queue_set_destroy_cb(hwc_window->cqueue,
1954 hwc_window->cqueue = NULL;
1957 EHWINF("Deactivate - {%s}",
1958 hwc_window->ec, hwc_window->hwc, hwc_window,
1959 e_hwc_window_name_get(hwc_window));
1961 hwc_window->activation_state = E_HWC_WINDOW_ACTIVATION_STATE_DEACTIVATED;
1967 e_hwc_window_is_on_hw_overlay(E_Hwc_Window *hwc_window)
1969 E_Hwc_Window_State accepted_state = E_HWC_WINDOW_STATE_NONE;
1970 E_Hwc_Window_State state = E_HWC_WINDOW_STATE_NONE;
1972 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1974 accepted_state = hwc_window->accepted_state;
1975 state = hwc_window->state;
1977 if ((accepted_state == E_HWC_WINDOW_STATE_DEVICE) ||
1978 (accepted_state == E_HWC_WINDOW_STATE_CURSOR) ||
1979 (accepted_state == E_HWC_WINDOW_STATE_VIDEO))
1981 if (accepted_state == state)
1988 EINTERN tbm_surface_h
1989 e_hwc_window_displaying_surface_get(E_Hwc_Window *hwc_window)
1991 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, NULL);
1993 return hwc_window->display.buffer.tsurface;
1997 e_hwc_window_accepted_state_set(E_Hwc_Window *hwc_window, E_Hwc_Window_State state)
1999 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2001 if (hwc_window->accepted_state != state)
2003 hwc_window->accepted_state = state;
2005 if (hwc_window->accepted_state == E_HWC_WINDOW_STATE_NONE)
2006 hwc_window->zpos = E_HWC_WINDOW_ZPOS_NONE;
2008 EHWINF("Set Accepted state:%s - {%s}",
2009 hwc_window->ec, hwc_window->hwc, hwc_window, e_hwc_window_state_string_get(state),
2010 e_hwc_window_name_get(hwc_window));
2014 _e_hwc_window_hook_call(E_HWC_WINDOW_HOOK_ACCEPTED_STATE_SET, hwc_window);
2019 EINTERN E_Hwc_Window_State
2020 e_hwc_window_accepted_state_get(E_Hwc_Window *hwc_window)
2022 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, E_HWC_WINDOW_STATE_NONE);
2024 return hwc_window->accepted_state;
2028 e_hwc_window_state_set(E_Hwc_Window *hwc_window, E_Hwc_Window_State state, Eina_Bool composition_update)
2030 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2032 if (hwc_window->state == state) return EINA_TRUE;
2034 if (((hwc_window->accepted_state == E_HWC_WINDOW_STATE_DEVICE) && (state == E_HWC_WINDOW_STATE_CLIENT)) ||
2035 ((hwc_window->accepted_state == E_HWC_WINDOW_STATE_DEVICE) && (state == E_HWC_WINDOW_STATE_NONE)))
2036 e_hwc_window_constraints_reset(hwc_window);
2038 hwc_window->state = state;
2040 /* update the composition type */
2041 if (composition_update)
2043 if (!e_hwc_window_composition_update(hwc_window))
2044 EHWERR("Cannot update window composition", hwc_window->ec, hwc_window->hwc, hwc_window);
2047 /* zpos is -999 at state none */
2048 if (state == E_HWC_WINDOW_STATE_NONE)
2049 e_hwc_window_zpos_set(hwc_window, -999);
2054 EINTERN E_Hwc_Window_State
2055 e_hwc_window_state_get(E_Hwc_Window *hwc_window)
2057 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, E_HWC_WINDOW_STATE_NONE);
2059 return hwc_window->state;
2063 e_hwc_window_device_state_available_get(E_Hwc_Window *hwc_window)
2065 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2067 return hwc_window->device_state_available;
2071 _e_hwc_window_client_transform_device_state_available_get(E_Client *ec)
2074 int x[4], y[4], z[4];
2077 if (!e_client_transform_core_enable_get(ec))
2080 map = e_client_map_get(ec);
2081 if (!map) return EINA_TRUE;
2083 for (i = 0; i < 4; i++)
2085 if (!e_map_point_coord_get(map, i, &x[i], &y[i], &z[i]))
2095 if ((z[0] != z[1]) || (z[0] != z[2]) || (z[0] != z[3]))
2098 /* check rectangle */
2099 if ((x[0] != x[3]) || (x[1] != x[2]))
2102 if ((y[0] != y[1]) || (y[2] != y[3]))
2108 // if ec has invalid buffer or scaled( transformed ) or forced composite(never_hwc)
2110 e_hwc_window_device_state_available_update(E_Hwc_Window *hwc_window)
2113 E_Comp_Wl_Client_Data *cdata;
2116 int minw = 0, minh = 0;
2118 Eina_Bool available = EINA_TRUE;
2119 E_Hwc_Window_Restriction restriction = E_HWC_WINDOW_RESTRICTION_NONE;
2123 Evas_Render_Op render_op;
2125 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2127 ec = hwc_window->ec;
2129 if ((hwc_window->is_deleted) || (!ec) || e_object_is_del(E_OBJECT(ec)))
2131 restriction = E_HWC_WINDOW_RESTRICTION_DELETED;
2132 available = EINA_FALSE;
2136 if (ec->comp_override > 0)
2138 restriction = E_HWC_WINDOW_RESTRICTION_OVERRIDE;
2139 available = EINA_FALSE;
2143 if (hwc_window->obscured_by_target)
2145 restriction = E_HWC_WINDOW_RESTRICTION_OBSCURED_BY_TARGET;
2146 available = EINA_FALSE;
2150 if (e_comp_object_is_animating(ec->frame))
2152 restriction = E_HWC_WINDOW_RESTRICTION_ANIMATING;
2153 available = EINA_FALSE;
2157 if (evas_object_data_get(ec->frame, "effect_running"))
2159 restriction = E_HWC_WINDOW_RESTRICTION_EFFECT_RUNNING;
2160 available = EINA_FALSE;
2164 cdata = e_client_cdata_get(ec);
2165 if ((!cdata) || (!cdata->buffer_ref.buffer))
2167 restriction = E_HWC_WINDOW_RESTRICTION_BUFFER;
2168 available = EINA_FALSE;
2172 pixmap = ec->pixmap;
2173 if ((!pixmap) || (!e_pixmap_resource_get(pixmap)))
2175 restriction = E_HWC_WINDOW_RESTRICTION_PIXMAP_RESOURCE;
2176 available = EINA_FALSE;
2180 if ((cdata->width_from_buffer != cdata->width_from_viewport) ||
2181 (cdata->height_from_buffer != cdata->height_from_viewport))
2183 restriction = E_HWC_WINDOW_RESTRICTION_VIEWPORT;
2184 available = EINA_FALSE;
2188 if (cdata->never_hwc)
2190 restriction = E_HWC_WINDOW_RESTRICTION_NEVER_HWC;
2191 available = EINA_FALSE;
2195 if (!_e_hwc_window_client_transform_device_state_available_get(ec))
2197 restriction = E_HWC_WINDOW_RESTRICTION_TRANSFORM;
2198 available = EINA_FALSE;
2202 switch (cdata->buffer_ref.buffer->type)
2204 case E_COMP_WL_BUFFER_TYPE_NATIVE:
2205 case E_COMP_WL_BUFFER_TYPE_TBM:
2207 case E_COMP_WL_BUFFER_TYPE_SHM:
2208 if (!e_util_strcmp("wl_pointer-cursor", ec->icccm.window_role))
2211 restriction = E_HWC_WINDOW_RESTRICTION_BUFFER_TYPE;
2212 available = EINA_FALSE;
2216 zone = hwc_window->zone;
2219 restriction = E_HWC_WINDOW_RESTRICTION_ZONE;
2220 available = EINA_FALSE;
2224 eout = e_output_find(zone->output_id);
2227 restriction = E_HWC_WINDOW_RESTRICTION_OUTPUT;
2228 available = EINA_FALSE;
2232 tdm_output_get_available_size(eout->toutput, &minw, &minh, NULL, NULL, NULL);
2234 if ((minw > 0) && (minw > cdata->buffer_ref.buffer->w))
2236 restriction = E_HWC_WINDOW_RESTRICTION_MIN_WIDTH;
2237 available = EINA_FALSE;
2241 if ((minh > 0) && (minh > cdata->buffer_ref.buffer->h))
2243 restriction = E_HWC_WINDOW_RESTRICTION_MIN_HEIGHT;
2244 available = EINA_FALSE;
2248 desk = e_desk_current_get(zone);
2251 if ((desk->geom.x != zone->x) || (desk->geom.y != zone->y) ||
2252 (desk->geom.w != zone->w) || (desk->geom.h != zone->h))
2254 restriction = E_HWC_WINDOW_RESTRICTION_DESK_GEOMETRY;
2255 available = EINA_FALSE;
2260 transform = e_comp_wl_output_buffer_transform_get(ec);
2261 if ((eout->config.rotation / 90) != transform)
2263 restriction = E_HWC_WINDOW_RESTRICTION_OUTPUT_TRANSFORM;
2264 available = EINA_FALSE;
2268 // if ec->frame is not for client buffer (e.g. launchscreen)
2269 if (e_comp_object_content_type_get(ec->frame) != E_COMP_OBJECT_CONTENT_TYPE_INT_IMAGE)
2271 restriction = E_HWC_WINDOW_RESTRICTION_CONTENT_IMAGE;
2272 available = EINA_FALSE;
2276 if (e_comp_object_image_filter_get(ec->frame) != E_COMP_IMAGE_FILTER_NONE)
2278 restriction = E_HWC_WINDOW_RESTRICTION_IMAGE_FILTER;
2279 available = EINA_FALSE;
2283 // if there is a ec which is lower than quickpanel and quickpanel is opened.
2284 if (E_POLICY_QUICKPANEL_LAYER >= evas_object_layer_get(ec->frame))
2286 // check whether quickpanel is open than break
2287 if (e_qps_visible_get())
2289 restriction = E_HWC_WINDOW_RESTRICTION_QUICKPANEL_OPEN;
2290 available = EINA_FALSE;
2295 if (e_comp_object_render_update_lock_get(ec->frame))
2297 restriction = E_HWC_WINDOW_RESTRICTION_RENDER_UPDATE_LOCK;
2298 available = EINA_FALSE;
2302 if (e_client_desk_zoom_enable_get(ec))
2304 restriction = E_HWC_WINDOW_RESTRICTION_DESK_ZOOM;
2305 available = EINA_FALSE;
2309 e_comp_object_color_get(ec->frame, NULL, NULL, NULL, &alpha);
2312 restriction = E_HWC_WINDOW_RESTRICTION_BLEND_ALPHA;
2313 available = EINA_FALSE;
2317 render_op = e_comp_object_render_op_get(ec->frame);
2318 if (render_op != EVAS_RENDER_BLEND)
2320 restriction = E_HWC_WINDOW_RESTRICTION_BLEND_EQUATION;
2321 available = EINA_FALSE;
2325 if (hwc_window->queue_unset_waiting)
2327 restriction = E_HWC_WINDOW_RESTRICTION_QUEUE_UNSET_WAITING;
2328 available = EINA_FALSE;
2333 hwc_window->restriction = restriction;
2335 if (hwc_window->device_state_available == available) return EINA_FALSE;
2337 hwc_window->device_state_available = available;
2343 e_hwc_window_constraints_update(E_Hwc_Window *hwc_window)
2347 struct wayland_tbm_client_queue *cqueue;
2349 EINA_SAFETY_ON_FALSE_RETURN_VAL(hwc_window, EINA_FALSE);
2350 EINA_SAFETY_ON_FALSE_RETURN_VAL(hwc_window->thwc_window, EINA_FALSE);
2352 /* get the constraints from libtdm */
2353 terror = tdm_hwc_window_get_constraints(hwc_window->thwc_window, &constraints);
2354 EINA_SAFETY_ON_TRUE_RETURN_VAL(terror != TDM_ERROR_NONE, EINA_FALSE);
2356 if (hwc_window->constraints == constraints) return EINA_TRUE;
2360 if (constraints & TDM_HWC_WIN_CONSTRAINT_BUFFER_QUEUE)
2362 cqueue = e_comp_wl_tbm_client_queue_get(hwc_window->ec);
2363 if (!cqueue) return EINA_FALSE;
2365 if (!_e_hwc_window_buffer_queue_set(hwc_window))
2367 EHWERR("fail to _e_hwc_window_buffer_queue_set", hwc_window->ec, hwc_window->hwc, hwc_window);
2372 _e_hwc_window_buffer_queue_unset(hwc_window);
2374 EHWTRACE("Set constranints:%x -- {%s}",
2375 hwc_window->ec, hwc_window->hwc, hwc_window, constraints, e_client_util_name_get(hwc_window->ec));
2377 hwc_window->constraints = constraints;
2380 e_hwc_window_constraints_reset(hwc_window);
2386 _e_hwc_window_client_recover(E_Hwc_Window *hwc_window, Eina_Bool *clear_attach)
2388 E_Comp_Wl_Buffer *recover_buffer;
2389 E_Comp_Wl_Buffer *comp_wl_buffer;
2390 tbm_surface_h tsurface;
2392 Eina_Bool new_buffer = EINA_FALSE;
2394 if (hwc_window->is_deleted) return EINA_FALSE;
2396 ec = hwc_window->ec;
2397 if (!ec) return EINA_FALSE;
2399 comp_wl_buffer = _e_hwc_window_comp_wl_buffer_get(hwc_window);
2401 if ((!comp_wl_buffer) &&
2402 (!evas_object_visible_get(ec->frame)) &&
2403 (ec->exp_iconify.buffer_flush) &&
2404 (e_policy_visibility_client_is_iconic(ec)))
2407 if (!comp_wl_buffer)
2409 tsurface = e_hwc_window_displaying_surface_get(hwc_window);
2410 if (!tsurface) return EINA_FALSE;
2412 recover_buffer = e_comp_wl_buffer_create_with_tbm_surface(tsurface);
2413 EINA_SAFETY_ON_NULL_RETURN_VAL(recover_buffer, EINA_FALSE);
2415 recover_buffer->transform = hwc_window->display.buffer.transform;
2416 new_buffer = EINA_TRUE;
2419 recover_buffer = comp_wl_buffer;
2421 EHWTRACE("Recover ts:%p - {%s}",
2422 hwc_window->ec, hwc_window->hwc, hwc_window, recover_buffer->tbm_surface,
2423 e_hwc_window_name_get(hwc_window));
2426 if (e_client_cdata_get(ec))
2427 e_comp_wl_surface_attach(ec, recover_buffer);
2430 /* to avoid resource leak */
2432 e_comp_wl_buffer_destroy(recover_buffer);
2435 e_hwc_window_buffer_fetch(hwc_window);
2439 if (!comp_wl_buffer)
2440 *clear_attach = EINA_TRUE;
2442 *clear_attach = EINA_FALSE;
2449 _e_hwc_window_rendered_window_set(E_Hwc_Window *hwc_window, Eina_Bool set)
2453 Eina_Bool clear_attach = EINA_FALSE;
2455 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2457 if (hwc_window->is_deleted) return EINA_FALSE;
2459 ec = hwc_window->ec;
2460 if (!ec) return EINA_FALSE;
2462 if (hwc_window->render_target == set) return EINA_TRUE;
2466 ret = _e_hwc_window_client_recover(hwc_window, &clear_attach);
2468 if (hwc_window->ec->redirected)
2470 e_comp_object_redirected_set(ec->frame, EINA_TRUE);
2472 e_pixmap_image_refresh(ec->pixmap);
2473 e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
2474 e_comp_object_dirty(ec->frame);
2475 e_comp_object_render(ec->frame);
2478 e_comp_object_render_update_del(ec->frame);
2480 e_hwc_windows_present_sync(hwc_window->hwc);
2482 EHWTRACE("Redirect - {%s}",
2483 hwc_window->ec, hwc_window->hwc, hwc_window, e_hwc_window_name_get(hwc_window));
2486 if (clear_attach && e_client_cdata_get(ec))
2487 e_comp_wl_surface_attach(ec, NULL);
2491 if (hwc_window->ec->redirected)
2493 e_comp_object_redirected_set(ec->frame, EINA_FALSE);
2495 e_hwc_windows_present_sync(hwc_window->hwc);
2497 EHWTRACE("Unredirect - {%s}",
2498 hwc_window->ec, hwc_window->hwc, hwc_window, e_hwc_window_name_get(hwc_window));
2502 hwc_window->render_target = set;
2508 e_hwc_window_rendered_window_update(E_Hwc_Window *hwc_window)
2511 E_Hwc_Window_State state;
2513 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2515 if (hwc_window->is_deleted) return EINA_TRUE;
2517 ec = hwc_window->ec;
2518 if (!ec) return EINA_TRUE;
2520 state = e_hwc_window_state_get(hwc_window);
2524 case E_HWC_WINDOW_STATE_DEVICE:
2525 case E_HWC_WINDOW_STATE_CURSOR:
2526 _e_hwc_window_rendered_window_set(hwc_window, EINA_FALSE);
2528 case E_HWC_WINDOW_STATE_CLIENT:
2529 case E_HWC_WINDOW_STATE_NONE:
2530 _e_hwc_window_rendered_window_set(hwc_window, EINA_TRUE);
2532 case E_HWC_WINDOW_STATE_VIDEO:
2541 e_hwc_window_client_type_override(E_Hwc_Window *hwc_window)
2543 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
2545 if (hwc_window->is_target) return;
2546 if (hwc_window->is_video) return;
2548 if ((hwc_window->state == E_HWC_WINDOW_STATE_CLIENT) ||
2549 (hwc_window->state == E_HWC_WINDOW_STATE_VIDEO) ||
2550 (hwc_window->state == E_HWC_WINDOW_STATE_NONE))
2553 if (hwc_window->ec && !hwc_window->ec->redirected)
2556 e_hwc_window_device_state_available_update(hwc_window);
2557 e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_CLIENT, EINA_TRUE);
2558 e_hwc_window_constraints_reset(hwc_window);
2559 e_hwc_window_rendered_window_update(hwc_window);
2561 EHWTRACE("set client override", hwc_window->ec, hwc_window->hwc, hwc_window);
2565 e_hwc_window_state_string_get(E_Hwc_Window_State hwc_window_state)
2567 switch (hwc_window_state)
2569 case E_HWC_WINDOW_STATE_NONE:
2570 return "NO"; // None
2571 case E_HWC_WINDOW_STATE_CLIENT:
2572 return "CL"; // Client
2573 case E_HWC_WINDOW_STATE_DEVICE:
2574 return "DV"; // Device
2575 case E_HWC_WINDOW_STATE_VIDEO:
2576 return "VD"; // Video
2577 case E_HWC_WINDOW_STATE_CURSOR:
2578 return "CS"; // Cursor
2585 e_hwc_window_restriction_string_get(E_Hwc_Window *hwc_window)
2587 if (!hwc_window) return "UNKNOWN";
2589 switch (hwc_window->restriction)
2591 case E_HWC_WINDOW_RESTRICTION_NONE:
2593 case E_HWC_WINDOW_RESTRICTION_DELETED:
2595 case E_HWC_WINDOW_RESTRICTION_OVERRIDE:
2597 case E_HWC_WINDOW_RESTRICTION_ANIMATING:
2599 case E_HWC_WINDOW_RESTRICTION_BUFFER:
2601 case E_HWC_WINDOW_RESTRICTION_VIEWPORT:
2603 case E_HWC_WINDOW_RESTRICTION_NEVER_HWC:
2605 case E_HWC_WINDOW_RESTRICTION_TRANSFORM:
2606 return "window transform";
2607 case E_HWC_WINDOW_RESTRICTION_BUFFER_TYPE:
2608 return "buffer type";
2609 case E_HWC_WINDOW_RESTRICTION_OUTPUT:
2611 case E_HWC_WINDOW_RESTRICTION_MIN_WIDTH:
2613 case E_HWC_WINDOW_RESTRICTION_MIN_HEIGHT:
2614 return "min height";
2615 case E_HWC_WINDOW_RESTRICTION_TOUCH_PRESS:
2616 return "touch press";
2617 case E_HWC_WINDOW_RESTRICTION_OUTPUT_TRANSFORM:
2618 return "output transform";
2619 case E_HWC_WINDOW_RESTRICTION_CONTENT_IMAGE:
2620 return "content image";
2621 case E_HWC_WINDOW_RESTRICTION_QUICKPANEL_OPEN:
2622 return "quickpanel open";
2623 case E_HWC_WINDOW_RESTRICTION_PIXMAP_RESOURCE:
2624 return "pixmap resource";
2625 case E_HWC_WINDOW_RESTRICTION_OBSCURED_BY_TARGET:
2626 return "obscured by target";
2627 case E_HWC_WINDOW_RESTRICTION_IMAGE_FILTER:
2628 return "image filter";
2629 case E_HWC_WINDOW_RESTRICTION_DESK_GEOMETRY:
2630 return "desk geometry";
2631 case E_HWC_WINDOW_RESTRICTION_EFFECT_RUNNING:
2632 return "effect running";
2633 case E_HWC_WINDOW_RESTRICTION_RENDER_UPDATE_LOCK:
2634 return "render update lock";
2635 case E_HWC_WINDOW_RESTRICTION_DESK_ZOOM:
2637 case E_HWC_WINDOW_RESTRICTION_BLEND_ALPHA:
2638 return "blend alpha";
2639 case E_HWC_WINDOW_RESTRICTION_BLEND_EQUATION:
2640 return "blend equation";
2641 case E_HWC_WINDOW_RESTRICTION_ZONE:
2643 case E_HWC_WINDOW_RESTRICTION_QUEUE_UNSET_WAITING:
2644 return "queue unset waiting";
2651 e_hwc_window_name_get(E_Hwc_Window *hwc_window)
2658 if (hwc_window->is_root_target)
2659 return "@ROOT TARGET WINDOW@";
2661 if (hwc_window->is_target)
2662 return "@TARGET WINDOW@";
2664 if (!hwc_window->ec)
2667 name = e_client_util_name_get(hwc_window->ec);
2675 e_hwc_window_name_set(E_Hwc_Window *hwc_window)
2679 Eina_Bool no_name = EINA_FALSE;
2681 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
2683 if (hwc_window->set_name) return;
2685 name = e_client_util_name_get(hwc_window->ec);
2689 no_name = EINA_TRUE;
2692 ret = tdm_hwc_window_set_name(hwc_window->thwc_window, name);
2693 EINA_SAFETY_ON_TRUE_RETURN(ret != TDM_ERROR_NONE);
2695 /* the name may be set later */
2696 if (no_name) return;
2698 hwc_window->set_name = EINA_TRUE;
2702 e_hwc_window_set_property(E_Hwc_Window *hwc_window, unsigned int id, const char *name, tdm_value value, Eina_Bool force)
2706 Hwc_Window_Prop *prop;
2709 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2711 ec = hwc_window->ec;
2712 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
2713 EINA_SAFETY_ON_TRUE_RETURN_VAL(e_object_is_del(E_OBJECT(ec)), EINA_FALSE);
2717 /* set the property on the fly */
2718 ret = tdm_hwc_window_set_property(hwc_window->thwc_window, id, value);
2719 EINA_SAFETY_ON_TRUE_RETURN_VAL(ret != TDM_ERROR_NONE, ret);
2721 EHWTRACE("Set Property: property(%s) value(%d) - {%s}",
2722 hwc_window->ec, hwc_window->hwc, hwc_window,
2723 name, (unsigned int)value.u32,
2724 e_hwc_window_name_get(hwc_window));
2728 /* change the vaule of the property if prop_list already has the property */
2729 EINA_LIST_FOREACH(hwc_window->prop_list, l, prop)
2731 if (!strncmp(name, prop->name, TDM_NAME_LEN))
2733 EHWTRACE("Change Property: property(%s) update value(%d -> %d) - {%s}",
2734 hwc_window->ec, hwc_window->hwc, hwc_window,
2735 prop->name, (unsigned int)prop->value.u32, (unsigned int)value.u32,
2736 e_hwc_window_name_get(hwc_window));
2737 prop->value.u32 = value.u32;
2742 /* store the properties and commit at the hwc_commit time */
2743 prop = calloc(1, sizeof(Hwc_Window_Prop));
2744 EINA_SAFETY_ON_NULL_RETURN_VAL(prop, EINA_FALSE);
2745 prop->value.u32 = value.u32;
2747 memcpy(prop->name, name, sizeof(TDM_NAME_LEN));
2748 hwc_window->prop_list = eina_list_append(hwc_window->prop_list, prop);
2750 EHWTRACE("Set Property: property(%s) value(%d) - {%s}",
2751 hwc_window->ec, hwc_window->hwc, hwc_window,
2752 prop->name, (unsigned int)value.u32,
2753 e_hwc_window_name_get(hwc_window));
2760 e_hwc_window_get_property(E_Hwc_Window *hwc_window, unsigned int id, tdm_value *value)
2764 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2765 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
2767 ret = tdm_hwc_window_get_property(hwc_window->thwc_window, id, value);
2768 EINA_SAFETY_ON_TRUE_RETURN_VAL(ret != TDM_ERROR_NONE, EINA_FALSE);
2773 EINTERN E_Hwc_Window_Update_Data *
2774 e_hwc_window_pending_update_data_dequeue(E_Hwc_Window *hwc_window)
2776 tdm_hwc_window_info hwc_win_info = {0, };
2778 E_Hwc_Window_Update_Data *update;
2779 E_Comp_Wl_Buffer *comp_buffer;
2780 tbm_surface_h tsurface;
2782 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, NULL);
2783 EINA_SAFETY_ON_TRUE_RETURN_VAL(hwc_window->is_target, NULL);
2785 /* not support cursor */
2786 if (e_hwc_window_is_cursor(hwc_window)) return NULL;
2788 ec = hwc_window->ec;
2790 if ((hwc_window->is_deleted) || (!ec) || e_object_is_del(E_OBJECT(ec)))
2793 if (e_hwc_window_is_video(hwc_window))
2795 if (!_e_hwc_window_video_info_get(hwc_window, &hwc_win_info))
2797 EHWERR("fail to _e_hwc_window_video_info_get",
2798 hwc_window->ec, hwc_window->hwc, hwc_window);
2802 tsurface = e_client_video_tbm_surface_get(hwc_window->ec);
2806 if (!_e_hwc_window_info_get(hwc_window, &hwc_win_info))
2808 EHWERR("fail to _e_hwc_window_info_get",
2809 hwc_window->ec, hwc_window->hwc, hwc_window);
2813 tsurface = _e_hwc_window_client_surface_acquire(hwc_window);
2816 update = E_NEW(E_Hwc_Window_Update_Data, 1);
2817 EINA_SAFETY_ON_NULL_RETURN_VAL(update, NULL);
2819 e_hwc_window_ref(hwc_window);
2820 update->hwc_window = hwc_window;
2822 comp_buffer = _e_hwc_window_comp_wl_buffer_get(hwc_window);
2824 memcpy(&update->info, &hwc_win_info, sizeof(tdm_hwc_window_info));
2825 e_hwc_window_buffer_set(&update->buffer, tsurface, hwc_window->queue,
2826 comp_buffer ? comp_buffer->transform : 0);
2827 e_comp_wl_buffer_reference(&update->buffer_ref, comp_buffer);
2829 EHWTRACE("PEN DEQ:%p ts:%10p src(%dx%d+%d+%d size:%dx%d fmt:%c%c%c%c) dst(%dx%d+%d+%d) trans(%d)",
2830 hwc_window->ec, hwc_window->hwc, hwc_window,
2833 update->info.src_config.pos.w, update->info.src_config.pos.h,
2834 update->info.src_config.pos.x, update->info.src_config.pos.y,
2835 update->info.src_config.size.h, update->info.src_config.size.v,
2836 EHW_FOURCC_STR(update->info.src_config.format),
2837 update->info.dst_pos.w, update->info.dst_pos.h,
2838 update->info.dst_pos.x, update->info.dst_pos.y,
2839 update->info.transform);
2841 hwc_window->pending_update_list = eina_list_append(hwc_window->pending_update_list, update);
2847 e_hwc_window_pending_update_data_dequeue_cancel(E_Hwc_Window *hwc_window, E_Hwc_Window_Update_Data *update)
2849 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2850 EINA_SAFETY_ON_NULL_RETURN_VAL(update, EINA_FALSE);
2852 EHWTRACE("PEN CAN:%p ts:%10p src(%dx%d+%d+%d size:%dx%d fmt:%c%c%c%c) dst(%dx%d+%d+%d) trans(%d)",
2853 hwc_window->ec, hwc_window->hwc, hwc_window,
2855 update->buffer.tsurface,
2856 update->info.src_config.pos.w, update->info.src_config.pos.h,
2857 update->info.src_config.pos.x, update->info.src_config.pos.y,
2858 update->info.src_config.size.h, update->info.src_config.size.v,
2859 EHW_FOURCC_STR(update->info.src_config.format),
2860 update->info.dst_pos.w, update->info.dst_pos.h,
2861 update->info.dst_pos.x, update->info.dst_pos.y,
2862 update->info.transform);
2864 e_comp_wl_buffer_reference(&update->buffer_ref, NULL);
2865 e_hwc_window_buffer_set(&update->buffer, NULL, NULL, 0);
2867 hwc_window->pending_update_list = eina_list_remove(hwc_window->pending_update_list, update);
2869 if (update->hwc_window)
2870 e_hwc_window_unref(update->hwc_window);
2878 e_hwc_window_pending_update_data_enqueue(E_Hwc_Window *hwc_window, E_Hwc_Window_Update_Data *update)
2880 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2881 EINA_SAFETY_ON_NULL_RETURN_VAL(update, EINA_FALSE);
2883 EHWTRACE("PEN ENQ:%p ts:%10p src(%dx%d+%d+%d size:%dx%d fmt:%c%c%c%c) dst(%dx%d+%d+%d) trans(%d)",
2884 hwc_window->ec, hwc_window->hwc, hwc_window,
2886 update->buffer.tsurface,
2887 update->info.src_config.pos.w, update->info.src_config.pos.h,
2888 update->info.src_config.pos.x, update->info.src_config.pos.y,
2889 update->info.src_config.size.h, update->info.src_config.size.v,
2890 EHW_FOURCC_STR(update->info.src_config.format),
2891 update->info.dst_pos.w, update->info.dst_pos.h,
2892 update->info.dst_pos.x, update->info.dst_pos.y,
2893 update->info.transform);
2895 _e_hwc_window_info_set(hwc_window, &update->info);
2896 _e_hwc_window_buffer_set(hwc_window, update->buffer.tsurface,
2897 update->buffer_ref.buffer, update->buffer.queue);
2899 e_comp_wl_buffer_reference(&update->buffer_ref, NULL);
2900 e_hwc_window_buffer_set(&update->buffer, NULL, NULL, 0);
2902 hwc_window->pending_update_list = eina_list_remove(hwc_window->pending_update_list, update);
2904 if (update->hwc_window)
2905 e_hwc_window_unref(update->hwc_window);
2913 e_hwc_window_pending_update_data_has(E_Hwc_Window *hwc_window)
2915 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2917 if (eina_list_count(hwc_window->pending_update_list))
2924 e_hwc_window_present_sync(E_Hwc_Window *hwc_window)
2926 E_Hwc_Window_Target *target_hwc_window;
2927 E_Hwc_Window_State state;
2929 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
2930 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->hwc, EINA_FALSE);
2932 target_hwc_window = hwc_window->hwc->target_hwc_window;
2933 EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
2935 if (e_hwc_window_is_cursor(hwc_window))
2937 EHWERR("cursor doesn't support present sync", hwc_window->ec, hwc_window->hwc, hwc_window);
2941 /* if gl compositor is disabled, present sync isn't needed */
2942 state = e_hwc_window_accepted_state_get((E_Hwc_Window *)target_hwc_window);
2943 if (state == E_HWC_WINDOW_STATE_NONE)
2946 if (hwc_window->present_sync) return EINA_TRUE;
2948 hwc_window->present_sync = EINA_TRUE;
2950 if (!eina_list_data_find(target_hwc_window->present_sync_windows, hwc_window))
2952 target_hwc_window->present_sync_windows = eina_list_append(target_hwc_window->present_sync_windows,
2954 e_hwc_window_ref(hwc_window);
2957 e_hwc_windows_target_window_force_render(target_hwc_window);
2959 EHWINF("Present Sync", hwc_window->ec, hwc_window->hwc, hwc_window);
2964 EINTERN E_Hwc_Window_Hook *
2965 e_hwc_window_hook_add(E_Hwc_Window_Hook_Point hookpoint, E_Hwc_Window_Hook_Cb func, const void *data)
2967 E_Hwc_Window_Hook *ch;
2969 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_HWC_WINDOW_HOOK_LAST, NULL);
2970 ch = E_NEW(E_Hwc_Window_Hook, 1);
2971 if (!ch) return NULL;
2972 ch->hookpoint = hookpoint;
2974 ch->data = (void*)data;
2975 _e_hwc_window_hooks[hookpoint] = eina_inlist_append(_e_hwc_window_hooks[hookpoint],
2976 EINA_INLIST_GET(ch));
2981 e_hwc_window_hook_del(E_Hwc_Window_Hook *ch)
2984 if (_e_hwc_window_hooks_walking == 0)
2986 _e_hwc_window_hooks[ch->hookpoint] = eina_inlist_remove(_e_hwc_window_hooks[ch->hookpoint],
2987 EINA_INLIST_GET(ch));
2991 _e_hwc_window_hooks_delete++;
2995 e_hwc_window_trace_debug(Eina_Bool onoff)
2997 if (onoff == ehw_trace) return;
2999 INF("EHW: hwc trace_debug is %s", onoff?"ON":"OFF");
3003 e_hwc_window_commit_data_buffer_dump(E_Hwc_Window *hwc_window, E_Hwc_Window_Commit_Data *commit_data)
3005 tbm_surface_h capturable_tsurface;
3008 EINA_SAFETY_ON_FALSE_RETURN(hwc_window);
3009 EINA_SAFETY_ON_FALSE_RETURN(commit_data);
3011 if (!commit_data->buffer.tsurface) return;
3013 if (hwc_window->is_target)
3014 snprintf(fname, sizeof(fname), "hwc_commit_composite_%p",
3017 snprintf(fname, sizeof(fname), "hwc_commit_0x%08zx_%p",
3018 e_client_util_win_get(hwc_window->ec), hwc_window);
3020 capturable_tsurface = e_comp_wl_tbm_capturable_buffer_get(commit_data->buffer.tsurface);
3021 EINA_SAFETY_ON_NULL_RETURN(capturable_tsurface);
3023 tbm_surface_internal_dump_buffer(capturable_tsurface,
3025 tbm_surface_internal_unref(capturable_tsurface);
3029 e_hwc_window_fps_get(E_Hwc_Window *hwc_window, double *fps)
3031 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
3033 if (hwc_window->fps.old_fps == hwc_window->fps.fps)
3036 if (hwc_window->fps.fps > 0.0)
3038 *fps = hwc_window->fps.fps;
3039 hwc_window->fps.old_fps = hwc_window->fps.fps;
3047 e_hwc_window_ref(E_Hwc_Window *hwc_window)
3049 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
3051 e_object_ref(E_OBJECT(hwc_window));
3055 e_hwc_window_unref(E_Hwc_Window *hwc_window)
3057 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
3059 e_object_unref(E_OBJECT(hwc_window));
3063 e_hwc_window_presentation_callback_pending_set(E_Hwc_Window *hwc_window, E_Hwc_Presentation_Callback *callback)
3065 E_Hwc_Window_Target *target_hwc_window;
3068 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
3070 hwc = hwc_window->hwc;
3071 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
3073 target_hwc_window = hwc->target_hwc_window;
3074 EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
3076 if ((hwc_window->accepted_state == E_HWC_WINDOW_STATE_NONE) ||
3077 (hwc_window->accepted_state == E_HWC_WINDOW_STATE_CLIENT))
3078 e_hwc_windows_target_window_force_render(hwc->target_hwc_window);
3080 if (!e_hwc_presentation_callback_list_set(&hwc_window->pending_presentation_callbacks, callback))
3082 EHWERR("fail to e_hwc_presentation_callback_list_set", hwc_window->ec, hwc_window->hwc, hwc_window);
3086 if (!eina_list_data_find(target_hwc_window->pending_presentation_cb_wins, hwc_window))
3088 target_hwc_window->pending_presentation_cb_wins =
3089 eina_list_append(target_hwc_window->pending_presentation_cb_wins, hwc_window);
3091 e_hwc_window_ref(hwc_window);
3098 e_hwc_window_presentation_callback_pending_take_over(E_Hwc_Window *hwc_window,
3099 E_Hwc_Presentation_Callback_List *dst_list)
3101 E_Hwc_Window_Target *target_hwc_window;
3104 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
3105 EINA_SAFETY_ON_NULL_RETURN_VAL(dst_list, EINA_FALSE);
3107 hwc = hwc_window->hwc;
3108 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
3110 target_hwc_window = hwc->target_hwc_window;
3111 EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
3113 if (eina_list_data_find(target_hwc_window->pending_presentation_cb_wins, hwc_window))
3115 target_hwc_window->pending_presentation_cb_wins =
3116 eina_list_remove(target_hwc_window->pending_presentation_cb_wins, hwc_window);
3118 e_hwc_window_unref(hwc_window);
3121 e_hwc_presentation_callback_list_merge(dst_list,
3122 &hwc_window->pending_presentation_callbacks);
3128 e_hwc_window_presentation_callback_take(E_Hwc_Window *hwc_window,
3129 E_Hwc_Presentation_Callback_List *src_list)
3131 E_Hwc_Window_Target *target_hwc_window;
3134 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
3135 EINA_SAFETY_ON_NULL_RETURN_VAL(src_list, EINA_FALSE);
3137 hwc = hwc_window->hwc;
3138 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
3140 target_hwc_window = hwc->target_hwc_window;
3141 EINA_SAFETY_ON_NULL_RETURN_VAL(target_hwc_window, EINA_FALSE);
3143 if (&hwc_window->presentation_callbacks == src_list)
3145 if (eina_list_data_find(target_hwc_window->pending_presentation_cb_wins, hwc_window))
3147 target_hwc_window->pending_presentation_cb_wins =
3148 eina_list_remove(target_hwc_window->pending_presentation_cb_wins, hwc_window);
3150 e_hwc_window_unref(hwc_window);
3154 e_hwc_presentation_callback_list_merge(&hwc_window->presentation_callbacks,
3161 e_hwc_window_presentation_callback_call(E_Hwc_Window *hwc_window)
3163 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
3165 if (!eina_list_count(hwc_window->presentation_callbacks.callbacks))
3168 e_hwc_presentation_callback_list_call(&hwc_window->presentation_callbacks);
3174 _e_hwc_window_below_transparent_obj_map_apply(E_Hwc_Window *hwc_window)
3176 E_Map *map = NULL, *new_map = NULL;
3180 EINA_SAFETY_ON_NULL_RETURN(hwc_window->below_transparent_obj);
3182 evas_object_geometry_get(hwc_window->below_transparent_obj, NULL, NULL, &w, &h);
3184 enable = e_client_transform_core_enable_get(hwc_window->ec);
3186 map = e_comp_object_map_get(hwc_window->ec->frame);
3188 if ((enable) && (map))
3190 new_map = e_map_dup(map);
3193 EHWERR("fail to dup e_map", hwc_window->ec, hwc_window->hwc, hwc_window);
3200 new_map = e_map_new();
3203 EHWERR("fail to new e_map", hwc_window->ec, hwc_window->hwc, hwc_window);
3207 e_map_util_points_populate_from_object_full(new_map, hwc_window->ec->frame, 0);
3208 e_map_util_points_color_set(new_map, 255, 255, 255, 255);
3211 e_map_point_image_uv_set(new_map, 0, 0, 0);
3212 e_map_point_image_uv_set(new_map, 1, w, 0);
3213 e_map_point_image_uv_set(new_map, 2, w, h);
3214 e_map_point_image_uv_set(new_map, 3, 0, h);
3216 e_comp_object_map_set(hwc_window->below_transparent_obj, new_map);
3217 e_comp_object_map_enable_set(hwc_window->below_transparent_obj, EINA_TRUE);
3219 if (map) e_map_free(map);
3221 e_map_free(new_map);
3225 _e_hwc_window_below_transparent_obj_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
3227 E_Hwc_Window *hwc_window;
3229 if (!(hwc_window = data)) return;
3231 evas_object_show(hwc_window->below_transparent_obj);
3235 _e_hwc_window_below_transparent_obj_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
3237 E_Hwc_Window *hwc_window;
3239 if (!(hwc_window = data)) return;
3241 evas_object_hide(hwc_window->below_transparent_obj);
3245 _e_hwc_window_below_transparent_obj_cb_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
3247 E_Hwc_Window *hwc_window;
3249 if (!(hwc_window = data)) return;
3251 evas_object_move(hwc_window->below_transparent_obj, hwc_window->ec->x, hwc_window->ec->y);
3253 _e_hwc_window_below_transparent_obj_map_apply(hwc_window);
3257 _e_hwc_window_below_transparent_obj_cb_resize(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
3259 E_Hwc_Window *hwc_window;
3261 if (!(hwc_window = data)) return;
3263 _e_hwc_window_below_transparent_obj_map_apply(hwc_window);
3267 _e_hwc_window_below_transparent_obj_cb_restack(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
3269 E_Hwc_Window *hwc_window;
3271 if (!(hwc_window = data)) return;
3273 evas_object_layer_set(hwc_window->below_transparent_obj, evas_object_layer_get(hwc_window->ec->frame));
3274 evas_object_stack_below(hwc_window->below_transparent_obj, hwc_window->ec->frame);
3278 e_hwc_window_below_transparent_obj_set(E_Hwc_Window *hwc_window, Eina_Bool set)
3280 Evas_Object *below_transparent_obj;
3282 EINA_SAFETY_ON_NULL_RETURN(hwc_window);
3286 EINA_SAFETY_ON_NULL_RETURN(hwc_window->ec);
3288 if (hwc_window->below_transparent_obj) return;
3290 below_transparent_obj = evas_object_rectangle_add(e_comp->evas);
3291 EINA_SAFETY_ON_NULL_RETURN(below_transparent_obj);
3293 evas_object_pass_events_set(below_transparent_obj, EINA_TRUE);
3295 evas_object_layer_set(below_transparent_obj, evas_object_layer_get(hwc_window->ec->frame));
3296 evas_object_stack_below(below_transparent_obj, hwc_window->ec->frame);
3297 evas_object_render_op_set(below_transparent_obj, EVAS_RENDER_COPY);
3299 evas_object_color_set(below_transparent_obj, 0, 0, 0, 0);
3300 evas_object_move(below_transparent_obj, hwc_window->ec->x, hwc_window->ec->y);
3301 evas_object_resize(below_transparent_obj, 1, 1);
3302 evas_object_name_set(below_transparent_obj, "hwc_below_transparent_obj");
3304 hwc_window->below_transparent_obj = below_transparent_obj;
3306 _e_hwc_window_below_transparent_obj_map_apply(hwc_window);
3308 if (evas_object_visible_get(hwc_window->ec->frame))
3309 evas_object_show(hwc_window->below_transparent_obj);
3311 evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_SHOW,
3312 _e_hwc_window_below_transparent_obj_cb_show,
3314 evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_HIDE,
3315 _e_hwc_window_below_transparent_obj_cb_hide,
3317 evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_MOVE,
3318 _e_hwc_window_below_transparent_obj_cb_move,
3320 evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_RESIZE,
3321 _e_hwc_window_below_transparent_obj_cb_resize,
3323 evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_RESTACK,
3324 _e_hwc_window_below_transparent_obj_cb_restack,
3327 EHWINF("Set below_transparent_obj", hwc_window->ec, hwc_window->hwc, hwc_window);
3331 if (!hwc_window->below_transparent_obj) return;
3333 E_FREE_FUNC(hwc_window->below_transparent_obj, evas_object_del);
3337 evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_SHOW,
3338 _e_hwc_window_below_transparent_obj_cb_show,
3340 evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_HIDE,
3341 _e_hwc_window_below_transparent_obj_cb_hide,
3343 evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_MOVE,
3344 _e_hwc_window_below_transparent_obj_cb_move,
3346 evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_RESIZE,
3347 _e_hwc_window_below_transparent_obj_cb_resize,
3349 evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_RESTACK,
3350 _e_hwc_window_below_transparent_obj_cb_restack,
3354 EHWINF("Unset below_transparent_obj", hwc_window->ec, hwc_window->hwc, hwc_window);