Ector: Use Ector Buffer inside SW and Cairo renderers

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.
This commit is contained in:
Jean-Philippe Andre 2015-12-01 15:22:20 +09:00
parent 0cf5719e52
commit bad7911cd0
26 changed files with 323 additions and 395 deletions

View 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 \

View 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;

View File

@ -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;

View 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"

View 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;

View 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]]

View 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

View 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);
}

View 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;

View 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*;
}

View File

@ -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"

View 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"

View 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());

View 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 void
_ector_software_buffer_eo_base_destructor(Eo *obj, Ector_Software_Buffer_Data *pd)
EOLIAN static Eo_Base *
_ector_software_buffer_eo_base_constructor(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_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, void *data EINA_UNUSED)
{
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"

View 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;
}
}

View File

@ -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;
}
}

View 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;

View 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;
}

View 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());

View 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;

View 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;
}
}

View 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 (pd->surface) cairo_surface_destroy(pd->surface); pd->surface = NULL;
if (pd->ctx) cairo_destroy(pd->ctx); pd->ctx = NULL;
if ((cspace != EFL_GFX_COLORSPACE_ARGB8888) || !writable)
{
ERR("Unsupported surface type!");
return EINA_FALSE;
}
pd->pixels = NULL;
pd->width = 0;
pd->height = 0;
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 (pixels)
if (pd->surface)
cairo_surface_destroy(pd->surface);
pd->surface = NULL;
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);
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"

View 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)

View 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;
}
}

View 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"

View 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();
}
}