cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=412191e5f8390e11274f8098b1eb4e665dd3b1a0

commit 412191e5f8390e11274f8098b1eb4e665dd3b1a0
Author: Cedric BAIL <ced...@osg.samsung.com>
Date:   Thu Nov 19 13:15:51 2015 +0100

    ector: improve uploading of GL texture for vector graphism
    
    This rely on a faster code path to upload dynamic texture. Once we get 
support
    for gbm, we should see significant performance improvement in speed, but 
this
    first step is already a 5 times improvement (Ok, we get from really bad, to 
not
    really useful...).
---
 src/lib/evas/canvas/evas_object_vg.c               |  13 ++-
 src/lib/evas/include/evas_private.h                |   8 +-
 src/modules/evas/engines/gl_generic/evas_engine.c  | 103 +++++++++++++++------
 .../evas/engines/software_generic/evas_engine.c    |  21 ++++-
 4 files changed, 109 insertions(+), 36 deletions(-)

diff --git a/src/lib/evas/canvas/evas_object_vg.c 
b/src/lib/evas/canvas/evas_object_vg.c
index e50d787..a574aed 100644
--- a/src/lib/evas/canvas/evas_object_vg.c
+++ b/src/lib/evas/canvas/evas_object_vg.c
@@ -113,8 +113,13 @@ _cleanup_reference(void *data,
 void
 _evas_vg_eo_base_destructor(Eo *eo_obj, Evas_VG_Data *pd)
 {
+   Evas_Object_Protected_Data *obj;
    Evas *e = evas_object_evas_get(eo_obj);
 
+   obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+   if (pd->engine_data)
+     obj->layer->evas->engine.func->ector_free(pd->engine_data);
+
    eo_do(e, eo_event_callback_del(EVAS_CANVAS_EVENT_RENDER_POST, 
_cleanup_reference, pd));
 
    eo_unref(pd->root);
@@ -179,7 +184,7 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, 
Evas_VG_Data *vd,
 
         nd = eo_data_scope_get(n, EFL_VG_BASE_CLASS);
 
-        obj->layer->evas->engine.func->ector_renderer_draw(output, context, 
surface, nd->renderer, clips, do_async);
+        obj->layer->evas->engine.func->ector_renderer_draw(output, context, 
surface, vd->engine_data, nd->renderer, clips, do_async);
 
         if (do_async)
           eina_array_push(&vd->cleanup, eo_ref(nd->renderer));
@@ -202,6 +207,9 @@ evas_object_vg_render(Evas_Object *eo_obj EINA_UNUSED,
    // to another Ector_Surface as long as that Ector_Surface is a
    // child of the main Ector_Surface (necessary for Evas_Map).
 
+   if (!vd->engine_data)
+     vd->engine_data = obj->layer->evas->engine.func->ector_new(output, 
context, ector, surface);
+
    /* render object to surface with context, and offxet by x,y */
    obj->layer->evas->engine.func->context_color_set(output,
                                                     context,
@@ -221,13 +229,14 @@ evas_object_vg_render(Evas_Object *eo_obj EINA_UNUSED,
                                                         obj->cur->render_op);
    obj->layer->evas->engine.func->ector_begin(output, context,
                                               ector, surface,
+                                              vd->engine_data,
                                               obj->cur->geometry.x + x, 
obj->cur->geometry.y + y,
                                               do_async);
    _evas_vg_render(obj, vd,
                    output, context, surface,
                    vd->root, NULL,
                    do_async);
-   obj->layer->evas->engine.func->ector_end(output, context, ector, surface, 
do_async);
+   obj->layer->evas->engine.func->ector_end(output, context, ector, surface, 
vd->engine_data, do_async);
 }
 
 static void
diff --git a/src/lib/evas/include/evas_private.h 
b/src/lib/evas/include/evas_private.h
index 92c4444..26868c1 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1448,9 +1448,11 @@ struct _Evas_Func
 
    Ector_Surface *(*ector_create)        (void *data);
    void  (*ector_destroy)                (void *data, Ector_Surface *surface);
-   void  (*ector_begin)                  (void *data, void *context, 
Ector_Surface *ector, void *surface, int x, int y, Eina_Bool do_async);
-   void  (*ector_renderer_draw)          (void *data, void *context, void 
*surface, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
-   void  (*ector_end)                    (void *data, void *context, 
Ector_Surface *ector, void *surface, Eina_Bool do_async);
+   void  (*ector_begin)                  (void *data, void *context, 
Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool 
do_async);
+   void  (*ector_renderer_draw)          (void *data, void *context, void 
*surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool 
do_async);
+   void  (*ector_end)                    (void *data, void *context, 
Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async);
+   void* (*ector_new)                    (void *data, void *context, 
Ector_Surface *ector, void *surface);
+   void  (*ector_free)                   (void *engine_data);
 };
 
 struct _Evas_Image_Save_Func
diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c 
b/src/modules/evas/engines/gl_generic/evas_engine.c
index 8278b05..d9b42ea 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -721,6 +721,7 @@ eng_image_data_get(void *data, void *image, int to_write, 
DATA32 **image_data, i
    if (!im)
      {
         if (err) *err = EVAS_LOAD_ERROR_GENERIC;
+        ERR("No image provided.");
         return NULL;
      }
 
@@ -734,6 +735,7 @@ eng_image_data_get(void *data, void *image, int to_write, 
DATA32 **image_data, i
         if (!im_new)
           {
              if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+             ERR("Rotation failed.");
              return im;
           }
         evas_gl_common_image_free(im);
@@ -745,7 +747,7 @@ eng_image_data_get(void *data, void *image, int to_write, 
DATA32 **image_data, i
 #ifdef GL_GLES
    re->window_use(re->software.ob);
 
-   if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) && 
+   if ((im->tex) && (im->tex->pt) && (im->tex->pt->dyn.img) &&
        (im->cs.space == EVAS_COLORSPACE_ARGB8888))
      {
         if (im->tex->pt->dyn.checked_out > 0)
@@ -779,6 +781,7 @@ eng_image_data_get(void *data, void *image, int to_write, 
DATA32 **image_data, i
         if (!im->tex->pt->dyn.data)
           {
              if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+             ERR("Ressource allocation failed.");
              return im;
           }
         im->tex->pt->dyn.checked_out++;
@@ -821,6 +824,7 @@ eng_image_data_get(void *data, void *image, int to_write, 
DATA32 **image_data, i
         if (!ok)
           {
              if (err) *err = EVAS_LOAD_ERROR_GENERIC;
+             ERR("Lock failed.");
              return NULL;
           }
 
@@ -830,6 +834,7 @@ eng_image_data_get(void *data, void *image, int to_write, 
DATA32 **image_data, i
         if (!im_new)
           {
              if (err) *err = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+             ERR("Allocation failed.");
              return NULL;
           }
 
@@ -840,6 +845,7 @@ eng_image_data_get(void *data, void *image, int to_write, 
DATA32 **image_data, i
         if (!ok)
           {
              if (err) *err = EVAS_LOAD_ERROR_GENERIC;
+             ERR("Unlock failed.");
              return NULL;
           }
         *image_data = im_new->im->image.data;
@@ -974,6 +980,7 @@ eng_image_data_put(void *data, void *image, DATA32 
*image_data)
               evas_gl_common_image_free(im);
               im = im2;
            }
+         evas_gl_common_image_dirty(im, 0, 0, 0, 0);
          break;
       case EVAS_COLORSPACE_YCBCR422P601_PL:
       case EVAS_COLORSPACE_YCBCR422P709_PL:
@@ -2460,7 +2467,7 @@ _evas_render_op_to_ector_rop(Evas_Render_Op op)
 }
 
 static void
-eng_ector_renderer_draw(void *data, void *context, void *surface, 
Ector_Renderer *renderer, Eina_Array *clips, Eina_Bool do_async EINA_UNUSED)
+eng_ector_renderer_draw(void *data, void *context, void *surface, void 
*engine_data EINA_UNUSED, Ector_Renderer *renderer, Eina_Array *clips, 
Eina_Bool do_async EINA_UNUSED)
 {
    Evas_GL_Image *dst = surface;
    Evas_Engine_GL_Context *gc;
@@ -2526,16 +2533,43 @@ eng_ector_renderer_draw(void *data, void *context, void 
*surface, Ector_Renderer
    eina_array_free(c);
 }
 
-static void *software_buffer = NULL;
+typedef struct _Evas_GL_Ector Evas_GL_Ector;
+struct _Evas_GL_Ector
+{
+   Evas_GL_Image *gl;
+   DATA32 *software;
+
+   Eina_Bool tofree;
+};
+
+static void*
+eng_ector_new(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface 
*ector EINA_UNUSED, void *surface EINA_UNUSED)
+{
+   Evas_GL_Ector *r;
+
+   r = calloc(1, sizeof (Evas_GL_Ector));
+   return r;
+}
+
+static void
+eng_ector_free(void *engine_data)
+{
+   Evas_GL_Ector *r = engine_data;
+
+   if (r->gl) evas_gl_common_image_free(r->gl);
+   if (r->tofree) free(r->software);
+   free(r);
+}
 
 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)
+eng_ector_begin(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
+                void *surface, void *engine_data,
+                int x, int y, Eina_Bool do_async EINA_UNUSED)
 {
    Evas_Engine_GL_Context *gl_context;
    Render_Engine_GL_Generic *re = data;
+   Evas_GL_Ector *buffer = engine_data;
    int w, h;
-   void *temp;
 
    re->window_use(re->software.ob);
    gl_context = re->window_gl_context_get(re->software.ob);
@@ -2544,36 +2578,51 @@ eng_ector_begin(void *data EINA_UNUSED, void *context 
EINA_UNUSED, Ector_Surface
 
    w = gl_context->w; h = gl_context->h;
 
-   temp = software_buffer;
-   software_buffer = realloc(software_buffer, sizeof (unsigned int) * w * h);
-   if (!software_buffer)
+   if (!buffer->gl || buffer->gl->w != w || buffer->gl->h != h)
      {
-        ERR("Realloc failed!!");
-        software_buffer = temp;
-        return;
+        int err = EVAS_LOAD_ERROR_NONE;
+
+        if (buffer->gl) evas_gl_common_image_free(buffer->gl);
+        if (buffer->tofree) free(buffer->software);
+        buffer->software = NULL;
+
+        buffer->gl = evas_gl_common_image_new(gl_context, w, h, 1, 
EVAS_COLORSPACE_ARGB8888);
+        if (!buffer->gl)
+          {
+             ERR("Creation of an image for vector graphics [%i, %i] failed\n", 
w, h);
+             return ;
+          }
+        /* evas_gl_common_image_content_hint_set(buffer->gl, 
EVAS_IMAGE_CONTENT_HINT_DYNAMIC); */
+        buffer->gl = eng_image_data_get(data, buffer->gl, 1, 
&buffer->software, &err, &buffer->tofree);
+        if (!buffer->gl && err != EVAS_LOAD_ERROR_NONE)
+          {
+             ERR("Mapping of an image for vector graphics [%i, %i] failed with 
%i\n", w, h, err);
+             return ;
+          }
      }
-   memset(software_buffer, 0, sizeof (unsigned int) * w * h);
+   memset(buffer->software, 0, sizeof (unsigned int) * w * h);
    if (use_cairo)
      {
         eo_do(ector,
-              ector_cairo_software_surface_set(software_buffer, w, h),
+              ector_cairo_software_surface_set(buffer->software, w, h),
               ector_surface_reference_point_set(x, y));
      }
    else
      {
         eo_do(ector,
-              ector_software_surface_set(software_buffer, w, h),
+              ector_software_surface_set(buffer->software, w, h),
               ector_surface_reference_point_set(x, y));
      }
 }
 
 static void
 eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
-              void *surface EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
+              void *surface EINA_UNUSED, void *engine_data,
+              Eina_Bool do_async EINA_UNUSED)
 {
    Evas_Engine_GL_Context *gl_context;
    Render_Engine_GL_Generic *re = data;
-   Evas_GL_Image *im;
+   Evas_GL_Ector *buffer = engine_data;
    int w, h;
    Eina_Bool mul_use;
 
@@ -2592,24 +2641,22 @@ eng_ector_end(void *data, void *context EINA_UNUSED, 
Ector_Surface *ector,
               ector_software_surface_set(NULL, 0, 0));
      }
 
-   im = evas_gl_common_image_new_from_copied_data(gl_context, w, h, 
software_buffer, 1, EVAS_COLORSPACE_ARGB8888);
+   eng_image_data_put(data, buffer->gl, buffer->software);
 
    if (!mul_use)
-   {
-      // @hack as image_draw uses below fields to do colour multiplication.
-      gl_context->dc->mul.col = 
ector_color_multiply(0xffffffff,gl_context->dc->col.col);
-      gl_context->dc->mul.use = EINA_TRUE;
-   }
-   
+     {
+        // @hack as image_draw uses below fields to do colour multiplication.
+        gl_context->dc->mul.col = ector_color_multiply(0xffffffff, 
gl_context->dc->col.col);
+        gl_context->dc->mul.use = EINA_TRUE;
+     }
+
    // We actually just bluntly push the pixel all over the
    // destination surface. We don't have the actual information
    // of the widget size. This is not a problem.
    // Later on, we don't want that information and today when
    // using GL backend, you just need to turn on Evas_Map on
    // the Evas_Object_VG.
-   evas_gl_common_image_draw(gl_context, im, 0, 0, w, h, 0, 0, w, h, 0);
-
-   evas_gl_common_image_free(im);
+   evas_gl_common_image_draw(gl_context, buffer->gl, 0, 0, w, h, 0, 0, w, h, 
0);
 
    // restore gl state
    gl_context->dc->mul.use = mul_use;
@@ -2764,6 +2811,8 @@ module_open(Evas_Module *em)
    ORD(ector_begin);
    ORD(ector_renderer_draw);
    ORD(ector_end);
+   ORD(ector_new);
+   ORD(ector_free);
 
    /* now advertise out own api */
    em->functions = (void *)(&func);
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c 
b/src/modules/evas/engines/software_generic/evas_engine.c
index 3d26fc6..e148813 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -3795,7 +3795,7 @@ _draw_thread_ector_draw(void *data)
 }
 
 static void
-eng_ector_renderer_draw(void *data EINA_UNUSED, void *context, void *surface, 
Ector_Renderer *renderer, Eina_Array *clips, Eina_Bool do_async)
+eng_ector_renderer_draw(void *data EINA_UNUSED, void *context, void *surface, 
void *engine_data EINA_UNUSED, Ector_Renderer *renderer, Eina_Array *clips, 
Eina_Bool do_async)
 {
    RGBA_Image *dst = surface;
    RGBA_Draw_Context *dc = context;
@@ -3919,8 +3919,19 @@ _draw_thread_ector_surface_set(void *data)
    eina_mempool_free(_mp_command_ector_surface, ector_surface);
 }
 
+static void*
+eng_ector_new(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface 
*ector EINA_UNUSED, void *surface EINA_UNUSED)
+{
+   return NULL;
+}
+
+static void
+eng_ector_free(void *engine_data EINA_UNUSED)
+{
+}
+
 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)
+eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, 
Ector_Surface *ector, void *surface, void *engine_data EINA_UNUSED, int x, int 
y, Eina_Bool do_async)
 {
    if (do_async)
      {
@@ -3963,7 +3974,7 @@ 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)
+eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface 
*ector, void *surface EINA_UNUSED, void *engine_data EINA_UNUSED, Eina_Bool 
do_async)
 {
    if (do_async)
      {
@@ -4182,7 +4193,9 @@ static Evas_Func func =
      eng_ector_destroy,
      eng_ector_begin,
      eng_ector_renderer_draw,
-     eng_ector_end
+     eng_ector_end,
+     eng_ector_new,
+     eng_ector_free
    /* FUTURE software generic calls go here */
 };
 

-- 


Reply via email to