From: Shinwoo Kim Date: Fri, 30 Apr 2021 09:31:44 +0000 (+0900) Subject: evas: add evas_map_direct_render_set X-Git-Tag: accepted/tizen/unified/20210602.122542~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F53%2F257753%2F7;p=platform%2Fupstream%2Fefl.git evas: add evas_map_direct_render_set This is for very special purpose interface to optimize memory usage of map. This is for a smart object which has only one image object as its children. The map will be applied to the image object instead of the smart object. Change-Id: Ieceff3413aba7ac1c88aec694f47fb8c4dcc741d --- diff --git a/src/lib/evas/Evas_Legacy.h b/src/lib/evas/Evas_Legacy.h index 3efe7fb..658313f 100755 --- a/src/lib/evas/Evas_Legacy.h +++ b/src/lib/evas/Evas_Legacy.h @@ -8578,6 +8578,25 @@ EAPI void evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled); */ EAPI Eina_Bool evas_object_map_enable_get(const Evas_Object *obj); +//TIZEN_ONLY(20210503): Add evas_map_direct_render_set +/** + * @brief Set direct render of map. + * + * This interface has very special purpose to optimize memory usage of map. + * It works when a map object has only one image object through its smart object tree. + * In this case, it regards the map has one image object which of buffer can be + * directly draw on the main surface so that it skips to create an additional frame + * buffer to composite the contents of the map. If the condition is not satisfied, + * map works as it's supposed to do in the default behavior. + * + * @param m map to enable direct render. + * @param direct_render @c true to enable direct render. + * + * @ingroup Evas_Object_Group + */ +EAPI void evas_map_direct_render_set(Evas_Map *m, Eina_Bool direct_render); +// + /** * @brief Apply an evas filter program on this text object. * diff --git a/src/lib/evas/canvas/evas_map.c b/src/lib/evas/canvas/evas_map.c index 272a2b8..e7423ac 100644 --- a/src/lib/evas/canvas/evas_map.c +++ b/src/lib/evas/canvas/evas_map.c @@ -207,6 +207,9 @@ _evas_map_copy(Evas_Map *dst, const Evas_Map *src) dst->alpha = src->alpha; dst->move_sync = src->move_sync; dst->persp = src->persp; + //TIZEN_ONLY(20210503): Add evas_map_direct_render_set + dst->direct_render = src->direct_render; + // return EINA_TRUE; } @@ -220,6 +223,9 @@ _evas_map_dup(const Evas_Map *orig) copy->alpha = orig->alpha; copy->move_sync = orig->move_sync; copy->persp = orig->persp; + //TIZEN_ONLY(20210503): Add evas_map_direct_render_set + copy->direct_render = orig->direct_render; + // return copy; } @@ -528,6 +534,18 @@ evas_object_map_enable_get(const Eo *eo_obj) return obj->map->cur.usemap; } +//TIZEN_ONLY(20210503): Add evas_map_direct_render_set +EAPI void +evas_map_direct_render_set(Evas_Map *m, Eina_Bool direct_render) +{ + MAGIC_CHECK(m, Evas_Map, MAGIC_MAP); + return; + MAGIC_CHECK_END(); + + m->direct_render = !!direct_render; +} +// + EAPI void evas_object_map_set(Evas_Object *eo_obj, const Evas_Map *map) { diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 5a863d8..077fcea 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -1793,6 +1793,96 @@ _evas_render_mapped_mask(Evas_Public_Data *evas, Evas_Object_Protected_Data *obj } } +//TIZEN_ONLY(20210503): Add evas_map_direct_render_set +/* This function checks if there is only one image object, and returns it */ +static Eina_Bool +_map_source_image_get(Evas_Object *eo_obj, Evas_Object **src_img) +{ + Eina_Bool ret; + Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); + Evas_Object_Protected_Data *obj2; + + if (obj->is_image_object) + { + if (*src_img) + { + /* more than one image object */ + *src_img = NULL; + return EINA_FALSE; + } + *src_img = obj->object; + } + else if (obj->is_smart) + { + EINA_INLIST_FOREACH + (evas_object_smart_members_get_direct(eo_obj), obj2) + { + ret = _map_source_image_get(obj2->object, src_img); + if (!ret) return ret; + } + } + + return EINA_TRUE; +} + +static void +_map_direct_render(Evas_Public_Data *evas, void *ctx, Evas_Object *src_img, + int w, int h, Evas_Object_Protected_Data *obj, + void *output, void *surface, int off_x, int off_y, + Eina_Bool do_async) +{ + int i; + Evas_Map_Point points[4]; + Evas_Map_Point *p; + + Evas_Object_Protected_Data *src_img_pd = efl_data_scope_get(src_img, EFL_CANVAS_OBJECT_CLASS); + const Evas_Object_Map_Data *tmap = src_img_pd->map; + + src_img_pd->map = obj->map; + + for (i = 0; i < obj->map->cur.map->count; i++) + { + p = obj->map->cur.map->points + i; + points[i].u = p->u; + points[i].v = p->v; + switch (i) + { + case 0: + p->u = 0; + p->v = 0; + break; + case 1: + p->u = w; + p->v = 0; + break; + case 2: + p->u = w; + p->v = h; + break; + case 3: + p->u = 0; + p->v = h; + break; + default: + break; + } + } + + src_img_pd->func->render(src_img, src_img_pd, src_img_pd->private_data, + ENC, output, ctx, surface, + off_x, off_y, do_async); + + for (i = 0; i < obj->map->cur.map->count; i++) + { + p = obj->map->cur.map->points + i; + p->u = points[i].u; + p->v = points[i].v; + } + + src_img_pd->map = tmap; +} +// + Eina_Bool evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *context, @@ -1952,6 +2042,36 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj, int sw, sh; Eina_Bool changed = EINA_FALSE, rendered = EINA_FALSE, pchanged = EINA_FALSE; + //TIZEN_ONLY(20210503): Add evas_map_direct_render_set + int src_img_w = 0; + int src_img_h = 0; + Evas_Object *direct_render_src_img = NULL; + if (obj->map->cur.map->direct_render && obj->map->cur.map->count == 4) + { + _map_source_image_get(eo_obj, &direct_render_src_img); + if (direct_render_src_img) + { + evas_object_image_size_get(direct_render_src_img, + &src_img_w, &src_img_h); + if (src_img_w == 0 || src_img_h == 0) + { + direct_render_src_img = NULL; + } + else + { + /* direct render will work, surface is not necessary */ + if (obj->map->surface) + { + ENFN->image_free(ENC, obj->map->surface); + EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write) + map_write->surface = NULL; + EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write); + } + } + } + } + // + clean_them = EINA_TRUE; sw = obj->cur->geometry.w; @@ -1975,7 +2095,12 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj, EINA_COW_WRITE_END(evas_object_map_cow, obj->map, map_write); } } + //TIZEN_ONLY(20210503): Add evas_map_direct_render_set + /* if (!obj->map->surface) + */ + if (!obj->map->surface && !direct_render_src_img) + // { EINA_COW_WRITE_BEGIN(evas_object_map_cow, obj->map, Evas_Object_Map_Data, map_write) { @@ -2093,7 +2218,12 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj, ENFN->context_clip_unset(ENC, ctx); //ENFN->context_multiplier_unset(ENC, ctx); // this probably should be here, too + //TIZEN_ONLY(20210503): Add evas_map_direct_render_set + /* if (obj->map->surface) + */ + if (obj->map->surface || direct_render_src_img) + // { Evas_Object_Protected_Data *mask = obj->clip.mask; @@ -2135,10 +2265,24 @@ evas_render_mapped(Evas_Public_Data *evas, Evas_Object *eo_obj, _c = ENFN->context_clip_get(ENC, ctx, &_cx, &_cy, &_cw, &_ch); RD(level, " draw image map(clip: [%d] %d,%d %dx%d)\n", _c, _cx, _cy, _cw, _ch); #endif + + //TIZEN_ONLY(20210503): Add evas_map_direct_render_set + if (direct_render_src_img) + { + _map_direct_render(evas, ctx, direct_render_src_img, + src_img_w, src_img_h, obj, output, + surface, off_x, off_y, do_async); + } + else + { + // evas_draw_image_map_async_check (obj, ENC, output, ctx, surface, obj->map->surface, obj->map->spans, obj->map->cur.map->smooth, 0, do_async); + //TIZEN_ONLY(20210503): Add evas_map_direct_render_set + } + // } } diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index aea246b..744de1b 100755 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -605,6 +605,9 @@ struct _Evas_Map } persp; Eina_Bool alpha : 1; Eina_Bool smooth : 1; + //TIZEN_ONLY(20210503): Add evas_map_direct_render_set + Eina_Bool direct_render : 1; + // struct { Eina_Bool enabled : 1; Evas_Coord diff_x, diff_y;