jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=5e075c193c51201071b8efc950b49b45b9caa92c

commit 5e075c193c51201071b8efc950b49b45b9caa92c
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Fri Dec 11 15:23:55 2015 +0900

    ector: on-the-fly convert sw buffers during map()
    
    Also use map to generate spans.
    This should simplify some filters code, making things work,
    albeit inefficiently. At least they should work.
    
    Fix doc too.
---
 src/lib/ector/ector_buffer.h                   |   1 -
 src/lib/ector/ector_generic_buffer.eo          |  20 +++--
 src/lib/ector/software/ector_software_buffer.c | 109 ++++++++++++-------------
 3 files changed, 62 insertions(+), 68 deletions(-)

diff --git a/src/lib/ector/ector_buffer.h b/src/lib/ector/ector_buffer.h
index f4a5f9d..0e12c79 100644
--- a/src/lib/ector/ector_buffer.h
+++ b/src/lib/ector/ector_buffer.h
@@ -35,7 +35,6 @@ typedef struct _Ector_Software_Buffer_Base_Data
    } internal;
    Eina_Bool            writable : 1; // pixels can be written to
    Eina_Bool            nofree : 1; // pixel data should not be free()'ed
-   Eina_Bool            span_free : 1; // FIXME
 } Ector_Software_Buffer_Base_Data;
 
 #endif
diff --git a/src/lib/ector/ector_generic_buffer.eo 
b/src/lib/ector/ector_generic_buffer.eo
index 8f98108..6e735b3 100644
--- a/src/lib/ector/ector_generic_buffer.eo
+++ b/src/lib/ector/ector_generic_buffer.eo
@@ -40,17 +40,21 @@ mixin Ector.Generic.Buffer
       }
       map {
         [[Map a region of this buffer for read or write access by the CPU,
-          fetch data from the GPU if needed.
+          fetch data from the GPU if needed. This operation may be slow if
+          cpu_readable_fast or cpu_writeable_fast are not true, or if the
+          required colorspace is different from the internal one.
         ]]
         params {
-           @out length: uint; [[Accessible buffer size in bytes]]
-           @in mode: Ector.Buffer.Access_Flag;
-           @in x: uint;
-           @in y: uint;
+           @out length: uint; [[Accessible buffer size in bytes, should not be 
$null.]]
+           @in mode: Ector.Buffer.Access_Flag; [[Specifies whether to map for 
read-only,
+                                                 write-only or read-write 
access (OR combinaison of flags).]]
+           @in x: uint; [[X position of the top-left pixel to map]]
+           @in y: uint; [[Y position of the top-left pixel to map]]
            @in w: uint; [[If 0, defaults to the buffer width]]
            @in h: uint; [[If 0, defaults to the buffer height]]
-           @in cspace: Efl.Gfx.Colorspace; [[Requested colorspace. If 
difference from the internal cspace, map may either fail or convert slowly]]
-           @out stride: uint; [[Optional]]
+           @in cspace: Efl.Gfx.Colorspace; [[Requested colorspace. If differen 
from the internal cspace,
+                                             map should try to convert the 
data into a new buffer]]
+           @out stride: uint @optional; [[Returns the length in bytes of a 
mapped line]]
         }
         return: void* @warn_unused; [[Pointer to the top-left pixel data. 
Returns $null in case of failure]]
       }
@@ -58,7 +62,7 @@ mixin Ector.Generic.Buffer
         [[Unmap a region of this buffer, and upload data to the GPU (if 
needed).]]
         params {
            @in data: void*; [[Data pointer returned by a previous call to map]]
-           @in length: uint;
+           @in length: uint; [[Must be the same as returned
         }
       }
       pixels_set {
diff --git a/src/lib/ector/software/ector_software_buffer.c 
b/src/lib/ector/software/ector_software_buffer.c
index 1783258..e64234d 100644
--- a/src/lib/ector/software/ector_software_buffer.c
+++ b/src/lib/ector/software/ector_software_buffer.c
@@ -16,7 +16,7 @@ typedef struct _Ector_Software_Buffer_Map
 {
    EINA_INLIST;
    void *ptr;
-   unsigned int len;
+   unsigned int size; // in bytes
    Eina_Bool allocated;
 } Ector_Software_Buffer_Map;
 
@@ -142,8 +142,11 @@ _ector_software_buffer_base_ector_generic_buffer_map(Eo 
*obj EINA_UNUSED, Ector_
                                                      unsigned int x, unsigned 
int y, unsigned int w, unsigned int h,
                                                      Efl_Gfx_Colorspace cspace 
EINA_UNUSED, unsigned int *stride)
 {
-   Ector_Software_Buffer_Map *map;
-   int off;
+   Ector_Software_Buffer_Map *map = NULL;
+   unsigned int off, k;
+
+   if (!w) w = pd->generic->w;
+   if (!h) h = pd->generic->h;
 
    if (!pd->pixels.u8 || !pd->stride)
      fail("Buffer has no pixel data yet");
@@ -153,20 +156,46 @@ _ector_software_buffer_base_ector_generic_buffer_map(Eo 
*obj EINA_UNUSED, Ector_
      fail("Invalid region requested: wanted %u,%u %ux%u but image is %ux%u",
           x, y, w, h, pd->generic->w, pd->generic->h);
    if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) && !pd->writable)
-     fail("can not map a read-only buffer for writing");
+     fail("Can not map a read-only buffer for writing");
+
+   map = calloc(1, sizeof(*map));
+   if (!map) fail("Out of memory");
 
    off = _min_stride_calc(x + pd->generic->l, pd->generic->cspace) + 
(pd->stride * (y + pd->generic->t));
 
-   map = calloc(1, sizeof(*map));
-   map->len = (pd->stride * h) - off;
-   map->ptr = pd->pixels.u8 + off;
-   pd->internal.maps = eina_inlist_append(pd->internal.maps, 
EINA_INLIST_GET(map));
+   if (cspace != pd->generic->cspace)
+     {
+        // convert on the fly
+        map->size = _min_stride_calc(w, cspace) * h;
+        map->allocated = EINA_TRUE;
+        map->ptr = malloc(map->size);
+        if (!map->ptr) fail("Out of memory");
+        if (stride) *stride = _min_stride_calc(w, cspace);
+
+        if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
+          {
+             for (k = 0; k < h; k++)
+               _pixels_gry8_to_argb_convert((uint32_t *) map->ptr + (k * w), 
pd->pixels.u8 + off + (k * pd->stride), w);
+          }
+        else
+          {
+             for (k = 0; k < h; k++)
+               _pixels_argb_to_gry8_convert((uint8_t *) map->ptr + (k * w), 
(uint32_t *) (pd->pixels.u8 + off + (k * pd->stride)), w);
+          }
+     }
+   else
+     {
+        map->size = (pd->stride * h) - off;
+        map->ptr = pd->pixels.u8 + off;
+        if (stride) *stride = pd->stride;
+     }
 
-   if (length) *length = map->len;
-   if (stride) *stride = pd->stride;
+   pd->internal.maps = eina_inlist_prepend(pd->internal.maps, 
EINA_INLIST_GET(map));
+   if (length) *length = map->size;
    return map->ptr;
 
 on_fail:
+   free(map);
    if (length) *length = 0;
    if (stride) *stride = 0;
    return NULL;
@@ -181,9 +210,11 @@ _ector_software_buffer_base_ector_generic_buffer_unmap(Eo 
*obj EINA_UNUSED, Ecto
 
    EINA_INLIST_FOREACH(pd->internal.maps, map)
      {
-        if ((map->ptr == data) && (map->len == length))
+        if ((map->ptr == data) && ((map->size == length) || (length == 
(unsigned int) -1)))
           {
              pd->internal.maps = eina_inlist_remove(pd->internal.maps, 
EINA_INLIST_GET(map));
+             if (map->allocated)
+               free(map->ptr);
              free(map);
              return;
           }
@@ -193,62 +224,22 @@ _ector_software_buffer_base_ector_generic_buffer_unmap(Eo 
*obj EINA_UNUSED, Ecto
 }
 
 EOLIAN static uint8_t *
-_ector_software_buffer_base_ector_generic_buffer_span_get(Eo *obj EINA_UNUSED, 
Ector_Software_Buffer_Base_Data *pd,
+_ector_software_buffer_base_ector_generic_buffer_span_get(Eo *obj, 
Ector_Software_Buffer_Base_Data *pd,
                                                           int x, int y, 
unsigned int w, Efl_Gfx_Colorspace cspace,
                                                           unsigned int *length)
 {
-   uint8_t *src;
-   int len, px;
-
-   if (!pd->pixels.u8)
-     fail("No pixel data");
-   if ((x < -pd->generic->l) || (y < -pd->generic->t) ||
-       ((unsigned) x > pd->generic->w) || ((unsigned) y > pd->generic->h))
-     fail("Out of bounds");
-   if (((unsigned) x + w) > (pd->generic->w + pd->generic->l + pd->generic->r))
-     fail("Requested span too large");
-
-   px = _min_stride_calc(1, pd->generic->cspace);
-   len = _min_stride_calc(w, cspace);
-   if (length) *length = len;
-
-   src = pd->pixels.u8 + ((pd->generic->t + y) * pd->stride) + (px * 
(pd->generic->l + x));
-
-   if (cspace == pd->generic->cspace)
-     {
-        pd->span_free = EINA_FALSE;
-        return src;
-     }
-   else if ((cspace == EFL_GFX_COLORSPACE_ARGB8888) &&
-            (pd->generic->cspace == EFL_GFX_COLORSPACE_GRY8))
-     {
-        uint32_t *buf = malloc(len);
-        _pixels_gry8_to_argb_convert(buf, src, w);
-        pd->span_free = EINA_TRUE;
-        return (uint8_t *) buf;
-     }
-   else if ((cspace == EFL_GFX_COLORSPACE_GRY8) &&
-            (pd->generic->cspace == EFL_GFX_COLORSPACE_ARGB8888))
-     {
-        uint8_t *buf = malloc(len);
-        _pixels_argb_to_gry8_convert(buf, (uint32_t *) src, w);
-        pd->span_free = EINA_TRUE;
-        return buf;
-     }
-   else
-     fail("Unsupported colorspace %u", cspace);
-
-on_fail:
-   if (length) *length = 0;
-   return NULL;
+   // ector_buffer_map
+   return _ector_software_buffer_base_ector_generic_buffer_map
+         (obj, pd, length, ECTOR_BUFFER_ACCESS_FLAG_READ, x, y, w, 1, cspace, 
NULL);
 }
 
 EOLIAN static void
-_ector_software_buffer_base_ector_generic_buffer_span_free(Eo *obj 
EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd,
+_ector_software_buffer_base_ector_generic_buffer_span_free(Eo *obj, 
Ector_Software_Buffer_Base_Data *pd,
                                                            uint8_t *data)
 {
-   if (pd->span_free) free(data);
-   pd->span_free = EINA_FALSE;
+   // ector_buffer_unmap
+   return _ector_software_buffer_base_ector_generic_buffer_unmap
+         (obj, pd, data, (unsigned int) -1);
 }
 
 EOLIAN static Ector_Buffer_Flag

-- 


Reply via email to