1 #include "e_hwc_window_intern.h"
2 #include "e_hwc_windows_intern.h"
3 #include "e_hwc_planes_intern.h"
4 #include "e_hwc_intern.h"
5 #include "e_utils_intern.h"
6 #include "e_comp_screen_intern.h"
7 #include "e_comp_intern.h"
8 #include "e_error_intern.h"
9 #include "e_hwc_window_queue_intern.h"
14 #define EHERR(f, hwc, x...) \
17 ELOGFE("HWC","%2d|"f, \
18 NULL, (e_hwc_output_index_get(hwc)), ##x); \
22 #define EHINF(f, hwc, x...) \
25 ELOGF("HWC", "%2d|"f, \
26 NULL, (e_hwc_output_index_get(hwc)), ##x); \
30 E_API int E_EVENT_HWC_ACTIVE = -1;
31 E_API int E_EVENT_HWC_DEACTIVE = -1;
33 static int E_EVENT_HWC_PROPERTY_CHANGED = -1;
35 static int _e_hwc_intercept_hooks_delete = 0;
36 static int _e_hwc_intercept_hooks_walking = 0;
38 static Eina_Inlist *_e_hwc_intercept_hooks[] =
40 [E_HWC_INTERCEPT_HOOK_PREPARE_PLANE] = NULL,
41 [E_HWC_INTERCEPT_HOOK_END_ALL_PLANE] = NULL,
44 static int _e_hwc_hooks_delete = 0;
45 static int _e_hwc_hooks_walking = 0;
47 static Eina_Inlist *_e_hwc_hooks[] =
49 [E_HWC_HOOK_NORENDER_SET] = NULL,
53 _e_hwc_intercept_hooks_clean(void)
56 E_Hwc_Intercept_Hook *ch;
59 for (x = 0; x < E_HWC_INTERCEPT_HOOK_LAST; x++)
60 EINA_INLIST_FOREACH_SAFE(_e_hwc_intercept_hooks[x], l, ch)
62 if (!ch->delete_me) continue;
63 _e_hwc_intercept_hooks[x] = eina_inlist_remove(_e_hwc_intercept_hooks[x], EINA_INLIST_GET(ch));
69 e_hwc_intercept_hook_call(E_Hwc_Intercept_Hook_Point hookpoint, E_Hwc *hwc)
71 E_Hwc_Intercept_Hook *ch;
72 Eina_Bool ret = EINA_TRUE;
74 _e_hwc_intercept_hooks_walking++;
75 EINA_INLIST_FOREACH(_e_hwc_intercept_hooks[hookpoint], ch)
77 if (ch->delete_me) continue;
78 if (!(ch->func(ch->data, hwc)))
84 _e_hwc_intercept_hooks_walking--;
85 if ((_e_hwc_intercept_hooks_walking == 0) && (_e_hwc_intercept_hooks_delete > 0))
86 _e_hwc_intercept_hooks_clean();
91 E_API E_Hwc_Intercept_Hook *
92 e_hwc_intercept_hook_add(E_Hwc_Intercept_Hook_Point hookpoint, E_Hwc_Intercept_Hook_Cb func, const void *data)
94 E_Hwc_Intercept_Hook *ch;
96 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_HWC_INTERCEPT_HOOK_LAST, NULL);
97 ch = E_NEW(E_Hwc_Intercept_Hook, 1);
99 ch->hookpoint = hookpoint;
101 ch->data = (void*)data;
102 _e_hwc_intercept_hooks[hookpoint] = eina_inlist_append(_e_hwc_intercept_hooks[hookpoint], EINA_INLIST_GET(ch));
107 e_hwc_intercept_hook_del(E_Hwc_Intercept_Hook *ch)
110 if (_e_hwc_intercept_hooks_walking == 0)
112 _e_hwc_intercept_hooks[ch->hookpoint] = eina_inlist_remove(_e_hwc_intercept_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
116 _e_hwc_intercept_hooks_delete++;
120 _e_hwc_hooks_clean(void)
126 for (x = 0; x < E_HWC_HOOK_LAST; x++)
127 EINA_INLIST_FOREACH_SAFE(_e_hwc_hooks[x], l, ch)
129 if (!ch->delete_me) continue;
130 _e_hwc_hooks[x] = eina_inlist_remove(_e_hwc_hooks[x], EINA_INLIST_GET(ch));
136 _e_hwc_hook_call(E_Hwc_Hook_Point hookpoint, E_Hwc *hwc)
140 _e_hwc_hooks_walking++;
141 EINA_INLIST_FOREACH(_e_hwc_hooks[hookpoint], ch)
143 if (ch->delete_me) continue;
144 ch->func(ch->data, hwc);
146 _e_hwc_hooks_walking--;
147 if ((_e_hwc_hooks_walking == 0) && (_e_hwc_hooks_delete > 0))
148 _e_hwc_hooks_clean();
152 e_hwc_hook_add(E_Hwc_Hook_Point hookpoint, E_Hwc_Hook_Cb func, const void *data)
156 EINA_SAFETY_ON_TRUE_RETURN_VAL(hookpoint >= E_HWC_HOOK_LAST, NULL);
157 ch = E_NEW(E_Hwc_Hook, 1);
158 if (!ch) return NULL;
159 ch->hookpoint = hookpoint;
161 ch->data = (void*)data;
162 _e_hwc_hooks[hookpoint] = eina_inlist_append(_e_hwc_hooks[hookpoint], EINA_INLIST_GET(ch));
167 e_hwc_hook_del(E_Hwc_Hook *ch)
170 if (_e_hwc_hooks_walking == 0)
172 _e_hwc_hooks[ch->hookpoint] = eina_inlist_remove(_e_hwc_hooks[ch->hookpoint], EINA_INLIST_GET(ch));
176 _e_hwc_hooks_delete++;
180 _e_hwc_tbm_surface_queue_alloc(void *data, int w, int h)
182 E_Hwc *hwc = (E_Hwc *)data;
183 E_Output *output = hwc->output;
184 E_Comp_Screen *e_comp_screen = output->e_comp_screen;
185 tbm_surface_queue_h tqueue = NULL;
187 int queue_w, queue_h;
189 if ((output->tdm_hwc) && (!output->fake_config))
191 tqueue = tdm_hwc_get_client_target_buffer_queue(hwc->thwc, &error);
192 if (error != TDM_ERROR_NONE)
194 EHERR("fail to tdm_hwc_get_client_target_buffer_queue", hwc);
200 tqueue = tbm_surface_queue_create(3, w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT);
203 EHERR("fail to tbm_surface_queue_create", hwc);
208 queue_w = tbm_surface_queue_get_width(tqueue);
209 queue_h = tbm_surface_queue_get_height(tqueue);
211 if ((w != queue_w) || (h != queue_h))
212 tbm_surface_queue_reset(tqueue, w, h, tbm_surface_queue_get_format(tqueue));
214 hwc->target_buffer_queue = tqueue;
215 e_comp_screen->tqueue = tqueue;
217 EHINF("The tqueue(%p, %dx%d) is created.", hwc, tqueue, queue_w, queue_h);
219 return (void *)tqueue;
223 _e_hwc_tbm_surface_queue_free(void *data, void *tqueue)
225 E_Hwc *hwc = (E_Hwc *)data;
227 tbm_surface_queue_destroy(tqueue);
228 hwc->target_buffer_queue = NULL;
232 _e_hwc_gbm_surface_alloc(void *data, int w, int h)
234 E_Hwc *hwc = (E_Hwc *)data;
235 E_Output *output = hwc->output;
236 struct gbm_device *gdevice;
237 struct gbm_surface *gsurface;
241 EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, NULL);
243 gdevice = e_comp_screen_gbm_device_get(e_comp->e_comp_screen);
244 EINA_SAFETY_ON_NULL_RETURN_VAL(gdevice, NULL);
246 gsurface = gbm_surface_create(gdevice, w, h,
248 GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
249 EINA_SAFETY_ON_NULL_RETURN_VAL(gsurface, NULL);
253 EHERR("only tdm hwc support gbm_surface", hwc);
254 return (void *) NULL;
257 hwc->gsurface = gsurface;
258 hwc->gsurface_width = w;
259 hwc->gsurface_height = h;
260 hwc->gsurface_format = hwc->gbm_format;
262 EHINF("The gbm_surface(%p, %dx%d) fmt(%c%c%c%c)is created.", hwc, gsurface, w, h, EHW_FOURCC_STR(hwc->gsurface_format));
264 return (void *)gsurface;
268 _e_hwc_gbm_surface_free(void *data, void *gsurface)
270 E_Hwc *hwc = (E_Hwc *)data;
272 EHINF("The gbm_surface(%p) is destroyed.", NULL, gsurface);
274 gbm_surface_destroy(gsurface);
275 hwc->gsurface = NULL;
279 _e_hwc_ecore_evas_tbm_alloc(E_Hwc *hwc, int src_w, int src_h)
283 if (e_comp->avoid_afill)
285 ee = ecore_evas_tbm_allocfunc_new("gl_tbm_ES", src_w, src_h,
286 _e_hwc_tbm_surface_queue_alloc,
287 _e_hwc_tbm_surface_queue_free,
292 ee = ecore_evas_tbm_allocfunc_new("gl_tbm", src_w, src_h,
293 _e_hwc_tbm_surface_queue_alloc,
294 _e_hwc_tbm_surface_queue_free,
298 EHINF("ecore_evas engine:gl_tbm ee:%p avoid_afill:%d", hwc, ee, e_comp->avoid_afill);
304 _e_hwc_ecore_evas_gbm_alloc(E_Hwc *hwc, int src_w, int src_h)
307 struct gbm_device *gdevice;
308 int gbm_formats[2] = {GBM_FORMAT_ABGR8888, GBM_FORMAT_ARGB8888};
311 gdevice = e_comp_screen_gbm_device_get(e_comp->e_comp_screen);
312 if (!gdevice) return NULL;
314 format_count = sizeof(gbm_formats) / sizeof(int);
315 for (i = 0; i < format_count; i++)
317 hwc->gbm_format = gbm_formats[i];
319 if (e_comp->avoid_afill)
321 ee = ecore_evas_tbm_native_allocfunc_new("gl_tbm_ES", gdevice, src_w, src_h,
322 _e_hwc_gbm_surface_alloc,
323 _e_hwc_gbm_surface_free,
328 ee = ecore_evas_tbm_native_allocfunc_new("gl_tbm", gdevice, src_w, src_h,
329 _e_hwc_gbm_surface_alloc,
330 _e_hwc_gbm_surface_free,
337 EHINF("ecore_evas engine:gl_tbm with gbm ee:%p avaoid_afill:%d", hwc, ee, e_comp->avoid_afill);
343 e_hwc_ecore_evas_deinit(void)
345 E_Output *primary_output = NULL;
348 primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
349 if (!primary_output) return;
351 hwc = primary_output->hwc;
353 if (!hwc->ee) return;
355 ecore_evas_free(hwc->ee);
360 _e_hwc_prefer_gbm_check(void)
362 const char *backend_name;
363 struct gbm_device *gdevice;
365 if (e_comp->hwc_prefer_gbm)
368 gdevice = e_comp_screen_gbm_device_get(e_comp->e_comp_screen);
369 if (!gdevice) return EINA_FALSE;
371 backend_name = gbm_device_get_backend_name(gdevice);
372 if (!backend_name) return EINA_FALSE;
373 if (!e_util_strcmp(backend_name, "gbm_tbm")) return EINA_FALSE;
379 e_hwc_ecore_evas_init(void)
381 E_Output *primary_output = NULL;
382 Ecore_Evas *ee = NULL;
383 int w = 0, h = 0, scr_w = 1, scr_h = 1;
388 primary_output = e_comp_screen_primary_output_get(e_comp->e_comp_screen);
389 EINA_SAFETY_ON_NULL_RETURN_VAL(primary_output, EINA_FALSE);
391 hwc = primary_output->hwc;
392 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
394 EHINF("ecore evase engine init.", hwc);
396 // TODO: fix me. change the screen_rotation into output_rotation.
397 screen_rotation = primary_output->e_comp_screen->rotation;
399 /* set env for use tbm_surface_queue*/
400 setenv("USE_EVAS_SOFTWARE_TBM_ENGINE", "1", 1);
401 //setenv("USE_EVAS_GL_TBM_ENGINE", "1", 1);
403 /* set gl available if we have ecore_evas support */
404 if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_DRM) ||
405 ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_TBM))
406 e_comp_gl_set(EINA_TRUE);
408 e_comp_screen_size_get(e_comp->e_comp_screen, &scr_w, &scr_h);
410 EHINF("GL available:%d config engine:%d screen size:%dx%d", hwc,
411 e_comp_gl_get(), e_comp_config_get()->engine, scr_w, scr_h);
413 if ((e_comp_gl_get()) &&
414 (e_comp_config_get()->engine == E_COMP_ENGINE_GL))
416 e_main_ts_begin("\tEE_GL_TBM New");
417 if (_e_hwc_prefer_gbm_check())
419 ee = _e_hwc_ecore_evas_gbm_alloc(hwc, scr_w, scr_h);
421 ee = _e_hwc_ecore_evas_tbm_alloc(hwc, scr_w, scr_h);
425 ee = _e_hwc_ecore_evas_tbm_alloc(hwc, scr_w, scr_h);
427 ee = _e_hwc_ecore_evas_gbm_alloc(hwc, scr_w, scr_h);
430 snprintf(buf, sizeof(buf), "\tEE_GL_TBM New Done %p %dx%d", ee, scr_w, scr_h);
434 e_comp_gl_set(EINA_FALSE);
437 /* fallback to framebuffer drm (non-accel) */
440 e_main_ts_begin("\tEE_DRM New");
441 ee = ecore_evas_tbm_allocfunc_new("software_tbm", scr_w, scr_h, _e_hwc_tbm_surface_queue_alloc, _e_hwc_tbm_surface_queue_free, (void *)hwc);
442 EHINF("ecore_evas engine:software_tbm fallback to software engine.", hwc);
443 snprintf(buf, sizeof(buf), "\tEE_DRM New Done %p %dx%d", ee, scr_w, scr_h);
449 e_error_message_show(_("Enlightenment cannot initialize outputs!\n"));
450 e_hwc_ecore_evas_deinit();
455 hwc->evas = ecore_evas_get(hwc->ee);
457 EHINF("ee(%p) with the tqueue(%p) is created.", hwc, ee, hwc->target_buffer_queue);
460 ecore_evas_data_set(e_comp->ee, "comp", e_comp);
464 /* SHOULD called with resize option after ecore_evas_resize */
465 ecore_evas_rotation_with_resize_set(e_comp->ee, screen_rotation);
466 ecore_evas_geometry_get(e_comp->ee, NULL, NULL, &w, &h);
467 snprintf(buf, sizeof(buf), "\tEE Rotate and Resize %d, %dx%d", screen_rotation, w, h);
471 if (hwc->hwc_policy == E_HWC_POLICY_WINDOWS)
473 if (!e_hwc_windows_ecore_evas_set(hwc, ee))
475 ERR("fail to e_hwc_windows_ecore_evas_set");
476 e_hwc_ecore_evas_deinit();
482 if (!e_hwc_planes_ecore_evas_set(hwc, ee))
484 ERR("fail to e_hwc_planes_ecore_evas_set");
485 e_hwc_ecore_evas_deinit();
496 E_EVENT_HWC_ACTIVE = ecore_event_type_new();
497 E_EVENT_HWC_DEACTIVE = ecore_event_type_new();
498 E_EVENT_HWC_PROPERTY_CHANGED = ecore_event_type_new();
509 e_hwc_new(E_Output *output, Eina_Bool primary_output)
512 tdm_hwc_capability hwc_caps = 0;
515 EINA_SAFETY_ON_NULL_RETURN_VAL(output, NULL);
517 hwc = E_NEW(E_Hwc, 1);
518 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
519 hwc->output = output;
521 hwc->commit_fence_fd = -1;
524 * E20 has two hwc policy options.
525 * 1. One is the E_HWC_POLICY_PLANES.
526 * - E20 decides the hwc policy with the E_Planes associated with the tdm_layers.
527 * - E20 manages how to set the surface(buffer) of the ec to the E_Plane.
528 * 2. Another is the E_HWC_POLICY_WIDNOWS.
529 * - The tdm-backend decides the hwc policy with the E_Hwc_Windows associated with the tdm_hwc_window.
530 * - E20 asks to verify the composition types of the E_Hwc_Window of the ec.
532 if (!output->tdm_hwc)
534 hwc->hwc_policy = E_HWC_POLICY_PLANES;
535 EHINF("Use the HWC PLANES Policy.", hwc);
539 hwc->hwc_policy = E_HWC_POLICY_WINDOWS;
540 EHINF("Use the HWC WINDOWS Policy.", hwc);
542 hwc->thwc = tdm_output_get_hwc(output->toutput, &error);
545 EHERR("tdm_output_get_hwc failed", hwc);
549 error = tdm_hwc_get_capabilities(hwc->thwc, &hwc_caps);
550 if (error != TDM_ERROR_NONE)
552 EHERR("fail to tdm_hwc_get_capabilities", hwc);
556 /* hwc video capabilities */
557 if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_STREAM)
558 hwc->tdm_hwc_video_stream = EINA_TRUE;
559 if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_SCALE)
560 hwc->tdm_hwc_video_scale = EINA_TRUE;
561 if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_TRANSFORM)
562 hwc->tdm_hwc_video_transform = EINA_TRUE;
563 if (hwc_caps & TDM_HWC_CAPABILITY_VIDEO_SCANOUT)
564 hwc->tdm_hwc_video_scanout = EINA_TRUE;
565 if (hwc_caps & TDM_HWC_CAPABILITY_FENCE)
566 hwc->tdm_hwc_fence = EINA_TRUE;
569 tdm_output_get_available_size(output->toutput,
570 &hwc->output_available.min_w,
571 &hwc->output_available.min_h,
572 &hwc->output_available.max_w,
573 &hwc->output_available.max_h,
576 /* set the pirmary_output */
577 hwc->primary_output = primary_output;
579 if (e_hwc_policy_get(hwc) == E_HWC_POLICY_WINDOWS)
581 /* create the target_window to the hwc */
582 hwc->target_hwc_window = e_hwc_windows_target_window_new(hwc, EINA_FALSE);
583 if (!hwc->target_hwc_window)
585 EHERR("e_hwc_windows_target_window_new failed", hwc);
591 hwc->root_target_hwc_window = e_hwc_windows_target_window_new(hwc, EINA_TRUE);
592 if (!hwc->root_target_hwc_window)
594 EHERR("e_hwc_windows_target_window_new failed", hwc);
600 /* default active hwc */
601 ecore_event_add(E_EVENT_HWC_ACTIVE, NULL, NULL, NULL);
612 e_hwc_del(E_Hwc *hwc)
614 E_Hwc_Sync_Callback *sync_callback;
615 E_Hwc_Window *hwc_window;
619 if (e_hwc_policy_get(hwc) == E_HWC_POLICY_WINDOWS)
621 if (hwc->target_hwc_window)
623 e_hwc_windows_target_window_del(hwc->target_hwc_window);
624 hwc->target_hwc_window = NULL;
627 if (hwc->root_target_hwc_window)
629 e_hwc_windows_target_window_del(hwc->root_target_hwc_window);
630 hwc->root_target_hwc_window = NULL;
634 e_hwc_window_queue_buffer_reference(&hwc->pp_update.queue_buffer_ref, NULL);
635 e_comp_wl_buffer_reference(&hwc->pp_update.buffer_ref, NULL);
637 EINA_LIST_FREE(hwc->sync_callback_list, sync_callback)
638 sync_callback->hwc = NULL;
640 EINA_LIST_FREE(hwc->visible_windows, hwc_window)
641 e_hwc_window_unref(hwc_window);
643 if (hwc->commit_fence_fd >= 0)
644 close(hwc->commit_fence_fd);
650 e_hwc_mode_get(E_Hwc *hwc)
652 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, E_HWC_MODE_NONE);
654 return hwc->hwc_mode;
658 e_hwc_policy_get(E_Hwc *hwc)
660 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, E_HWC_MODE_NONE);
662 return hwc->hwc_policy;
666 e_hwc_deactive_set(E_Hwc *hwc, Eina_Bool set)
668 EINA_SAFETY_ON_NULL_RETURN(hwc);
670 if (hwc->hwc_deactive == set) return;
672 if (e_hwc_policy_get(hwc) == E_HWC_POLICY_PLANES)
673 e_hwc_planes_end(hwc, __FUNCTION__);
675 hwc->hwc_deactive = set;
679 e_hwc_windows_restriction_set(hwc, E_HWC_WINS_RESTRICTION_DEACTIVE);
680 ecore_event_add(E_EVENT_HWC_DEACTIVE, NULL, NULL, NULL);
684 e_hwc_windows_restriction_unset(hwc, E_HWC_WINS_RESTRICTION_DEACTIVE);
685 ecore_event_add(E_EVENT_HWC_ACTIVE, NULL, NULL, NULL);
688 EHINF("e_hwc_deactive_set : %d", hwc, set);
692 e_hwc_deactive_get(E_Hwc *hwc)
694 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
696 return hwc->hwc_deactive;
700 e_hwc_client_is_above_hwc(E_Client *ec, E_Client *hwc_ec)
703 int layer, hwc_layer;
705 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
706 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_ec, EINA_FALSE);
708 if (ec == hwc_ec) return EINA_FALSE;
709 if (!evas_object_visible_get(ec->frame)) return EINA_FALSE;
711 layer = evas_object_layer_get(ec->frame);
712 hwc_layer = evas_object_layer_get(hwc_ec->frame);
715 if (hwc_layer > layer) return EINA_FALSE;
716 if (layer > hwc_layer) return EINA_TRUE;
718 o = evas_object_above_get(hwc_ec->frame);
719 if (evas_object_layer_get(o) == hwc_layer)
724 o = evas_object_above_get(o);
725 } while (o && (evas_object_layer_get(o) == hwc_layer));
734 e_hwc_output_index_get(E_Hwc *hwc)
738 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc->output, -1);
740 return hwc->output->index;
743 EINTERN tbm_surface_queue_h
744 e_hwc_tbm_surface_queue_get(E_Hwc *hwc)
746 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
748 if (e_hwc_policy_get(hwc) != E_HWC_POLICY_WINDOWS)
750 EHERR("fail to get target_buffer_queue. It is not E_HWC_POLICY_WINDOWS>", hwc);
754 return hwc->target_buffer_queue;
758 e_hwc_gbm_surface_get(E_Hwc *hwc, int *width, int *height, int *format)
760 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
762 if (e_hwc_policy_get(hwc) != E_HWC_POLICY_WINDOWS)
764 EHERR("fail to get target_buffer_queue. It is not E_HWC_POLICY_WINDOWS", hwc);
768 if (width) *width = hwc->gsurface_width;
769 if (height) *height = hwc->gsurface_height;
770 if (format) *format = hwc->gsurface_format;
772 return hwc->gsurface;
776 e_hwc_norender_push(E_Hwc *hwc)
778 EINA_SAFETY_ON_FALSE_RETURN(hwc);
782 if (hwc->norender == 1)
784 _e_hwc_hook_call(E_HWC_HOOK_NORENDER_SET, hwc);
785 EHINF("Norender enabled", hwc);
790 e_hwc_norender_pop(E_Hwc *hwc)
792 EINA_SAFETY_ON_FALSE_RETURN(hwc);
794 if (hwc->norender <= 0) return;
798 if (hwc->norender == 0)
799 EHINF("Norender disabled", hwc);
803 e_hwc_norender_get(E_Hwc *hwc)
805 EINA_SAFETY_ON_FALSE_RETURN_VAL(hwc, 0);
807 return hwc->norender;
811 _e_hwc_prop_name_get_by_id(E_Hwc *hwc, unsigned int id)
813 const hwc_prop *props;
816 if (!e_hwc_available_properties_get(hwc, &props, &count))
818 EHERR("e_hwc_available_properties_get failed.", hwc);
822 for (i = 0; i < count; i++)
824 if (props[i].id == id)
825 return props[i].name;
828 EHERR("No available property: id %d", hwc, id);
834 e_hwc_available_properties_get(E_Hwc *hwc, const hwc_prop **props, int *count)
836 const tdm_prop *tprops;
838 EINA_SAFETY_ON_NULL_RETURN_VAL(count, EINA_FALSE);
839 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
841 if (!e_hwc_windows_get_available_properties(hwc, &tprops, count))
843 EHERR("e_hwc_windows_get_available_properties failed", hwc);
847 *props = (hwc_prop *)tprops;
853 e_hwc_property_get(E_Hwc *hwc, unsigned int id, hwc_value *value)
858 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
859 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
861 ret = tdm_hwc_get_property(hwc->thwc, id, &tvalue);
862 EINA_SAFETY_ON_TRUE_RETURN_VAL(ret != TDM_ERROR_NONE, EINA_FALSE);
864 memcpy(&value->ptr, &tvalue.ptr, sizeof(tdm_value));
866 EHINF("Get property id:%u value:%u", hwc, id, (unsigned int)value->u32);
872 e_hwc_property_set(E_Hwc *hwc, unsigned int id, hwc_value value)
878 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
880 name = _e_hwc_prop_name_get_by_id(hwc, id);
881 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
883 memcpy(&tvalue.ptr, &value.ptr, sizeof(hwc_value));
885 ret = tdm_hwc_set_property(hwc->thwc, id, tvalue);
886 EINA_SAFETY_ON_TRUE_RETURN_VAL(ret != TDM_ERROR_NONE, EINA_FALSE);
888 hwc->property_changed = EINA_TRUE;
890 e_hwc_windows_changed_set(hwc, E_HWC_WINS_CHANGED_PROPERTY);
892 ecore_event_add(E_EVENT_HWC_PROPERTY_CHANGED, NULL, NULL, NULL);
894 EHINF("Set property id:%u value:%u", hwc, id, (unsigned int)value.u32);
900 e_client_hwc_available_properties_get(E_Client *ec, const hwc_prop **props, int *count)
903 E_Hwc_Window *hwc_window;
904 E_Hwc_Window_State state;
905 const tdm_prop *tprops;
907 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
908 EINA_SAFETY_ON_NULL_RETURN_VAL(count, EINA_FALSE);
909 hwc_window = ec->hwc_window;
910 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
911 hwc = hwc_window->hwc;
912 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
914 state = e_hwc_window_state_get(hwc_window);
915 if (state == E_HWC_WINDOW_STATE_VIDEO)
917 if (!e_hwc_windows_get_video_available_properties(hwc, &tprops, count))
919 EHERR("e_hwc_windows_get_video_available_properties failed", hwc);
925 if (!e_hwc_windows_get_available_properties(hwc, &tprops, count))
927 EHERR("e_hwc_windows_get_available_properties failed", hwc);
932 *props = (hwc_prop *)tprops;
938 e_client_hwc_property_get(E_Client *ec, unsigned int id, hwc_value *value)
940 E_Hwc_Window *hwc_window;
943 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
944 EINA_SAFETY_ON_NULL_RETURN_VAL(value, EINA_FALSE);
945 hwc_window = ec->hwc_window;
946 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
947 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window->hwc, EINA_FALSE);
949 if (!e_hwc_window_get_property(hwc_window, id, &tvalue))
951 EHERR("e_hwc_window_get_property failed", hwc_window->hwc);
955 memcpy(&value->ptr, &tvalue.ptr, sizeof(tdm_value));
957 EHINF("Get hwc_window:%p property id:%u value:%u",
958 hwc_window->hwc, hwc_window, id, (unsigned int)value->u32);
964 _e_client_hwc_prop_name_get_by_id(E_Client *ec, unsigned int id)
966 const hwc_prop *props;
969 if (!e_client_hwc_available_properties_get(ec, &props, &count))
971 EHERR("e_client_hwc_available_properties_get failed.", ec->hwc_window->hwc);
975 for (i = 0; i < count; i++)
977 if (props[i].id == id)
978 return props[i].name;
981 EHERR("No available property: id %d", ec->hwc_window->hwc, id);
987 e_client_hwc_property_set(E_Client *ec, unsigned int id, hwc_value value)
989 E_Hwc_Window *hwc_window;
993 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
994 hwc_window = ec->hwc_window;
995 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
997 name = _e_client_hwc_prop_name_get_by_id(ec, id);
998 EINA_SAFETY_ON_NULL_RETURN_VAL(name, EINA_FALSE);
1000 memcpy(&tvalue.ptr, &value.ptr, sizeof(hwc_value));
1002 if (!e_hwc_window_set_property(hwc_window, id, name, tvalue, EINA_TRUE))
1004 EHERR("e_hwc_window_set_property failed", hwc_window->hwc);
1008 EHINF("Set hwc_window:%p property id:%u value:%u",
1009 hwc_window->hwc, hwc_window, id, (unsigned int)value.u32);
1015 e_client_hwc_on_plane(E_Client *ec)
1017 E_Output *output = NULL;
1018 E_Plane *plane = NULL;
1019 E_Client *plane_ec = NULL;
1020 E_Hwc_Window *hwc_window;
1022 Eina_List *l = NULL;
1023 Eina_Bool ret = EINA_FALSE;
1025 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1026 zone = e_comp_zone_find_by_ec(ec);
1027 EINA_SAFETY_ON_NULL_RETURN_VAL(zone, EINA_FALSE);
1029 output = e_output_find(zone->output_id);
1030 EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
1032 if (e_hwc_policy_get(output->hwc) == E_HWC_POLICY_PLANES)
1034 EINA_SAFETY_ON_NULL_RETURN_VAL(output, EINA_FALSE);
1036 EINA_LIST_FOREACH(output->planes, l, plane)
1038 plane_ec = e_plane_ec_get(plane);
1048 hwc_window = ec->hwc_window;
1049 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, EINA_FALSE);
1051 ret = e_hwc_window_is_on_hw_overlay(hwc_window);
1058 e_client_hwc_visible_skip_set(E_Client *ec, Eina_Bool skip)
1060 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
1062 ec->hwc_visible_skip = skip;
1065 e_hwc_window_visible_skip_set(ec->hwc_window, skip);
1070 E_API E_Hwc_Sync_Callback *
1071 e_hwc_sync_callback_add(E_Hwc *hwc, E_Hwc_Sync_Done_Cb cb, void *data)
1073 E_Hwc_Sync_Callback *sync_callback;
1075 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
1076 EINA_SAFETY_ON_FALSE_RETURN_VAL(hwc->hwc_policy == E_HWC_POLICY_WINDOWS, NULL);
1078 sync_callback = E_NEW(E_Hwc_Sync_Callback, 1);
1079 EINA_SAFETY_ON_NULL_RETURN_VAL(sync_callback, NULL);
1081 sync_callback->hwc = hwc;
1082 sync_callback->cb = cb;
1083 sync_callback->data = data;
1085 hwc->sync_callback_list = eina_list_append(hwc->sync_callback_list, sync_callback);
1087 return sync_callback;
1091 e_hwc_sync_callback_del(E_Hwc_Sync_Callback *sync_callback)
1093 EINA_SAFETY_ON_NULL_RETURN(sync_callback);
1095 if (sync_callback->hwc)
1097 sync_callback->hwc->sync_callback_list =
1098 eina_list_remove(sync_callback->hwc->sync_callback_list, sync_callback);
1101 E_FREE(sync_callback);
1105 e_hwc_sync_callback_call(E_Hwc_Sync_Callback *sync_callback)
1107 EINA_SAFETY_ON_NULL_RETURN_VAL(sync_callback, EINA_FALSE);
1109 if (sync_callback->done) return EINA_TRUE;
1111 sync_callback->done = EINA_TRUE;
1113 if (!sync_callback->cb) return EINA_TRUE;
1115 /* it is possible callback is freed in callback */
1116 sync_callback->cb(sync_callback->data, sync_callback->hwc);
1121 E_API E_Hwc_Presentation_Callback *
1122 e_client_hwc_presentation_callback_add(E_Client *ec, E_Hwc_Presentation_Done_Cb cb, void *data)
1124 E_Hwc_Presentation_Callback *callback;
1126 E_Hwc_Window *hwc_window;
1128 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, NULL);
1129 EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
1130 hwc_window = ec->hwc_window;
1131 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc_window, NULL);
1132 hwc = hwc_window->hwc;
1133 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
1134 EINA_SAFETY_ON_FALSE_RETURN_VAL(hwc->hwc_policy == E_HWC_POLICY_WINDOWS, NULL);
1136 callback = E_NEW(E_Hwc_Presentation_Callback, 1);
1137 EINA_SAFETY_ON_NULL_RETURN_VAL(callback, NULL);
1139 callback->hwc = hwc;
1141 callback->data = data;
1143 if (!e_hwc_window_presentation_callback_pending_set(hwc_window, callback))
1145 ERR("fail to e_hwc_window_presentation_callback_set");
1150 EHINF("Add Presentation Callback:%p ec:%p hwc_window:%p",
1160 e_hwc_presentation_callback_del(E_Hwc_Presentation_Callback *callback)
1162 EINA_SAFETY_ON_NULL_RETURN(callback);
1164 EHINF("Del Presentation Callback:%p", callback->hwc, callback);
1167 callback->list->callbacks = eina_list_remove(callback->list->callbacks, callback);
1173 e_hwc_presentation_callback_list_init(E_Hwc_Presentation_Callback_List *list)
1175 EINA_SAFETY_ON_NULL_RETURN(list);
1179 e_hwc_presentation_callback_list_finish(E_Hwc_Presentation_Callback_List *list)
1181 E_Hwc_Presentation_Callback *callback = NULL;
1186 /* remove list in resource_destroy callback */
1187 EINA_LIST_FOREACH_SAFE(list->callbacks, l, ll, callback)
1189 callback->list = NULL;
1190 list->callbacks = eina_list_remove_list(list->callbacks, l);
1191 e_hwc_presentation_callback_call(callback);
1196 e_hwc_presentation_callback_list_set(E_Hwc_Presentation_Callback_List *list,
1197 E_Hwc_Presentation_Callback *callback)
1199 EINA_SAFETY_ON_NULL_RETURN_VAL(list, EINA_FALSE);
1200 EINA_SAFETY_ON_NULL_RETURN_VAL(callback, EINA_FALSE);
1203 callback->list->callbacks = eina_list_remove(callback->list->callbacks, callback);
1205 if (!eina_list_data_find(list->callbacks, callback))
1206 list->callbacks = eina_list_prepend(list->callbacks, callback);
1208 callback->list = list;
1214 e_hwc_presentation_callback_list_unset(E_Hwc_Presentation_Callback_List *list,
1215 E_Hwc_Presentation_Callback *callback)
1217 EINA_SAFETY_ON_NULL_RETURN_VAL(list, EINA_FALSE);
1218 EINA_SAFETY_ON_NULL_RETURN_VAL(callback, EINA_FALSE);
1221 callback->list->callbacks = eina_list_remove(callback->list->callbacks, callback);
1223 callback->list = NULL;
1229 e_hwc_presentation_callback_list_merge(E_Hwc_Presentation_Callback_List *inout,
1230 E_Hwc_Presentation_Callback_List *input)
1232 E_Hwc_Presentation_Callback *callback = NULL;
1235 EINA_SAFETY_ON_NULL_RETURN(inout);
1236 EINA_SAFETY_ON_NULL_RETURN(input);
1238 /* remove list in feedback_set */
1239 EINA_LIST_FOREACH_SAFE(input->callbacks, l, ll, callback)
1240 e_hwc_presentation_callback_list_set(inout, callback);
1244 e_hwc_presentation_callback_call(E_Hwc_Presentation_Callback *callback)
1246 EINA_SAFETY_ON_NULL_RETURN_VAL(callback, EINA_FALSE);
1248 if (callback->done) return EINA_TRUE;
1250 callback->done = EINA_TRUE;
1252 if (!callback->cb) return EINA_TRUE;
1254 EHINF("Call Presentation Callback:%p", callback->hwc, callback);
1256 /* it is possible callback is freed in callback */
1257 callback->cb(callback->data, callback);
1263 e_hwc_presentation_callback_list_call(E_Hwc_Presentation_Callback_List *list)
1265 E_Hwc_Presentation_Callback *callback = NULL;
1268 EINA_SAFETY_ON_NULL_RETURN(list);
1270 /* remove list in resource_destroy callback */
1271 EINA_LIST_FOREACH_SAFE(list->callbacks, l, ll, callback)
1272 e_hwc_presentation_callback_call(callback);
1276 e_hwc_output_get(E_Hwc *hwc)
1278 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, NULL);
1284 e_hwc_hwc_policy_get(E_Hwc *hwc)
1286 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, E_HWC_POLICY_NONE);
1288 return hwc->hwc_policy;
1292 e_hwc_hwc_use_multi_plane_set(E_Hwc *hwc, Eina_Bool set)
1294 EINA_SAFETY_ON_NULL_RETURN(hwc);
1296 hwc->hwc_use_multi_plane = set;
1300 e_hwc_hwc_use_multi_plane_get(E_Hwc *hwc)
1302 EINA_SAFETY_ON_NULL_RETURN_VAL(hwc, EINA_FALSE);
1304 return hwc->hwc_use_multi_plane;