From 33dacf6e50cdc04d7c91e396a170ede3051a28ec Mon Sep 17 00:00:00 2001 From: Joogab Yun Date: Wed, 6 Apr 2016 12:05:36 +0900 Subject: [PATCH] support tbm rot, flip Change-Id: Ie0547222846446bb74bfe0c310f22870c23d93ab --- src/lib/evas/Evas_Common.h | 3 + src/lib/evas/canvas/evas_object_image.c | 44 +++ .../evas/engines/gl_common/evas_gl_common.h | 3 + .../evas/engines/gl_common/evas_gl_context.c | 369 +++++++++++++++------ src/modules/evas/engines/wayland_egl/evas_engine.c | 4 + 5 files changed, 329 insertions(+), 94 deletions(-) diff --git a/src/lib/evas/Evas_Common.h b/src/lib/evas/Evas_Common.h index a32d674..05a487f 100755 --- a/src/lib/evas/Evas_Common.h +++ b/src/lib/evas/Evas_Common.h @@ -364,6 +364,9 @@ struct _Evas_Native_Surface struct { void *buffer; /**< tbm surface buffer to use @since 1.14 */ + 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_object_image.c b/src/lib/evas/canvas/evas_object_image.c index f86deeb..c5f300f 100755 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -135,6 +135,7 @@ struct _Evas_Object_Image Eina_Bool written : 1; Eina_Bool direct_render : 1; Eina_Bool has_filter : 1; + Eina_Bool native_video : 1; struct { Eina_Bool video_move : 1; @@ -2135,6 +2136,9 @@ _evas_image_native_surface_set(Eo *eo_obj, Evas_Image_Data *o, Evas_Native_Surfa ((surf->version < 2) || (surf->version > EVAS_NATIVE_SURFACE_VERSION))) return; o->engine_data = ENFN->image_native_set(ENDT, o->engine_data, surf); + if ((surf) && + (surf->type == EVAS_NATIVE_SURFACE_TBM)) + o->native_video = EINA_TRUE; } EOLIAN static Evas_Native_Surface* @@ -3390,6 +3394,46 @@ _evas_image_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, } else { + if (o->native_video) + { + // for native surface video rendering + Evas_Native_Surface *ns; + ns = ENFN->image_native_get(ENDT, o->engine_data); + if (ns && (ns->type == EVAS_NATIVE_SURFACE_TBM)) + { + float ratio = ns->data.tbm.ratio; + if (ratio > 0.01f) + { + ix = iy = 0; + if (ns->data.tbm.rot == EVAS_IMAGE_ORIENT_90 || ns->data.tbm.rot == EVAS_IMAGE_ORIENT_270) + { + 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; + } + 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; + } + _draw_image + (obj, output, context, surface, pixels, + 0, 0, + imagew, imageh, + obj->cur->geometry.x + o->cur->fill.x + ix, + obj->cur->geometry.y + o->cur->fill.y + iy, + o->cur->fill.w - ix * 2, + o->cur->fill.h - iy * 2, + o->cur->smooth_scale, + do_async); + return; + } + } + } + int offx, offy; ENFN->image_scale_hint_set(output, pixels, o->scale_hint); 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 dc1c352..59ca10f 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_common.h +++ b/src/modules/evas/engines/gl_common/evas_gl_common.h @@ -430,6 +430,9 @@ struct _Evas_GL_Image int yinvert; int target; int mipmap; + int rot; + float ratio; + int flip; unsigned char loose : 1; } native; 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 d57d094..9064349 100755 --- a/src/modules/evas/engines/gl_common/evas_gl_context.c +++ b/src/modules/evas/engines/gl_common/evas_gl_context.c @@ -93,6 +93,11 @@ evas_gl_symbols(void *(*GetProcAddress)(const char *name)) #define FINDSYM2(dst, sym, typ) if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym) #define FALLBAK(dst, typ) if (!dst) dst = (typ)sym_missing +#define SWAP(a, b, tmp) \ + tmp = *a; \ + *a = *b; \ + *b = tmp; + #ifdef GL_GLES FINDSYM(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void); FINDSYM2(glsym_glGenFramebuffers, "glGenFramebuffers", glsym_func_void); @@ -2014,71 +2019,111 @@ again: PUSH_6_COLORS(pn, r, g, b, a); } +// 1-2 4-1 +// | | => | | +// 4-3 3-2 +static void +_rotate_90(double *x1, double *y1, double *x2, double *y2, double *x3, double *y3, double *x4, double *y4) +{ + double tmp; + + SWAP(x1, x4, tmp); + SWAP(y1, y4, tmp); + + SWAP(x4, x3, tmp); + SWAP(y4, y3, tmp); + + SWAP(x3, x2, tmp); + SWAP(y3, y2, tmp); +} + +// 1-2 3-4 +// | | => | | +// 4-3 2-1 +static void +_rotate_180(double *x1, double *y1, double *x2, double *y2, double *x3, double *y3, double *x4, double *y4) +{ + double tmp; + + SWAP(x1, x3, tmp); + SWAP(y1, y3, tmp); + + SWAP(x2, x4, tmp); + SWAP(y2, y4, tmp); +} + +// 1-2 2-3 +// | | => | | +// 4-3 1-4 static void -_rotate_point_90(double *x, double *y, double w, double h) +_rotate_270(double *x1, double *y1, double *x2, double *y2, double *x3, double *y3, double *x4, double *y4) { - double tx, ty, t; - - tx = *x - w / 2; - ty = *y - h / 2; - t = tx; - tx = ty; - ty = t; - tx = tx + h / 2; - ty = ty + w / 2; - *x = tx * h / w; - *y = w - ty * w / h; + double tmp; + + SWAP(x1, x2, tmp); + SWAP(y1, y2, tmp); + + SWAP(x2, x3, tmp); + SWAP(y2, y3, tmp); + + SWAP(x3, x4, tmp); + SWAP(y3, y4, tmp); } +// 1-2 2-1 +// | | => | | +// 4-3 3-4 static void -_rotate_point_180(double *x, double *y, double w, double h) +_flip_horizontal(double *x1, double *y1, double *x2, double *y2, double *x3, double *y3, double *x4, double *y4) { - double tx, ty; - - tx = *x - w / 2; - ty = *y - h / 2; - tx = -tx; - ty = -ty; - tx = tx + w / 2; - ty = ty + h / 2; - *x = tx; - *y = ty; + double tmp; + + SWAP(x1, x2, tmp); + SWAP(y1, y2, tmp); + + SWAP(x3, x4, tmp); + SWAP(y3, y4, tmp); } +// 1-2 4-3 +// | | => | | +// 4-3 1-2 static void -_rotate_point_270(double *x, double *y, double w, double h) +_flip_vertical(double *x1, double *y1, double *x2, double *y2, double *x3, double *y3, double *x4, double *y4) { - double tx, ty, t; - - tx = *x - h / 2; - ty = *y - w / 2; - t = tx; - tx = ty; - ty = t; - tx = tx + w / 2; - ty = ty + h / 2; - *x = h - tx * h / w; - *y = ty * w / h; + double tmp; + + SWAP(x1, x4, tmp); + SWAP(y1, y4, tmp); + + SWAP(x2, x3, tmp); + SWAP(y2, y3, tmp); } +// 1-2 1-4 +// | | => | | +// 4-3 2-3 static void -_transpose(double *x, double *y, double w, double h) +_transpose(double *x1 EINA_UNUSED, double *y1 EINA_UNUSED, double *x2, double *y2, + double *x3 EINA_UNUSED, double *y3 EINA_UNUSED, double *x4, double *y4) { - double t; + double tmp; - t = *x; - *x = *y * h / w; - *y = t * w / h; + SWAP(x2, x4, tmp); + SWAP(y2, y4, tmp); } +// 1-2 3-2 +// | | => | | +// 4-3 4-1 static void -_transverse(double *x, double *y, double w, double h) +_transverse(double *x1, double *y1, double *x2 EINA_UNUSED, double *y2 EINA_UNUSED, + double *x3, double *y3, double *x4 EINA_UNUSED, double *y4 EINA_UNUSED) { - double t; + double tmp; - t = *x; - *x = (w - *y) * h / w; - *y = (h - t) * w / h; + SWAP(x1, x3, tmp); + SWAP(y1, y3, tmp); } void @@ -2103,6 +2148,7 @@ 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; if (tex->im) { @@ -2110,6 +2156,7 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc, shd_in = SHD_IMAGENATIVE; if (tex->im->native.target == GL_TEXTURE_EXTERNAL_OES) tex_target = GL_TEXTURE_EXTERNAL_OES; + ens = tex->im->native.data; } if (!!mtex) @@ -2186,17 +2233,129 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc, pw = pt->w; ph = pt->h; + + if (tex->im && + (tex->im->orient == EVAS_IMAGE_ORIENT_90)) + { + double tmp; + + SWAP(&sw, &sh, tmp); + SWAP(&sx, &sy, tmp); + + sy = tex->im->h - sh - sy; + } + + if (tex->im && + (tex->im->orient == EVAS_IMAGE_ORIENT_180)) + { + sx = tex->im->w - sw - sx; + sy = tex->im->h - sh - sy; + } + + if (tex->im && + (tex->im->orient == EVAS_IMAGE_ORIENT_270)) + { + double tmp; + + SWAP(&sw, &sh, tmp); + SWAP(&sx, &sy, tmp); + + sx = tex->im->w - sw - sx; + } + + if (tex->im && + (tex->im->orient == EVAS_IMAGE_FLIP_HORIZONTAL)) + { + sx = tex->im->w - sw - sx; + } + + if (tex->im && + (tex->im->orient == EVAS_IMAGE_FLIP_VERTICAL)) + { + sy = tex->im->h - sh - sy; + } + if (tex->im && - (tex->im->orient == EVAS_IMAGE_ORIENT_90 || - tex->im->orient == EVAS_IMAGE_ORIENT_270 || - tex->im->orient == EVAS_IMAGE_FLIP_TRANSPOSE || - tex->im->orient == EVAS_IMAGE_FLIP_TRANSVERSE)) + (tex->im->orient == EVAS_IMAGE_FLIP_TRANSVERSE)) { - // Adjust size for taking rotation into account as im->w and h are already modified. - pw = pt->h; - ph = pt->w; + 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 && + (tex->im->orient == EVAS_IMAGE_FLIP_TRANSPOSE)) + { + double tmp; + + SWAP(&sw, &sh, tmp); + SWAP(&sx, &sy, tmp); + } + + + if ((tex->im) && (tex->im->native.data) + && (ens) && (ens->type == EVAS_NATIVE_SURFACE_TBM)) + { + double tmp; + 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 && + (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.flip == EVAS_IMAGE_FLIP_TRANSPOSE) + { + double tmp; + + SWAP(&sw, &sh, tmp); + SWAP(&sx, &sy, tmp); + } + } + ox1 = sx; oy1 = sy; ox2 = sx + sw; @@ -2222,68 +2381,90 @@ evas_gl_common_context_image_push(Evas_Engine_GL_Context *gc, case EVAS_IMAGE_ORIENT_NONE: break; case EVAS_IMAGE_ORIENT_90: - _rotate_point_90(&ox1, &oy1, tex->im->w, tex->im->h); - _rotate_point_90(&ox2, &oy2, tex->im->w, tex->im->h); - _rotate_point_90(&ox3, &oy3, tex->im->w, tex->im->h); - _rotate_point_90(&ox4, &oy4, tex->im->w, tex->im->h); + _rotate_90(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); break; case EVAS_IMAGE_ORIENT_180: - _rotate_point_180(&ox1, &oy1, tex->im->w, tex->im->h); - _rotate_point_180(&ox2, &oy2, tex->im->w, tex->im->h); - _rotate_point_180(&ox3, &oy3, tex->im->w, tex->im->h); - _rotate_point_180(&ox4, &oy4, tex->im->w, tex->im->h); + _rotate_180(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); break; case EVAS_IMAGE_ORIENT_270: - _rotate_point_270(&ox1, &oy1, tex->im->w, tex->im->h); - _rotate_point_270(&ox2, &oy2, tex->im->w, tex->im->h); - _rotate_point_270(&ox3, &oy3, tex->im->w, tex->im->h); - _rotate_point_270(&ox4, &oy4, tex->im->w, tex->im->h); + _rotate_270(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); break; case EVAS_IMAGE_FLIP_HORIZONTAL: - ox1 = tex->im->w - ox1; - ox2 = tex->im->w - ox2; - ox3 = tex->im->w - ox3; - ox4 = tex->im->w - ox4; + _flip_horizontal(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); break; case EVAS_IMAGE_FLIP_VERTICAL: - oy1 = tex->im->h - oy1; - oy2 = tex->im->h - oy2; - oy3 = tex->im->h - oy3; - oy4 = tex->im->h - oy4; + _flip_vertical(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); break; case EVAS_IMAGE_FLIP_TRANSVERSE: - _transverse(&ox1, &oy1, tex->im->w, tex->im->h); - _transverse(&ox2, &oy2, tex->im->w, tex->im->h); - _transverse(&ox3, &oy3, tex->im->w, tex->im->h); - _transverse(&ox4, &oy4, tex->im->w, tex->im->h); + _transverse(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); break; case EVAS_IMAGE_FLIP_TRANSPOSE: - _transpose(&ox1, &oy1, tex->im->w, tex->im->h); - _transpose(&ox2, &oy2, tex->im->w, tex->im->h); - _transpose(&ox3, &oy3, tex->im->w, tex->im->h); - _transpose(&ox4, &oy4, tex->im->w, tex->im->h); + _transpose(&ox1, &oy1, &ox2, &oy2, &ox3, &oy3, &ox4, &oy4); break; default: ERR("Wrong orientation ! %i", tex->im->orient); } } - - tx1 = ((double)(offsetx) + ox1) / pw; - ty1 = ((double)(offsety) + oy1) / ph; - tx2 = ((double)(offsetx) + ox2) / pw; - ty2 = ((double)(offsety) + oy2) / ph; - tx3 = ((double)(offsetx) + ox3) / pw; - ty3 = ((double)(offsety) + oy3) / ph; - tx4 = ((double)(offsetx) + ox4) / pw; - ty4 = ((double)(offsety) + oy4) / ph; - if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert)) + else if ((tex->im) && (tex->im->native.data) + && (ens) && (ens->type == EVAS_NATIVE_SURFACE_TBM)) { - ty1 = 1.0 - ty1; - ty2 = 1.0 - ty2; - ty3 = 1.0 - ty3; - ty4 = 1.0 - ty4; + switch (tex->im->native.rot) + { + case EVAS_IMAGE_ORIENT_NONE: + break; + case EVAS_IMAGE_ORIENT_90: + _rotate_90(&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_270(&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; + tx2 = ((double)(offsetx) + ox2) / pw; + ty2 = ((double)(offsety) + oy2) / ph; + tx3 = ((double)(offsetx) + ox3) / pw; + ty3 = ((double)(offsety) + oy3) / ph; + tx4 = ((double)(offsetx) + ox4) / pw; + ty4 = ((double)(offsety) + oy4) / ph; + if ((tex->im) && (tex->im->native.data) && (!tex->im->native.yinvert)) + { + ty1 = 1.0 - ty1; + ty2 = 1.0 - ty2; + ty3 = 1.0 - ty3; + ty4 = 1.0 - ty4; + } + + PUSH_6_VERTICES(pn, x, y, w, h); PUSH_6_QUAD(pn, tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4); diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.c b/src/modules/evas/engines/wayland_egl/evas_engine.c index 92a1f14..d77d122 100755 --- a/src/modules/evas/engines/wayland_egl/evas_engine.c +++ b/src/modules/evas/engines/wayland_egl/evas_engine.c @@ -1685,6 +1685,10 @@ eng_image_native_set(void *data, void *image, void *native) img->native.func.free = _native_cb_free; img->native.target = GL_TEXTURE_EXTERNAL_OES; img->native.mipmap = 0; + img->native.rot = ns->data.tbm.rot; + img->native.ratio = ns->data.tbm.ratio; + img->native.flip = ns->data.tbm.flip; + glsym_evas_gl_common_image_native_enable(img); } } -- 2.7.4