From e35a4dd5cf81af2c78a8c40453d55f860cf67bdd Mon Sep 17 00:00:00 2001 From: Joogab Yun Date: Tue, 21 Nov 2017 14:13:23 +0900 Subject: [PATCH] evas_tbm : support ROI mode (tbm rot, flip, ratio) 1. color format of native tbm surface - sdk camera test - If a other flag setup before the SHD_EXTERNAL then color format problem happens 2. perform native buffer surface video rendering at evas object render level - Now origin size mode (when image size is smaller than evas object size) is supported 3. draw black rectangle image for native surface video when there is ratio value 4. don't use a clip in case of the tbm surface type. - message app -> new message -> attach -> camera -> change to front camera -> recoding -> flip is operated which each a clip 5. calculate flip flag before rotating 6. changed concept custom ROI mode @tizen_feature : support ROI mode Change-Id: I564b6131a46ae9dd1dba59a4a74c7d689486a3fa --- src/lib/evas/Evas_Legacy.h | 4 + src/lib/evas/canvas/evas_image_private.h | 1 + src/lib/evas/canvas/evas_object_image.c | 165 +++++++++++++++++++++ .../evas/engines/gl_common/evas_gl_common.h | 4 + .../evas/engines/gl_common/evas_gl_context.c | 110 +++++++++++++- .../engines/gl_common/shader/evas_gl_shaders.x | 6 +- .../evas/engines/gl_common/shader/fragment.glsl | 7 +- 7 files changed, 292 insertions(+), 5 deletions(-) mode change 100644 => 100755 src/lib/evas/Evas_Legacy.h mode change 100644 => 100755 src/lib/evas/canvas/evas_image_private.h mode change 100644 => 100755 src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x mode change 100644 => 100755 src/modules/evas/engines/gl_common/shader/fragment.glsl diff --git a/src/lib/evas/Evas_Legacy.h b/src/lib/evas/Evas_Legacy.h old mode 100644 new mode 100755 index 4a0f4d6..86c8fe6 --- a/src/lib/evas/Evas_Legacy.h +++ b/src/lib/evas/Evas_Legacy.h @@ -4503,6 +4503,10 @@ typedef struct _Evas_Native_Surface struct { void *buffer; /**< tbm surface buffer to use @since 1.14 */ + // TIZEN_ONLY(20171121) : support ROI mode (tbm rot, ratio, flip) + int rot; /**< rotation (EVAS_IMAGE_ORIENT_NONE, EVAS_IMAGE_ORIENT_90, EVAS_IMAGE_ORIENT_180, EVAS_IMAGE_ORIENT_270) @since 1.14 */ + float ratio; /**< width/height ratio of the source image @since 1.14 */ + int flip; /**< flip (EVAS_IMAGE_FLIP_HORIZONTAL:horizontal, EVAS_IMAGE_FLIP_VERTICAL:vertical) @since 1.14 */ } tbm; /**< Set this struct fields if surface data is Tizen based. @since 1.14 */ struct { diff --git a/src/lib/evas/canvas/evas_image_private.h b/src/lib/evas/canvas/evas_image_private.h old mode 100644 new mode 100755 index b4e0f27..da4cc0b --- a/src/lib/evas/canvas/evas_image_private.h +++ b/src/lib/evas/canvas/evas_image_private.h @@ -135,6 +135,7 @@ struct _Evas_Image_Data Eina_Bool direct_render : 1; Eina_Bool has_filter : 1; Eina_Bool buffer_data_set : 1; + Eina_Bool native_video : 1; // TIZEN_ONLY(20171121) : support ROI mode (tbm rot, flip, ratio) struct { Eina_Bool video_move : 1; diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 31302d1..e9021c0 100755 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -1020,6 +1020,11 @@ _evas_image_native_surface_set(Eo *eo_obj, Evas_Native_Surface *surf) (surf->version > EVAS_NATIVE_SURFACE_VERSION))) return EINA_FALSE; o->engine_data = ENFN->image_native_set(ENC, o->engine_data, surf); + // TIZEN_ONLY(20171121) : support ROI mode (tbm rot, flip, ratio) + if ((surf) && + (surf->type == EVAS_NATIVE_SURFACE_TBM)) + o->native_video = EINA_TRUE; + if (surf && surf->version > 4) { switch (surf->type) @@ -2101,6 +2106,166 @@ _evas_image_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, return; } + else + { + // TIZEN_ONLY(20171121) : support ROI mode (tbm rot, flip, ratio) + if (o->native_video) + { + // for native surface video rendering + Evas_Native_Surface *ns; + ns = ENFN->image_native_get(ENC, o->engine_data); + if (ns && (ns->type == EVAS_NATIVE_SURFACE_TBM)) + { + float ratio = ns->data.tbm.ratio; + + if (ratio > 0.01f || ratio == -1) + { + // we need to draw a black rectangle underneath the video + // since image dimensions will be different from object dimensions in case of letterbox mode + ENFN->context_color_set(engine, + context, + 0, 0, 0, 255); + ENFN->context_render_op_set(engine, context, EVAS_RENDER_COPY); + ENFN->rectangle_draw(engine, + output, + context, + surface, + obj->cur->geometry.x + x, + obj->cur->geometry.y + y, + obj->cur->geometry.w, + obj->cur->geometry.h, + do_async); + ENFN->context_render_op_set(engine, context, obj->cur->render_op); + ENFN->context_cutout_clear(ENC, context); + ENFN->context_clip_unset(ENC, context); + + ix = iy = 0; + int dstx, dsty; + if (ns->data.tbm.rot == EVAS_IMAGE_ORIENT_90 || ns->data.tbm.rot == EVAS_IMAGE_ORIENT_270) + { + /* ROI mode */ + if (ratio == -1) + { + if (ns->data.tbm.rot == EVAS_IMAGE_ORIENT_270) + { + dstx = obj->cur->geometry.x + (obj->cur->geometry.w - o->cur->fill.y - o->cur->fill.w); + dsty = obj->cur->geometry.y + o->cur->fill.x; + } + else + { + dstx = obj->cur->geometry.x + o->cur->fill.y; + dsty = obj->cur->geometry.y + (obj->cur->geometry.h - o->cur->fill.x - o->cur->fill.h); + } + } + /* letter box mode */ + else + { + if (o->cur->fill.w * ratio < o->cur->fill.h) + iy = (double)(o->cur->fill.h - (double)(o->cur->fill.w * ratio)) * 0.5f; + else if (o->cur->fill.w * ratio > o->cur->fill.h) + ix = (double)(o->cur->fill.w - (double)(o->cur->fill.h / ratio)) * 0.5f; + + dstx = obj->cur->geometry.x + o->cur->fill.x; + dsty = obj->cur->geometry.y + o->cur->fill.y; + } + } + else + { + + /* ROI mode */ + if (ratio == -1) + { + if (ns->data.tbm.rot == EVAS_IMAGE_ORIENT_180) + { + dstx = obj->cur->geometry.x + (obj->cur->geometry.w - o->cur->fill.x - o->cur->fill.w); + dsty = obj->cur->geometry.y + (obj->cur->geometry.h - o->cur->fill.y - o->cur->fill.h); + } + else + { + dstx = obj->cur->geometry.x + o->cur->fill.x; + dsty = obj->cur->geometry.y + o->cur->fill.y; + } + + } + /* letter box mode */ + else + { + if (o->cur->fill.w < o->cur->fill.h * ratio) + iy = (double)(o->cur->fill.h - (double)(o->cur->fill.w / ratio)) * 0.5f; + else if (o->cur->fill.w > o->cur->fill.h * ratio) + ix = (double)(o->cur->fill.w - (double)(o->cur->fill.h * ratio)) * 0.5f; + + dstx = obj->cur->geometry.x + o->cur->fill.x; + dsty = obj->cur->geometry.y + o->cur->fill.y; + } + } + + + ENFN->image_draw + (engine, output, context, surface, pixels, + 0, 0, + imagew, imageh, + dstx + ix, + dsty + iy, + o->cur->fill.w - ix * 2, + o->cur->fill.h - iy * 2, + o->cur->smooth_scale, + do_async); + } + else if ((obj->cur->geometry.w > o->cur->fill.w) || + (obj->cur->geometry.h > o->cur->fill.h)) + ENFN->image_draw(engine, + output, + context, + surface, + pixels, + 0, 0, + imagew, + imageh, + o->cur->fill.x + (o->cur->fill.w - imagew) / 2, + o->cur->fill.y + (o->cur->fill.h - imageh) / 2, + imagew, + imageh, + o->cur->smooth_scale, + do_async); + else + { + if ((o->cur->border.l == 0) && + (o->cur->border.r == 0) && + (o->cur->border.t == 0) && + (o->cur->border.b == 0) && + (o->cur->border.fill != 0)) + { + ENFN->image_draw(engine, output, context, surface, pixels, 0, 0, imagew, imageh, + obj->cur->geometry.x + o->cur->fill.x + x, obj->cur->geometry.y + o->cur->fill.y + y, + o->cur->fill.w, o->cur->fill.h, o->cur->smooth_scale, do_async); + } + else + { + if ((o->cur->border.fill == EVAS_BORDER_FILL_SOLID) && + (obj->cur->cache.clip.a == 255) && + (!obj->clip.mask) && + (obj->cur->render_op == EVAS_RENDER_BLEND)) + { + ENFN->context_render_op_set(engine, context, EVAS_RENDER_COPY); + ENFN->image_draw(engine, output, context, surface, pixels, 0, 0, imagew, imageh, + obj->cur->geometry.x + o->cur->fill.x + x, obj->cur->geometry.y + o->cur->fill.y + y, + o->cur->fill.w, o->cur->fill.h, o->cur->smooth_scale, do_async); + ENFN->context_render_op_set(engine, context, obj->cur->render_op); + } + else + { + ENFN->image_draw(engine, output, context, surface, pixels, 0, 0, imagew, imageh, + obj->cur->geometry.x + o->cur->fill.x + x, obj->cur->geometry.y + o->cur->fill.y + y, + o->cur->fill.w, o->cur->fill.h, o->cur->smooth_scale, do_async); + } + } + } + return; + } + } + } + ENFN->image_scale_hint_set(engine, pixels, o->scale_hint); idx = evas_object_image_figure_x_fill(eo_obj, obj, o->cur->fill.x, o->cur->fill.w, &idw); diff --git a/src/modules/evas/engines/gl_common/evas_gl_common.h b/src/modules/evas/engines/gl_common/evas_gl_common.h index a68ea82..4b2b16e 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -479,6 +479,10 @@ struct _Evas_GL_Image Eina_Bool yinvert : 1; Eina_Bool mipmap : 1; Eina_Bool loose : 1; + // TIZEN_ONLY(20171121) : support ROI mode (tbm rot, flip, ratio) + int rot; + int flip; + float ratio; } native; struct { diff --git a/src/modules/evas/engines/gl_common/evas_gl_context.c b/src/modules/evas/engines/gl_common/evas_gl_context.c index 76f1cd4..aac39d2 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_context.c +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c @@ -2224,13 +2224,14 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc, int yinvert = 0; Shader_Type shd_in = SHD_IMAGE; int tex_target = GL_TEXTURE_2D; - + Evas_Native_Surface *ens = NULL; // TIZEN_ONLY(20171121) : support ROI mode (tbm rot, flip, ratio) if (tex->im) { if (tex->im->native.data) shd_in = SHD_IMAGENATIVE; if (tex->im->native.target == GL_TEXTURE_EXTERNAL_OES) tex_target = GL_TEXTURE_EXTERNAL_OES; + ens = tex->im->native.data; // TIZEN_ONLY(20171121) : support ROI mode (tbm rot, flip, ratio) } if (!!mtex) @@ -2369,6 +2370,70 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc, SWAP(&sx, &sy, tmp); } + + // TIZEN_ONLY(20171121) : support ROI mode (tbm rot, flip, ratio) + if ((tex->im) && (tex->im->native.data) + && (ens) && (ens->type == EVAS_NATIVE_SURFACE_TBM)) + { + double tmp; + + if (tex->im && + (tex->im->native.flip == EVAS_IMAGE_FLIP_HORIZONTAL)) + { + sx = tex->im->w - sw - sx; + } + + if (tex->im->native.flip == EVAS_IMAGE_FLIP_VERTICAL) + { + sy = tex->im->h - sh - sy; + } + + if (tex->im->native.flip == EVAS_IMAGE_FLIP_TRANSVERSE) + { + double tmp; + + SWAP(&sw, &sh, tmp); + SWAP(&sx, &sy, tmp); + + sx = tex->im->w - sw - sx; + sy = tex->im->h - sh - sy; + } + + if (tex->im->native.rot == EVAS_IMAGE_ORIENT_90) + { + tmp = sx; sx = (tex->im->h - sy - sh) * tex->im->w / (double)tex->im->h; + sy = tmp * tex->im->h / (double)tex->im->w; + + tmp = sw; sw = sh * tex->im->w / (double)tex->im->h; + sh = tmp * tex->im->h / (double)tex->im->w; + } + + // both HORIZONTAL and VERTICAL flip + if (tex->im->native.rot == EVAS_IMAGE_ORIENT_180 + || tex->im->native.flip == EVAS_IMAGE_ORIENT_180) + { + sx = tex->im->w - sw - sx; + sy = tex->im->h - sh - sy; + } + + if (tex->im->native.rot == EVAS_IMAGE_ORIENT_270) + { + tmp = sy; sy = (tex->im->w - sx - sw) * tex->im->h / (double)tex->im->w; + sx = tmp * tex->im->w / (double)tex->im->h; + + tmp = sw; sw = sh * tex->im->w / (double)tex->im->h; + sh = tmp * tex->im->h / (double)tex->im->w; + } + + if (tex->im->native.flip == EVAS_IMAGE_FLIP_TRANSPOSE) + { + double tmp; + + SWAP(&sw, &sh, tmp); + SWAP(&sx, &sy, tmp); + } + } + ox1 = sx; oy1 = sy; ox2 = sx + sw; @@ -2418,6 +2483,49 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc, ERR("Wrong orientation ! %i", tex->im->orient); } } + // TIZEN_ONLY(20171121) : support ROI mode (tbm rot, flip, ratio) + else if ((tex->im) && (tex->im->native.data) + && (ens) && (ens->type == EVAS_NATIVE_SURFACE_TBM)) + { + switch (tex->im->native.rot) + { + case EVAS_IMAGE_ORIENT_NONE: + break; + case EVAS_IMAGE_ORIENT_90: + _rotate_270(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); + break; + case EVAS_IMAGE_ORIENT_180: + _rotate_180(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); + break; + case EVAS_IMAGE_ORIENT_270: + _rotate_90(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); + break; + default: + ERR("Wrong native rotation orientation ! %i", tex->im->native.rot); + } + switch (tex->im->native.flip) + { + case EVAS_IMAGE_ORIENT_NONE: + break; + case EVAS_IMAGE_ORIENT_180: + _rotate_180(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); + break; + case EVAS_IMAGE_FLIP_HORIZONTAL: + _flip_horizontal(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); + break; + case EVAS_IMAGE_FLIP_VERTICAL: + _flip_vertical(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); + break; + case EVAS_IMAGE_FLIP_TRANSVERSE: + _transverse(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); + break; + case EVAS_IMAGE_FLIP_TRANSPOSE: + _transpose(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); + break; + default: + ERR("Wrong native flip orientation ! %i", tex->im->native.flip); + } + } tx1 = ((double)(offsetx) + ox1) / pw; ty1 = ((double)(offsety) + oy1) / ph; diff --git a/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x b/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x old mode 100644 new mode 100755 index 1120163..8f5c56f --- a/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x +++ b/src/modules/evas/engines/gl_common/shader/evas_gl_shaders.x @@ -147,6 +147,8 @@ static const char fragment_glsl[] = " g = y - vmu;\n" " b = y + u;\n" " c = vec4(r, g, b, 1.0);\n" + "#elif defined(SHD_EXTERNAL)\n" + " c = texture2D(tex, tex_c);\n" "#elif defined(SHD_SAM12) || defined(SHD_SAM21)\n" " vec4 col00 = texture2D(tex, coord + tex_s[0]).SWZ;\n" " vec4 col01 = texture2D(tex, coord + tex_s[1]).SWZ;\n" @@ -157,8 +159,8 @@ static const char fragment_glsl[] = " vec4 col10 = texture2D(tex, coord + tex_s[2]).SWZ;\n" " vec4 col11 = texture2D(tex, coord + tex_s[3]).SWZ;\n" " c = (col00 + col01 + col10 + col11) / div_s;\n" - "#elif defined(SHD_TEX) || defined(SHD_EXTERNAL)\n" - " c = texture2D(tex, coord).SWZ;\n" + "#elif defined(SHD_TEX)\n" + " c = texture2D(tex, tex_c).SWZ;\n" "#else\n" " c = vec4(1, 1, 1, 1);\n" "#endif\n" diff --git a/src/modules/evas/engines/gl_common/shader/fragment.glsl b/src/modules/evas/engines/gl_common/shader/fragment.glsl old mode 100644 new mode 100755 index 89f3060..3404910 --- a/src/modules/evas/engines/gl_common/shader/fragment.glsl +++ b/src/modules/evas/engines/gl_common/shader/fragment.glsl @@ -154,6 +154,9 @@ vec4 fetch_pixel(float ox, float oy) b = y + u; c = vec4(r, g, b, 1.0); +#elif defined(SHD_EXTERNAL) + c = texture2D(tex, tex_c); + #elif defined(SHD_SAM12) || defined(SHD_SAM21) vec4 col00 = texture2D(tex, coord + tex_s[0]).SWZ; vec4 col01 = texture2D(tex, coord + tex_s[1]).SWZ; @@ -166,8 +169,8 @@ vec4 fetch_pixel(float ox, float oy) vec4 col11 = texture2D(tex, coord + tex_s[3]).SWZ; c = (col00 + col01 + col10 + col11) / div_s; -#elif defined(SHD_TEX) || defined(SHD_EXTERNAL) - c = texture2D(tex, coord).SWZ; +#elif defined(SHD_TEX) + c = texture2D(tex, tex_c).SWZ; #else c = vec4(1, 1, 1, 1); -- 2.7.4