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;
 }

-- 


Reply via email to