Ector: Use Ector Buffer inside SW and Cairo renderers
authorJean-Philippe Andre <jp.andre@samsung.com>
Tue, 1 Dec 2015 06:22:20 +0000 (15:22 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Thu, 3 Dec 2015 09:42:50 +0000 (18:42 +0900)
Ector Surface now inherits from Ector Buffer, and the current
two renderers (SW and Cairo SW) use Ector.Software.Buffer
implementations for pixel surfaces.

Basic pixel handling is merged and will allow easy extension
(color conversion, etc...).

Buffer classes are Mixins to be fully implemented by the final
class, such as: Ector.Software.Buffer, Ector.Software.Surface
or Ector.Cairo.Surface.

This is a large ugly commit. Sorry.
The code is quite a mess right now.

26 files changed:
src/Makefile_Ector.am
src/lib/ector/cairo/ector_cairo_surface.eo
src/lib/ector/ector_buffer.h [new file with mode: 0644]
src/lib/ector/ector_generic_buffer.c
src/lib/ector/ector_generic_buffer.eo
src/lib/ector/ector_generic_surface.eo
src/lib/ector/ector_private.h
src/lib/ector/ector_renderer_base.c
src/lib/ector/ector_renderer_generic_base.eo
src/lib/ector/ector_renderer_generic_buffer.eo
src/lib/ector/ector_surface.c [deleted file]
src/lib/ector/software/Ector_Software.h
src/lib/ector/software/ector_renderer_software_buffer.c
src/lib/ector/software/ector_software_buffer.c
src/lib/ector/software/ector_software_buffer.eo
src/lib/ector/software/ector_software_buffer_base.eo [new file with mode: 0644]
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/modules/evas/engines/gl_generic/ector_cairo_software_surface.eo
src/modules/evas/engines/gl_generic/ector_surface.c
src/modules/evas/engines/gl_generic/evas_engine.c
src/modules/evas/engines/software_generic/ector_cairo_software_surface.eo
src/modules/evas/engines/software_generic/ector_surface.c
src/modules/evas/engines/software_generic/evas_engine.c

index b6cda51..3dc4c73 100644 (file)
@@ -24,6 +24,7 @@ ector_eolian_cairo_h = $(ector_eolian_files_cairo:%.eo=%.eo.h)
 ector_eolian_files_software = \
        lib/ector/software/ector_software_surface.eo \
        lib/ector/software/ector_software_buffer.eo \
+       lib/ector/software/ector_software_buffer_base.eo \
        lib/ector/software/ector_renderer_software_base.eo \
        lib/ector/software/ector_renderer_software_shape.eo \
        lib/ector/software/ector_renderer_software_buffer.eo \
@@ -67,7 +68,6 @@ lib/ector/software/Ector_Software.h
 
 lib_ector_libector_la_SOURCES = \
 lib/ector/ector_main.c \
-lib/ector/ector_surface.c \
 lib/ector/ector_generic_buffer.c \
 lib/ector/ector_renderer_shape.c \
 lib/ector/ector_renderer_base.c \
index 78dbe15..001d73a 100644 (file)
@@ -1,4 +1,4 @@
-class Ector.Cairo.Surface (Ector.Generic.Surface)
+class Ector.Cairo.Surface (Eo.Base, Ector.Generic.Surface)
 {
    eo_prefix: ector_cairo_surface;
    legacy_prefix: null;
diff --git a/src/lib/ector/ector_buffer.h b/src/lib/ector/ector_buffer.h
new file mode 100644 (file)
index 0000000..41a75cb
--- /dev/null
@@ -0,0 +1,27 @@
+#include <Ector.h>
+
+#include "ector_generic_buffer.eo.h"
+#include "software/ector_software_buffer_base.eo.h"
+
+typedef struct _Ector_Generic_Buffer_Data
+{
+   Eo                 *eo;
+   unsigned int        w, h;
+   unsigned char       l, r, t, b;
+   Efl_Gfx_Colorspace  cspace;
+} Ector_Generic_Buffer_Data;
+
+typedef struct _Ector_Software_Buffer_Base_Data
+{
+   Ector_Generic_Buffer_Data *generic; /* ugly */
+   union {
+      unsigned int     *u32;
+      unsigned char    *u8;
+   } pixels;
+   unsigned int         stride;
+   unsigned int         pixel_size; // in bytes
+   unsigned int         map_count;
+   Eina_Bool            writable : 1;
+   Eina_Bool            nofree : 1; // pixel data should not be free()'ed
+   Eina_Bool            span_free : 1;
+} Ector_Software_Buffer_Base_Data;
index ba5955b..9c97ff8 100644 (file)
@@ -8,8 +8,6 @@
 #include "ector_private.h"
 #include "ector_generic_buffer.eo.h"
 
-#define MY_CLASS ECTOR_GENERIC_BUFFER_CLASS
-
 EOLIAN static Efl_Gfx_Colorspace
 _ector_generic_buffer_cspace_get(Eo *obj EINA_UNUSED, Ector_Generic_Buffer_Data *pd)
 {
@@ -38,13 +36,5 @@ _ector_generic_buffer_flags_get(Eo *obj EINA_UNUSED, Ector_Generic_Buffer_Data *
    return ECTOR_BUFFER_FLAG_NONE;
 }
 
-EOLIAN static Eo_Base *
-_ector_generic_buffer_eo_base_constructor(Eo *obj, Ector_Generic_Buffer_Data *pd)
-{
-   eo_do_super(obj, MY_CLASS, obj = eo_constructor());
-   pd->eo = obj;
-
-   return obj;
-}
-
 #include "ector_generic_buffer.eo.c"
+#include "ector_generic_surface.eo.c"
index f0f1566..7b8a3ed 100644 (file)
@@ -15,7 +15,7 @@ enum Ector.Buffer.Access_Flag {
    write = 0x2,
 }
 
-abstract Ector.Generic.Buffer (Eo.Base)
+mixin Ector.Generic.Buffer
 {
    [[2D pixel buffer interface for Ector
      @since 1.17
@@ -122,7 +122,6 @@ abstract Ector.Generic.Buffer (Eo.Base)
       detached; [[Emitted whenever the previously attached pixels are detached during pixels_set]]
    }
    implements {
-      Eo.Base.constructor;
       @virtual .pixels_set;
       @virtual .span_get;
       @virtual .span_free;
index a391ea0..cb05c6d 100644 (file)
@@ -1,19 +1,9 @@
-abstract Ector.Generic.Surface (Eo.Base)
+mixin Ector.Generic.Surface (Ector.Generic.Buffer)
 {
    eo_prefix: ector_surface;
+   legacy_prefix: null;
+   data: null;
    methods {
-      @property size {
-         set {
-            [[Changes the size of the given Evas object.]]
-         }
-         get {
-            [[Retrieves the (rectangular) size of the given Evas object.]]
-         }
-         values {
-            w: int;
-            h: int;
-         }
-      }
       @property reference_point {
          set {
             [[This define where is (0,0) in pixels coordinate inside the surface]]
index 13cfc7e..3418c99 100644 (file)
@@ -91,7 +91,6 @@ typedef struct _Ector_Renderer_Generic_Gradient_Linear_Data Ector_Renderer_Gener
 typedef struct _Ector_Renderer_Generic_Gradient_Radial_Data Ector_Renderer_Generic_Gradient_Radial_Data;
 typedef struct _Ector_Renderer_Generic_Shape_Data Ector_Renderer_Generic_Shape_Data;
 typedef struct _Ector_Renderer_Generic_Buffer_Data Ector_Renderer_Generic_Buffer_Data;
-typedef struct _Ector_Generic_Buffer_Data Ector_Generic_Buffer_Data;
 
 struct _Ector_Renderer_Generic_Base_Data
 {
@@ -110,7 +109,8 @@ struct _Ector_Renderer_Generic_Base_Data
    Ector_Renderer *mask;
 
    Ector_Quality q;
-   Eina_Bool visibility;
+   Eina_Bool visibility : 1;
+   Eina_Bool finalized : 1;
 };
 
 struct _Ector_Renderer_Generic_Gradient_Data
@@ -145,14 +145,6 @@ struct _Ector_Renderer_Generic_Shape_Data
    } stroke;
 };
 
-struct _Ector_Generic_Buffer_Data
-{
-   Eo                 *eo;
-   unsigned int        w, h;
-   unsigned char       l, r, t, b;
-   Efl_Gfx_Colorspace  cspace;
-};
-
 struct _Ector_Renderer_Generic_Buffer_Data
 {
    Ector_Generic_Buffer *eo_buffer;
@@ -172,4 +164,6 @@ _renderer_crc_get(Eo *obj, unsigned int crc)
    return crc;
 }
 
+#include "ector_buffer.h"
+
 #endif
index 2b9a594..66423bf 100644 (file)
@@ -7,13 +7,27 @@
 
 #include "ector_private.h"
 
+#define MY_CLASS ECTOR_RENDERER_GENERIC_BASE_CLASS
+
 static void
 _ector_renderer_generic_base_eo_base_destructor(Eo *obj, Ector_Renderer_Generic_Base_Data *pd)
 {
    if (pd->m) free(pd->m);
    eo_unref(pd->surface);
 
-   eo_do_super(obj, ECTOR_RENDERER_GENERIC_BASE_CLASS, eo_destructor());
+   eo_do_super(obj, MY_CLASS, eo_destructor());
+}
+
+static Eo_Base *
+_ector_renderer_generic_base_eo_base_finalize(Eo *obj, Ector_Renderer_Generic_Base_Data *pd)
+{
+   if (!pd->surface)
+     {
+        CRI("surface is not set yet, go fix your code!");
+        return NULL;
+     }
+   pd->finalized = EINA_TRUE;
+   return eo_do_super_ret(obj, MY_CLASS, obj, eo_finalize());
 }
 
 static Ector_Generic_Surface *
@@ -25,6 +39,11 @@ _ector_renderer_generic_base_surface_get(Eo *obj EINA_UNUSED, Ector_Renderer_Gen
 static void
 _ector_renderer_generic_base_surface_set(Eo *obj EINA_UNUSED, Ector_Renderer_Generic_Base_Data *pd, Ector_Generic_Surface *s)
 {
+   if (pd->finalized)
+     {
+        CRI("surface_set can be called during object creation only!");
+        return;
+     }
    pd->surface = eo_xref(s, obj);
 }
 
index 8c6ce6e..ea9c3ab 100644 (file)
@@ -121,6 +121,7 @@ abstract Ector.Renderer.Generic.Base (Eo.Base)
    }
    implements {
       Eo.Base.destructor;
+      Eo.Base.finalize;
       @virtual .draw;
       @virtual .bounds_get;
       @virtual .done;
index 94e1ef2..4d88105 100644 (file)
@@ -1,12 +1,12 @@
-mixin Ector.Renderer.Generic.Buffer (Eo.Base, Efl.Gfx.Fill)
+mixin Ector.Renderer.Generic.Buffer (Ector.Renderer.Generic.Base, Efl.Gfx.Fill)
 {
    [[Ector buffers have a default fill set to repeat]]
    eo_prefix: ector_renderer_buffer;
    legacy_prefix: null;
    methods {
       @property buffer {
-        set {}
-        get {}
+        set { [[Sets the source buffer for this renderer, adds a ref]] }
+        get { [[Return the current source, no ref change]] }
         values {
            buf: Ector.Generic.Buffer*;
         }
diff --git a/src/lib/ector/ector_surface.c b/src/lib/ector/ector_surface.c
deleted file mode 100644 (file)
index 23ad7eb..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <Eina.h>
-#include <Ector.h>
-
-#include "ector_private.h"
-
-typedef struct _Ector_Generic_Surface_Data Ector_Generic_Surface_Data;
-struct _Ector_Generic_Surface_Data
-{
-   int w, h;
-};
-
-void
-_ector_generic_surface_size_set(Eo *obj EINA_UNUSED,
-                                Ector_Generic_Surface_Data *pd,
-                                int w, int h)
-{
-   pd->w = w;
-   pd->h = h;
-}
-
-void
-_ector_generic_surface_size_get(Eo *obj EINA_UNUSED,
-                                Ector_Generic_Surface_Data *pd,
-                                int *w, int *h)
-{
-   if (w) *w = pd->w;
-   if (h) *h = pd->h;
-}
-
-#include "ector_generic_surface.eo.c"
index 8e2a921..430315a 100644 (file)
@@ -14,6 +14,7 @@ typedef struct _Software_Rasterizer Software_Rasterizer;
 
 #include "software/ector_software_surface.eo.h"
 #include "software/ector_software_buffer.eo.h"
+#include "software/ector_software_buffer_base.eo.h"
 #include "software/ector_renderer_software_base.eo.h"
 #include "software/ector_renderer_software_shape.eo.h"
 #include "software/ector_renderer_software_buffer.eo.h"
index 2cda712..0eb6fa9 100644 (file)
@@ -34,7 +34,7 @@ _ector_renderer_software_buffer_buffer_get(Eo *obj EINA_UNUSED, Ector_Renderer_S
 EOLIAN static Eina_Bool
 _ector_renderer_software_buffer_ector_renderer_software_base_fill(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd)
 {
-   Ector_Software_Buffer *buffer = eo_data_scope_get(obj, ECTOR_SOFTWARE_BUFFER_CLASS);
+   Ector_Software_Buffer *buffer = eo_data_scope_get(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
    ector_software_rasterizer_buffer_set(pd->surface, buffer);
    return EINA_TRUE;
 }
@@ -51,7 +51,7 @@ _ector_renderer_software_buffer_ector_renderer_generic_base_prepare(Eo *obj, Ect
 EOLIAN static unsigned int
 _ector_renderer_software_buffer_ector_renderer_generic_base_crc_get(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd)
 {
-   Ector_Software_Buffer_Data *buffer = eo_data_scope_get(pd->eo_buffer, ECTOR_SOFTWARE_BUFFER_CLASS);
+   Ector_Software_Buffer_Base_Data *buffer = eo_data_scope_get(pd->eo_buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
    unsigned int crc;
 
    eo_do_super(obj, MY_CLASS, crc = ector_renderer_crc_get());
index 4fdbcde..541417f 100644 (file)
@@ -9,6 +9,9 @@
 #include "ector_private.h"
 #include "ector_software_private.h"
 #include "ector_generic_buffer.eo.h"
+#include "ector_software_buffer_base.eo.h"
+
+#define MY_CLASS ECTOR_SOFTWARE_BUFFER_CLASS
 
 #define fail(fmt, ...) do { ERR(fmt, ##__VA_ARGS__); goto on_fail; } while (0)
 
@@ -47,7 +50,7 @@ _pixels_gry8_to_argb_convert(uint32_t *dst, const uint8_t *src, int len)
 }
 
 EOLIAN static void
-_ector_software_buffer_pixels_clear(Eo *obj, Ector_Software_Buffer_Data *pd)
+_ector_software_buffer_base_pixels_clear(Eo *obj, Ector_Software_Buffer_Base_Data *pd)
 {
    if (!pd->pixels.u8)
      return;
@@ -62,11 +65,11 @@ _ector_software_buffer_pixels_clear(Eo *obj, Ector_Software_Buffer_Data *pd)
 }
 
 EOLIAN static Eina_Bool
-_ector_software_buffer_ector_generic_buffer_pixels_set(Eo *obj, Ector_Software_Buffer_Data *pd,
-                                                       void *pixels, int width, int height, int stride,
-                                                       Efl_Gfx_Colorspace cspace, Eina_Bool writable,
-                                                       unsigned char l, unsigned char r,
-                                                       unsigned char t, unsigned char b)
+_ector_software_buffer_base_ector_generic_buffer_pixels_set(Eo *obj, Ector_Software_Buffer_Base_Data *pd,
+                                                            void *pixels, int width, int height, int stride,
+                                                            Efl_Gfx_Colorspace cspace, Eina_Bool writable,
+                                                            unsigned char l, unsigned char r,
+                                                            unsigned char t, unsigned char b)
 {
    // safety check
    unsigned px = _min_stride_calc(1, cspace);
@@ -86,12 +89,15 @@ _ector_software_buffer_ector_generic_buffer_pixels_set(Eo *obj, Ector_Software_B
      {
         ERR("Invalid stride %u for width %u (+%u+%u) cspace %u. pixels_set failed.",
             stride, width, l, r, cspace);
-        _ector_software_buffer_pixels_clear(obj, pd);
+        _ector_software_buffer_base_pixels_clear(obj, pd);
         return EINA_FALSE;
      }
 
+   if ((px > 1) && (stride & (px - 1)))
+     ERR("Stride (%d) is not aligned to the pixel size (%d)", stride, px);
+
    if (pd->pixels.u8 && (pd->pixels.u8 != pixels))
-     _ector_software_buffer_pixels_clear(obj, pd);
+     _ector_software_buffer_base_pixels_clear(obj, pd);
 
    if (pixels)
      {
@@ -105,38 +111,39 @@ _ector_software_buffer_ector_generic_buffer_pixels_set(Eo *obj, Ector_Software_B
         pd->nofree = EINA_FALSE;
         pd->writable = EINA_TRUE;
      }
-   pd->generic.w = width;
-   pd->generic.h = height;
-   pd->generic.l = l;
-   pd->generic.r = r;
-   pd->generic.t = t;
-   pd->generic.b = b;
-   pd->generic.cspace = cspace;
+   pd->generic->w = width;
+   pd->generic->h = height;
+   pd->generic->l = l;
+   pd->generic->r = r;
+   pd->generic->t = t;
+   pd->generic->b = b;
+   pd->generic->cspace = cspace;
    pd->stride = stride;
+   pd->pixel_size = px;
    return EINA_TRUE;
 }
 
 EOLIAN static uint8_t *
-_ector_software_buffer_ector_generic_buffer_map(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Data *pd,
-                                                int *offset, unsigned int *length,
-                                                Ector_Buffer_Access_Flag mode EINA_UNUSED,
-                                                unsigned int x, unsigned int y, unsigned int w, unsigned int h,
-                                                Efl_Gfx_Colorspace cspace EINA_UNUSED, unsigned int *stride)
+_ector_software_buffer_base_ector_generic_buffer_map(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd,
+                                                     int *offset, unsigned int *length,
+                                                     Ector_Buffer_Access_Flag mode EINA_UNUSED,
+                                                     unsigned int x, unsigned int y, unsigned int w, unsigned int h,
+                                                     Efl_Gfx_Colorspace cspace EINA_UNUSED, unsigned int *stride)
 {
    int off;
 
    if (!pd->pixels.u8 || !pd->stride)
      fail("Buffer has no pixel data yet");
-   if (cspace != pd->generic.cspace)
+   if (cspace != pd->generic->cspace)
      fail("Invalid colorspace");
-   if (!w || !h || ((x + w) > pd->generic.w) || (y + h > pd->generic.h))
+   if (!w || !h || ((x + w) > pd->generic->w) || (y + h > pd->generic->h))
      fail("Invalid region requested: wanted %u,%u %ux%u but image is %ux%u",
-          x, y, w, h, pd->generic.w, pd->generic.h);
+          x, y, w, h, pd->generic->w, pd->generic->h);
 
    pd->map_count++;
-   off = _min_stride_calc(x + pd->generic.l, pd->generic.cspace) + (pd->stride * (y + pd->generic.t));
+   off = _min_stride_calc(x + pd->generic->l, pd->generic->cspace) + (pd->stride * (y + pd->generic->t));
    if (offset) *offset = off;
-   if (length) *length = (pd->stride * pd->generic.h) - off;
+   if (length) *length = (pd->stride * pd->generic->h) - off;
    if (stride) *stride = pd->stride;
    return pd->pixels.u8;
 
@@ -148,7 +155,7 @@ on_fail:
 }
 
 EOLIAN static void
-_ector_software_buffer_ector_generic_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Data *pd, void *data, int offset EINA_UNUSED, unsigned int length EINA_UNUSED)
+_ector_software_buffer_base_ector_generic_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd, void *data, int offset EINA_UNUSED, unsigned int length EINA_UNUSED)
 {
    if (!data) return;
    if (data != pd->pixels.u8)
@@ -164,35 +171,35 @@ _ector_software_buffer_ector_generic_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Sof
    pd->map_count--;
 }
 
-EOLIAN uint8_t *
-_ector_software_buffer_ector_generic_buffer_span_get(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Data *pd,
-                                                     int x, int y, unsigned int w, Efl_Gfx_Colorspace cspace,
-                                                     unsigned int *length)
+EOLIAN static uint8_t *
+_ector_software_buffer_base_ector_generic_buffer_span_get(Eo *obj EINA_UNUSED, 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))
+   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))
+   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);
+   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));
+   src = pd->pixels.u8 + ((pd->generic->t + y) * pd->stride) + (px * (pd->generic->l + x));
 
-   if (cspace == pd->generic.cspace)
+   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))
+            (pd->generic->cspace == EFL_GFX_COLORSPACE_GRY8))
      {
         uint32_t *buf = malloc(len);
         _pixels_gry8_to_argb_convert(buf, src, w);
@@ -200,7 +207,7 @@ _ector_software_buffer_ector_generic_buffer_span_get(Eo *obj EINA_UNUSED, Ector_
         return (uint8_t *) buf;
      }
    else if ((cspace == EFL_GFX_COLORSPACE_GRY8) &&
-            (pd->generic.cspace == EFL_GFX_COLORSPACE_ARGB8888))
+            (pd->generic->cspace == EFL_GFX_COLORSPACE_ARGB8888))
      {
         uint8_t *buf = malloc(len);
         _pixels_argb_to_gry8_convert(buf, (uint32_t *) src, w);
@@ -215,16 +222,16 @@ on_fail:
    return NULL;
 }
 
-EOLIAN void
-_ector_software_buffer_ector_generic_buffer_span_free(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Data *pd,
-                                                      uint8_t *data)
+EOLIAN static void
+_ector_software_buffer_base_ector_generic_buffer_span_free(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd,
+                                                           uint8_t *data)
 {
    if (pd->span_free) free(data);
    pd->span_free = EINA_FALSE;
 }
 
 EOLIAN static Ector_Buffer_Flag
-_ector_software_buffer_ector_generic_buffer_flags_get(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Data *pd)
+_ector_software_buffer_base_ector_generic_buffer_flags_get(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd)
 {
    return ECTOR_BUFFER_FLAG_CPU_READABLE |
          ECTOR_BUFFER_FLAG_CPU_READABLE_FAST |
@@ -234,11 +241,24 @@ _ector_software_buffer_ector_generic_buffer_flags_get(Eo *obj EINA_UNUSED, Ector
                        : 0);
 }
 
+EOLIAN static Eo_Base *
+_ector_software_buffer_eo_base_constructor(Eo *obj, void *data EINA_UNUSED)
+{
+   Ector_Software_Buffer_Base_Data *pd;
+   eo_do_super(obj, MY_CLASS, obj = eo_constructor());
+   pd = eo_data_scope_get(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
+   pd->generic = eo_data_ref(obj, ECTOR_GENERIC_BUFFER_MIXIN);
+   pd->generic->eo = obj;
+   return obj;
+}
+
 EOLIAN static void
-_ector_software_buffer_eo_base_destructor(Eo *obj, Ector_Software_Buffer_Data *pd)
+_ector_software_buffer_eo_base_destructor(Eo *obj, void *data EINA_UNUSED)
 {
-   _ector_software_buffer_pixels_clear(obj, pd);
-   eo_do_super(obj, ECTOR_SOFTWARE_BUFFER_CLASS, eo_destructor());
+   Ector_Software_Buffer_Base_Data *pd = eo_data_scope_get(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
+   _ector_software_buffer_base_pixels_clear(obj, pd);
+   eo_data_unref(obj, pd->generic);
+   eo_do_super(obj, MY_CLASS, eo_destructor());
    if (pd->map_count)
      {
         ERR("Pixel data is still mapped during destroy! Check your code!");
@@ -246,3 +266,4 @@ _ector_software_buffer_eo_base_destructor(Eo *obj, Ector_Software_Buffer_Data *p
 }
 
 #include "ector_software_buffer.eo.c"
+#include "ector_software_buffer_base.eo.c"
index a2e365a..1190dce 100644 (file)
@@ -1,19 +1,9 @@
-class Ector.Software.Buffer (Ector.Generic.Buffer)
+class Ector.Software.Buffer (Eo.Base, Ector.Software.Buffer.Base)
 {
-   [[A buffer in Ector Software is a readable & optionally writable image]]
    legacy_prefix: null;
-   methods {
-      pixels_clear @protected {
-        [[Clear internal pixel buffer]]
-      }
-   }
+   data: null;
    implements {
+      Eo.Base.constructor;
       Eo.Base.destructor;
-      Ector.Generic.Buffer.flags.get;
-      Ector.Generic.Buffer.pixels_set;
-      Ector.Generic.Buffer.span_get;
-      Ector.Generic.Buffer.span_free;
-      Ector.Generic.Buffer.map;
-      Ector.Generic.Buffer.unmap;
    }
 }
diff --git a/src/lib/ector/software/ector_software_buffer_base.eo b/src/lib/ector/software/ector_software_buffer_base.eo
new file mode 100644 (file)
index 0000000..d10df04
--- /dev/null
@@ -0,0 +1,19 @@
+mixin Ector.Software.Buffer.Base (Ector.Generic.Buffer)
+{
+   [[A buffer in Ector Software is a readable & optionally writable image]]
+   eo_prefix: ector_software_buffer;
+   legacy_prefix: null;
+   methods {
+      pixels_clear @protected {
+       [[Clear internal pixel buffer]]
+      }
+   }
+   implements {
+      Ector.Generic.Buffer.flags.get;
+      Ector.Generic.Buffer.pixels_set;
+      Ector.Generic.Buffer.span_get;
+      Ector.Generic.Buffer.span_free;
+      Ector.Generic.Buffer.map;
+      Ector.Generic.Buffer.unmap;
+   }
+}
index d0ec132..51b856d 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef ECTOR_SOFTWARE_PRIVATE_H_
 # define ECTOR_SOFTWARE_PRIVATE_H_
 
+#include "Ector_Software.h"
 #include "sw_ft_raster.h"
 #include "sw_ft_stroker.h"
 #include "../ector_private.h"
@@ -14,9 +15,14 @@ typedef unsigned int uint;
 #endif
 
 typedef struct _Ector_Software_Surface_Data Ector_Software_Surface_Data;
+typedef struct _Ector_Renderer_Software_Base_Data Ector_Renderer_Software_Base_Data;
 
 #define CHECK_SOFTWARE(Parent) (!(Parent && Parent->software))
 
+struct _Ector_Renderer_Software_Base_Data
+{
+};
+
 // Gradient related structure
 typedef struct _Software_Gradient_Linear_Data
 {
@@ -47,30 +53,6 @@ typedef struct _Ector_Renderer_Software_Gradient_Data
    uint* color_table;
 } Ector_Renderer_Software_Gradient_Data;
 
-
-// Rasterizer related structure
-// FIXME: Merge with Ector_Software_Buffer
-typedef struct _Raster_Buffer
-{
-   int            width;
-   int            height;
-   DATA32        *buffer;
-} Raster_Buffer;
-
-typedef struct _Ector_Software_Buffer_Data
-{
-   Ector_Generic_Buffer_Data generic;
-   union {
-      unsigned int     *u32;
-      unsigned char    *u8;
-   } pixels;
-   unsigned int         stride;
-   unsigned int         map_count;
-   Eina_Bool            writable : 1;
-   Eina_Bool            nofree : 1; // pixel data should not be free()'ed
-   Eina_Bool            span_free : 1;
-} Ector_Software_Buffer_Data;
-
 typedef struct _Shape_Rle_Data
 {
    Eina_Rectangle   bbox;
@@ -99,8 +81,7 @@ typedef enum _Span_Data_Type {
 
 typedef struct _Span_Data
 {
-   Raster_Buffer    raster_buffer;
-
+   Ector_Software_Buffer_Base_Data *raster_buffer;
    SW_FT_SpanFunc   blend;
    SW_FT_SpanFunc   unclipped_blend;
 
@@ -114,7 +95,7 @@ typedef struct _Span_Data
    union {
       DATA32 color;
       Ector_Renderer_Software_Gradient_Data *gradient;
-      Ector_Software_Buffer_Data *buffer;
+      Ector_Software_Buffer_Base_Data *buffer;
    };
 } Span_Data;
 
index e58d611..21bcb94 100644 (file)
@@ -17,17 +17,18 @@ _blend_color_argb(int count, const SW_FT_Span *spans, void *user_data)
    RGBA_Comp_Func_Solid comp_func;
    Span_Data *data = (Span_Data *)(user_data);
    uint color, *buffer, *target;
+   const int pix_stride = data->raster_buffer->stride / 4;
 
    // multiply the color with mul_col if any
    color = ECTOR_MUL4_SYM(data->color, data->mul_col);
    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->pixels.u32 + ((pix_stride * data->offy) + data->offx);
 
    while (count--)
      {
-        target = buffer + ((data->raster_buffer.width * spans->y) + spans->x);
+        target = buffer + ((pix_stride * spans->y) + spans->x);
         comp_func(target, spans->len, color, spans->coverage);
         ++spans;
      }
@@ -45,6 +46,7 @@ _blend_gradient(int count, const SW_FT_Span *spans, void *user_data)
    src_fetch fetchfunc = NULL;
    unsigned int buffer[BLEND_GRADIENT_BUFFER_SIZE], *target, *destbuffer;
    int length, l;
+   const int pix_stride = data->raster_buffer->stride / 4;
 
    //@TODO, Get the proper composition function using ,color, ECTOR_OP etc.
    if (data->type == LinearGradient) fetchfunc = &fetch_linear_gradient;
@@ -56,11 +58,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->pixels.u32 + ((pix_stride * data->offy) + data->offx);
 
    while (count--)
      {
-        target = destbuffer + ((data->raster_buffer.width * spans->y) + spans->x);
+        target = destbuffer + ((pix_stride * spans->y) + spans->x);
         length = spans->len;
         while (length)
           {
@@ -95,30 +97,31 @@ _blend_image_argb(int count, const SW_FT_Span *spans, void *user_data)
    DATA32 *buffer, *target;
    DATA8 *src8;
    unsigned int l, length, sy = 0;
+   const int pix_stride = data->raster_buffer->stride / 4;
 
 #warning FIXME: Image scaling, anyone?
 #warning FIXME: Optimize eo call with early call resolution
 
    comp_func = ector_comp_func_span_get(data->op, data->mul_col, EINA_TRUE);
 
-   buffer = data->raster_buffer.buffer + ((data->raster_buffer.width * data->offy) + data->offx);
+   buffer = data->raster_buffer->pixels.u32 + ((pix_stride * data->offy) + data->offx);
 
    while (count--)
      {
-        target = buffer + ((data->raster_buffer.width * spans->y) + spans->x);
+        target = buffer + ((pix_stride * spans->y) + spans->x);
         length = spans->len;
         while (length)
           {
-             l = MIN(length, data->buffer->generic.w);
-             eo_do(data->buffer->generic.eo, src8 = ector_buffer_span_get(0, sy, l, EFL_GFX_COLORSPACE_ARGB8888, NULL));
+             l = MIN(length, data->buffer->generic->w);
+             eo_do(data->buffer->generic->eo, src8 = ector_buffer_span_get(0, sy, l, EFL_GFX_COLORSPACE_ARGB8888, NULL));
              comp_func(target, (DATA32 *) src8, l, data->mul_col, spans->coverage);
-             eo_do(data->buffer->generic.eo, ector_buffer_span_free(src8));
+             eo_do(data->buffer->generic->eo, ector_buffer_span_free(src8));
              target += l;
              length -= l;
           }
         ++spans;
         ++sy;
-        if (sy >= data->buffer->generic.h)
+        if (sy >= data->buffer->generic->h)
           sy = 0;
      }
 }
@@ -327,7 +330,7 @@ _adjust_span_fill_methods(Span_Data *spdata)
           spdata->unclipped_blend = &_blend_gradient;
           break;
         case Image:
-          if (spdata->buffer->generic.cspace == EFL_GFX_COLORSPACE_GRY8)
+          if (spdata->buffer->generic->cspace == EFL_GFX_COLORSPACE_GRY8)
             spdata->unclipped_blend = &_blend_image_gry8;
           else
             spdata->unclipped_blend = &_blend_image_argb;
@@ -362,7 +365,6 @@ void ector_software_rasterizer_init(Software_Rasterizer *rasterizer)
    SW_FT_Stroker_Set(rasterizer->stroker, 1<<6,SW_FT_STROKER_LINECAP_BUTT,SW_FT_STROKER_LINEJOIN_MITER,0);
 
    //initialize the span data.
-   rasterizer->fill_data.raster_buffer.buffer = NULL;
    rasterizer->fill_data.clip.enabled = EINA_FALSE;
    rasterizer->fill_data.unclipped_blend = 0;
    rasterizer->fill_data.blend = 0;
@@ -570,7 +572,7 @@ void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasteriz
 void ector_software_rasterizer_buffer_set(Software_Rasterizer *rasterizer,
                                           Ector_Software_Buffer *buffer)
 {
-   rasterizer->fill_data.buffer = eo_data_scope_get(buffer, ECTOR_SOFTWARE_BUFFER_CLASS);
+   rasterizer->fill_data.buffer = eo_data_scope_get(buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
    rasterizer->fill_data.type = Image;
 }
 
index 4767e4e..bdd0599 100644 (file)
@@ -8,10 +8,7 @@
 #include "ector_private.h"
 #include "ector_software_private.h"
 
-typedef struct _Ector_Renderer_Software_Base_Data Ector_Renderer_Software_Base_Data;
-struct _Ector_Renderer_Software_Base_Data
-{
-};
+#define MY_CLASS ECTOR_SOFTWARE_SURFACE_CLASS
 
 static Ector_Renderer *
 _ector_software_surface_ector_generic_surface_renderer_factory_new(Eo *obj,
@@ -34,56 +31,21 @@ _ector_software_surface_ector_generic_surface_renderer_factory_new(Eo *obj,
    return NULL;
 }
 
-static void
-_ector_software_surface_context_set(Eo *obj EINA_UNUSED,
-                                    Ector_Software_Surface_Data *pd,
-                                    Software_Rasterizer *ctx)
-{
-   pd->software = ctx;
-}
-
-static Software_Rasterizer *
-_ector_software_surface_context_get(Eo *obj EINA_UNUSED,
-                                    Ector_Software_Surface_Data *pd)
-{
-   return pd->software;
-}
-
-void
-_ector_software_surface_surface_set(Eo *obj EINA_UNUSED,
-                                    Ector_Software_Surface_Data *pd,
-                                    void *pixels, unsigned int width, unsigned int height)
-{
-   pd->software->fill_data.raster_buffer.buffer = pixels;
-   pd->software->fill_data.raster_buffer.width = width;
-   pd->software->fill_data.raster_buffer.height = height;
-}
-
-void
-_ector_software_surface_surface_get(Eo *obj EINA_UNUSED,
-                                    Ector_Software_Surface_Data *pd,
-                                    void **pixels, unsigned int *width, unsigned int *height)
-{
-   *pixels = pd->software->fill_data.raster_buffer.buffer;
-   *width = pd->software->fill_data.raster_buffer.width;
-   *height = pd->software->fill_data.raster_buffer.height;
-}
-
 static Eo *
-_ector_software_surface_eo_base_constructor(Eo *obj,
-                                            Ector_Software_Surface_Data *pd EINA_UNUSED)
+_ector_software_surface_eo_base_constructor(Eo *obj, Ector_Software_Surface_Data *pd)
 {
-   obj = eo_do_super_ret(obj, ECTOR_SOFTWARE_SURFACE_CLASS, obj, eo_constructor());
+   obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
    pd->software = (Software_Rasterizer *) calloc(1, sizeof(Software_Rasterizer));
    ector_software_rasterizer_init(pd->software);
-  return obj;
+   pd->software->fill_data.raster_buffer = eo_data_ref(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
+   return obj;
 }
 
 static void
-_ector_software_surface_eo_base_destructor(Eo *obj EINA_UNUSED,
-                                           Ector_Software_Surface_Data *pd EINA_UNUSED)
+_ector_software_surface_eo_base_destructor(Eo *obj, Ector_Software_Surface_Data *pd)
 {
    ector_software_rasterizer_done(pd->software);
+   eo_data_unref(obj, pd->software->fill_data.raster_buffer);
    free(pd->software);
    pd->software = NULL;
    eo_do_super(obj, ECTOR_SOFTWARE_SURFACE_CLASS, eo_destructor());
index bea11cd..34507e6 100644 (file)
@@ -1,30 +1,8 @@
-class Ector.Software.Surface (Ector.Generic.Surface)
+class Ector.Software.Surface (Ector.Software.Buffer, Ector.Generic.Surface)
 {
    eo_prefix: ector_software_surface;
    legacy_prefix: null;
-   methods {
-      @property context {
-         set {
-        }
-        get {
-        }
-        values {
-           ctx: Software_Rasterizer *;
-        }
-      }
-      @property surface {
-         set {
-        }
-        get {
-        }
-        values {
-           pixels: void *;
-           width: uint;
-           height: uint;
-        }
-      }
-   }
-
+   methods {}
    implements {
       Ector.Generic.Surface.renderer_factory_new;
       Ector.Generic.Surface.reference_point.set;
index 2c47042..8d4e789 100644 (file)
@@ -1,18 +1,11 @@
-class Ector.Cairo_Software.Surface (Ector.Cairo.Surface)
+class Ector.Cairo_Software.Surface (Ector.Cairo.Surface, Ector.Software.Buffer.Base)
 {
    eo_prefix: ector_cairo_software_surface;
    legacy_prefix: null;
-   methods {
-      @property surface {
-         set {
-        }
-        get {
-        }
-        values {
-           pixels: void *;
-           width: uint;
-           height: uint;
-        }
-      }
+   methods {}
+   implements {
+      Ector.Generic.Buffer.pixels_set;
+      Eo.Base.constructor;
+      Eo.Base.destructor;
    }
 }
index 01e3c5d..2d4658a 100644 (file)
@@ -4,12 +4,15 @@
 
 #include <Ector.h>
 
-#include "cairo/Ector_Cairo.h"
-#include "software/Ector_Software.h"
+#include <cairo/Ector_Cairo.h>
+#include <software/Ector_Software.h>
 
 #include "evas_common_private.h"
 #include "evas_private.h"
 #include "ector_cairo_software_surface.eo.h"
+#include "ector_buffer.h"
+
+#define MY_CLASS ECTOR_CAIRO_SOFTWARE_SURFACE_CLASS
 
 #define USE(Obj, Sym, Error)                            \
   if (!Sym) Sym = _ector_cairo_symbol_get(Obj, #Sym);   \
@@ -49,55 +52,76 @@ typedef struct _Ector_Cairo_Software_Surface_Data Ector_Cairo_Software_Surface_D
 struct _Ector_Cairo_Software_Surface_Data
 {
    cairo_surface_t *surface;
-   cairo_t *ctx;
-
-   void *pixels;
-
-   unsigned int width;
-   unsigned int height;
+   Ector_Software_Buffer_Base_Data *base;
 };
 
-static void
-_ector_cairo_software_surface_surface_set(Eo *obj, Ector_Cairo_Software_Surface_Data *pd, void *pixels, unsigned int width, unsigned int height)
+EOLIAN static Eina_Bool
+_ector_cairo_software_surface_ector_generic_buffer_pixels_set(Eo *obj, Ector_Cairo_Software_Surface_Data *pd,
+                                                              void *pixels, int width, int height, int stride,
+                                                              Efl_Gfx_Colorspace cspace, Eina_Bool writable,
+                                                              unsigned char l, unsigned char r, unsigned char t, unsigned char b)
 {
-   USE(obj, cairo_image_surface_create_for_data, );
-   USE(obj, cairo_surface_destroy, );
-   USE(obj, cairo_create, );
-   USE(obj, cairo_destroy, );
+   cairo_t *ctx = NULL;
+   Eina_Bool ok = EINA_FALSE;
+
+   if ((cspace != EFL_GFX_COLORSPACE_ARGB8888) || !writable)
+     {
+        ERR("Unsupported surface type!");
+        return EINA_FALSE;
+     }
+
+   USE(obj, cairo_image_surface_create_for_data, EINA_FALSE);
+   USE(obj, cairo_surface_destroy, EINA_FALSE);
+   USE(obj, cairo_create, EINA_FALSE);
+   USE(obj, cairo_destroy, EINA_FALSE);
 
-   if (pd->surface) cairo_surface_destroy(pd->surface); pd->surface = NULL;
-   if (pd->ctx) cairo_destroy(pd->ctx); pd->ctx = NULL;
+   if (pd->surface)
+     cairo_surface_destroy(pd->surface);
+   pd->surface = NULL;
 
-   pd->pixels = NULL;
-   pd->width = 0;
-   pd->height = 0;
+   eo_do_super(obj, MY_CLASS,
+               ok = ector_buffer_pixels_set(pixels, width, height, stride,
+                                            cspace, writable, l, r, t, b));
 
-   if (pixels)
+   if (ok && pixels)
      {
         pd->surface = cairo_image_surface_create_for_data(pixels,
                                                           CAIRO_FORMAT_ARGB32,
-                                                          width, height, width);
+                                                          width, height, pd->base->stride);
         if (!pd->surface) goto end;
 
-        pd->ctx = cairo_create(pd->surface);
-        if (!pd->ctx) goto end;
+        ctx = cairo_create(pd->surface);
      }
-   pd->pixels = pixels;
-   pd->width = width;
-   pd->height = height;
 
  end:
-   eo_do(obj,
-         ector_cairo_surface_context_set(pd->ctx),
-         ector_surface_size_set(pd->width, pd->height));
+   evas_common_cpu_end_opt();
+   eo_do(obj, ector_cairo_surface_context_set(ctx));
+   return ok;
 }
 
-static void
+void
 _ector_cairo_software_surface_surface_get(Eo *obj EINA_UNUSED, Ector_Cairo_Software_Surface_Data *pd, void **pixels, unsigned int *width, unsigned int *height)
 {
-   if (pixels) *pixels = pd->pixels;
-   if (width) *width = pd->width;
-   if (height) *height = pd->height;
+   if (pixels) *pixels = pd->base->pixels.u8;
+   if (width) *width = pd->base->generic->w;
+   if (height) *height = pd->base->generic->h;
+}
+
+static Eo_Base *
+_ector_cairo_software_surface_eo_base_constructor(Eo *obj, Ector_Cairo_Software_Surface_Data *pd)
+{
+   eo_do_super(obj, MY_CLASS, obj = eo_constructor());
+   pd->base = eo_data_ref(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
+   pd->base->generic = eo_data_ref(obj, ECTOR_GENERIC_BUFFER_MIXIN);
+   pd->base->generic->eo = obj;
+   return obj;
+}
+
+EOLIAN static void
+_ector_cairo_software_surface_eo_base_destructor(Eo *obj, Ector_Cairo_Software_Surface_Data *pd)
+{
+   eo_data_unref(obj, pd->base);
+   eo_do_super(obj, MY_CLASS, eo_destructor());
 }
 
 #include "ector_cairo_software_surface.eo.c"
index d9b42ea..8771d75 100644 (file)
@@ -2601,18 +2601,10 @@ eng_ector_begin(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
           }
      }
    memset(buffer->software, 0, sizeof (unsigned int) * w * h);
-   if (use_cairo)
-     {
-        eo_do(ector,
-              ector_cairo_software_surface_set(buffer->software, w, h),
-              ector_surface_reference_point_set(x, y));
-     }
-   else
-     {
-        eo_do(ector,
-              ector_software_surface_set(buffer->software, w, h),
-              ector_surface_reference_point_set(x, y));
-     }
+   eo_do(ector,
+         ector_buffer_pixels_set(buffer->software, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888,
+                                 EINA_TRUE, 0, 0, 0, 0),
+         ector_surface_reference_point_set(x, y));
 }
 
 static void
@@ -2630,17 +2622,7 @@ eng_ector_end(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
    w = gl_context->w; h = gl_context->h;
    mul_use = gl_context->dc->mul.use;
 
-   if (use_cairo)
-     {
-        eo_do(ector,
-              ector_cairo_software_surface_set(NULL, 0, 0));
-     }
-   else
-     {
-        eo_do(ector,
-              ector_software_surface_set(NULL, 0, 0));
-     }
-
+   eo_do(ector, ector_buffer_pixels_set(NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0));
    eng_image_data_put(data, buffer->gl, buffer->software);
 
    if (!mul_use)
index 2c47042..8d4e789 100644 (file)
@@ -1,18 +1,11 @@
-class Ector.Cairo_Software.Surface (Ector.Cairo.Surface)
+class Ector.Cairo_Software.Surface (Ector.Cairo.Surface, Ector.Software.Buffer.Base)
 {
    eo_prefix: ector_cairo_software_surface;
    legacy_prefix: null;
-   methods {
-      @property surface {
-         set {
-        }
-        get {
-        }
-        values {
-           pixels: void *;
-           width: uint;
-           height: uint;
-        }
-      }
+   methods {}
+   implements {
+      Ector.Generic.Buffer.pixels_set;
+      Eo.Base.constructor;
+      Eo.Base.destructor;
    }
 }
index ffa3231..2d4658a 100644 (file)
@@ -10,6 +10,9 @@
 #include "evas_common_private.h"
 #include "evas_private.h"
 #include "ector_cairo_software_surface.eo.h"
+#include "ector_buffer.h"
+
+#define MY_CLASS ECTOR_CAIRO_SOFTWARE_SURFACE_CLASS
 
 #define USE(Obj, Sym, Error)                            \
   if (!Sym) Sym = _ector_cairo_symbol_get(Obj, #Sym);   \
@@ -49,57 +52,76 @@ typedef struct _Ector_Cairo_Software_Surface_Data Ector_Cairo_Software_Surface_D
 struct _Ector_Cairo_Software_Surface_Data
 {
    cairo_surface_t *surface;
-
-   void *pixels;
-
-   unsigned int width;
-   unsigned int height;
+   Ector_Software_Buffer_Base_Data *base;
 };
 
-void
-_ector_cairo_software_surface_surface_set(Eo *obj, Ector_Cairo_Software_Surface_Data *pd, void *pixels, unsigned int width, unsigned int height)
+EOLIAN static Eina_Bool
+_ector_cairo_software_surface_ector_generic_buffer_pixels_set(Eo *obj, Ector_Cairo_Software_Surface_Data *pd,
+                                                              void *pixels, int width, int height, int stride,
+                                                              Efl_Gfx_Colorspace cspace, Eina_Bool writable,
+                                                              unsigned char l, unsigned char r, unsigned char t, unsigned char b)
 {
    cairo_t *ctx = NULL;
+   Eina_Bool ok = EINA_FALSE;
 
-   USE(obj, cairo_image_surface_create_for_data, );
-   USE(obj, cairo_surface_destroy, );
-   USE(obj, cairo_create, );
-   USE(obj, cairo_destroy, );
+   if ((cspace != EFL_GFX_COLORSPACE_ARGB8888) || !writable)
+     {
+        ERR("Unsupported surface type!");
+        return EINA_FALSE;
+     }
 
-   if (pd->surface) cairo_surface_destroy(pd->surface); pd->surface = NULL;
+   USE(obj, cairo_image_surface_create_for_data, EINA_FALSE);
+   USE(obj, cairo_surface_destroy, EINA_FALSE);
+   USE(obj, cairo_create, EINA_FALSE);
+   USE(obj, cairo_destroy, EINA_FALSE);
 
-   pd->pixels = NULL;
-   pd->width = 0;
-   pd->height = 0;
+   if (pd->surface)
+     cairo_surface_destroy(pd->surface);
+   pd->surface = NULL;
 
-   if (pixels)
+   eo_do_super(obj, MY_CLASS,
+               ok = ector_buffer_pixels_set(pixels, width, height, stride,
+                                            cspace, writable, l, r, t, b));
+
+   if (ok && pixels)
      {
         pd->surface = cairo_image_surface_create_for_data(pixels,
                                                           CAIRO_FORMAT_ARGB32,
-                                                          width, height, width * sizeof (int));
+                                                          width, height, pd->base->stride);
         if (!pd->surface) goto end;
 
         ctx = cairo_create(pd->surface);
      }
 
-   pd->pixels = pixels;
-   pd->width = width;
-   pd->height = height;
-
  end:
    evas_common_cpu_end_opt();
-
-   eo_do(obj,
-         ector_cairo_surface_context_set(ctx),
-         ector_surface_size_set(pd->width, pd->height));
+   eo_do(obj, ector_cairo_surface_context_set(ctx));
+   return ok;
 }
 
 void
 _ector_cairo_software_surface_surface_get(Eo *obj EINA_UNUSED, Ector_Cairo_Software_Surface_Data *pd, void **pixels, unsigned int *width, unsigned int *height)
 {
-   if (pixels) *pixels = pd->pixels;
-   if (width) *width = pd->width;
-   if (height) *height = pd->height;
+   if (pixels) *pixels = pd->base->pixels.u8;
+   if (width) *width = pd->base->generic->w;
+   if (height) *height = pd->base->generic->h;
+}
+
+static Eo_Base *
+_ector_cairo_software_surface_eo_base_constructor(Eo *obj, Ector_Cairo_Software_Surface_Data *pd)
+{
+   eo_do_super(obj, MY_CLASS, obj = eo_constructor());
+   pd->base = eo_data_ref(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
+   pd->base->generic = eo_data_ref(obj, ECTOR_GENERIC_BUFFER_MIXIN);
+   pd->base->generic->eo = obj;
+   return obj;
+}
+
+EOLIAN static void
+_ector_cairo_software_surface_eo_base_destructor(Eo *obj, Ector_Cairo_Software_Surface_Data *pd)
+{
+   eo_data_unref(obj, pd->base);
+   eo_do_super(obj, MY_CLASS, eo_destructor());
 }
 
 #include "ector_cairo_software_surface.eo.c"
index e148813..d1a48f8 100644 (file)
@@ -406,7 +406,7 @@ struct _Evas_Thread_Command_Ector
 struct _Evas_Thread_Command_Ector_Surface
 {
    Ector_Surface *ector;
-   void *surface;
+   void *pixels;
    int x, y;
 };
 
@@ -3884,7 +3884,7 @@ static void
 _draw_thread_ector_surface_set(void *data)
 {
    Evas_Thread_Command_Ector_Surface *ector_surface = data;
-   RGBA_Image *surface = ector_surface->surface;
+   RGBA_Image *surface = ector_surface->pixels;
    void *pixels = NULL;
    unsigned int w = 0;
    unsigned int h = 0;
@@ -3903,18 +3903,10 @@ _draw_thread_ector_surface_set(void *data)
         y = ector_surface->y;
      }
 
-   if (use_cairo)
-     {
-        eo_do(ector_surface->ector,
-              ector_cairo_software_surface_set(pixels, w, h),
-              ector_surface_reference_point_set(x, y));
-     }
-   else
-     {
-        eo_do(ector_surface->ector,
-              ector_software_surface_set(pixels, w, h),
-              ector_surface_reference_point_set(x, y));
-     }
+   eo_do(ector_surface->ector,
+         ector_buffer_pixels_set(pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888,
+                                 EINA_TRUE, 0, 0, 0, 0),
+         ector_surface_reference_point_set(x, y));
 
    eina_mempool_free(_mp_command_ector_surface, ector_surface);
 }
@@ -3941,7 +3933,7 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface
         if (!nes) return ;
 
         nes->ector = ector;
-        nes->surface = surface;
+        nes->pixels = surface;
         nes->x = x;
         nes->y = y;
 
@@ -3958,18 +3950,10 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface
         w = sf->cache_entry.w;
         h = sf->cache_entry.h;
 
-        if (use_cairo)
-          {
-             eo_do(ector,
-                   ector_cairo_software_surface_set(pixels, w, h),
-                   ector_surface_reference_point_set(x, y));
-          }
-        else
-          {
-             eo_do(ector,
-                   ector_software_surface_set(pixels, w, h),
-                   ector_surface_reference_point_set(x, y));
-          }
+        eo_do(ector,
+              ector_buffer_pixels_set(pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888,
+                                      EINA_TRUE, 0, 0, 0, 0),
+              ector_surface_reference_point_set(x, y));
      }
 }
 
@@ -3984,23 +3968,13 @@ eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *
         if (!nes) return ;
 
         nes->ector = ector;
-        nes->surface = NULL;
+        nes->pixels = NULL;
 
         QCMD(_draw_thread_ector_surface_set, nes);
      }
    else
      {
-        if (use_cairo)
-          {
-             eo_do(ector,
-                   ector_cairo_software_surface_set(NULL, 0, 0));
-          }
-        else
-          {
-             eo_do(ector,
-                   ector_software_surface_set(NULL, 0, 0));
-          }
-
+        eo_do(ector, ector_renderer_surface_set(NULL));
         evas_common_cpu_end_opt();
      }
 }