Evas proxy: Implement buffer map/unmap
authorJean-Philippe Andre <jp.andre@samsung.com>
Fri, 25 Mar 2016 08:46:41 +0000 (17:46 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Mon, 28 Mar 2016 07:40:02 +0000 (16:40 +0900)
src/lib/evas/canvas/efl_canvas_image.c
src/lib/evas/canvas/efl_canvas_proxy.c
src/lib/evas/canvas/efl_canvas_proxy.eo
src/lib/evas/include/evas_private.h
src/modules/evas/engines/gl_generic/evas_engine.c
src/modules/evas/engines/software_generic/evas_engine.c

index 45e5d50..66d7b8c 100644 (file)
@@ -762,34 +762,39 @@ _efl_canvas_image_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
 {
    Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
    Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS);
-   int len = 0, str = 0;
+   int len = 0, s = 0, width = 0, height = 0;
    void *data = NULL;
 
    if (!ENFN->image_data_map)
      goto end; // not implemented
 
-   if (!o->engine_data)
+   if (o->engine_data)
+     ENFN->image_size_get(ENDT, o->engine_data, &width, &height);
+
+   if (!o->engine_data || !width || !height)
      {
-        if (o->cur->u.file)
-          ERR("image is not loaded yet");
+        // TODO: Create a map_surface and draw there. Maybe. This could
+        // depend on the flags (eg. add a "force render" flag).
+        WRN("This image image has no data available");
         goto end;
      }
 
-   if (!w) w = o->cur->image.w;
-   if (!h) h = o->cur->image.h;
+   if (!w) w = width;
+   if (!h) h = height;
 
-   if ((x < 0) || (y < 0) || ((x + (int) w) > (int) o->cur->image.w) || ((y + (int) h) > (int) o->cur->image.h))
+   if ((x < 0) || (y < 0) || ((x + w) > width) || ((y + h) > height))
      {
         ERR("Invalid map dimensions: %dx%d +%d,%d. Image is %dx%d.",
-            w, h, x, y, o->cur->image.w, o->cur->image.h);
+            w, h, x, y, width, height);
         goto end;
      }
 
-   data = ENFN->image_data_map(ENDT, &o->engine_data, &len, &str, x, y, w, h, cspace, mode);
+   data = ENFN->image_data_map(ENDT, &o->engine_data, &len, &s, x, y, w, h, cspace, mode);
+   DBG("map(%p, %d,%d %dx%d) -> %p (%d bytes)", eo_obj, x, y, w, h, data, len);
 
 end:
    if (length) *length = len;
-   if (stride) *stride = str;
+   if (stride) *stride = s;
    return data;
 }
 
@@ -803,7 +808,7 @@ _efl_canvas_image_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED,
    if (!ENFN->image_data_unmap || !o->engine_data)
      return EINA_FALSE;
 
-   if (!ENFN->image_data_unmap(ENDT, &o->engine_data, data, length))
+   if (!ENFN->image_data_unmap(ENDT, o->engine_data, data, length))
      return EINA_FALSE;
 
    return EINA_TRUE;
index 9648027..27d8170 100644 (file)
@@ -57,7 +57,7 @@ _evas_image_proxy_source_set(Eo *eo_obj, Evas_Object *eo_src)
 }
 
 EOLIAN static Eina_Bool
-_efl_canvas_proxy_source_set(Eo *eo_obj, void *pd EINA_UNUSED, Evas_Object *eo_src)
+_efl_canvas_proxy_source_set(Eo *eo_obj, void *_pd EINA_UNUSED, Evas_Object *eo_src)
 {
    return _evas_image_proxy_source_set(eo_obj, eo_src);
 }
@@ -70,7 +70,7 @@ _evas_image_proxy_source_get(const Eo *eo_obj)
 }
 
 EOLIAN static Evas_Object *
-_efl_canvas_proxy_source_get(Eo *eo_obj, void *pd EINA_UNUSED)
+_efl_canvas_proxy_source_get(Eo *eo_obj, void *_pd EINA_UNUSED)
 {
    return _evas_image_proxy_source_get(eo_obj);
 }
@@ -94,7 +94,7 @@ _evas_image_proxy_source_clip_set(Eo *eo_obj, Eina_Bool source_clip)
 }
 
 EOLIAN static void
-_efl_canvas_proxy_source_clip_set(Eo *eo_obj, void *pd EINA_UNUSED, Eina_Bool source_clip)
+_efl_canvas_proxy_source_clip_set(Eo *eo_obj, void *_pd EINA_UNUSED, Eina_Bool source_clip)
 {
    return _evas_image_proxy_source_clip_set(eo_obj, source_clip);
 }
@@ -107,7 +107,7 @@ _evas_image_proxy_source_clip_get(const Eo *eo_obj)
 }
 
 EOLIAN static Eina_Bool
-_efl_canvas_proxy_source_clip_get(Eo *eo_obj, void *pd EINA_UNUSED)
+_efl_canvas_proxy_source_clip_get(Eo *eo_obj, void *_pd EINA_UNUSED)
 {
    return _evas_image_proxy_source_clip_get(eo_obj);
 }
@@ -131,7 +131,7 @@ _evas_image_proxy_source_events_set(Eo *eo_obj, Eina_Bool source_events)
 }
 
 EOLIAN static void
-_efl_canvas_proxy_source_events_set(Eo *eo_obj, void *pd EINA_UNUSED, Eina_Bool repeat)
+_efl_canvas_proxy_source_events_set(Eo *eo_obj, void *_pd EINA_UNUSED, Eina_Bool repeat)
 {
    return _evas_image_proxy_source_events_set(eo_obj, repeat);
 }
@@ -144,7 +144,7 @@ _evas_image_proxy_source_events_get(const Eo *eo_obj)
 }
 
 EOLIAN static Eina_Bool
-_efl_canvas_proxy_source_events_get(Eo *eo_obj, void *pd EINA_UNUSED)
+_efl_canvas_proxy_source_events_get(Eo *eo_obj, void *_pd EINA_UNUSED)
 {
    return _evas_image_proxy_source_events_get(eo_obj);
 }
@@ -241,6 +241,92 @@ _evas_image_proxy_set(Evas_Object *eo_proxy, Evas_Object *eo_src)
    EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_src_write);
 }
 
+static inline void *
+_proxy_image_get(Evas_Image_Data *o)
+{
+   Evas_Object_Protected_Data *source = eo_data_scope_get(o->cur->source, EVAS_OBJECT_CLASS);
+   Evas_Image_Data *source_img = NULL;
+
+   if (!source)
+     return NULL;
+
+   if (eo_isa(o->cur->source, EVAS_IMAGE_CLASS))
+     source_img = eo_data_scope_get(o->cur->source, EVAS_IMAGE_CLASS);
+
+   if (source_img)
+     return source_img->engine_data;
+   else
+     return source->proxy->surface;
+}
+
+EOLIAN static void *
+_efl_canvas_proxy_efl_gfx_buffer_buffer_map(Eo *eo_obj, void *_pd EINA_UNUSED,
+                                            int *length,
+                                            Efl_Gfx_Buffer_Access_Mode mode,
+                                            int x, int y, int w, int h,
+                                            Efl_Gfx_Colorspace cspace, int *stride)
+{
+   Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+   Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS);
+   int len = 0, s = 0, width = 0, height = 0;
+   void *image, *data = NULL;
+
+   if (!ENFN->image_data_map)
+     goto end; // not implemented
+
+   if (mode & EFL_GFX_BUFFER_ACCESS_MODE_WRITE)
+     {
+        ERR("invalid map mode for Proxy object");
+        goto end;
+     }
+
+   image = _proxy_image_get(o);
+   if (image)
+     ENFN->image_size_get(ENDT, image, &width, &height);
+
+   if (!image || !width || !height)
+     {
+        // TODO: Create a map_surface and draw there. Maybe. This could
+        // depend on the flags (eg. add a "force render" flag).
+        WRN("This proxy image has no data available");
+        goto end;
+     }
+
+   if (!w) w = width;
+   if (!h) h = height;
+
+   if ((x < 0) || (y < 0) || ((x + w) > width) || ((y + h) > height))
+     {
+        ERR("Invalid map dimensions: %dx%d +%d,%d. Image is %dx%d.",
+            w, h, x, y, width, height);
+        goto end;
+     }
+
+   data = ENFN->image_data_map(ENDT, &image, &len, &s, x, y, w, h, cspace, mode);
+   DBG("map(%p, %d,%d %dx%d) -> %p (%d bytes)", eo_obj, x, y, w, h, data, len);
+
+end:
+   if (length) *length = len;
+   if (stride) *stride = s;
+   return data;
+}
+
+EOLIAN static Eina_Bool
+_efl_canvas_proxy_efl_gfx_buffer_buffer_unmap(Eo *eo_obj, void *_pd EINA_UNUSED,
+                                              void *data, int length)
+{
+   Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+   Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS);
+
+   if (!ENFN->image_data_unmap || !o->engine_data)
+     return EINA_FALSE;
+
+   if (!ENFN->image_data_unmap(ENDT, o->engine_data, data, length))
+     return EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
 /* Some moron just set a proxy on a proxy.
  * Give them some pixels.  A random color
  */
index 2c6f6b3..6c42aa7 100644 (file)
@@ -1,4 +1,4 @@
-class Efl.Canvas.Proxy (Evas.Image)
+class Efl.Canvas.Proxy (Evas.Image, Efl.Gfx.Buffer)
 {
    [[Low-level proxy image object.
 
@@ -73,5 +73,7 @@ class Efl.Canvas.Proxy (Evas.Image)
       }
    }
    implements {
+      Efl.Gfx.Buffer.buffer_map;
+      Efl.Gfx.Buffer.buffer_unmap;
    }
 }
index 92ef4b5..4a8b37a 100644 (file)
@@ -1361,9 +1361,10 @@ struct _Evas_Func
    Evas_Colorspace (*image_file_colorspace_get)(void *data, void *image);
    Eina_Bool (*image_can_region_get)       (void *data, void *image);
 
+   /* image data map/unmap: direct or indirect access to pixels data */
    void *(*image_data_map)                 (void *data, void **image, int *length, int *stride, int x, int y, int w, int h, Evas_Colorspace cspace, Efl_Gfx_Buffer_Access_Mode mode);
-   Eina_Bool (*image_data_unmap)           (void *data, void **image, void *map, int length);
-   int (*image_data_maps_get)              (void *data, void *image, void **maps, int *lengths);
+   Eina_Bool (*image_data_unmap)           (void *data, void *image, void *map, int length);
+   int (*image_data_maps_get)              (void *data, const void *image, void **maps, int *lengths);
 
    int (*image_native_init)                (void *data, Evas_Native_Surface_Type type);
    void (*image_native_shutdown)           (void *data, Evas_Native_Surface_Type type);
index cb25114..c46fb75 100644 (file)
@@ -2770,6 +2770,11 @@ module_open(Evas_Module *em)
         return 0;
      }
 
+   /* disable map/unmap for now as it's not implemented */
+   pfunc.image_data_map = NULL;
+   pfunc.image_data_unmap = NULL;
+   pfunc.image_data_maps_get = NULL;
+
    ector_init();
    ector_glsym_set(dlsym, RTLD_DEFAULT);
 
index 1d43e78..2d50fb3 100644 (file)
@@ -1666,17 +1666,15 @@ _image_data_commit(RGBA_Image *im, RGBA_Image_Data_Map *map)
 }
 
 static Eina_Bool
-eng_image_data_unmap(void *engdata EINA_UNUSED, void **image, void *memory, int length)
+eng_image_data_unmap(void *engdata EINA_UNUSED, void *image, void *memory, int length)
 {
    RGBA_Image_Data_Map *map;
-   RGBA_Image *im;
+   RGBA_Image *im = image;
    Eina_Bool found = EINA_FALSE;
 
-   if (!image || !*image || !memory)
+   if (!im || !memory)
      return EINA_FALSE;
 
-   im = *image;
-
    EINA_INLIST_FOREACH(EINA_INLIST_GET(im->maps), map)
      {
         if ((map->ptr == memory) && (map->size == length))
@@ -1702,10 +1700,10 @@ eng_image_data_unmap(void *engdata EINA_UNUSED, void **image, void *memory, int
 }
 
 static int
-eng_image_data_maps_get(void *engdata EINA_UNUSED, void *image, void **maps, int *lenghts)
+eng_image_data_maps_get(void *engdata EINA_UNUSED, const void *image, void **maps, int *lenghts)
 {
    RGBA_Image_Data_Map *map;
-   RGBA_Image *im = image;
+   const RGBA_Image *im = image;
    int k = 0;
 
    if (!im) return -1;