static Eina_Inlist *_e_comp_hooks[] =
{
- [E_COMP_HOOK_ASSIGN_PLANE] = NULL,
+ [E_COMP_HOOK_PREPARE_PLANE] = NULL,
};
E_API int E_EVENT_COMPOSITOR_RESIZE = -1;
}
static void
-_e_comp_hook_call(E_Comp_Hook_Point hookpoint, E_Comp *c)
+_e_comp_hook_call(E_Comp_Hook_Point hookpoint, void *data EINA_UNUSED)
{
E_Comp_Hook *ch;
EINA_INLIST_FOREACH(_e_comp_hooks[hookpoint], ch)
{
if (ch->delete_me) continue;
- ch->func(ch->data, c);
+ ch->func(ch->data, NULL);
}
_e_comp_hooks_walking--;
if ((_e_comp_hooks_walking == 0) && (_e_comp_hooks_delete > 0))
}
}
+static Eina_Bool
+_e_comp_hwc_active(void)
+{
+ if (e_comp->hwc_override > 0)
+ return EINA_FALSE;
+
+ switch (e_comp->hwc_mode)
+ {
+ case E_HWC_MODE_NO_COMPOSITE:
+ case E_HWC_MODE_HWC_COMPOSITE:
+ case E_HWC_MODE_HWC_NO_COMPOSITE:
+ return EINA_TRUE;
+ }
+ return EINA_FALSE;
+}
+
static void
_e_comp_cb_nocomp_begin(void)
{
{
e_comp->nocomp_want = 0;
E_FREE_FUNC(e_comp->nocomp_delay_timer, ecore_timer_del);
+ if (!e_comp->nocomp) return;
INF("HWC : NOCOMP_END at %s\n", location);
_e_comp_cb_nocomp_end();
}
#ifdef MULTI_PLANE_HWC
static Eina_Bool
-_e_comp_selcomp_check(void)
-{
- Eina_List *l, *ll;
- E_Zone *zone;
- E_Client *ec;
- int ret = 0;
-
- // instead of zones, canvas list will be the condition of each output check
- // TODO: e_comp->canvases
- EINA_LIST_FOREACH_SAFE(e_comp->zones, l, ll, zone)
- {
- int ly_total = 0, ly_cnt = 0;
- E_Hwc_Mode mode = E_HWC_MODE_INVALID;
-
- if (zone->screen) ly_total = zone->screen->plane_count;
-
- E_CLIENT_REVERSE_FOREACH(ec)
- {
- E_Comp_Wl_Client_Data *cdata = (E_Comp_Wl_Client_Data*)ec->comp_data;
-
- // check clients to skip composite
- if (ec->ignored || ec->input_only || (!evas_object_visible_get(ec->frame)) || (ec->zone != zone))
- continue;
-
- if (!E_INTERSECTS(0, 0, e_comp->w, e_comp->h,
- ec->client.x, ec->client.y, ec->client.w, ec->client.h))
- {// check quick panel
- continue;
- }
-
- if (evas_object_data_get(ec->frame, "comp_skip"))
- continue;
-
- // check clients not able to use hwc
- if ((!cdata->buffer_ref.buffer) ||
- (cdata->buffer_ref.buffer->type != E_COMP_WL_BUFFER_TYPE_NATIVE) ||
- (cdata->width_from_buffer != cdata->width_from_viewport) ||
- (cdata->height_from_buffer != cdata->height_from_viewport))
- {
- if (ly_cnt) mode = E_HWC_MODE_HWC_COMPOSITE;
- else mode = E_HWC_MODE_COMPOSITE;
- break;
- }
-
- ly_cnt++;
- }
- if (mode == E_HWC_MODE_INVALID)
- {
- if (ly_cnt == 1 ) mode = E_HWC_MODE_NO_COMPOSITE;
- else if (ly_cnt <= ly_total && ly_cnt > 1) mode = E_HWC_MODE_HWC_NO_COMPOSITE;
- else if (ly_cnt > ly_total) mode = E_HWC_MODE_HWC_COMPOSITE;
- }
-
- if((mode != E_HWC_MODE_COMPOSITE) && (mode != E_HWC_MODE_INVALID)) ret++;
- }
-
- return (ret > 0);
-}
-
-static Eina_Bool
-_e_comp_selcomp_assign_planes(void)
+_e_comp_prepare_overlay(void)
{
Eina_List *l, *ll;
E_Zone *zone;
if (!zone && !zone->screen) continue;
eout = zone->screen;
- printf("reassign all clients from zone %p\n", zone);
num_of_ly = eout->plane_count;
E_CLIENT_REVERSE_FOREACH(ec)
else if (ly_cnt > num_of_ly) mode = E_HWC_MODE_HWC_COMPOSITE;
}
-#ifdef HAVE_HWC
- // comepare clist with current and assign it to planes refer to core policy : FIXME
- // ......
- e_output_planes_clear(eout);
- e_output_planes_set(eout, mode, clist);
-#endif
- eina_list_free(clist);
- clist = NULL;
+ e_output_planes_prepare(eout, mode, clist);
+ eina_list_free(clist);
+ clist = NULL;
}
return EINA_TRUE;
}
+static Eina_Bool
+_e_comp_hwc_usable(void)
+{
+ if (!e_comp->hwc) return EINA_FALSE;
+
+ // check whether to use hwcomposer by assignment policy
+ // core policy
+ _e_comp_prepare_overlay();
+
+ // extra policy
+ _e_comp_hook_call(E_COMP_HOOK_PREPARE_PLANE, NULL);
+
+ switch (e_comp->prepare_mode)
+ {
+ case E_HWC_MODE_NO_COMPOSITE:
+ case E_HWC_MODE_HWC_COMPOSITE:
+ case E_HWC_MODE_HWC_NO_COMPOSITE:
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
static void
-_e_comp_cb_selcomp_begin(void)
+_e_comp_cb_hwc_begin(void)
{
Eina_List *l;
E_Zone *zone;
if (!e_comp->hwc) return;
E_FREE_FUNC(e_comp->selcomp_delay_timer, ecore_timer_del);
- if (!_e_comp_selcomp_check()) return;
e_comp->selcomp_want = 1;
-#ifdef HAVE_HWC
- // check core policy of plane assignment
- _e_comp_selcomp_assign_planes();
-
- // check extra policy
- _e_comp_hook_call(E_COMP_HOOK_ASSIGN_PLANE, NULL);
-
EINA_LIST_FOREACH(e_comp->zones, l, zone)
{
- if(zone->screen) mode_set |= e_output_update(zone->screen);
+ if(zone->screen) mode_set |= e_output_planes_apply(zone->screen);
}
-#endif
+
if (!mode_set) return;
+ if (!_e_comp_hwc_active()) return;
if (e_comp->calc_fps) e_comp->frametimes[0] = 0;
- e_comp->selcomp = 1;
- INF("JOB2...");
-
- e_comp_render_queue();
- e_comp_shape_queue_block(1);
- ecore_event_add(E_EVENT_COMPOSITOR_DISABLE, NULL, NULL, NULL);
+ INF("HWC : Begin to use HWComposer...");
}
static Eina_Bool
-_e_comp_cb_selcomp_begin_timeout(void *data EINA_UNUSED)
+_e_comp_cb_hwc_begin_timeout(void *data EINA_UNUSED)
{
e_comp->selcomp_delay_timer = NULL;
- if (e_comp->selcomp_override == 0)
+ if (e_comp->hwc_override == 0 && _e_comp_hwc_usable())
{
- _e_comp_cb_selcomp_begin();
+ _e_comp_cb_hwc_begin();
}
return EINA_FALSE;
}
-E_API void
-e_comp_selcomp_end(const char *location)
+void
+_e_comp_hwc_end(const char *location)
{
Eina_Bool mode_set = EINA_FALSE;
E_Client *ec;
Eina_List *l, *ll;
if (!e_comp->hwc) return;
- if (!e_comp->selcomp) return;
+ if (!_e_comp_hwc_active()) return;
e_comp->selcomp_want = 0;
E_FREE_FUNC(e_comp->selcomp_delay_timer, ecore_timer_del);
-#ifdef HAVE_HWC
// e_comp->canvases will be replace e_comp->zones
EINA_LIST_FOREACH_SAFE(e_comp->zones, l, ll, zone)
{
if (zone->screen)
{
- e_output_planes_clear(zone->screen);
- mode_set |= e_output_update(zone->screen);
+ mode_set |= e_output_planes_clear(zone->screen);
}
}
-#endif
+
if (!mode_set) return;
- INF("HWC : selective comp _END at %s\n", location);
- INF("COMP RESUME!");
+ INF("HWC : End... at %s", location);
- E_CLIENT_FOREACH(ec)
- {
- if (ec->visible && (!ec->input_only))
- e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
+ e_comp->prepare_mode = 0;
+ e_comp->hwc_mode = 0;
- }
- e_comp->selcomp = 0;
e_comp_render_queue();
- e_comp_shape_queue_block(0);
- ecore_event_add(E_EVENT_COMPOSITOR_ENABLE, NULL, NULL, NULL);
}
#endif
e_comp->update_job = NULL;
else
ecore_animator_freeze(e_comp->render_animator);
+
DBG("UPDATE ALL");
- if (e_comp->nocomp || e_comp->selcomp) goto hwcompose;
+ if (e_comp->nocomp) goto setup_hwcompose;
+ if (_e_comp_hwc_active()) goto setup_hwcompose;
+
if (conf->grab && (!e_comp->grabbed))
{
if (e_comp->grab_cb) e_comp->grab_cb();
if (e_comp->updates && (!e_comp->update_job))
ecore_animator_thaw(e_comp->render_animator);
-hwcompose:
+setup_hwcompose:
// TO DO :
// query if selective HWC plane can be used
if (!e_comp_gl_get() && !e_comp->hwc)
goto end;
}
#ifdef MULTI_PLANE_HWC
- if(_e_comp_selcomp_check())
+ if(_e_comp_hwc_usable())
{
- // switch mode
- if (conf->selcomp_use_timer)
+ if (_e_comp_hwc_active())
{
- if (!e_comp->selcomp_delay_timer)
- {
- e_comp->selcomp_delay_timer = ecore_timer_add(conf->selcomp_begin_timeout,
- _e_comp_cb_selcomp_begin_timeout,
- NULL);
- }
+ // FIXME : will remove out this condition
+ // new(ec at prepared list) and current(ec on e_plane)
+ if (e_output_planes_need_change)
+ _e_comp_hwc_end("overlay surface changed");
}
- else
+ else if (!_e_comp_hwc_active())
{
- _e_comp_cb_selcomp_begin();
+ // switch mode
+ if (conf->selcomp_use_timer)
+ {
+ if (!e_comp->selcomp_delay_timer)
+ {
+ e_comp->selcomp_delay_timer = ecore_timer_add(conf->selcomp_begin_timeout,
+ _e_comp_cb_hwc_begin_timeout,
+ NULL);
+ }
+ }
+ else
+ {
+ _e_comp_cb_hwc_begin();
+ }
}
}
else
{
- if (e_comp->selcomp) e_comp_selcomp_end(__FUNCTION__);
+ if (_e_comp_hwc_active()) _e_comp_hwc_end(__FUNCTION__);
}
#else
ec = _e_comp_fullscreen_check();
{
return e_comp->nocomp_ec == ec;
}
- else if (e_comp->selcomp)
+ else if (_e_comp_hwc_active())
{
Eina_List *l, *ll;
E_Output_Screen * screen;
static void _info_free(E_Output *r);
static void _screen_config_eval(void);
static void _screen_config_maxsize(void);
+static Eina_Bool _hwc_set(E_Output_Screen * screen, E_Hwc_Mode mode, Eina_List* prepare_ec_list);
+
/////////////////////////////////////////////////////////////////////////
all_screens = screens;
}
-E_API void
+static Eina_Bool
+_hwc_set(E_Output_Screen * screen, E_Hwc_Mode mode, Eina_List* prepare_ec_list)
+{
+ Eina_List *l_p, *l_ec;
+ Eina_List *l, *ll;
+ E_Plane *ep;
+ int num_c, num_p;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(screen, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(screen->planes, EINA_FALSE);
+ INF("HWC : mode(%d) (%d)overlays\n", mode, eina_list_count(prepare_ec_list));
+
+ l_p = screen->planes; // Overlay sort by Z
+ num_p = screen->plane_count;
+
+ l_ec = prepare_ec_list; // Visible clients sort by Z
+ num_c = eina_list_count(prepare_ec_list);
+
+ if ((mode == E_HWC_MODE_COMPOSITE) ||
+ (mode == E_HWC_MODE_HWC_COMPOSITE))
+ {
+ ep = eina_list_data_get(l_p);
+ if (ep)
+ {
+ num_p--;
+ e_client_redirected_set(ep->ec, 1);
+ ep->ec = NULL; // 1st plane is assigned for e_comp->evas
+ }
+ l_p = eina_list_next(l_p);
+ }
+
+ if ((num_c < 1) || (num_p < 1))
+ {
+ INF("HWC : prepared (%d) overlays on (%d) planes are wrong\n", num_c, num_p);
+ return EINA_FALSE;
+ }
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(l_p, EINA_FALSE);
+ EINA_LIST_REVERSE_FOREACH_SAFE(l_p, l, ll, ep)
+ {
+ E_Client *ec = NULL;
+
+ if (ep->ec) e_client_redirected_set(ep->ec, 1);
+
+ if (num_p < 1) break;
+
+ if (num_c < num_p)
+ {
+ num_p--; continue;
+ }
+
+ if (!l_ec) break;
+ ec = eina_list_data_get(l_ec);
+ if(ec)
+ {
+ INF("HWC : set '%s' on overlay(%d)\n", ec->icccm.title, num_p);
+ e_client_redirected_set(ec, 0);
+ ep->ec = ec;
+ }
+ num_p--;
+ l_ec = eina_list_next(l_ec);
+ }
+ e_comp->hwc_mode = mode;
+
+ return EINA_TRUE;
+}
+
+EINTERN void
e_output_screens_setup(int rw, int rh)
{
int i;
return NULL;
}
+
E_API Eina_Bool
+e_output_planes_prepare(E_Output_Screen * screen, E_Hwc_Mode mode, Eina_List* clist)
+{
+ if (!e_comp) return EINA_FALSE;
+
+ e_comp->prepare_mode = mode;
+ if (e_comp->prepare_ec_list)
+ {
+ eina_list_free(e_comp->prepare_ec_list);
+ e_comp->prepare_ec_list = NULL;
+ }
+ e_comp->prepare_ec_list = eina_list_clone(clist);
+ return EINA_TRUE;
+}
+
+E_API Eina_Bool
+e_output_planes_apply(E_Output_Screen * screen)
+{
+ e_comp->hwc_mode = e_comp->prepare_mode;
+ switch (e_comp->prepare_mode)
+ {
+ case E_HWC_MODE_NO_COMPOSITE:
+ case E_HWC_MODE_HWC_COMPOSITE:
+ case E_HWC_MODE_HWC_NO_COMPOSITE:
+ return _hwc_set(screen, e_comp->prepare_mode, e_comp->prepare_ec_list);
+
+ default :
+ e_output_planes_clear(screen);
+ break;
+ }
+
+ return EINA_FALSE;
+}
+
+EINTERN Eina_Bool
e_output_planes_clear(E_Output_Screen * screen)
{
Eina_List *l, *ll;
E_Plane *ep;
- INF("HWC : %s\n",__FUNCTION__);
EINA_SAFETY_ON_NULL_RETURN_VAL(screen, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(screen->planes, EINA_FALSE);
+ e_comp->hwc_mode = 0;
+
EINA_LIST_FOREACH_SAFE(screen->planes, l, ll, ep)
{
+ if (ep->ec) e_client_redirected_set(ep->ec, 1);
ep->ec = NULL;
}
+
return EINA_TRUE;
}
-E_API Eina_Bool
-e_output_planes_set(E_Output_Screen * screen, E_Hwc_Mode mode, Eina_List* clist)
+EINTERN Eina_Bool
+e_output_planes_need_change()
{
- Eina_List *l_p, *l_ec;
- Eina_List *l, *ll;
+ E_Zone *zone;
+ E_Output_Screen * screen;
E_Plane *ep;
- int num_c;
- INF("HWC : %s\n",__FUNCTION__);
-
- num_c = eina_list_count(clist);
+ int num_ov;
+ Eina_List *l_p, *l_ov, *l, *ll;
- EINA_SAFETY_ON_NULL_RETURN_VAL(screen, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(screen->planes, EINA_FALSE);
- if ((num_c > screen->plane_count) ||
- (num_c < 1))
+ if (!e_comp) return EINA_FALSE;
+ if (e_comp->hwc_mode != e_comp->prepare_mode)
return EINA_FALSE;
+ zone = eina_list_data_get(e_comp->zones);
+ if (!zone) return EINA_FALSE;
+ screen = zone->screen;
+ if (!screen) return EINA_FALSE;
l_p = screen->planes;
- l_ec = clist;
- if ((mode == E_HWC_MODE_COMPOSITE) ||
- (mode == E_HWC_MODE_HWC_COMPOSITE))
+ if (!l_p) return EINA_FALSE;
+
+ num_ov = eina_list_count(e_comp->prepare_ec_list);
+ if ((num_ov > screen->plane_count) ||
+ (num_ov < 1))
+ return EINA_FALSE;
+
+ l_ov = e_comp->prepare_ec_list;
+
+ if ((e_comp->prepare_mode == E_HWC_MODE_COMPOSITE) ||
+ (e_comp->prepare_mode == E_HWC_MODE_HWC_COMPOSITE))
{
ep = eina_list_data_get(l_p);
- if (ep) ep->ec = NULL; // 1st plane is assigned for e_comp->evas
+ if (ep) return EINA_FALSE;
l_p = eina_list_next(l_p);
}
{
E_Client *ec = NULL;
- if (!l_ec) break;
- ec = eina_list_data_get(l_ec);
-
+ if (!l_ov) break;
+ ec = eina_list_data_get(l_ov);
if(ec)
{
- ep->ec = ec;
+ if (ep->ec != ec) return EINA_TRUE;
}
- l_ec = eina_list_next(l_ec);
+
+ l_ov = eina_list_next(l_ov);
}
- return EINA_TRUE;
+ return EINA_FALSE;
}
E_API Eina_Bool
-e_output_update(E_Output_Screen * screen)
+e_output_util_planes_print(void)
{
Eina_List *l, *ll;
- E_Plane *ep;
- E_Client *ec;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(screen, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(screen->planes, EINA_FALSE);
+ E_Zone *zone;
- EINA_LIST_FOREACH_SAFE(screen->planes, l, ll, ep)
+ EINA_LIST_FOREACH_SAFE(e_comp->zones, l, ll, zone)
{
- ec = ep->ec;
- if (ec) INF("HWC:\t|---\t %s 0x%08x\n", ec->icccm.title, (unsigned int)ec->frame);
+ E_Output_Screen * screen = NULL;
+ E_Plane *ep;
+ E_Client *ec;
+
+ if (!zone && !zone->screen) continue;
+ screen = zone->screen;
+ if (!screen) continue;
+ if (!screen->planes) continue;
+
+ EINA_LIST_FOREACH_SAFE(screen->planes, l, ll, ep)
+ {
+ ec = ep->ec;
+ if (ec) INF("HWC:\t|---\t %s 0x%08x\n", ec->icccm.title, (unsigned int)ec->frame);
+ }
}
- // TODO: hwc mode change
return EINA_FALSE; // SHALL BE EINA_TRUE after hwc multi plane implementation
}