evas: handle multiple output for plane assignment.

This commit is contained in:
Cedric BAIL 2017-08-25 10:51:20 -07:00
parent d8871109d3
commit 7bcf483d6f
4 changed files with 81 additions and 21 deletions

View File

@ -1842,7 +1842,9 @@ _efl_canvas_image_internal_efl_canvas_filter_internal_filter_input_render(
}
void
_evas_object_image_plane_release(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj)
_evas_object_image_plane_release(Evas_Object *eo_obj EINA_UNUSED,
Evas_Object_Protected_Data *obj,
Efl_Canvas_Output *output)
{
Evas_Image_Data *o;
@ -1854,12 +1856,14 @@ _evas_object_image_plane_release(Evas_Object *eo_obj EINA_UNUSED, Evas_Object_Pr
if (!o->plane) return;
ENFN->image_plane_release(ENDT, o->engine_data, o->plane);
ENFN->image_plane_release(output->output, o->engine_data, o->plane);
output->planes = eina_list_remove(output->planes, obj);
o->plane = NULL;
}
Eina_Bool
_evas_object_image_can_use_plane(Evas_Object_Protected_Data *obj)
_evas_object_image_can_use_plane(Evas_Object_Protected_Data *obj,
Efl_Canvas_Output *output)
{
Evas_Native_Surface *ns;
Evas_Image_Data *o = obj->private_data;
@ -1883,13 +1887,15 @@ _evas_object_image_can_use_plane(Evas_Object_Protected_Data *obj)
ns = ENFN->image_native_get(ENC, o->engine_data);
if (!ns) return EINA_FALSE;
o->plane = ENFN->image_plane_assign(ENDT, o->engine_data,
// FIXME: adjust position with output offset.
o->plane = ENFN->image_plane_assign(output->output, o->engine_data,
obj->cur->geometry.x,
obj->cur->geometry.y);
if (!o->plane)
return EINA_FALSE;
output->planes = eina_list_append(output->planes, obj);
return EINA_TRUE;
}

View File

@ -99,10 +99,10 @@ efl_canvas_output_view_set(Efl_Canvas_Output *output,
e = _efl_canvas_output_async_block(output);
if (!e) return ;
output->x = x;
output->y = y;
output->w = w;
output->h = h;
output->geometry.x = x;
output->geometry.y = y;
output->geometry.w = w;
output->geometry.h = h;
// XXX: tell engine about any output size etc. changes
// XXX: tell evas to add damage if viewport loc/size changed
}
@ -111,10 +111,10 @@ EAPI void
efl_canvas_output_view_get(Efl_Canvas_Output *output,
Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
{
if (x) *x = output->x;
if (y) *y = output->y;
if (w) *w = output->w;
if (h) *h = output->h;
if (x) *x = output->geometry.x;
if (y) *y = output->geometry.y;
if (w) *w = output->geometry.w;
if (h) *h = output->geometry.h;
}
EAPI Eina_Bool

View File

@ -1342,7 +1342,7 @@ pending_change(void *data, void *gdata EINA_UNUSED)
}
static Eina_Bool
_evas_render_can_use_overlay(Evas_Public_Data *e, Evas_Object *eo_obj)
_evas_render_can_use_overlay(Evas_Public_Data *e, Evas_Object *eo_obj, Efl_Canvas_Output *output)
{
Eina_Rectangle *r;
Evas_Object *eo_tmp;
@ -1360,7 +1360,7 @@ _evas_render_can_use_overlay(Evas_Public_Data *e, Evas_Object *eo_obj)
Eina_Bool surface_below, stacking_check, object_above = EINA_FALSE;
Eina_Bool ignore_window;
if (!_evas_object_image_can_use_plane(obj))
if (!_evas_object_image_can_use_plane(obj, output))
return EINA_FALSE;
video_parent = _evas_object_image_video_parent_get(eo_obj);
@ -3085,6 +3085,39 @@ evas_render_updates_internal_loop(Evas *eo_e, Evas_Public_Data *evas,
return clean_them;
}
static Efl_Canvas_Output *
_evas_overlay_output_find(Evas_Public_Data *e, Evas_Object_Protected_Data *obj)
{
Efl_Canvas_Output *output;
Eina_List *lo;
const Eina_Rectangle geometry = {
obj->cur->geometry.x,
obj->cur->geometry.y,
obj->cur->geometry.w,
obj->cur->geometry.h
};
Eina_Rectangle copy = geometry;
/* A video object can only be in one output at a time, check that first */
EINA_LIST_FOREACH(e->outputs, lo, output)
{
if (!eina_rectangle_intersection(&copy, &output->geometry))
{
copy = geometry;
continue ;
}
if (memcmp(&copy, &geometry, sizeof (Eina_Rectangle)) != 0)
{
/* This means that it does intersect this output and another */
return NULL;
}
return output;
}
return NULL;
}
static Eina_Bool
evas_render_updates_internal(Evas *eo_e,
unsigned char make_updates,
@ -3185,8 +3218,13 @@ evas_render_updates_internal(Evas *eo_e,
EINA_LIST_FOREACH(e->video_objects, ll, eo_obj)
{
Efl_Canvas_Output *output;
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
output = _evas_overlay_output_find(e, obj);
/* we need the surface to be transparent to display the underlying overlay */
if (alpha && _evas_render_can_use_overlay(e, eo_obj))
if (output && alpha && _evas_render_can_use_overlay(e, eo_obj, output))
_evas_object_image_video_overlay_show(eo_obj);
else
_evas_object_image_video_overlay_hide(eo_obj);
@ -3198,6 +3236,8 @@ evas_render_updates_internal(Evas *eo_e,
{
Evas_Object_Protected_Data *obj2;
Evas_Object *eo_obj2;
Efl_Canvas_Output *output;
Eina_List *lo;
obj2 = ao->obj;
eo_obj2 = obj2->object;
@ -3206,12 +3246,23 @@ evas_render_updates_internal(Evas *eo_e,
if (evas_object_image_video_surface_get(eo_obj2)) continue;
_evas_object_image_plane_release(eo_obj2, obj2);
if (!_evas_render_can_use_overlay(e, eo_obj2))
/* Find the output the object was in */
EINA_LIST_FOREACH(e->outputs, lo, output)
{
if (!eina_list_data_find(output->planes, obj2)) continue ;
_evas_object_image_plane_release(eo_obj2, obj2, output);
break;
}
/* A video object can only be in one output at a time, check that first */
output = _evas_overlay_output_find(e, obj2);
if (!output) continue ;
if (!_evas_render_can_use_overlay(e, eo_obj2, output))
{
/* This may free up things temporarily allocated by
* _can_use_overlay() testing in the engine */
_evas_object_image_plane_release(eo_obj2, obj2);
_evas_object_image_plane_release(eo_obj2, obj2, output);
}
}

View File

@ -1337,7 +1337,10 @@ struct _Efl_Canvas_Output
Evas_Engine_Info *info;
void *output;
Evas_Coord x, y, w, h;
Eina_List *planes;
Eina_Rectangle geometry;
int info_magic;
};
@ -1709,8 +1712,8 @@ Evas_Object *_evas_object_image_video_parent_get(Evas_Object *obj);
void _evas_object_image_video_overlay_show(Evas_Object *obj);
void _evas_object_image_video_overlay_hide(Evas_Object *obj);
void _evas_object_image_video_overlay_do(Evas_Object *obj);
Eina_Bool _evas_object_image_can_use_plane(Evas_Object_Protected_Data *obj);
void _evas_object_image_plane_release(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj);
Eina_Bool _evas_object_image_can_use_plane(Evas_Object_Protected_Data *obj, Efl_Canvas_Output *output);
void _evas_object_image_plane_release(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Efl_Canvas_Output *output);
void _evas_object_image_free(Evas_Object *obj);
void evas_object_smart_bounding_box_get(Evas_Object_Protected_Data *obj,
Evas_Coord_Rectangle *cur_bounding_box,