evas: enable dynamic flag for zero copy texture upload in ector / Bind to TEXTURE_EXT... 92/65892/1
authorhuiyu.eun <huiyu.eun@samsung.com>
Thu, 14 Apr 2016 01:02:12 +0000 (10:02 +0900)
committerhuiyu.eun <huiyu.eun@samsung.com>
Thu, 14 Apr 2016 01:04:40 +0000 (10:04 +0900)
This is backport from MCD TIZEN :
   commit ID : 8e2bc203d2cc2ea36123589f2eed70ef59b6a404a2dc65a843e02fd0932673caa21d6d81f00c19fc
   Author: Dongyeon Kim <dy5.kim@samsung.com>
   Date: 2015-10-13 16:07:18, 2015-10-01 10:05:28

[Title] evas: enable dynamic flag for zero copy texture upload in ector / Bind to TEXTURE_EXTERNAL for images with dynamic hint and tbm[Problem] Animation slow

[Cause] Texture uploading in Adreno is slow

[Solution] Remove texture uploading by enabling dynamic hint set
for images used in ector, and use GL_TEXTURE_EXTERNAL_OES target
for texture bound from tbm surface

[Team] Graphics

Change-Id: Iac74ab2a7ccb22dd58464da655e7a126f46ed03d
Signed-off-by: huiyu.eun <huiyu.eun@samsung.com>
src/lib/ector/software/ector_software_private.h
src/lib/ector/software/ector_software_rasterizer.c
src/lib/ector/software/ector_software_surface.c
src/lib/ector/software/ector_software_surface.eo
src/lib/evas/canvas/evas_object_vg.c
src/modules/evas/engines/gl_common/evas_gl_common.h
src/modules/evas/engines/gl_common/evas_gl_context.c
src/modules/evas/engines/gl_common/evas_gl_texture.c
src/modules/evas/engines/gl_generic/evas_engine.c
src/modules/evas/engines/software_generic/evas_engine.c

index a4d1221..fdbdb5c 100644 (file)
@@ -52,6 +52,7 @@ typedef struct _Raster_Buffer
 {
    int            width;
    int            height;
+   int            stride;
    DATA32        *buffer;
 } Raster_Buffer;
 
index 0cb74a0..d5d0479 100644 (file)
@@ -23,11 +23,11 @@ _blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
    comp_func = ector_comp_func_solid_span_get(data->op, color);
 
    // move to the offset location
-   buffer = data->raster_buffer.buffer + ((data->raster_buffer.width * data->offy) + data->offx);
+   buffer = data->raster_buffer.buffer + ((data->raster_buffer.stride / 4) * data->offy + data->offx);
 
    while (count--)
      {
-        target = buffer + ((data->raster_buffer.width * spans->y) + spans->x);
+        target = buffer + ((data->raster_buffer.stride / 4) * spans->y + spans->x);
         comp_func(target, spans->len, color, spans->coverage);
         ++spans;
      }
@@ -56,11 +56,11 @@ _blend_gradient(int count, const SW_FT_Span *spans, void *user_data)
    comp_func = ector_comp_func_span_get(data->op, data->mul_col, data->gradient->alpha);
 
    // move to the offset location
-   destbuffer = data->raster_buffer.buffer + ((data->raster_buffer.width * data->offy) + data->offx);
+   destbuffer = data->raster_buffer.buffer + ((data->raster_buffer.stride / 4) * data->offy + data->offx);
 
    while (count--)
      {
-        target = destbuffer + ((data->raster_buffer.width * spans->y) + spans->x);
+        target = destbuffer + ((data->raster_buffer.stride / 4) * spans->y + spans->x);
         length = spans->len;
         while (length)
           {
index 0391150..27fe0ae 100644 (file)
@@ -46,21 +46,29 @@ _ector_software_surface_context_get(Eo *obj EINA_UNUSED,
 void
 _ector_software_surface_surface_set(Eo *obj EINA_UNUSED,
                                     Ector_Software_Surface_Data *pd,
-                                    void *pixels, unsigned int width, unsigned int height)
+                                    void *pixels, unsigned int width,
+                                    unsigned int height, unsigned int stride)
 {
    pd->software->fill_data.raster_buffer.buffer = pixels;
    pd->software->fill_data.raster_buffer.width = width;
    pd->software->fill_data.raster_buffer.height = height;
+   pd->software->fill_data.raster_buffer.stride = stride;
 }
 
 void
 _ector_software_surface_surface_get(Eo *obj EINA_UNUSED,
                                     Ector_Software_Surface_Data *pd,
-                                    void **pixels, unsigned int *width, unsigned int *height)
+                                    void **pixels, unsigned int *width,
+                                    unsigned int *height, unsigned int *stride)
 {
-   *pixels = pd->software->fill_data.raster_buffer.buffer;
-   *width = pd->software->fill_data.raster_buffer.width;
-   *height = pd->software->fill_data.raster_buffer.height;
+   if (pixels)
+     *pixels = pd->software->fill_data.raster_buffer.buffer;
+   if (width)
+     *width = pd->software->fill_data.raster_buffer.width;
+   if (height)
+     *height = pd->software->fill_data.raster_buffer.height;
+   if (stride)
+     *stride = pd->software->fill_data.raster_buffer.stride;
 }
 
 static Eo *
index bea11cd..5d68e00 100644 (file)
@@ -5,23 +5,24 @@ class Ector.Software.Surface (Ector.Generic.Surface)
    methods {
       @property context {
          set {
-        }
-        get {
-        }
-        values {
-           ctx: Software_Rasterizer *;
-        }
+         }
+         get {
+         }
+         values {
+            ctx: Software_Rasterizer *;
+         }
       }
       @property surface {
          set {
-        }
-        get {
-        }
-        values {
-           pixels: void *;
-           width: uint;
-           height: uint;
-        }
+         }
+         get {
+         }
+         values {
+            pixels: void *;
+            width: uint;
+            height: uint;
+            stride: uint;
+         }
       }
    }
 
index aff87f8..54e3a31 100644 (file)
@@ -247,7 +247,7 @@ evas_object_vg_render(Evas_Object *eo_obj EINA_UNUSED,
              _evas_vg_render(obj, vd, output, context, vd->backing_store, vd->root, NULL,do_async);
              obj->layer->evas->engine.func->image_dirty_region(obj->layer->evas->engine.data.output, vd->backing_store,
                                                                0, 0, 0, 0);
-             obj->layer->evas->engine.func->ector_end(output, context, ector, surface, do_async);
+             obj->layer->evas->engine.func->ector_end(output, context, ector, vd->backing_store, do_async);
           }
         obj->layer->evas->engine.func->image_draw(output, context, surface,
                                                   vd->backing_store, 0, 0,
index dc1c352..9517bf4 100755 (executable)
@@ -666,6 +666,9 @@ Evas_GL_Polygon  *evas_gl_common_poly_point_add(Evas_GL_Polygon *poly, int x, in
 Evas_GL_Polygon  *evas_gl_common_poly_points_clear(Evas_GL_Polygon *poly);
 void              evas_gl_common_poly_draw(Evas_Engine_GL_Context *gc, Evas_GL_Polygon *poly, int x, int y);
 
+void              evas_gl_common_texture_shared_specific(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt, int i);
+void              evas_gl_common_texture_shared_back(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt);
+
 void              evas_gl_common_line_draw(Evas_Engine_GL_Context *gc, int x1, int y1, int x2, int y2);
 
 extern void       (*glsym_glGenFramebuffers)      (GLsizei a, GLuint *b);
index d57d094..266668b 100755 (executable)
@@ -1156,7 +1156,7 @@ evas_gl_common_context_newframe(Evas_Engine_GL_Context *gc)
    else glUseProgram(gc->state.current.cur_prog);
 
    glActiveTexture(GL_TEXTURE0);
-   glBindTexture(gc->pipe[0].shader.tex_target, gc->pipe[0].shader.cur_tex);
+   evas_gl_common_texture_shared_back(gc, NULL);
 
    _evas_gl_common_viewport_set(gc,1);
 }
@@ -3164,7 +3164,7 @@ shader_array_flush(Evas_Engine_GL_Context *gc)
                }
 #endif
              glActiveTexture(GL_TEXTURE0);
-             glBindTexture(gc->pipe[i].shader.tex_target, gc->pipe[i].shader.cur_tex);
+             evas_gl_common_texture_shared_specific(gc, NULL, i);
           }
         if (gc->pipe[i].array.im)
           {
index 9c31dda..0ecc218 100644 (file)
@@ -161,6 +161,31 @@ _evas_gl_texture_search_format(Eina_Bool alpha, Eina_Bool bgra, Evas_Colorspace
    return -1;
 }
 
+void
+evas_gl_common_texture_shared_specific(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt, int i)
+{
+   if (!pt || pt->texture != gc->pipe[i].shader.cur_tex)
+     {
+        if (gc->pipe[i].array.im)
+          {
+             if (gc->pipe[i].array.im->tex->pt->dyn.img)
+               gc->pipe[i].shader.tex_target = gc->pipe[i].array.im->tex->pt->dyn.target;
+             else
+               gc->pipe[i].shader.tex_target = gc->pipe[i].array.im->native.target;
+          }
+        else
+          gc->pipe[i].shader.tex_target = GL_TEXTURE_2D;
+
+        glBindTexture(gc->pipe[i].shader.tex_target, gc->pipe[i].shader.cur_tex);
+     }
+}
+
+void
+evas_gl_common_texture_shared_back(Evas_Engine_GL_Context *gc, Evas_GL_Texture_Pool *pt)
+{
+   evas_gl_common_texture_shared_specific(gc, pt, 0);
+}
+
 static void
 _print_tex_count(void)
 {
@@ -735,7 +760,10 @@ _pool_tex_dynamic_new(Evas_Engine_GL_Context *gc, int w, int h, int intformat, i
 
    _print_tex_count();
 
-   pt->dyn.target = GL_TEXTURE_2D;
+   if (gc->shared->info.sec_tbm_surface)
+     pt->dyn.target = GL_TEXTURE_EXTERNAL_OES;
+   else
+     pt->dyn.target = GL_TEXTURE_2D;
 
    glGenTextures(1, &(pt->texture));
    glBindTexture(pt->dyn.target, pt->texture);
index 22570e7..8fe092c 100644 (file)
@@ -2447,15 +2447,16 @@ static void
 eng_ector_renderer_draw(void *data, void *context, void *surface, Ector_Renderer *renderer, Eina_Array *clips EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
 {
    Evas_GL_Image *glimg = surface;
-   RGBA_Image *img = glimg->im;
    Evas_Engine_GL_Context *gc;
    Render_Engine_GL_Generic *re = data;
    Eina_Array *c;
    Eina_Rectangle *r;
+   int w, h;
+   eng_image_size_get(data, glimg, &w, &h);
 
    //TODO handle, clips properly
    c = eina_array_new(1);
-   eina_array_push(c, eina_rectangle_new(0, 0, img->cache_entry.w, img->cache_entry.h));
+   eina_array_push(c, eina_rectangle_new(0, 0, w, h));
 
    gc = re->window_gl_context_get(re->software.ob);
    gc->dc = context;
@@ -2477,23 +2478,22 @@ eng_ector_surface_create(void *data, void *surface, int width, int height)
    if (!surface)
      {
         surface = eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
+        //Use this hint for ZERO COPY texture upload.
+        eng_image_content_hint_set(data, surface, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
      }
    else
      {
         int cur_w , cur_h;
         glim = surface;
-        cur_w = glim->im->cache_entry.w;
-        cur_h = glim->im->cache_entry.h;
+        eng_image_size_get(data, glim, &cur_w, &cur_h);
         if (width != cur_w || height != cur_h)
           {
              eng_image_free(data, surface);
              surface =  eng_image_new_from_copied_data(data, width, height, NULL, EINA_TRUE, EVAS_COLORSPACE_ARGB8888);
+             //Use this hint for ZERO COPY texture upload.
+             eng_image_content_hint_set(data, surface, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
           }
       }
-   // clear the buffer
-   glim = surface;
-   void *pixels = evas_cache_image_pixels(&glim->im->cache_entry);
-   memset(pixels, 0, width * height *4);
    return surface;
 }
 
@@ -2501,12 +2501,15 @@ static void
 eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector,
                 void *surface, int x, int y, Eina_Bool do_async EINA_UNUSED)
 {
-   int w, h;
+   int w, h, stride;
    Evas_GL_Image *glim = surface;
    RGBA_Image *dst = glim->im;
-   w = dst->cache_entry.w;
-   h = dst->cache_entry.h;
+
    void *pixels = evas_cache_image_pixels(&dst->cache_entry);
+   eng_image_stride_get(data, glim, &stride);
+   eng_image_size_get(data, glim, &w, &h);
+   memset(pixels, 0, stride * h);
+
    if (use_cairo)
      {
         eo_do(ector,
@@ -2516,7 +2519,7 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface
    else
      {
         eo_do(ector,
-              ector_software_surface_set(pixels, w, h),
+              ector_software_surface_set(pixels, w, h, stride),
               ector_surface_reference_point_set(x, y));
      }
 }
@@ -2524,6 +2527,19 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface
 static void
 eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *ector, void *surface EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
 {
+   void *pixels = NULL;
+   if (use_cairo)
+     {
+        eo_do(ector,
+        ector_cairo_software_surface_get(&pixels, NULL, NULL));
+     }
+   else
+     {
+        eo_do(ector,
+        ector_software_surface_get(&pixels, NULL, NULL, NULL));
+     }
+   eng_image_data_put(data, surface, pixels);
+
    if (use_cairo)
      {
         eo_do(ector,
@@ -2532,7 +2548,7 @@ eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *
    else
      {
         eo_do(ector,
-              ector_software_surface_set(NULL, 0, 0));
+              ector_software_surface_set(NULL, 0, 0, 0));
      }
 }
 
index e5c9505..3c0e5e4 100644 (file)
@@ -3877,7 +3877,7 @@ _draw_thread_ector_surface_set(void *data)
    else
      {
         eo_do(ector_surface->ector,
-              ector_software_surface_set(pixels, w, h),
+              ector_software_surface_set(pixels, w, h, w * 4),
               ector_surface_reference_point_set(x, y));
      }
 
@@ -3927,7 +3927,7 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface
         else
           {
              eo_do(ector,
-                   ector_software_surface_set(pixels, w, h),
+                   ector_software_surface_set(pixels, w, h, w * 4),
                    ector_surface_reference_point_set(x, y));
           }
      }
@@ -3958,7 +3958,7 @@ eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *
         else
           {
              eo_do(ector,
-                   ector_software_surface_set(NULL, 0, 0));
+                   ector_software_surface_set(NULL, 0, 0, 0));
           }
 
         evas_common_cpu_end_opt();