jpeg pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=93b4df1f5a506492bb322a9761b5379f5f9cf6ad
commit 93b4df1f5a506492bb322a9761b5379f5f9cf6ad Author: Minkyoung Kim <mer....@samsung.com> Date: Mon Jun 13 15:24:14 2016 +0900 evas-native-tbm: fix stride mismatch and allocate image data for converting from yuv to rgb. Summary: 1. For converting tbm buffer from yuv to rgb, image.data should be allocated. 2. Stride should be set by info of tbm surface. 3. The number of row is height*2. but if height is odd, last row is invalid in process of _evas_video_i420. Test Plan: Local Test, Tizen2.4 Mobile Reviewers: spacegrapher, wonsik, jpeg Subscribers: cedric, dkdk Differential Revision: https://phab.enlightenment.org/D3870 --- .../engines/software_generic/evas_native_common.h | 2 + .../engines/software_generic/evas_native_tbm.c | 45 +++++++++++++++++----- .../evas/engines/software_x11/evas_engine.c | 16 ++++++-- src/modules/evas/engines/wayland_shm/evas_engine.c | 16 ++++++-- 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/src/modules/evas/engines/software_generic/evas_native_common.h b/src/modules/evas/engines/software_generic/evas_native_common.h index 7bcc5ea..a13b7a0 100644 --- a/src/modules/evas/engines/software_generic/evas_native_common.h +++ b/src/modules/evas/engines/software_generic/evas_native_common.h @@ -107,11 +107,13 @@ struct _Native }; EAPI void *_evas_native_tbm_surface_image_set(void *data, void *image, void *native); +EAPI int _evas_native_tbm_surface_stride_get(void *data, void *native); EAPI int _evas_native_tbm_init(void); EAPI void _evas_native_tbm_shutdown(void); void *_evas_native_dmabuf_surface_image_set(void *image, void *native); typedef void *(*Evas_Native_Tbm_Surface_Image_Set_Call)(void *data, void *image, void *native); +typedef int (*Evas_Native_Tbm_Surface_Stride_Get_Call)(void *data, void *native); #endif //_EVAS_NATIVE_COMMON_H diff --git a/src/modules/evas/engines/software_generic/evas_native_tbm.c b/src/modules/evas/engines/software_generic/evas_native_tbm.c index 752d750..af6a1ab 100644 --- a/src/modules/evas/engines/software_generic/evas_native_tbm.c +++ b/src/modules/evas/engines/software_generic/evas_native_tbm.c @@ -66,6 +66,7 @@ typedef struct _tbm_surface_info /* returns 0 on success */ static int (*sym_tbm_surface_map) (tbm_surface_h surface, int opt, tbm_surface_info_s *info) = NULL; static int (*sym_tbm_surface_unmap) (tbm_surface_h surface) = NULL; +static int (*sym_tbm_surface_get_info) (tbm_surface_h surface, tbm_surface_info_s *info) = NULL; EAPI int _evas_native_tbm_init(void) @@ -100,6 +101,7 @@ _evas_native_tbm_init(void) fail = 0; SYM(tbm_lib, tbm_surface_map); SYM(tbm_lib, tbm_surface_unmap); + SYM(tbm_lib, tbm_surface_get_info); if (fail) { dlclose(tbm_lib); @@ -171,18 +173,18 @@ _evas_video_i420(unsigned char *evas_data, const unsigned char *source_data, uns rows = (const unsigned char **)evas_data; - stride_y = EVAS_ROUND_UP_4(w); - stride_uv = EVAS_ROUND_UP_8(w) / 2; + stride_y = w; + stride_uv = w / 2; for (i = 0; i < rh; i++) rows[i] = &source_data[i * stride_y]; - for (j = 0; j < (rh / 2); j++, i++) + for (j = 0; j < ((rh + 1) / 2); j++, i++) rows[i] = &source_data[h * stride_y + j * stride_uv]; for (j = 0; j < (rh / 2); j++, i++) rows[i] = &source_data[h * stride_y + - (rh / 2) * stride_uv + + ((rh + 1) / 2) * stride_uv + j * stride_uv]; } @@ -245,17 +247,40 @@ _native_free_cb(void *image) Native *n = im->native.data; if (!im) return; + im->native.data = NULL; im->native.func.bind = NULL; im->native.func.unbind = NULL; im->native.func.free = NULL; - im->image.data = NULL; free(n); _evas_native_tbm_shutdown(); } +EAPI int +_evas_native_tbm_surface_stride_get(void *data EINA_UNUSED, void *native) +{ + Evas_Native_Surface *ns = native; + tbm_surface_info_s info; + int stride; + + if (!ns) + return -1; + + if (!_evas_native_tbm_init()) + { + ERR("Could not initialize TBM!"); + return -1; + } + + if (sym_tbm_surface_get_info(ns->data.tbm.buffer, &info)) + return -1; + + stride = info.planes[0].stride; + return stride; + } + EAPI void * _evas_native_tbm_surface_image_set(void *data EINA_UNUSED, void *image, void *native) { @@ -277,13 +302,13 @@ _evas_native_tbm_surface_image_set(void *data EINA_UNUSED, void *image, void *na return NULL; tbm_surf = ns->data.tbm.buffer; - +/* if (!_evas_native_tbm_init()) { ERR("Could not initialize TBM!"); return NULL; } - +*/ n = calloc(1, sizeof(Native)); if (!n) return NULL; @@ -318,17 +343,17 @@ _evas_native_tbm_surface_image_set(void *data EINA_UNUSED, void *image, void *na /* borrowing code from emotion here */ case TBM_FORMAT_YVU420: /* EVAS_COLORSPACE_YCBCR422P601_PL */ evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_YCBCR422P601_PL); - _evas_video_yv12(im->cs.data, pixels_data, w, h, h); + _evas_video_yv12(im->cs.data, pixels_data, stride, h, h); evas_common_image_colorspace_dirty(im); break; case TBM_FORMAT_YUV420: /* EVAS_COLORSPACE_YCBCR422P601_PL */ evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_YCBCR422P601_PL); - _evas_video_i420(im->cs.data, pixels_data, w, h, h); + _evas_video_i420(im->cs.data, pixels_data, stride, h, h); evas_common_image_colorspace_dirty(im); break; case TBM_FORMAT_NV12: /* EVAS_COLORSPACE_YCBCR420NV12601_PL */ evas_cache_image_colorspace(&im->cache_entry, EVAS_COLORSPACE_YCBCR420NV12601_PL); - _evas_video_nv12(im->cs.data, pixels_data, w, h, h); + _evas_video_nv12(im->cs.data, pixels_data, stride, h, h); evas_common_image_colorspace_dirty(im); break; /* Not planning to handle those in software */ diff --git a/src/modules/evas/engines/software_x11/evas_engine.c b/src/modules/evas/engines/software_x11/evas_engine.c index 6db8840..fcb556b 100644 --- a/src/modules/evas/engines/software_x11/evas_engine.c +++ b/src/modules/evas/engines/software_x11/evas_engine.c @@ -32,7 +32,8 @@ # include <dlfcn.h> #endif -Evas_Native_Tbm_Surface_Image_Set_Call glsym_evas_native_tbm_surface_image_set = NULL; +Evas_Native_Tbm_Surface_Image_Set_Call glsym__evas_native_tbm_surface_image_set = NULL; +Evas_Native_Tbm_Surface_Stride_Get_Call glsym__evas_native_tbm_surface_stride_get = NULL; int _evas_engine_soft_x11_log_dom = -1; /* function tables - filled in later (func and parent func) */ @@ -432,7 +433,8 @@ _symbols(void) glsym_##sym = dlsym(RTLD_DEFAULT, #sym); // Get function pointer to native_common that is now provided through the link of SW_Generic. - LINK2GENERIC(evas_native_tbm_surface_image_set); + LINK2GENERIC(_evas_native_tbm_surface_image_set); + LINK2GENERIC(_evas_native_tbm_surface_stride_get); done = 1; } @@ -714,6 +716,7 @@ eng_image_native_set(void *data EINA_UNUSED, void *image, void *native) Evas_Native_Surface *ns = native; Image_Entry *ie = image, *ie2 = NULL; RGBA_Image *im = image; + int stride; if (!im) return NULL; if (!ns) @@ -755,6 +758,13 @@ eng_image_native_set(void *data EINA_UNUSED, void *image, void *native) ie2 = evas_cache_image_data(evas_common_image_cache_get(), ie->w, ie->h, ns->data.evasgl.surface, 1, EVAS_COLORSPACE_ARGB8888); + else if (ns->type == EVAS_NATIVE_SURFACE_TBM) + { + stride = glsym__evas_native_tbm_surface_stride_get(re->generic.ob, ns); + ie2 = evas_cache_image_copied_data(evas_common_image_cache_get(), + stride, ie->h, NULL, ie->flags.alpha, + EVAS_COLORSPACE_ARGB8888); + } else ie2 = evas_cache_image_data(evas_common_image_cache_get(), ie->w, ie->h, NULL, ie->flags.alpha, @@ -789,7 +799,7 @@ eng_image_native_set(void *data EINA_UNUSED, void *image, void *native) } else if (ns->type == EVAS_NATIVE_SURFACE_TBM) { - return glsym_evas_native_tbm_surface_image_set(re->generic.ob, ie, ns); + return glsym__evas_native_tbm_surface_image_set(re->generic.ob, ie, ns); } else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL) { diff --git a/src/modules/evas/engines/wayland_shm/evas_engine.c b/src/modules/evas/engines/wayland_shm/evas_engine.c index 07a5f22..9c3c631 100644 --- a/src/modules/evas/engines/wayland_shm/evas_engine.c +++ b/src/modules/evas/engines/wayland_shm/evas_engine.c @@ -17,7 +17,8 @@ int _evas_engine_way_shm_log_dom = -1; /* evas function tables - filled in later (func and parent func) */ static Evas_Func func, pfunc; -Evas_Native_Tbm_Surface_Image_Set_Call glsym_evas_native_tbm_surface_image_set = NULL; +Evas_Native_Tbm_Surface_Image_Set_Call glsym__evas_native_tbm_surface_image_set = NULL; +Evas_Native_Tbm_Surface_Stride_Get_Call glsym__evas_native_tbm_surface_stride_get = NULL; /* engine structure data */ typedef struct _Render_Engine Render_Engine; @@ -90,7 +91,8 @@ _symbols(void) glsym_##sym = dlsym(RTLD_DEFAULT, #sym); // Get function pointer to native_common that is now provided through the link of SW_Generic. - LINK2GENERIC(evas_native_tbm_surface_image_set); + LINK2GENERIC(_evas_native_tbm_surface_image_set); + LINK2GENERIC(_evas_native_tbm_surface_stride_get); done = 1; } @@ -260,6 +262,7 @@ eng_image_native_set(void *data EINA_UNUSED, void *image, void *native) Evas_Native_Surface *ns = native; Image_Entry *ie = image; RGBA_Image *im = image, *im2; + int stride; if (!im || !ns) return im; @@ -284,6 +287,13 @@ eng_image_native_set(void *data EINA_UNUSED, void *image, void *native) ie->w, ie->h, ns->data.x11.visual, 1, EVAS_COLORSPACE_ARGB8888); + else if (ns->type == EVAS_NATIVE_SURFACE_TBM) + { + stride = glsym__evas_native_tbm_surface_stride_get(NULL, ns); + im2 = evas_cache_image_copied_data(evas_common_image_cache_get(), + stride, ie->h, NULL, ie->flags.alpha, + EVAS_COLORSPACE_ARGB8888); + } else im2 = (RGBA_Image *)evas_cache_image_data(evas_common_image_cache_get(), ie->w, ie->h, @@ -305,7 +315,7 @@ eng_image_native_set(void *data EINA_UNUSED, void *image, void *native) im = im2; if (ns->type == EVAS_NATIVE_SURFACE_TBM) - return glsym_evas_native_tbm_surface_image_set(NULL, im, ns); + return glsym__evas_native_tbm_surface_image_set(NULL, im, ns); return im; } --