evas filters: Refactor ector and gfx filters A LOT

Alright, so this is a massive patch that is the result of
trying to get rid of unused or poorly implemented classes in
ector. Originally ector was meant to support VG but extend to
things like filters as well. At the moment, ector's design
makes it quite hard to plug in the filters.

For now I think it's easier to implement the GL support for
the filters directly in the engine, where I hope to interfere
as little as possible.

This massive patch keeps only the required minimum to support
a versatile gl buffer that can be mapped, drawn or rendered to (FBO).
It's extremely inefficient as it relies on glReadPixels and lots
of texture uploads, as well as conversions between ARGB and Alpha.

Another type of GL buffer is a wrap around an existing GL image,
but that one is read-only (map or draw: no write map, no FBO).

No, all the filters run fine, and the high-level implementation
(evas_filters.c) does not need to know whether the underlying engine
is SW or GL. One problem though appears with the blending or blurring
of some Alpha buffers, the colors are wrong.

This patch removes more lines than it adds so it must be good ;)
This commit is contained in:
Jean-Philippe Andre 2017-01-18 11:47:25 +09:00
parent fb52c15e85
commit 2ef8d6f39a
45 changed files with 1088 additions and 1366 deletions

View File

@ -5,7 +5,6 @@ ector_eolian_files_generic = \
lib/ector/ector_buffer.eo \
lib/ector/ector_renderer.eo \
lib/ector/ector_renderer_shape.eo \
lib/ector/ector_renderer_buffer.eo \
lib/ector/ector_renderer_gradient.eo \
lib/ector/ector_renderer_gradient_radial.eo \
lib/ector/ector_renderer_gradient_linear.eo
@ -28,7 +27,6 @@ ector_eolian_files_software = \
lib/ector/software/ector_software_buffer_base.eo \
lib/ector/software/ector_renderer_software.eo \
lib/ector/software/ector_renderer_software_shape.eo \
lib/ector/software/ector_renderer_software_buffer.eo \
lib/ector/software/ector_renderer_software_gradient_radial.eo \
lib/ector/software/ector_renderer_software_gradient_linear.eo
ector_eolian_software_h = $(ector_eolian_files_software:%.eo=%.eo.h)
@ -37,7 +35,6 @@ ector_eolian_software_h = $(ector_eolian_files_software:%.eo=%.eo.h)
ector_eolian_files_gl = \
lib/ector/gl/ector_gl_surface.eo \
lib/ector/gl/ector_gl_buffer.eo \
lib/ector/gl/ector_gl_buffer_base.eo \
lib/ector/gl/ector_renderer_gl.eo \
lib/ector/gl/ector_renderer_gl_shape.eo \
lib/ector/gl/ector_renderer_gl_gradient_radial.eo \
@ -84,7 +81,6 @@ lib/ector/ector_gl_internal.h \
lib/ector/ector_buffer.c \
lib/ector/ector_renderer_shape.c \
lib/ector/ector_renderer.c \
lib/ector/ector_renderer_buffer.c \
lib/ector/ector_renderer_gradient.c \
lib/ector/ector_renderer_gradient_radial.c \
lib/ector/ector_renderer_gradient_linear.c
@ -121,7 +117,6 @@ lib_ector_libector_la_SOURCES += \
lib/ector/software/ector_renderer_software_gradient_linear.c \
lib/ector/software/ector_renderer_software_gradient_radial.c \
lib/ector/software/ector_renderer_software_shape.c \
lib/ector/software/ector_renderer_software_buffer.c \
lib/ector/software/ector_software_gradient.c \
lib/ector/software/ector_software_rasterizer.c \
lib/ector/software/ector_software_surface.c \
@ -138,7 +133,6 @@ lib/ector/gl/ector_renderer_gl_gradient_radial.c \
lib/ector/gl/ector_renderer_gl_shape.c \
lib/ector/gl/ector_renderer_gl.c \
lib/ector/gl/ector_gl_buffer.c \
lib/ector/gl/ector_gl_buffer_base.c \
lib/ector/gl/ector_gl_surface.c \
lib/ector/gl/ector_gl_private.h \
lib/ector/gl/shader/ector_gl_shaders.x \

View File

@ -842,7 +842,6 @@ modules/evas/engines/gl_generic/Evas_Engine_GL_Generic.h \
modules/evas/engines/gl_generic/Evas_Engine_GL_Shared.h \
modules/evas/engines/gl_generic/evas_ector_gl_buffer.c \
modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.c \
modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.c \
modules/evas/engines/gl_generic/filters/gl_engine_filter.h \
modules/evas/engines/gl_generic/filters/gl_filter_blend.c \
$(NULL)
@ -850,7 +849,6 @@ $(NULL)
evas_gl_generic_eolian_files = \
modules/evas/engines/gl_generic/evas_ector_gl_buffer.eo \
modules/evas/engines/gl_generic/evas_ector_gl_image_buffer.eo \
modules/evas/engines/gl_generic/evas_ector_gl_rgbaimage_buffer.eo \
$(NULL)
evas_gl_generic_eolian_c = $(evas_gl_generic_eolian_files:%.eo=%.eo.c)

View File

@ -47,6 +47,8 @@ static const Filter_Image images_anim[] = {
/* builtin filter examples */
static const Filter templates[] = {
{ "Custom", NULL, NULL },
{ "Simple blend",
"blend { color = 'darkblue' }", NULL },
{ "Black shadow",
"if not myColor then myColor = color('yellow') end\n"
"blur { 6, ox = 2, oy = 2, color = 'black' }\n"
@ -521,13 +523,19 @@ test_gfx_filters(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *eve
efl_ui_text_scrollable_set(efl_added, 1));
efl_event_callback_add(o, EFL_UI_TEXT_EVENT_CHANGED_USER, _code_changed, win);
// Insert filter code inside style string: DEFAULT='blah blah <here>'
buf = eina_strbuf_new();
eina_strbuf_append(buf, efl_canvas_text_style_get(o, NULL));
eina_strbuf_insert(buf, " gfx_filter=code", eina_strbuf_length_get(buf) - 1);
efl_gfx_filter_program_set(o, code_filter, "code");
efl_canvas_text_style_set(o, NULL, eina_strbuf_string_get(buf));
eina_strbuf_free(buf);
// HACK: For now only set filter on code if engine is not GL (WIP)
const char *engine = ecore_evas_engine_name_get
(ecore_evas_ecore_evas_get(evas_object_evas_get(win)));
if (engine && !strstr(engine, "gl"))
{
// Insert filter code inside style string: DEFAULT='blah blah <here>'
buf = eina_strbuf_new();
eina_strbuf_append(buf, efl_canvas_text_style_get(o, NULL));
eina_strbuf_insert(buf, " gfx_filter=code", eina_strbuf_length_get(buf) - 1);
efl_gfx_filter_program_set(o, code_filter, "code");
efl_canvas_text_style_set(o, NULL, eina_strbuf_string_get(buf));
eina_strbuf_free(buf);
}
// FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
// Efl.Ui.Text doesn't seem to trigger the proper events during edit

View File

@ -51,9 +51,8 @@ struct _Ector_Cairo_Software_Surface_Data
EOLIAN static Eina_Bool
_ector_cairo_software_surface_ector_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)
void *pixels, int width, int height,
Efl_Gfx_Colorspace cspace, Eina_Bool writable)
{
cairo_t *ctx = NULL;
Eina_Bool ok = EINA_FALSE;
@ -73,7 +72,7 @@ _ector_cairo_software_surface_ector_buffer_pixels_set(Eo *obj, Ector_Cairo_Softw
cairo_surface_destroy(pd->surface);
pd->surface = NULL;
ok = ector_buffer_pixels_set(efl_super(obj, MY_CLASS), pixels, width, height, stride, cspace, writable, l, r, t, b);
ok = ector_buffer_pixels_set(efl_super(obj, MY_CLASS), pixels, width, height, cspace, writable);
if (ok && pixels)
{

View File

@ -14,15 +14,6 @@ _ector_buffer_cspace_get(Eo *obj EINA_UNUSED, Ector_Buffer_Data *pd)
return pd->cspace;
}
EOLIAN static void
_ector_buffer_border_get(Eo *obj EINA_UNUSED, Ector_Buffer_Data *pd EINA_UNUSED, int *l, int *r, int *t, int *b)
{
if (l) *l = pd->l;
if (r) *r = pd->r;
if (t) *t = pd->t;
if (b) *b = pd->b;
}
EOLIAN static void
_ector_buffer_size_get(Eo *obj EINA_UNUSED, Ector_Buffer_Data *pd, int *w, int *h)
{

View File

@ -24,6 +24,7 @@ enum Ector.Buffer.Access_Flag {
mixin Ector.Buffer
{
[[2D pixel buffer interface for Ector
@since 1.17
]]
eo_prefix: ector_buffer;
@ -76,38 +77,11 @@ mixin Ector.Buffer
@in pixels: void_ptr; [[If $null, allocates an empty buffer]]
@in width: int; [[Buffer width]]
@in height: int; [[Buffer height]]
@in stride: int; [[Can be 0]]
@in cspace: Efl.Gfx.Colorspace; [[Buffer colorspace]]
@in writable: bool; [[Buffer is writable]]
@in l: ubyte; [[Left border pixels, usually 0 or 1]]
@in r: ubyte; [[Right border pixels, usually 0 or 1]]
@in t: ubyte; [[Top border pixels, usually 0 or 1]]
@in b: ubyte; [[Bottom border pixels, usually 0 or 1]]
}
return: bool; [[True if pixels_set was successful]]
}
span_get @pure_virtual {
[[Get a single horizontal span of length w starting from (x,y)
Call span_free() to release it. This function will try not to
allocate any new buffer, whenever possible. This means the data
might be mapped directly from the backing memory buffer.
]]
params {
@in x: int; [[Ranges from -l to w+r-1]]
@in y: int; [[Ranges from -t to h+b-1]]
@in w: uint; [[Ranges from 1 to w+l+r]]
@in cspace: Efl.Gfx.Colorspace; [[Requested colorspace, may trigger conversion on the fly.]]
@out length: uint; [[Length in bytes of the returned buffer]]
}
return: ptr(uint8); [[A temporary memory buffer containing the pixels requested.]]
}
span_free @pure_virtual {
[[Must be called as soon as possible after span_get]]
params {
data: ptr(uint8); [[Data to be freed]]
}
}
@property flags {
[[The capabilities of this buffer]]
get {}
@ -115,16 +89,6 @@ mixin Ector.Buffer
flag: Ector.Buffer.Flag; [[A bitmask of capability flags]]
}
}
@property border {
[[Duplicated pixel borders of this buffer, used for GL scaling]]
get {}
values {
l: int; [[Left border]]
r: int; [[Right border]]
t: int; [[Top border]]
b: int; [[Bottom border]]
}
}
}
events {
detached; [[Emitted whenever the previously attached pixels are detached during pixels_set]]

View File

@ -18,13 +18,11 @@ typedef Eo Ector_Buffer;
typedef struct _Ector_Buffer_Data Ector_Buffer_Data;
typedef struct _Ector_Software_Buffer_Base_Data Ector_Software_Buffer_Base_Data;
typedef struct _Ector_GL_Buffer_Base_Data Ector_GL_Buffer_Base_Data;
struct _Ector_Buffer_Data
{
Ector_Buffer *eo;
unsigned int w, h;
unsigned char l, r, t, b;
Efl_Gfx_Colorspace cspace;
Eina_Bool immutable : 1; // pixels_set is forbidden
};
@ -45,17 +43,4 @@ struct _Ector_Software_Buffer_Base_Data
Eina_Bool nofree : 1; // pixel data should not be free()'ed
};
struct _Ector_GL_Buffer_Base_Data
{
Ector_Buffer_Data *generic;
int texid;
int fboid;
struct {
// x,y offset within the atlas
// w,h size of the atlas itself
int x, y, w, h;
} atlas;
Eina_Bool whole : 1;
};
#endif

View File

@ -3,7 +3,6 @@
#include "ector_renderer.eo.h"
#include "ector_renderer_shape.eo.h"
#include "ector_renderer_buffer.eo.h"
#include "ector_renderer_gradient.eo.h"
#include "ector_renderer_gradient_linear.eo.h"
#include "ector_renderer_gradient_radial.eo.h"

View File

@ -1,45 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#else
# define EFL_BETA_API_SUPPORT
#endif
#include <Eo.h>
#include "ector_private.h"
#include "ector_renderer_buffer.eo.h"
#define MY_CLASS ECTOR_RENDERER_BUFFER_MIXIN
EOLIAN static void
_ector_renderer_buffer_efl_gfx_fill_fill_get(Eo *obj EINA_UNUSED, Ector_Renderer_Buffer_Data *pd, int *x, int *y, int *w, int *h)
{
if (x) *x = pd->fill.x;
if (y) *y = pd->fill.y;
if (w) *w = pd->fill.w;
if (h) *h = pd->fill.h;
}
EOLIAN static void
_ector_renderer_buffer_efl_gfx_fill_fill_set(Eo *obj EINA_UNUSED, Ector_Renderer_Buffer_Data *pd, int x, int y, int w, int h)
{
if (w < 0) w = 0;
if (h < 0) h = 0;
pd->fill.x = x;
pd->fill.y = y;
pd->fill.w = w;
pd->fill.h = h;
}
EOLIAN static void
_ector_renderer_buffer_buffer_set(Eo *obj EINA_UNUSED, Ector_Renderer_Buffer_Data *pd, Ector_Buffer *buf)
{
_efl_xrefplace(&pd->eo_buffer, buf, obj);
}
EOLIAN static Ector_Buffer *
_ector_renderer_buffer_buffer_get(Eo *obj EINA_UNUSED, Ector_Renderer_Buffer_Data *pd)
{
return pd->eo_buffer;
}
#include "ector_renderer_buffer.eo.c"

View File

@ -1,17 +0,0 @@
mixin Ector.Renderer.Buffer (Efl.Interface, Ector.Renderer, Efl.Gfx.Fill)
{
[[Ector buffers have a default fill set to repeat]]
eo_prefix: ector_renderer_buffer;
methods {
@property buffer {
set { [[Sets the source buffer for this renderer, adds a ref]] }
get { [[Return the current source, no ref change]] }
values {
buf: Ector.Buffer; [[Buffer]]
}
}
}
implements {
Efl.Gfx.Fill.fill { get; set; }
}
}

View File

@ -15,7 +15,6 @@ typedef Eo Ector_Cairo_Surface;
typedef unsigned int GLuint;
typedef short GLshort;
#include "gl/ector_gl_buffer_base.eo.h"
#include "gl/ector_gl_buffer.eo.h"
#include "gl/ector_gl_surface.eo.h"
#include "gl/ector_renderer_gl.eo.h"

View File

@ -1,4 +1,4 @@
class Ector.GL.Buffer (Efl.Object, Ector.GL.Buffer.Base)
class Ector.GL.Buffer (Efl.Object, Ector.Buffer)
{
[[Ector GL buffer class]]
data: null;

View File

@ -1,65 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "Ector_GL.h"
#include "ector_gl_private.h"
#include "ector_buffer.h"
#include "ector_gl_buffer_base.eo.h"
#define MY_CLASS ECTOR_GL_BUFFER_BASE_MIXIN
EOLIAN static int
_ector_gl_buffer_base_texture_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd)
{
return pd->texid;
}
EOLIAN static int
_ector_gl_buffer_base_fbo_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd)
{
return pd->fboid;
}
EOLIAN static Eina_Bool
_ector_gl_buffer_base_whole_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd)
{
return pd->whole;
}
EOLIAN static void
_ector_gl_buffer_base_vertices_get(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd, double *x, double *y, double *w, double *h)
{
if (x) *x = (double) pd->atlas.x / pd->atlas.w;
if (y) *y = (double) pd->atlas.y / pd->atlas.h;
if (w) *w = (double) pd->generic->w / pd->atlas.w;
if (h) *h = (double) pd->generic->h / pd->atlas.h;
}
EOLIAN static void
_ector_gl_buffer_base_attach(Eo *obj EINA_UNUSED, Ector_GL_Buffer_Base_Data *pd,
int texid, int fboid, Efl_Gfx_Colorspace cspace,
int imw, int imh, int tx, int ty, int tw, int th,
int l, int r, int t, int b)
{
EINA_SAFETY_ON_NULL_RETURN(pd->generic);
EINA_SAFETY_ON_FALSE_RETURN(!pd->generic->immutable);
pd->generic->cspace = cspace;
pd->generic->w = imw;
pd->generic->h = imh;
pd->atlas.x = tx;
pd->atlas.y = ty;
pd->atlas.w = tw;
pd->atlas.h = th;
pd->generic->l = l;
pd->generic->r = r;
pd->generic->t = t;
pd->generic->b = b;
if (!(tx - l) && !(ty - t) && ((tw + l + r) == imw) && ((th + t + b) == imh))
pd->whole = EINA_TRUE;
pd->fboid = fboid;
pd->texid = texid;
}
#include "ector_gl_buffer_base.eo.c"

View File

@ -1,60 +0,0 @@
mixin Ector.GL.Buffer.Base (Ector.Buffer)
{
[[Ector GL buffer base class]]
methods {
@property texture {
[[GL texture ID]]
get {}
values {
texid: int; [[GL texture ID]]
}
}
@property fbo {
[[Framebuffer object ID]]
get {}
values {
fboid: int; [[GL framebuffer ID, 0 if there is no FBO]]
}
}
@property whole {
[[If $true, the image is covering the entire GL texture, ie. it's not
part of an atlas.
]]
get {}
values {
is_whole: bool; [[$true if the image is covering the whole GL texture, $false otherwise]]
}
}
@property vertices {
[[Returns the texture vertices to draw this image with no rotation
The 4 points are then defined as (x,y), (x+w,y), (x,y+h), (x+w,y+h).
]]
get {}
values {
x: double; [[X position of this image inside the texture atlas, from 0 to 1]]
y: double; [[Y position of this image inside the texture atlas, from 0 to 1]]
w: double; [[Width of this image inside the texture atlas, from 0 to 1]]
h: double; [[Height of this image inside the texture atlas, from 0 to 1]]
}
}
attach @protected {
[[Attach to an existing texture (or FBO). Used from child classes.]]
params {
texid: int; [[GL texture ID]]
fboid: int; [[Framebuffer object ID]]
cspace: Efl.Gfx.Colorspace; [[Colorspace]]
imw: int; [[Image width]]
imh: int; [[Image height]]
tx: int; [[Texture X coordinate]]
ty: int; [[Texture Y coordinate]]
tw: int; [[Texture width]]
th: int; [[Texture height]]
l: int; [[Left padding]]
r: int; [[Right padding]]
t: int; [[Top padding]]
b: int; [[Bottom padding]]
}
}
}
}

View File

@ -10,7 +10,6 @@
#include "software/ector_software_buffer_base.eo.h"
#include "software/ector_renderer_software.eo.h"
#include "software/ector_renderer_software_shape.eo.h"
#include "software/ector_renderer_software_buffer.eo.h"
#include "software/ector_renderer_software_gradient_linear.eo.h"
#include "software/ector_renderer_software_gradient_radial.eo.h"

View File

@ -1,72 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#else
# define EFL_BETA_API_SUPPORT
#endif
#include <Eo.h>
#include "Ector_Software.h"
#include "ector_private.h"
#include "ector_software_private.h"
#define MY_CLASS ECTOR_RENDERER_SOFTWARE_BUFFER_CLASS
typedef struct
{
Ector_Renderer_Data *base;
Software_Rasterizer *surface;
Ector_Buffer *eo_buffer;
} Ector_Renderer_Software_Buffer_Data;
EOLIAN static void
_ector_renderer_software_buffer_buffer_set(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd, Ector_Buffer *buf)
{
_efl_xrefplace(&pd->eo_buffer, buf, obj);
}
EOLIAN static Ector_Buffer *
_ector_renderer_software_buffer_buffer_get(Eo *obj EINA_UNUSED, Ector_Renderer_Software_Buffer_Data *pd)
{
return pd->eo_buffer;
}
EOLIAN static Eina_Bool
_ector_renderer_software_buffer_ector_renderer_software_fill(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd)
{
Ector_Software_Buffer *buffer = efl_data_scope_get(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
ector_software_rasterizer_buffer_set(pd->surface, buffer);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_ector_renderer_software_buffer_ector_renderer_prepare(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd)
{
if (!pd->surface)
pd->surface = efl_data_xref(pd->base->surface, ECTOR_SOFTWARE_SURFACE_CLASS, obj);
return EINA_TRUE;
}
EOLIAN static unsigned int
_ector_renderer_software_buffer_ector_renderer_crc_get(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd)
{
Ector_Software_Buffer_Base_Data *buffer = efl_data_scope_get(pd->eo_buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
unsigned int crc;
crc = ector_renderer_crc_get(efl_super(obj, MY_CLASS));
crc = eina_crc((const char *) buffer, sizeof(*buffer), crc, EINA_FALSE);
if (pd->surface)
crc = eina_crc((const char *) pd->surface, sizeof(*pd->surface), crc, EINA_FALSE);
return crc;
}
EOLIAN static void
_ector_renderer_software_buffer_efl_object_destructor(Eo *obj, Ector_Renderer_Software_Buffer_Data *pd)
{
efl_data_xunref(pd->base->surface, pd->surface, obj);
efl_destructor(efl_super(obj, MY_CLASS));
}
#include "ector_renderer_software_buffer.eo.c"

View File

@ -1,20 +0,0 @@
class Ector.Renderer.Software.Buffer (Ector.Renderer.Software, Ector.Renderer.Buffer)
{
[[Ecto software renderer buffer class]]
methods {
@property buffer {
[[Buffer property]]
set {}
get {}
values {
buf: Ector.Buffer; [[Buffer]]
}
}
}
implements {
Ector.Renderer.prepare;
Ector.Renderer.crc { get; }
Ector.Renderer.Software.fill;
Efl.Object.destructor;
}
}

View File

@ -16,24 +16,13 @@ typedef struct _Ector_Software_Buffer_Map
{
EINA_INLIST;
uint8_t *ptr;
unsigned int size; // in bytes
unsigned int size, stride; // in bytes
unsigned int x, y, w, h;
Efl_Gfx_Colorspace cspace;
Eina_Bool allocated;
Ector_Buffer_Access_Flag mode;
} Ector_Software_Buffer_Map;
static inline int
_min_stride_calc(int width, Efl_Gfx_Colorspace cspace)
{
switch (cspace)
{
case EFL_GFX_COLORSPACE_ARGB8888: return width * 4;
case EFL_GFX_COLORSPACE_GRY8: return width;
default: return 0;
}
}
/* FIXME: Conversion routines don't belong here */
static inline void
_pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len)
@ -64,10 +53,7 @@ _ector_software_buffer_base_pixels_clear(Eo *obj, Ector_Software_Buffer_Base_Dat
return;
if (pd->internal.maps)
{
CRI("Can not call pixels_clear when the buffer is mapped.");
return;
}
fail("Can not call pixels_clear when the buffer is mapped.");
efl_event_callback_call(obj, ECTOR_BUFFER_EVENT_DETACHED, pd->pixels.u8);
if (!pd->nofree)
@ -76,54 +62,37 @@ _ector_software_buffer_base_pixels_clear(Eo *obj, Ector_Software_Buffer_Base_Dat
}
pd->pixels.u8 = NULL;
pd->nofree = EINA_FALSE;
return;
on_fail:
return;
}
EOLIAN static Eina_Bool
_ector_software_buffer_base_ector_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)
void *pixels, int width, int height,
Efl_Gfx_Colorspace cspace, Eina_Bool writable)
{
unsigned px;
unsigned pxs, stride;
if (pd->generic->immutable)
{
ERR("This buffer is immutable.");
return EINA_FALSE;
}
fail("This buffer is immutable.");
if (pd->internal.maps)
{
ERR("Can not call pixels_set when the buffer is mapped.");
return EINA_FALSE;
}
fail("Can not call pixels_set when the buffer is mapped.");
// safety check
px = _min_stride_calc(1, cspace);
if (px && ((unsigned long long)(uintptr_t)pixels) & (px - 1))
ERR("Pixel data is not aligned to %u bytes!", px);
if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
pxs = 4;
else if (cspace == EFL_GFX_COLORSPACE_GRY8)
pxs = 1;
else
fail("Unsupported colorspace: %u", cspace);
if ((cspace != EFL_GFX_COLORSPACE_ARGB8888) &&
(cspace != EFL_GFX_COLORSPACE_GRY8))
{
ERR("Unsupported colorspace: %u", cspace);
return EINA_FALSE;
}
if (!stride)
stride = _min_stride_calc(width + l + r, cspace);
else if (stride < _min_stride_calc(width + l + r, cspace))
{
ERR("Invalid stride %u for width %u (+%u+%u) cspace %u. pixels_set failed.",
stride, width, l, r, cspace);
_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 (((unsigned long long)(uintptr_t)pixels) & (pxs - 1))
fail ("Pixel data is not aligned to %u bytes!", pxs);
stride = width * pxs;
if (pd->pixels.u8 && (pd->pixels.u8 != pixels))
_ector_software_buffer_base_pixels_clear(obj, pd);
@ -135,31 +104,30 @@ _ector_software_buffer_base_ector_buffer_pixels_set(Eo *obj, Ector_Software_Buff
}
else
{
pd->pixels.u8 = calloc(stride * (height + t + b), 1);
pd->pixels.u8 = calloc(stride * height, 1);
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->stride = stride;
pd->pixel_size = px;
pd->pixel_size = pxs;
return EINA_TRUE;
on_fail:
return EINA_FALSE;
}
EOLIAN static void *
_ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd,
unsigned int *length, Ector_Buffer_Access_Flag mode,
unsigned int x, unsigned int y, unsigned int w, unsigned int h,
Efl_Gfx_Colorspace cspace EINA_UNUSED, unsigned int *stride)
unsigned int *length, Ector_Buffer_Access_Flag mode,
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 = NULL;
Eina_Bool need_cow = EINA_FALSE;
unsigned int off, k, dst_stride;
unsigned int off, k, dst_stride, pxs, pxs_dest;
if (!w) w = pd->generic->w;
if (!h) h = pd->generic->h;
@ -172,6 +140,14 @@ _ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software
if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) && !pd->writable)
fail("Can not map a read-only buffer for writing");
pxs = (pd->generic->cspace == EFL_GFX_COLORSPACE_ARGB8888) ? 4 : 1;
if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
pxs_dest = 4;
else if (cspace == EFL_GFX_COLORSPACE_GRY8)
pxs_dest = 1;
else
fail("Unsupported colorspace: %u", cspace);
if ((mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE) &&
(mode & ECTOR_BUFFER_ACCESS_FLAG_COW))
{
@ -186,20 +162,21 @@ _ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software
map = calloc(1, sizeof(*map));
if (!map) fail("Out of memory");
off = (pxs * x) + (pd->stride * y);
dst_stride = w * pxs_dest;
map->mode = mode;
map->cspace = cspace;
map->stride = dst_stride;
map->x = x;
map->y = y;
map->w = w;
map->h = h;
off = _min_stride_calc(x + pd->generic->l, pd->generic->cspace) + (pd->stride * (y + pd->generic->t));
dst_stride = _min_stride_calc(w, cspace);
if (cspace != pd->generic->cspace)
{
// convert on the fly
map->size = _min_stride_calc(w, cspace) * h;
map->size = w * h * pxs_dest;
map->allocated = EINA_TRUE;
map->ptr = malloc(map->size);
if (!map->ptr) fail("Out of memory");
@ -218,7 +195,7 @@ _ector_software_buffer_base_ector_buffer_map(Eo *obj EINA_UNUSED, Ector_Software
else if (need_cow)
{
// copy-on-write access
map->size = _min_stride_calc(w, cspace) * h;
map->size = w * h * pxs_dest;
map->allocated = EINA_TRUE;
map->ptr = malloc(map->size);
if (!map->ptr) fail("Out of memory");
@ -261,7 +238,7 @@ _ector_software_buffer_base_ector_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Softwa
{
if (map->mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE)
{
unsigned k, dst_stride;
unsigned k;
if (map->cspace != pd->generic->cspace)
{
@ -282,12 +259,10 @@ _ector_software_buffer_base_ector_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Softwa
}
else
{
dst_stride = _min_stride_calc(map->w, map->cspace);
for (k = 0; k < map->h; k++)
{
memcpy(pd->pixels.u8 + map->x + (k + map->y) * pd->stride,
map->ptr + k * dst_stride,
dst_stride);
map->ptr + k * map->stride, map->stride);
}
}
}
@ -301,33 +276,14 @@ _ector_software_buffer_base_ector_buffer_unmap(Eo *obj EINA_UNUSED, Ector_Softwa
CRI("Tried to unmap a non-mapped region!");
}
EOLIAN static uint8_t *
_ector_software_buffer_base_ector_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)
{
// ector_buffer_map
return _ector_software_buffer_base_ector_buffer_map
(obj, pd, length, ECTOR_BUFFER_ACCESS_FLAG_READ, x, y, w, 1, cspace, NULL);
}
EOLIAN static void
_ector_software_buffer_base_ector_buffer_span_free(Eo *obj, Ector_Software_Buffer_Base_Data *pd,
uint8_t *data)
{
// ector_buffer_unmap
return _ector_software_buffer_base_ector_buffer_unmap
(obj, pd, data, (unsigned int) -1);
}
EOLIAN static Ector_Buffer_Flag
_ector_software_buffer_base_ector_buffer_flags_get(Eo *obj EINA_UNUSED, Ector_Software_Buffer_Base_Data *pd)
{
return ECTOR_BUFFER_FLAG_CPU_READABLE |
ECTOR_BUFFER_FLAG_DRAWABLE |
ECTOR_BUFFER_FLAG_CPU_READABLE_FAST |
ECTOR_BUFFER_FLAG_RENDERABLE |
(pd->writable ? (ECTOR_BUFFER_FLAG_CPU_WRITABLE |
ECTOR_BUFFER_FLAG_RENDERABLE |
ECTOR_BUFFER_FLAG_CPU_WRITABLE_FAST)
: 0);
}

View File

@ -10,8 +10,6 @@ mixin Ector.Software.Buffer.Base (Ector.Buffer)
implements {
Ector.Buffer.flags { get; }
Ector.Buffer.pixels_set;
Ector.Buffer.span_get;
Ector.Buffer.span_free;
Ector.Buffer.map;
Ector.Buffer.unmap;
}

View File

@ -61,7 +61,6 @@ typedef enum _Span_Data_Type {
Solid,
LinearGradient,
RadialGradient,
Image
} Span_Data_Type;
typedef struct _Span_Data
@ -114,7 +113,6 @@ void ector_software_rasterizer_transform_set(Software_Rasterizer *rasterizer, Ei
void ector_software_rasterizer_color_set(Software_Rasterizer *rasterizer, int r, int g, int b, int a);
void ector_software_rasterizer_linear_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *linear);
void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasterizer, Ector_Renderer_Software_Gradient_Data *radial);
void ector_software_rasterizer_buffer_set(Software_Rasterizer *rasterizer, Ector_Software_Buffer *image);
void ector_software_rasterizer_clip_rect_set(Software_Rasterizer *rasterizer, Eina_Array *clips);
void ector_software_rasterizer_clip_shape_set(Software_Rasterizer *rasterizer, Shape_Rle_Data *clip);

View File

@ -76,45 +76,6 @@ _blend_gradient(int count, const SW_FT_Span *spans, void *user_data)
}
}
static void
_blend_image_argb(int count, const SW_FT_Span *spans, void *user_data)
{
Span_Data *data = user_data;
RGBA_Comp_Func comp_func;
uint32_t *buffer, *target;
uint8_t *src8;
unsigned int l, length, sy = 0;
const int pix_stride = data->raster_buffer->stride / 4;
/* FIXME:
* optimize eo call
* implement image scaling
* tile and repeat image properly
*/
comp_func = efl_draw_func_span_get(data->op, data->mul_col, EINA_TRUE);
buffer = data->raster_buffer->pixels.u32 + ((pix_stride * data->offy) + data->offx);
while (count--)
{
target = buffer + ((pix_stride * spans->y) + spans->x);
length = spans->len;
while (length)
{
l = MIN(length, data->buffer->generic->w);
src8 = ector_buffer_span_get(data->buffer->generic->eo, 0, sy, l, EFL_GFX_COLORSPACE_ARGB8888, NULL);
comp_func(target, (uint32_t *) src8, l, data->mul_col, spans->coverage);
ector_buffer_span_free(data->buffer->generic->eo, src8);
target += l;
length -= l;
}
++spans;
++sy;
if (sy >= data->buffer->generic->h)
sy = 0;
}
}
/*!
\internal
spans must be sorted on y
@ -318,9 +279,6 @@ _adjust_span_fill_methods(Span_Data *spdata)
case RadialGradient:
spdata->unclipped_blend = &_blend_gradient;
break;
case Image:
spdata->unclipped_blend = &_blend_image_argb;
break;
}
// setup clipping
@ -568,13 +526,6 @@ void ector_software_rasterizer_radial_gradient_set(Software_Rasterizer *rasteriz
rasterizer->fill_data.type = RadialGradient;
}
void ector_software_rasterizer_buffer_set(Software_Rasterizer *rasterizer,
Ector_Software_Buffer *buffer)
{
rasterizer->fill_data.buffer = efl_data_scope_get(buffer, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN);
rasterizer->fill_data.type = Image;
}
void ector_software_rasterizer_draw_rle_data(Software_Rasterizer *rasterizer,
int x, int y, uint32_t mul_col,
Efl_Gfx_Render_Op op, Shape_Rle_Data* rle)

View File

@ -12,8 +12,8 @@
static Ector_Renderer *
_ector_software_surface_ector_surface_renderer_factory_new(Eo *obj,
Ector_Software_Surface_Data *pd EINA_UNUSED,
const Efl_Class *type)
Ector_Software_Surface_Data *pd EINA_UNUSED,
const Efl_Class *type)
{
if (type == ECTOR_RENDERER_SHAPE_MIXIN)
return efl_add(ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
@ -21,9 +21,8 @@ _ector_software_surface_ector_surface_renderer_factory_new(Eo *obj,
return efl_add(ECTOR_RENDERER_SOFTWARE_GRADIENT_LINEAR_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
else if (type == ECTOR_RENDERER_GRADIENT_RADIAL_MIXIN)
return efl_add(ECTOR_RENDERER_SOFTWARE_GRADIENT_RADIAL_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
else if (type == ECTOR_RENDERER_BUFFER_MIXIN)
return efl_add(ECTOR_RENDERER_SOFTWARE_BUFFER_CLASS, NULL, ector_renderer_surface_set(efl_added, obj));
ERR("Couldn't find class for type: %s\n", efl_class_name_get(type));
ERR("Couldn't find class for type: %s", efl_class_name_get(type));
return NULL;
}
@ -49,8 +48,8 @@ _ector_software_surface_efl_object_destructor(Eo *obj, Ector_Software_Surface_Da
static void
_ector_software_surface_ector_surface_reference_point_set(Eo *obj EINA_UNUSED,
Ector_Software_Surface_Data *pd,
int x, int y)
Ector_Software_Surface_Data *pd,
int x, int y)
{
pd->x = x;
pd->y = y;

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@
#define EVAS_FILTER_MODE_BUFFER (EVAS_FILTER_MODE_LAST+2)
#define INSTR_PARAM_CHECK(a) do { if (!(a)) { \
ERR("Argument %s can not be nil in %s!", #a, instr->name); return -1; } \
ERR("Argument %s can not be nil in %s!", #a, instr->name); return NULL; } \
} while (0)
/* Note on the documentation:
@ -913,8 +913,8 @@ _blend_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
INSTR_PARAM_CHECK(src);
INSTR_PARAM_CHECK(dst);
EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0);
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0);
fillmode = _fill_mode_get(instr);
if (fillmode & (EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_REPEAT_X)) ox = 0;
@ -1022,8 +1022,8 @@ _blur_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
INSTR_PARAM_CHECK(src);
INSTR_PARAM_CHECK(dst);
EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0);
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0);
if (typestr && !strcasecmp(typestr, "box"))
type = EVAS_FILTER_BLUR_BOX;
@ -1405,8 +1405,8 @@ _displace_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
intensity = _instruction_param_geti(instr, "intensity", NULL);
src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
INSTR_PARAM_CHECK(src);
INSTR_PARAM_CHECK(dst);
EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0);
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0);
l = intensity + src->pad.l;
r = intensity + src->pad.r;
@ -1552,8 +1552,8 @@ _grow_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
radius = _instruction_param_geti(instr, "radius", NULL);
src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
INSTR_PARAM_CHECK(src);
INSTR_PARAM_CHECK(dst);
EINA_SAFETY_ON_NULL_RETURN_VAL(src, 0);
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0);
if (radius < 0) radius = 0;
@ -1684,7 +1684,7 @@ _transform_padding_update(Evas_Filter_Program *pgm EINA_UNUSED,
ox = 0;
oy = _instruction_param_geti(instr, "oy", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
INSTR_PARAM_CHECK(dst);
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 0);
if (ox < 0) l = (-ox) * 2;
else r = ox * 2;
@ -3018,15 +3018,16 @@ _fill_mode_get(Evas_Filter_Instruction *instr)
return EVAS_FILTER_FILL_MODE_NONE;
}
static int
static Evas_Filter_Command *
_instr2cmd_blend(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr, void *dc)
{
Eina_Bool isset = EINA_FALSE;
Evas_Filter_Command *cmd;
DATA32 color;
Buffer *src, *dst;
Evas_Filter_Fill_Mode fillmode;
int cmdid, ox, oy, A, R, G, B;
int ox, oy, A, R, G, B;
ox = _instruction_param_geti(instr, "ox", NULL);
oy = _instruction_param_geti(instr, "oy", NULL);
@ -3038,24 +3039,23 @@ _instr2cmd_blend(Evas_Filter_Context *ctx,
INSTR_PARAM_CHECK(dst);
if (isset) SETCOLOR(color);
cmdid = evas_filter_command_blend_add(ctx, dc, src->cid, dst->cid, ox, oy,
fillmode);
cmd = evas_filter_command_blend_add(ctx, dc, src->cid, dst->cid, ox, oy, fillmode);
if (isset) RESETCOLOR();
if (cmdid < 0) return cmdid;
return cmdid;
return cmd;
}
static int
static Evas_Filter_Command *
_instr2cmd_blur(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr, void *dc)
{
Eina_Bool colorset = EINA_FALSE, yset = EINA_FALSE, cntset = EINA_FALSE;
Evas_Filter_Blur_Type type = EVAS_FILTER_BLUR_DEFAULT;
Evas_Filter_Command *cmd;
const char *typestr;
DATA32 color;
Buffer *src, *dst;
int cmdid, ox, oy, rx, ry, A, R, G, B, count;
int ox, oy, rx, ry, A, R, G, B, count;
ox = _instruction_param_geti(instr, "ox", NULL);
oy = _instruction_param_geti(instr, "oy", NULL);
@ -3098,14 +3098,14 @@ _instr2cmd_blur(Evas_Filter_Context *ctx,
if (!yset) ry = rx;
if (colorset) SETCOLOR(color);
cmdid = evas_filter_command_blur_add(ctx, dc, src->cid, dst->cid, type,
rx, ry, ox, oy, count);
cmd = evas_filter_command_blur_add(ctx, dc, src->cid, dst->cid, type,
rx, ry, ox, oy, count);
if (colorset) RESETCOLOR();
return cmdid;
return cmd;
}
static int
static Evas_Filter_Command *
_instr2cmd_bump(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr, void *dc)
{
@ -3114,7 +3114,7 @@ _instr2cmd_bump(Evas_Filter_Context *ctx,
DATA32 color, black, white;
Buffer *src, *dst, *map;
double azimuth, elevation, depth, specular;
int cmdid, compensate;
int compensate;
color = _instruction_param_getc(instr, "color", NULL);
white = _instruction_param_getc(instr, "white", NULL);
@ -3134,15 +3134,13 @@ _instr2cmd_bump(Evas_Filter_Context *ctx,
INSTR_PARAM_CHECK(dst);
INSTR_PARAM_CHECK(map);
cmdid = evas_filter_command_bump_map_add(ctx, dc, src->cid, map->cid, dst->cid,
azimuth, elevation, depth, specular,
black, color, white, flags,
fillmode);
return cmdid;
return evas_filter_command_bump_map_add(ctx, dc, src->cid, map->cid, dst->cid,
azimuth, elevation, depth, specular,
black, color, white, flags,
fillmode);
}
static int
static Evas_Filter_Command *
_instr2cmd_displace(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr, void *dc)
{
@ -3151,7 +3149,7 @@ _instr2cmd_displace(Evas_Filter_Context *ctx,
EVAS_FILTER_DISPLACE_STRETCH | EVAS_FILTER_DISPLACE_LINEAR;
const char *flagsstr;
Buffer *src, *dst, *map;
int cmdid, intensity;
int intensity;
Eina_Bool isset = EINA_FALSE;
src = _instruction_param_getbuf(instr, "src", NULL);
@ -3176,23 +3174,19 @@ _instr2cmd_displace(Evas_Filter_Context *ctx,
else if (isset)
WRN("Invalid flags '%s' in displace operation. Using default instead", flagsstr);
cmdid = evas_filter_command_displacement_map_add(ctx, dc, src->cid, dst->cid,
map->cid, flags, intensity,
fillmode);
return cmdid;
return evas_filter_command_displacement_map_add(ctx, dc, src->cid, dst->cid,
map->cid, flags, intensity,
fillmode);
}
static int
static Evas_Filter_Command *
_instr2cmd_fill(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr, void *dc)
{
Buffer *dst;
int R, G, B, A, l, r, t, b;
Evas_Filter_Command *cmd;
Eina_Inlist *il;
DATA32 color;
int cmdid;
dst = _instruction_param_getbuf(instr, "dst", NULL);
color = _instruction_param_getc(instr, "color", NULL);
@ -3203,31 +3197,27 @@ _instr2cmd_fill(Evas_Filter_Context *ctx,
INSTR_PARAM_CHECK(dst);
SETCOLOR(color);
cmdid = evas_filter_command_fill_add(ctx, dc, dst->cid);
cmd = evas_filter_command_fill_add(ctx, dc, dst->cid);
RESETCOLOR();
if (!cmd) return NULL;
if (cmdid < 0) return -1;
il = eina_inlist_last(ctx->commands);
if (!il) return -1;
cmd = EINA_INLIST_CONTAINER_GET(il, Evas_Filter_Command);
cmd->draw.clip.l = l;
cmd->draw.clip.r = r;
cmd->draw.clip.t = t;
cmd->draw.clip.b = b;
cmd->draw.clip_mode_lrtb = EINA_TRUE;
return cmdid;
return cmd;
}
static int
static Evas_Filter_Command *
_instr2cmd_grow(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr, void *dc)
{
Evas_Filter_Command *cmd;
Buffer *src, *dst;
Eina_Bool smooth;
int cmdid, radius;
int radius;
src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
@ -3236,23 +3226,21 @@ _instr2cmd_grow(Evas_Filter_Context *ctx,
INSTR_PARAM_CHECK(src);
INSTR_PARAM_CHECK(dst);
cmdid = evas_filter_command_grow_add(ctx, dc, src->cid, dst->cid,
radius, smooth);
cmd = _evas_filter_command_get(ctx, cmdid);
cmd = evas_filter_command_grow_add(ctx, dc, src->cid, dst->cid, radius, smooth);
if (cmd) cmd->draw.need_temp_buffer = EINA_TRUE;
return cmdid;
return cmd;
}
static int
static Evas_Filter_Command *
_instr2cmd_mask(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr, void *dc)
{
Evas_Filter_Fill_Mode fillmode;
Evas_Filter_Command *cmd;
Buffer *src, *dst, *mask;
DATA32 color;
int R, G, B, A, cmdid;
int R, G, B, A;
src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
@ -3264,22 +3252,17 @@ _instr2cmd_mask(Evas_Filter_Context *ctx,
INSTR_PARAM_CHECK(mask);
SETCOLOR(color);
cmdid = evas_filter_command_mask_add(ctx, dc, src->cid, mask->cid, dst->cid, fillmode);
cmd = evas_filter_command_mask_add(ctx, dc, src->cid, mask->cid, dst->cid, fillmode);
RESETCOLOR();
if (cmdid < 0) return cmdid;
if (!cmd) return NULL;
if (!src->alpha && !mask->alpha && !dst->alpha)
{
Evas_Filter_Command *cmd;
if (!src->alpha && !mask->alpha && !dst->alpha && !ctx->gl)
cmd->draw.need_temp_buffer = EINA_TRUE;
cmd = _evas_filter_command_get(ctx, cmdid);
cmd->draw.need_temp_buffer = EINA_TRUE;
}
return cmdid;
return cmd;
}
static int
static Evas_Filter_Command *
_instr2cmd_curve(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr, void *dc)
{
@ -3289,7 +3272,6 @@ _instr2cmd_curve(Evas_Filter_Context *ctx,
Buffer *src, *dst;
DATA8 values[256];
int *points;
int cmdid;
src = _instruction_param_getbuf(instr, "src", NULL);
dst = _instruction_param_getbuf(instr, "dst", NULL);
@ -3328,12 +3310,10 @@ _instr2cmd_curve(Evas_Filter_Context *ctx,
values[x] = x;
}
cmdid = evas_filter_command_curve_add(ctx, dc, src->cid, dst->cid, values, channel);
return cmdid;
return evas_filter_command_curve_add(ctx, dc, src->cid, dst->cid, values, channel);
}
static int
static Evas_Filter_Command *
_instr2cmd_transform(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr, void *dc)
{
@ -3355,17 +3335,18 @@ _instr2cmd_transform(Evas_Filter_Context *ctx,
else
{
ERR("Invalid transform '%s'", op);
return -1;
return NULL;
}
return evas_filter_command_transform_add(ctx, dc, src->cid, dst->cid, flags, ox, oy);
}
static int
static Eina_Bool
_command_from_instruction(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr, void *dc)
{
int (* instr2cmd) (Evas_Filter_Context *, Evas_Filter_Instruction *, void *);
Evas_Filter_Command * (* instr2cmd) (Evas_Filter_Context *, Evas_Filter_Instruction *, void *);
Evas_Filter_Command *cmd;
switch (instr->type)
{
@ -3401,10 +3382,19 @@ _command_from_instruction(Evas_Filter_Context *ctx,
return EINA_TRUE;
default:
CRI("Invalid instruction type: %d", instr->type);
return -1;
return EINA_FALSE;
}
return instr2cmd(ctx, instr, dc);
cmd = instr2cmd(ctx, instr, dc);
if (!cmd) return EINA_FALSE;
if (cmd->output && ctx->gl)
{
if (ENFN->gfx_filter_supports(ENDT, cmd) == EVAS_FILTER_SUPPORT_GL)
cmd->output->is_render = EINA_TRUE;
}
return EINA_TRUE;
}
#ifdef FILTERS_DEBUG
@ -3477,7 +3467,6 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
Evas_Filter_Instruction *instr;
Eina_Bool success = EINA_FALSE;
void *dc = NULL;
int cmdid;
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(pgm, EINA_FALSE);
@ -3518,8 +3507,7 @@ evas_filter_context_program_use(Evas_Filter_Context *ctx,
EINA_INLIST_FOREACH(pgm->instructions, instr)
{
_instruction_dump(instr);
cmdid = _command_from_instruction(ctx, instr, dc);
if (cmdid <= 0)
if (!_command_from_instruction(ctx, instr, dc))
goto end;
}

View File

@ -8,9 +8,9 @@
extern int _evas_filter_log_dom;
#define EVAS_FILTER_LOG_COLOR EINA_COLOR_LIGHTBLUE
#ifdef DEBUG
//#ifdef DEBUG
# define FILTERS_DEBUG
#endif
//#endif
#ifdef ERR
# undef ERR
@ -136,7 +136,7 @@ struct _Evas_Filter_Context
struct
{
int bufid;
void *surface;
int x, y;
int cx, cy, cw, ch; // clip
int r, g, b, a; // clip color
@ -150,6 +150,7 @@ struct _Evas_Filter_Context
Eina_Bool async : 1;
Eina_Bool running : 1;
Eina_Bool has_proxies : 1;
Eina_Bool gl : 1;
};
struct _Evas_Filter_Command
@ -242,6 +243,7 @@ struct _Evas_Filter_Buffer
Eina_Bool locked : 1; // internal flag
Eina_Bool delete_me : 1; // request delete asap (after released by client)
Eina_Bool dirty : 1; // Marked as dirty as soon as a command writes to it
Eina_Bool is_render : 1; // Is render target of a filter using engine functions (ie. needs FBO in GL)
};
enum _Evas_Filter_Interpolation_Mode
@ -264,13 +266,9 @@ void evas_filter_context_source_set(Evas_Filter_Context *ctx
void _clip_to_target(int *sx, int *sy, int sw, int sh, int ox, int oy, int dw, int dh, int *dx, int *dy, int *rows, int *cols);
Eina_Bool evas_filter_buffer_alloc(Evas_Filter_Buffer *fb, int w, int h);
Evas_Filter_Buffer *_filter_buffer_get(Evas_Filter_Context *ctx, int bufid);
Eina_Bool _filter_buffer_data_set(Evas_Filter_Context *ctx, int bufid, void *data, int w, int h, Eina_Bool alpha_only);
Evas_Filter_Buffer *_filter_buffer_data_new(Evas_Filter_Context *ctx, void *data, int w, int h, Eina_Bool alpha_only);
#define evas_filter_buffer_alloc_new(ctx, w, h, a) _filter_buffer_data_new(ctx, NULL, w, h, a)
Evas_Filter_Buffer *evas_filter_temporary_buffer_get(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only);
Evas_Filter_Buffer *evas_filter_buffer_scaled_get(Evas_Filter_Context *ctx, Evas_Filter_Buffer *src, unsigned w, unsigned h);
Eina_Bool evas_filter_interpolate(DATA8* output /* 256 values */, int *points /* 256 values */, Evas_Filter_Interpolation_Mode mode);
Evas_Filter_Command *_evas_filter_command_get(Evas_Filter_Context *ctx, int cmdid);
int evas_filter_smallest_pow2_larger_than(int val);
void evas_filter_parser_shutdown(void);

View File

@ -1,19 +1,42 @@
/* Note: only for internal C API */
import evas_canvas;
interface Evas.Ector.Buffer
{
[[Evas ector buffer interface]]
[[Binding layer between ector buffers and evas images.
Subclasses implement support for RGBA_Image for SW & GL,
and Evas_GL_Image for GL.
Note: Internal class, not API stable.
]]
methods {
@property engine_image {
[[Engine image property]]
get {}
set { [[This Buffer will hold a reference to the evas image struct.]] }
values {
evas: Evas.Canvas; [[The current Evas.]]
image: void_ptr; [[The engine-specific image struct.]]
engine_image_set {
[[Attach this ector buffer to an existing engine image.]]
params {
@in evas: Evas.Canvas; [[The current Evas.]]
@in image: void_ptr; [[The RGBA_Image or Evas_GL_Image.]]
}
}
drawable_image_get {
[[Fetch an engine image from this ector buffer as a drawable.]]
params {
@in update: bool; [[$true to update the data to the remote image.]]
}
return: void_ptr; [[The engine image (RGBA_Image or Evas_GL_Image).]]
}
render_image_get {
[[Fetch an engine image from this ector buffer as a render target.]]
params {
@in update: bool; [[$true to update the data to the remote image.]]
}
return: void_ptr; [[The engine image (RGBA_Image or Evas_GL_Image).]]
}
engine_image_release {
[[Release an image from @.drawable_image_get or @.render_image_get.]]
params {
@in image: void_ptr; [[Return value of @.drawable_image_get or @.render_image_get.]]
}
return: bool; [[$false in case of error.]]
}
}
}

View File

@ -146,7 +146,6 @@ void evas_filter_context_post_run_callback_set(Evas_Filter_C
Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx);
int evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, Eina_Bool alpha_only);
void *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid);
void *evas_filter_buffer_backing_steal(Evas_Filter_Context *ctx, int bufid);
Eina_Bool evas_filter_buffer_backing_release(Evas_Filter_Context *ctx, void *stolen_buffer);
@ -171,7 +170,7 @@ void _evas_filter_source_hash_free_cb(void *data);
* @return Filter command ID or -1 in case of error
* @internal
*/
int evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int ox, int oy, Evas_Filter_Fill_Mode fillmode);
Evas_Filter_Command *evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int ox, int oy, Evas_Filter_Fill_Mode fillmode);
/**
* @brief Apply a blur effect on a buffer
@ -188,7 +187,7 @@ int evas_filter_command_blend_add(Evas_Filter_Context *ctx,
* @return Filter command ID or -1 in case of error
* @internal
*/
int evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Blur_Type type, int dx, int dy, int ox, int oy, int count);
Evas_Filter_Command *evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Blur_Type type, int dx, int dy, int ox, int oy, int count);
/**
* @brief Fill a buffer with the current color
@ -199,7 +198,7 @@ int evas_filter_command_blur_add(Evas_Filter_Context *ctx,
* @note The current draw context's render operation is ignored (always uses COPY mode).
* @internal
*/
int evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, int buf);
Evas_Filter_Command *evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, int buf);
/**
* @brief evas_filter_command_curve_add
@ -212,7 +211,7 @@ int evas_filter_command_fill_add(Evas_Filter_Context *ctx,
* @return Filter command ID or -1 in case of error
* @internal
*/
int evas_filter_command_curve_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, DATA8 *curve /* 256 elements */, Evas_Filter_Channel channel);
Evas_Filter_Command *evas_filter_command_curve_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, DATA8 *curve /* 256 elements */, Evas_Filter_Channel channel);
/**
* @brief Grow/Shrink an image, as defined in image processing (this is not a scale algorithm!)
@ -225,7 +224,7 @@ int evas_filter_command_curve_add(Evas_Filter_Context *ctx,
* @return Filter command ID or -1 in case of error
* @internal
*/
int evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth);
Evas_Filter_Command *evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth);
/**
* @brief Apply a displacement map to a buffer. This will move pixels from the source to the destination based on pixel per pixel offset, as defined in the displacement map
@ -240,7 +239,7 @@ int evas_filter_command_grow_add(Evas_Filter_Context *ctx,
* @return Filter command ID or -1 in case of error
* @internal
*/
int evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int dispbuf, Evas_Filter_Displacement_Flags flags, int intensity, Evas_Filter_Fill_Mode fillmode);
Evas_Filter_Command *evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int dispbuf, Evas_Filter_Displacement_Flags flags, int intensity, Evas_Filter_Fill_Mode fillmode);
/**
* @brief Apply a texture to a buffer
@ -254,7 +253,7 @@ int evas_filter_command_displacement_map_add(Evas_Filter_Co
* @note For the moment, inbuf can only be ALPHA, and output must be RGBA if mask is RGBA as well
* @internal
*/
int evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int maskbuf, int outbuf, Evas_Filter_Fill_Mode fillmode);
Evas_Filter_Command *evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int maskbuf, int outbuf, Evas_Filter_Fill_Mode fillmode);
/**
* @brief Apply a relief effect based on a bump map (Z map)
@ -275,7 +274,7 @@ int evas_filter_command_mask_add(Evas_Filter_Context *ctx,
* @return Filter command ID or -1 in case of error
* @internal
*/
int evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int bumpbuf, int outbuf, float azimuth, float elevation, float depth, float specular_factor, DATA32 black, DATA32 color, DATA32 white, Evas_Filter_Bump_Flags flags, Evas_Filter_Fill_Mode fillmode);
Evas_Filter_Command *evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int bumpbuf, int outbuf, float azimuth, float elevation, float depth, float specular_factor, DATA32 black, DATA32 color, DATA32 white, Evas_Filter_Bump_Flags flags, Evas_Filter_Fill_Mode fillmode);
/**
* @brief Apply a geometrical transformation to the buffer
@ -289,7 +288,7 @@ int evas_filter_command_bump_map_add(Evas_Filter_Context *c
* @return Filter command ID or -1 in case of error
* @internal
*/
int evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags, int ox, int oy);
Evas_Filter_Command *evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags, int ox, int oy);
/* Simple binding between a filter object and its sources */
struct _Evas_Filter_Proxy_Binding

View File

@ -1572,8 +1572,8 @@ struct _Evas_Func
Ector_Surface *(*ector_create) (void *data);
void (*ector_destroy) (void *data, Ector_Surface *surface);
Ector_Buffer *(*ector_buffer_wrap) (void *data, Evas *e, void *engine_image, Eina_Bool is_rgba_image);
Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, void *pixels, int width, int height, int stride, Efl_Gfx_Colorspace cspace, Eina_Bool writeable, int l, int r, int t, int b, Ector_Buffer_Flag flags);
Ector_Buffer *(*ector_buffer_wrap) (void *data, Evas *e, void *engine_image);
Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, int width, int height, Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags);
void (*ector_begin) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, int x, int y, Eina_Bool do_async);
void (*ector_renderer_draw) (void *data, void *context, void *surface, void *engine_data, Ector_Renderer *r, Eina_Array *clips, Eina_Bool do_async);
void (*ector_end) (void *data, void *context, Ector_Surface *ector, void *surface, void *engine_data, Eina_Bool do_async);

View File

@ -688,6 +688,7 @@ void evas_gl_common_image_dirty(Evas_GL_Image *im, unsigned int x,
void evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
void evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int npoints, RGBA_Map_Point *p, int smooth, int level);
void evas_gl_common_image_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int smooth);
Evas_GL_Image *evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im);
void *evas_gl_font_texture_new(void *gc, RGBA_Font_Glyph *fg);
void evas_gl_font_texture_free(void *);

View File

@ -248,6 +248,8 @@ evas_gl_common_image_new_from_rgbaimage(Evas_Engine_GL_Context *gc, RGBA_Image *
}
*/
if (error) *error = EVAS_LOAD_ERROR_NONE;
// FIXME: keep unreffed shared images around
EINA_LIST_FOREACH(gc->shared->images, l, im)
{
@ -1039,6 +1041,65 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
}
}
Evas_GL_Image *
evas_gl_common_image_surface_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
{
Evas_GL_Image *glim = NULL;
Eina_Bool alpha;
int w, h;
if (!gc || !im || !im->im || !im->im->image.data)
goto fail;
if (im->im->cache_entry.space == EFL_GFX_COLORSPACE_ARGB8888)
alpha = EINA_FALSE;
else if (im->im->cache_entry.space == EFL_GFX_COLORSPACE_GRY8)
alpha = EINA_TRUE;
else goto fail;
w = im->im->cache_entry.w;
h = im->im->cache_entry.h;
glim = evas_gl_common_image_surface_new(gc, w, h, EINA_TRUE, EINA_FALSE);
if (!glim) goto fail;
if (alpha)
{
RGBA_Image *image;
uint32_t *rgba;
uint8_t *gry8;
int k;
image = evas_common_image_new(w, h, EINA_TRUE);
if (!image) goto fail;
rgba = image->image.data;
gry8 = im->im->image.data8;
for (k = 0; k < (w * h); k++)
{
const int c = *gry8++;
*rgba++ = ARGB_JOIN(c, c, c, c);
}
glim->im = image;
}
else
{
evas_cache_image_ref(&im->im->cache_entry);
glim->im = im->im;
}
glim->dirty = EINA_TRUE;
evas_gl_common_image_update(gc, glim);
evas_gl_common_image_free(im);
return glim;
fail:
ERR("Failed to update surface pixels!");
if (glim) evas_gl_common_image_free(glim);
return NULL;
}
void
evas_gl_common_image_map_draw(Evas_Engine_GL_Context *gc, Evas_GL_Image *im,
int npoints, RGBA_Map_Point *p, int smooth, int level EINA_UNUSED)

View File

@ -82,6 +82,7 @@ static const struct {
{ MATCH_FALSE, MATCH_FALSE, EVAS_COLORSPACE_ARGB8888, &rgb_ifmt, &rgb_fmt },
#endif
{ MATCH_FALSE, MATCH_ANY, EVAS_COLORSPACE_GRY8, &lum_fmt, &lum_ifmt },
{ MATCH_TRUE, MATCH_ANY, EVAS_COLORSPACE_GRY8, &alpha_fmt, &alpha_ifmt },
{ MATCH_TRUE, MATCH_ANY, EVAS_COLORSPACE_AGRY88, &lum_alpha_fmt, &lum_alpha_ifmt },
// ETC1/2 support
{ MATCH_FALSE, MATCH_ANY, EVAS_COLORSPACE_ETC1, &etc1_fmt, &etc1_fmt },

View File

@ -2,13 +2,357 @@
# include "config.h"
#endif
#define ECTOR_GL_BUFFER_BASE_PROTECTED
#include "evas_common_private.h"
#include "evas_gl_private.h"
#include <gl/Ector_GL.h>
#include "gl/ector_gl_private.h"
#include "evas_common_private.h"
#include "../gl_common/evas_gl_common.h"
#include "evas_private.h"
#include "ector_buffer.h"
#include "Evas_Engine_GL_Generic.h"
#include "evas_ector_buffer.eo.h"
#include "evas_ector_gl_buffer.eo.h"
#define MY_CLASS EVAS_ECTOR_GL_BUFFER_CLASS
typedef struct _Ector_GL_Buffer_Map Ector_GL_Buffer_Map;
typedef struct _Evas_Ector_GL_Buffer_Data Evas_Ector_GL_Buffer_Data;
struct _Ector_GL_Buffer_Map
{
EINA_INLIST;
void *ptr;
unsigned int base_size; // in bytes
unsigned int x, y, w, h;
void *image_data, *base_data;
size_t length;
Efl_Gfx_Colorspace cspace;
Evas_GL_Image *im;
Eina_Bool allocated;
Ector_Buffer_Access_Flag mode;
};
struct _Evas_Ector_GL_Buffer_Data
{
Evas_Public_Data *evas;
Evas_GL_Image *glim;
Eina_Bool alpha_only;
Ector_GL_Buffer_Map *maps;
};
#define ENFN pd->evas->engine.func
#define ENDT pd->evas->engine.data.output
// testing out some macros to maybe add to eina
#define EINA_INLIST_REMOVE(l,i) do { l = (__typeof__(l)) eina_inlist_remove(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
#define EINA_INLIST_APPEND(l,i) do { l = (__typeof__(l)) eina_inlist_append(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
#define EINA_INLIST_PREPEND(l,i) do { l = (__typeof__(l)) eina_inlist_prepend(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
#define fail(fmt, ...) do { ERR(fmt, ##__VA_ARGS__); goto on_fail; } while (0)
/* FIXME: Conversion routines don't belong here */
static inline void
_pixels_argb_to_gry8_convert(uint8_t *dst, const uint32_t *src, int len)
{
int k;
for (k = 0; k < len; k++)
{
const uint32_t *s = src++;
*dst++ = A_VAL(s);
}
}
static inline void
_pixels_gry8_to_argb_convert(uint32_t *dst, const uint8_t *src, int len)
{
int k;
for (k = 0; k < len; k++)
{
const uint8_t s = *src++;
*dst++ = ARGB_JOIN(s, s, s, s);
}
}
static inline Eina_Bool
_evas_gl_image_is_fbo(Evas_GL_Image *glim)
{
return glim && glim->tex && glim->tex->pt && glim->tex->pt->fb;
}
EOLIAN static void
_evas_ector_gl_buffer_gl_buffer_prepare(Eo *obj, Evas_Ector_GL_Buffer_Data *pd,
Evas_Canvas *eo_evas,
int w, int h, Efl_Gfx_Colorspace cspace,
Ector_Buffer_Flag flags EINA_UNUSED)
{
Render_Engine_GL_Generic *re;
Evas_Engine_GL_Context *gc;
Evas_GL_Image *im;
// this is meant to be called only once
EINA_SAFETY_ON_FALSE_GOTO(!pd->evas, on_fail);
EINA_SAFETY_ON_FALSE_GOTO(!efl_finalized_get(obj), on_fail);
if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
pd->alpha_only = EINA_FALSE;
else if (cspace == EFL_GFX_COLORSPACE_GRY8)
pd->alpha_only = EINA_TRUE;
else
fail("Unsupported colorspace: %u", cspace);
pd->evas = efl_data_xref(eo_evas, EVAS_CANVAS_CLASS, obj);
re = pd->evas->engine.data.output;
gc = re->window_gl_context_get(re->software.ob);
im = evas_gl_common_image_surface_new(gc, w, h, EINA_TRUE, EINA_FALSE);
if (!im) fail("Failed to create GL surface!");
pd->glim = im;
return;
on_fail:
if (pd->glim) evas_gl_common_image_free(pd->glim);
pd->glim = NULL;
}
EOLIAN static void *
_evas_ector_gl_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Buffer_Data *pd,
Eina_Bool update)
{
Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
Evas_Engine_GL_Context *gc;
if (pd->maps != NULL)
fail("Image is currently mapped!");
evas_gl_common_image_ref(pd->glim);
if (!update) return pd->glim;
gc = re->window_gl_context_get(re->software.ob);
evas_gl_common_image_update(gc, pd->glim);
return pd->glim;
on_fail:
return NULL;
}
EOLIAN static void *
_evas_ector_gl_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Buffer_Data *pd,
Eina_Bool update)
{
Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
Evas_Engine_GL_Context *gc;
if (pd->maps != NULL)
fail("Image is currently mapped!");
evas_gl_common_image_ref(pd->glim);
if (!update) return pd->glim;
gc = re->window_gl_context_get(re->software.ob);
evas_gl_common_image_update(gc, pd->glim);
return pd->glim;
on_fail:
return NULL;
}
EOLIAN static Eina_Bool
_evas_ector_gl_buffer_evas_ector_buffer_engine_image_release(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Buffer_Data *pd,
void *image)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->glim == image, EINA_FALSE);
evas_gl_common_image_free(pd->glim);
return EINA_TRUE;
}
EOLIAN static void
_evas_ector_gl_buffer_ector_buffer_size_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Buffer_Data *pd,
int *w, int *h)
{
if (w) *w = pd->glim->w;
if (h) *h = pd->glim->h;
}
EOLIAN static Efl_Gfx_Colorspace
_evas_ector_gl_buffer_ector_buffer_cspace_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Buffer_Data *pd)
{
if (pd->alpha_only)
return EFL_GFX_COLORSPACE_GRY8;
else
return EFL_GFX_COLORSPACE_ARGB8888;
}
EOLIAN static Ector_Buffer_Flag
_evas_ector_gl_buffer_ector_buffer_flags_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Buffer_Data *pd EINA_UNUSED)
{
return ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_DRAWABLE |
ECTOR_BUFFER_FLAG_CPU_WRITABLE | ECTOR_BUFFER_FLAG_RENDERABLE;
}
EOLIAN static void *
_evas_ector_gl_buffer_ector_buffer_map(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buffer_Data *pd,
unsigned int *length,
Ector_Buffer_Access_Flag mode,
unsigned int x, unsigned int y, unsigned int w, unsigned int h,
Efl_Gfx_Colorspace cspace, unsigned int *stride)
{
Eina_Bool write = !!(mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE);
Ector_GL_Buffer_Map *map = NULL;
Eina_Bool tofree = EINA_FALSE;
Evas_GL_Image *im = NULL;
unsigned int W, H;
int len, err;
uint32_t *data;
int pxs;
W = pd->glim->w;
H = pd->glim->h;
if (!w) w = W - x;
if (!h) h = H - y;
if ((x + w > W) || (y + h > H)) return NULL;
if (write && _evas_gl_image_is_fbo(pd->glim))
{
// Can not open FBO data to write!
im = ENFN->image_data_get(ENDT, pd->glim, EINA_FALSE, &data, &err, &tofree);
if (!im) return NULL;
}
else
{
im = ENFN->image_data_get(ENDT, pd->glim, write, &data, &err, &tofree);
if (!im) return NULL;
}
map = calloc(1, sizeof(*map));
map->mode = mode;
map->cspace = cspace;
map->x = x;
map->y = y;
map->w = w;
map->h = h;
map->image_data = data;
map->im = tofree ? im : NULL;
len = W * H;
if (cspace == EFL_GFX_COLORSPACE_GRY8)
{
uint8_t *data8 = malloc(len);
if (!data8) goto on_fail;
_pixels_argb_to_gry8_convert(data8, data, len);
map->allocated = EINA_TRUE;
map->base_data = data8;
map->ptr = data8 + x + (y * W);
pxs = 1;
}
else
{
map->allocated = EINA_FALSE;
map->base_data = data;
map->ptr = data + x + (y * W);
pxs = 4;
}
map->base_size = len * pxs;
map->length = (W * h + w - W) * pxs;
if (stride) *stride = W * pxs;
if (length) *length = map->length;
EINA_INLIST_PREPEND(pd->maps, map);;
return map->ptr;
on_fail:
free(map);
return NULL;
}
EOLIAN static void
_evas_ector_gl_buffer_ector_buffer_unmap(Eo *obj EINA_UNUSED, Evas_Ector_GL_Buffer_Data *pd,
void *data, unsigned int length)
{
Ector_GL_Buffer_Map *map;
if (!data) return;
EINA_INLIST_FOREACH(pd->maps, map)
{
if ((map->ptr == data) && (map->length == length))
{
EINA_INLIST_REMOVE(pd->maps, map);
if (map->mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE)
{
Render_Engine_GL_Generic *re = pd->evas->engine.data.output;
Evas_GL_Image *old_glim = pd->glim;
Evas_Engine_GL_Context *gc;
int W, H;
W = pd->glim->w;
H = pd->glim->h;
gc = re->window_gl_context_get(re->software.ob);
if (map->cspace == EFL_GFX_COLORSPACE_GRY8)
_pixels_gry8_to_argb_convert(map->image_data, map->base_data, W * H);
if (map->im)
{
pd->glim = evas_gl_common_image_surface_update(gc, map->im);
evas_gl_common_image_free(old_glim);
}
else
{
pd->glim = evas_gl_common_image_surface_update(gc, old_glim);
}
}
else
{
if (map->im)
ENFN->image_free(ENDT, map->im);
else
ENFN->image_data_put(ENDT, pd->glim, map->image_data);
}
if (map->allocated)
free(map->base_data);
free(map);
return;
}
}
ERR("Tried to unmap a non-mapped region!");
}
EOLIAN static Efl_Object *
_evas_ector_gl_buffer_efl_object_finalize(Eo *obj, Evas_Ector_GL_Buffer_Data *pd)
{
if (!pd->glim)
{
ERR("Buffer was not initialized properly!");
return NULL;
}
return efl_finalize(efl_super(obj, MY_CLASS));
}
EOLIAN static void
_evas_ector_gl_buffer_efl_object_destructor(Eo *obj, Evas_Ector_GL_Buffer_Data *pd)
{
evas_gl_common_image_free(pd->glim);
efl_data_xunref(pd->evas->evas, pd->evas, obj);
efl_destructor(efl_super(obj, MY_CLASS));
}
#include "evas_ector_gl_buffer.eo.c"

View File

@ -1,5 +1,35 @@
class Evas.Ector.GL.Buffer (Efl.Object, Evas.Ector.Buffer, Ector.GL.Buffer.Base)
class Evas.Ector.GL.Buffer (Efl.Object, Evas.Ector.Buffer, Ector.GL.Buffer)
{
[[Evas ector GL buffer class]]
data: null;
[[An Ector GL buffer capable of being mapped, drawn and rendered to.
Potentially very inefficient (may rely on glReadPixels).
]]
methods {
gl_buffer_prepare {
[[Set the main properties to create a gl buffer.]]
params {
evas: Evas.Canvas; [[The current canvas]]
w: int; [[Width]]
h: int; [[Height]]
cspace: Efl.Gfx.Colorspace; [[Alpha or RGBA]]
flags: Ector.Buffer.Flag; [[Required buffer capabilities
(map/draw/render, etc...)]]
}
}
}
constructors {
.gl_buffer_prepare;
}
implements {
Efl.Object.finalize;
Efl.Object.destructor;
Evas.Ector.Buffer.drawable_image_get;
Evas.Ector.Buffer.render_image_get;
Evas.Ector.Buffer.engine_image_release;
Ector.Buffer.size { get; }
Ector.Buffer.cspace { get; }
Ector.Buffer.flags { get; }
Ector.Buffer.map;
Ector.Buffer.unmap;
}
}

View File

@ -2,14 +2,20 @@
# include "config.h"
#endif
/* this one is read-only buffer wrapping an existing evas_gl_image */
#define ECTOR_GL_BUFFER_BASE_PROTECTED
#include "evas_common_private.h"
#include "evas_gl_private.h"
#include <gl/Ector_GL.h>
#include "gl/ector_gl_private.h"
#include "evas_common_private.h"
#include "../gl_common/evas_gl_common.h"
#include "evas_private.h"
#include "ector_buffer.h"
#include "Evas_Engine_GL_Generic.h"
#include "evas_ector_buffer.eo.h"
#include "evas_ector_gl_buffer.eo.h"
@ -17,30 +23,36 @@
#define MY_CLASS EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS
typedef struct _Ector_GL_Buffer_Map
typedef struct _Ector_GL_Buffer_Map Ector_GL_Buffer_Map;
typedef struct _Evas_Ector_GL_Image_Buffer_Data Evas_Ector_GL_Image_Buffer_Data;
struct _Ector_GL_Buffer_Map
{
EINA_INLIST;
void *ptr;
unsigned int size; // in bytes
unsigned int base_size; // in bytes
unsigned int x, y, w, h;
void *image_data, *base_data;
size_t length;
Efl_Gfx_Colorspace cspace;
Evas_GL_Image *im;
Eina_Bool allocated;
Eina_Bool allocated, free_image;
Ector_Buffer_Access_Flag mode;
} Ector_GL_Buffer_Map;
};
typedef struct
struct _Evas_Ector_GL_Image_Buffer_Data
{
Ector_GL_Buffer_Base_Data *base;
Evas *evas;
Evas_GL_Image *image;
struct {
Eina_Inlist *maps; // Ector_GL_Buffer_Map
} internal;
} Evas_Ector_GL_Image_Buffer_Data;
Evas_Public_Data *evas;
Evas_GL_Image *glim;
Ector_GL_Buffer_Map *maps;
};
#define ENFN e->engine.func
#define ENDT e->engine.data.output
#define ENFN pd->evas->engine.func
#define ENDT pd->evas->engine.data.output
// testing out some macros to maybe add to eina
#define EINA_INLIST_REMOVE(l,i) do { l = (__typeof__(l)) eina_inlist_remove(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
#define EINA_INLIST_APPEND(l,i) do { l = (__typeof__(l)) eina_inlist_append(EINA_INLIST_GET(l), EINA_INLIST_GET(i)); } while (0)
/* FIXME: Conversion routines don't belong here */
static inline void
@ -58,92 +70,99 @@ EOLIAN static void
_evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd,
Evas *evas, void *image)
{
Evas_Public_Data *e = efl_data_scope_get(evas, EVAS_CANVAS_CLASS);
Evas_GL_Image *im = image;
int l = 0, r = 0, t = 0, b = 0;
if (pd->base->generic->immutable)
{
CRI("Can't set image after finalize");
return;
}
pd->evas = efl_xref(evas, obj);
EINA_SAFETY_ON_FALSE_RETURN(!pd->glim);
EINA_SAFETY_ON_NULL_RETURN(im);
if (im->tex && im->tex->pt)
{
if (im->im)
{
l = im->im->cache_entry.borders.l;
r = im->im->cache_entry.borders.r;
t = im->im->cache_entry.borders.t;
b = im->im->cache_entry.borders.b;
}
else
{
// always 1 pixel border, except FBO
if (!im->tex->pt->fb)
l = r = t = b = 1;
}
pd->image = ENFN->image_ref(ENDT, im);
ector_gl_buffer_base_attach(obj, im->tex->pt->texture, im->tex->pt->fb, (Efl_Gfx_Colorspace) evas_gl_common_gl_format_to_colorspace(im->tex->pt->format), im->tex->w, im->tex->h, im->tex->x, im->tex->y, im->tex->pt->w, im->tex->pt->h, l, r, t, b);
}
else
{
// FIXME: This might be required to support texture upload here
ERR("Image has no attached texture! Unsupported!");
pd->image = NULL;
}
pd->evas = efl_data_xref(evas, EVAS_CANVAS_CLASS, obj);
evas_gl_common_image_ref(im);
pd->glim = im;
}
EOLIAN static void
_evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Image_Buffer_Data *pd,
Evas **evas, void **image)
EOLIAN static void *
_evas_ector_gl_image_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Image_Buffer_Data *pd,
Eina_Bool update EINA_UNUSED)
{
if (evas) *evas = pd->evas;
if (image) *image = pd->image;
evas_gl_common_image_ref(pd->glim);
return pd->glim;
}
EOLIAN static Eina_Bool
_evas_ector_gl_image_buffer_evas_ector_buffer_engine_image_release(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Image_Buffer_Data *pd,
void *image)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->glim == image, EINA_FALSE);
evas_gl_common_image_free(pd->glim);
return EINA_TRUE;
}
EOLIAN static Ector_Buffer_Flag
_evas_ector_gl_image_buffer_ector_buffer_flags_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Image_Buffer_Data *pd)
Evas_Ector_GL_Image_Buffer_Data *pd EINA_UNUSED)
{
Ector_Buffer_Flag flags;
return ECTOR_BUFFER_FLAG_CPU_READABLE | ECTOR_BUFFER_FLAG_DRAWABLE;
}
if (!pd->image) return 0;
EOLIAN static void
_evas_ector_gl_image_buffer_ector_buffer_size_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Image_Buffer_Data *pd,
int *w, int *h)
{
if (w) *w = pd->glim->w;
if (h) *h = pd->glim->h;
}
flags = ECTOR_BUFFER_FLAG_CPU_READABLE;
if (pd->image->tex)
{
flags |= ECTOR_BUFFER_FLAG_DRAWABLE;
if (pd->image->tex->pt->fb)
flags |= ECTOR_BUFFER_FLAG_RENDERABLE;
}
if (pd->image->im)
flags |= ECTOR_BUFFER_FLAG_CPU_WRITABLE;
return flags;
EOLIAN static Efl_Gfx_Colorspace
_evas_ector_gl_image_buffer_ector_buffer_cspace_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Image_Buffer_Data *pd EINA_UNUSED)
{
return EFL_GFX_COLORSPACE_ARGB8888;
}
EOLIAN static void *
_evas_ector_gl_image_buffer_ector_buffer_map(Eo *obj EINA_UNUSED, Evas_Ector_GL_Image_Buffer_Data *pd, unsigned int *length,
Ector_Buffer_Access_Flag mode,
unsigned int x, unsigned int y, unsigned int w, unsigned int h,
Efl_Gfx_Colorspace cspace, unsigned int *stride)
Ector_Buffer_Access_Flag mode,
unsigned int x, unsigned int y, unsigned int w, unsigned int h,
Efl_Gfx_Colorspace cspace, unsigned int *stride)
{
Evas_Public_Data *e = efl_data_scope_get(pd->evas, EVAS_CANVAS_CLASS);
Ector_GL_Buffer_Map *map = NULL;
Eina_Bool tofree = EINA_FALSE;
Evas_GL_Image *im;
uint32_t *data;
Evas_GL_Image *im = NULL;
unsigned int W, H;
int len, err;
uint32_t *data;
int pxs;
im = ENFN->image_data_get(ENDT, pd->image,
mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE,
&data, &err, &tofree);
if ((cspace != EFL_GFX_COLORSPACE_GRY8) && (cspace != EFL_GFX_COLORSPACE_ARGB8888))
{
ERR("Unsupported colorspace for map: %d", (int) cspace);
return NULL;
}
if (mode == EFL_GFX_BUFFER_ACCESS_MODE_NONE)
{
ERR("Invalid access mode for map (none)");
return NULL;
}
if (mode & EFL_GFX_BUFFER_ACCESS_MODE_WRITE)
{
ERR("%s does not support write access for map", efl_class_name_get(MY_CLASS));
return NULL;
}
W = pd->glim->w;
H = pd->glim->h;
if (!w) w = W - x;
if (!h) h = H - y;
if ((x + w > W) || (y + h > H)) return NULL;
im = ENFN->image_data_get(ENDT, pd->glim, EINA_FALSE, &data, &err, &tofree);
if (!im) return NULL;
map = calloc(1, sizeof(*map));
@ -153,111 +172,89 @@ _evas_ector_gl_image_buffer_ector_buffer_map(Eo *obj EINA_UNUSED, Evas_Ector_GL_
map->y = y;
map->w = w;
map->h = h;
map->ptr = data;
map->image_data = data;
map->im = im;
map->free_image = tofree;
if (tofree)
map->im = im;
else
map->im = NULL;
len = w * h;
len = W * H;
if (cspace == EFL_GFX_COLORSPACE_GRY8)
{
uint8_t *data8 = malloc(len);
if (!data8) goto fail;
_pixels_argb_to_gry8_convert(data8, data, len);
map->allocated = EINA_TRUE;
map->ptr = data8;
map->size = len;
if (stride) *stride = w;
map->base_data = data8;
map->ptr = data8 + x + (y * W);
pxs = 1;
}
else
{
map->allocated = EINA_FALSE;
map->ptr = data;
map->size = len * 4;
if (stride) *stride = w * 4;
map->base_data = data;
map->ptr = data + x + (y * W);
pxs = 4;
}
if (length) *length = map->size;
map->base_size = len * pxs;
map->length = (W * h + w - W) * pxs;
if (stride) *stride = W * pxs;
if (length) *length = map->length;
pd->internal.maps = eina_inlist_prepend(pd->internal.maps, EINA_INLIST_GET(map));
if (!tofree)
pd->glim = im;
EINA_INLIST_APPEND(pd->maps, map);
return map->ptr;
fail:
free(map);
return NULL;
}
EOLIAN static void
_evas_ector_gl_image_buffer_ector_buffer_unmap(Eo *obj EINA_UNUSED, Evas_Ector_GL_Image_Buffer_Data *pd,
void *data, unsigned int length)
_evas_ector_gl_image_buffer_ector_buffer_unmap(Eo *obj EINA_UNUSED,
Evas_Ector_GL_Image_Buffer_Data *pd,
void *data, unsigned int length)
{
Evas_Public_Data *e = efl_data_scope_get(pd->evas, EVAS_CANVAS_CLASS);
Ector_GL_Buffer_Map *map;
if (!data) return;
EINA_INLIST_FOREACH(pd->internal.maps, map)
EINA_INLIST_FOREACH(pd->maps, map)
{
if ((map->ptr == data) && ((map->size == length) || (length == (unsigned int) -1)))
if ((map->base_data == data) && (map->length == length))
{
pd->internal.maps = eina_inlist_remove(pd->internal.maps, EINA_INLIST_GET(map));
if (map->mode & ECTOR_BUFFER_ACCESS_FLAG_WRITE)
{
CRI("Not implemented yet. Dropping pixel changes.");
}
if (map->im)
EINA_INLIST_REMOVE(pd->maps, map);
if (map->free_image)
ENFN->image_free(ENDT, map->im);
else
ENFN->image_data_put(ENDT, map->im, map->image_data);
if (map->allocated)
free(map->ptr);
free(map->base_data);
free(map);
return;
}
}
CRI("Tried to unmap a non-mapped region!");
}
EOLIAN static uint8_t *
_evas_ector_gl_image_buffer_ector_buffer_span_get(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd, int x, int y, unsigned int w,
Efl_Gfx_Colorspace cspace, unsigned int *length)
{
// ector_buffer_map
return _evas_ector_gl_image_buffer_ector_buffer_map
(obj, pd, length, ECTOR_BUFFER_ACCESS_FLAG_READ, x, y, w, 1, cspace, NULL);
}
EOLIAN static void
_evas_ector_gl_image_buffer_ector_buffer_span_free(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd, uint8_t *data)
{
// ector_buffer_unmap
return _evas_ector_gl_image_buffer_ector_buffer_unmap
(obj, pd, data, (unsigned int) -1);
}
EOLIAN static Efl_Object *
_evas_ector_gl_image_buffer_efl_object_constructor(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
pd->base = efl_data_ref(obj, ECTOR_GL_BUFFER_BASE_MIXIN);
pd->base->generic = efl_data_ref(obj, ECTOR_BUFFER_MIXIN);
pd->base->generic->eo = obj;
return obj;
ERR("Tried to unmap a non-mapped region: %p +%u", data, length);
}
EOLIAN static Efl_Object *
_evas_ector_gl_image_buffer_efl_object_finalize(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->base, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->image, NULL);
pd->base->generic->immutable = EINA_TRUE;
if (!pd->glim)
{
ERR("Buffer was not initialized properly!");
return NULL;
}
return efl_finalize(efl_super(obj, MY_CLASS));
}
EOLIAN static void
_evas_ector_gl_image_buffer_efl_object_destructor(Eo *obj, Evas_Ector_GL_Image_Buffer_Data *pd)
{
Evas_Public_Data *e = efl_data_scope_get(pd->evas, EVAS_CANVAS_CLASS);
efl_data_unref(obj, pd->base->generic);
efl_data_unref(obj, pd->base);
ENFN->image_free(ENDT, pd->image);
efl_xunref(pd->evas, obj);
evas_gl_common_image_free(pd->glim);
efl_data_xunref(pd->evas->evas, pd->evas, obj);
efl_destructor(efl_super(obj, MY_CLASS));
}

View File

@ -1,14 +1,15 @@
class Evas.Ector.GL.Image.Buffer (Evas.Ector.GL.Buffer, Evas.Ector.Buffer)
class Evas.Ector.GL.Image.Buffer (Efl.Object, Evas.Ector.Buffer, Ector.GL.Buffer)
{
[[An Ector GL buffer wrapping an existing Evas_GL_Image.]]
implements {
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.destructor;
Evas.Ector.Buffer.engine_image { get; set; }
Evas.Ector.Buffer.engine_image_set;
Evas.Ector.Buffer.drawable_image_get;
Evas.Ector.Buffer.engine_image_release;
Ector.Buffer.size { get; }
Ector.Buffer.cspace { get; }
Ector.Buffer.flags { get; }
Ector.Buffer.span_get;
Ector.Buffer.span_free;
Ector.Buffer.map;
Ector.Buffer.unmap;
}

View File

@ -1,117 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "evas_common_private.h"
#include "evas_gl_private.h"
#include <software/Ector_Software.h>
#include <gl/Ector_GL.h>
#include "Evas_Engine_GL_Generic.h"
#include "evas_ector_buffer.eo.h"
#include "evas_ector_gl_rgbaimage_buffer.eo.h"
#include "../software_generic/evas_ector_software_buffer.eo.h"
#define MY_CLASS EVAS_ECTOR_GL_RGBAIMAGE_BUFFER_CLASS
typedef struct {
Ector_Software_Buffer_Base_Data *base;
Evas *evas;
RGBA_Image *image;
Evas_GL_Image *glim;
} Evas_Ector_GL_RGBAImage_Buffer_Data;
// GL engine stuff, do not use with RGBA_Image / Image_Entry
#define ENFN e->engine.func
#define ENDT e->engine.data.output
EOLIAN static void
_evas_ector_gl_rgbaimage_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ector_GL_RGBAImage_Buffer_Data *pd,
Evas *evas, void *image)
{
RGBA_Image *im = image;
EINA_SAFETY_ON_NULL_RETURN(image);
if (efl_finalized_get(obj))
{
CRI("engine_image must be set at construction time only");
return;
}
if (!im->image.data)
{
CRI("image has no pixels yet");
return;
}
pd->evas = efl_xref(evas, obj);
evas_cache_image_ref(&im->cache_entry);
pd->image = im;
ector_buffer_pixels_set(obj, im->image.data, im->cache_entry.w, im->cache_entry.h, 0, (Efl_Gfx_Colorspace) im->cache_entry.space, EINA_TRUE, 0, 0, 0, 0);
}
EOLIAN static void
_evas_ector_gl_rgbaimage_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_UNUSED,
Evas_Ector_GL_RGBAImage_Buffer_Data *pd,
Evas **evas, void **image)
{
Evas_Public_Data *e = efl_data_scope_get(pd->evas, EVAS_CANVAS_CLASS);
Render_Engine_GL_Generic *re = e->engine.data.output;
int err = EVAS_LOAD_ERROR_NONE;
Evas_Engine_GL_Context *gc;
if (evas) *evas = pd->evas;
if (image) *image = NULL;
if (pd->glim)
goto end;
gc = re->window_gl_context_get(re->software.ob);
#ifdef EVAS_CSERVE2
if (evas_cache2_image_cached(&pd->image->cache_entry))
evas_cache2_image_ref(&pd->image->cache_entry);
else
#endif
evas_cache_image_ref(&pd->image->cache_entry);
pd->glim = evas_gl_common_image_new_from_rgbaimage(gc, pd->image, NULL, &err);
if ((err != EVAS_LOAD_ERROR_NONE) || !pd->glim)
{
ERR("Failed to create GL image! error %d", err);
return;
}
end:
if (image) *image = pd->glim;
}
EOLIAN static Eo *
_evas_ector_gl_rgbaimage_buffer_efl_object_constructor(Eo *obj, Evas_Ector_GL_RGBAImage_Buffer_Data *pd)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
pd->base = efl_data_xref(obj, ECTOR_SOFTWARE_BUFFER_BASE_MIXIN, obj);
return obj;
}
EOLIAN static Eo *
_evas_ector_gl_rgbaimage_buffer_efl_object_finalize(Eo *obj, Evas_Ector_GL_RGBAImage_Buffer_Data *pd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->base, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(pd->image, NULL);
pd->base->generic->immutable = EINA_TRUE;
return efl_finalize(efl_super(obj, MY_CLASS));
}
EOLIAN static void
_evas_ector_gl_rgbaimage_buffer_efl_object_destructor(Eo *obj, Evas_Ector_GL_RGBAImage_Buffer_Data *pd)
{
Evas_Public_Data *e = efl_data_scope_get(pd->evas, EVAS_CANVAS_CLASS);
efl_data_xunref(obj, pd->base, obj);
ENFN->image_free(ENDT, pd->glim);
evas_cache_image_drop(&pd->image->cache_entry);
efl_xunref(pd->evas, obj);
efl_destructor(efl_super(obj, MY_CLASS));
}
#include "evas_ector_gl_rgbaimage_buffer.eo.c"

View File

@ -1,10 +0,0 @@
class Evas.Ector.GL.RGBAImage.Buffer (Ector.Software.Buffer, Evas.Ector.Buffer)
{
[[A buffer object wrapping an existing Evas RGBA_Image for the GL Engine.]]
implements {
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.destructor;
Evas.Ector.Buffer.engine_image { get; set; }
}
}

View File

@ -7,7 +7,6 @@
#include "evas_ector_buffer.eo.h"
#include "evas_ector_gl_buffer.eo.h"
#include "evas_ector_gl_image_buffer.eo.h"
#include "evas_ector_gl_rgbaimage_buffer.eo.h"
#include "filters/gl_engine_filter.h"
#if defined HAVE_DLSYM && ! defined _WIN32
@ -844,11 +843,11 @@ eng_image_data_get(void *data, void *image, int to_write, DATA32 **image_data, i
if (!ok)
{
if (err) *err = EVAS_LOAD_ERROR_GENERIC;
ERR("Unlock failed.");
ERR("ReadPixels failed.");
return NULL;
}
*image_data = im_new->im->image.data;
if (tofree) *tofree = EINA_TRUE;
*tofree = EINA_TRUE;
return im_new;
}
@ -2539,85 +2538,22 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector)
}
static Ector_Buffer *
eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *evas, void *engine_image, Eina_Bool is_rgba_image)
eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *evas, void *engine_image)
{
Ector_Buffer *buf = NULL;
Evas_GL_Image *im = engine_image;
EINA_SAFETY_ON_NULL_RETURN_VAL(engine_image, NULL);
if (is_rgba_image)
{
RGBA_Image *im = engine_image;
buf = efl_add(EVAS_ECTOR_GL_RGBAIMAGE_BUFFER_CLASS, evas, evas_ector_buffer_engine_image_set(efl_added, evas, im));
}
else
{
Evas_GL_Image *im = engine_image;
buf = efl_add(EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS, evas, evas_ector_buffer_engine_image_set(efl_added, evas, im));
}
return buf;
return efl_add(EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS, evas,
evas_ector_buffer_engine_image_set(efl_added, evas, im));
}
static Ector_Buffer *
eng_ector_buffer_new(void *data, Evas *evas, void *pixels,
int width, int height, int stride,
Efl_Gfx_Colorspace cspace, Eina_Bool writeable EINA_UNUSED,
int l, int r, int t, int b, Ector_Buffer_Flag flags)
eng_ector_buffer_new(void *data EINA_UNUSED, Evas *evas, int w, int h,
Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags)
{
Evas_Public_Data *e = efl_data_scope_get(evas, EVAS_CANVAS_CLASS);
Render_Engine_GL_Generic *re = e->engine.data.output;
Evas_Engine_GL_Context *gc = NULL;
Ector_Buffer *buf = NULL;
int iw = width + l + r;
int ih = height + t + b;
int pxs = (cspace == EFL_GFX_COLORSPACE_ARGB8888) ? 4 : 1;
if (stride && (stride != iw * pxs))
WRN("stride support is not implemented for ector gl buffers at this point!");
if ((flags & ECTOR_BUFFER_FLAG_RENDERABLE) == 0)
{
// Create an RGBA Image as backing
Image_Entry *ie;
if (pixels)
{
// no copy
ie = evas_cache_image_data(evas_common_image_cache_get(), iw, ih,
pixels, EINA_TRUE, (Evas_Colorspace) cspace);
if (!ie) return NULL;
}
else
{
// alloc buffer
ie = evas_cache_image_copied_data(evas_common_image_cache_get(), iw, ih,
NULL, EINA_TRUE, (Evas_Colorspace) cspace);
if (!ie) return NULL;
pixels = ((RGBA_Image *) ie)->image.data;
memset(pixels, 0, iw * ih * pxs);
}
ie->borders.l = l;
ie->borders.r = r;
ie->borders.t = t;
ie->borders.b = b;
buf = eng_ector_buffer_wrap(data, evas, ie, EINA_TRUE);
evas_cache_image_drop(ie);
}
else
{
// Create only an Evas_GL_Image as backing
Evas_GL_Image *im;
if (l || r || t || b)
WRN("Borders are not supported by Evas surfaces!");
gc = re->window_gl_context_get(re->software.ob);
im = evas_gl_common_image_surface_new(gc, iw, ih, EINA_TRUE, EINA_FALSE);
buf = efl_add(EVAS_ECTOR_GL_IMAGE_BUFFER_CLASS, evas, evas_ector_buffer_engine_image_set(efl_added, evas, im));
im->references--;
}
return buf;
return efl_add(EVAS_ECTOR_GL_BUFFER_CLASS, evas,
evas_ector_gl_buffer_prepare(efl_added, evas, w, h, cspace, flags));
}
static Efl_Gfx_Render_Op
@ -2768,7 +2704,7 @@ eng_ector_begin(void *data, void *context EINA_UNUSED, Ector_Surface *ector,
}
}
memset(buffer->software, 0, sizeof (unsigned int) * w * h);
ector_buffer_pixels_set(ector, buffer->software, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE, 0, 0, 0, 0);
ector_buffer_pixels_set(ector, buffer->software, w, h, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
ector_surface_reference_point_set(ector, x, y);
}
else
@ -2796,7 +2732,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;
ector_buffer_pixels_set(ector, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0);
ector_buffer_pixels_set(ector, NULL, 0, 0, 0, 0);
buffer->gl = eng_image_data_put(data, buffer->gl, buffer->software);
if (!mul_use)

View File

@ -4,17 +4,40 @@ static Eina_Bool
_gl_filter_blend(Render_Engine_GL_Generic *re, Evas_Filter_Command *cmd)
{
Evas_Engine_GL_Context *gc;
Evas_GL_Image *image;
Evas_Canvas *eo_evas;
void *im = NULL;
Evas_GL_Image *image, *surface;
RGBA_Draw_Context *dc_save;
re->window_use(re->software.ob);
gc = re->window_gl_context_get(re->software.ob);
evas_ector_buffer_engine_image_get(cmd->input->buffer, &eo_evas, &im);
image = im;
image = evas_ector_buffer_drawable_image_get(cmd->input->buffer, EINA_TRUE);
evas_gl_common_image_draw(gc, image, 0, 0, image->w, image->h, 0, 0, image->w, image->h, EINA_TRUE);
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(image->tex, EINA_FALSE);
surface = evas_ector_buffer_render_image_get(cmd->output->buffer, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(surface->tex, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(surface->tex->pt, EINA_FALSE);
EINA_SAFETY_ON_FALSE_RETURN_VAL(surface->tex->pt->fb != 0, EINA_FALSE);
evas_gl_common_context_target_surface_set(gc, surface);
// TODO: mapped render iteration
dc_save = gc->dc;
gc->dc = evas_common_draw_context_new();
evas_common_draw_context_set_multiplier(gc->dc, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
evas_gl_common_image_draw(gc, image, 0, 0, image->w, image->h,
cmd->draw.ox, cmd->draw.oy, image->w, image->h,
EINA_TRUE);
evas_common_draw_context_free(gc->dc);
gc->dc = dc_save;
evas_ector_buffer_engine_image_release(cmd->input->buffer, image);
evas_ector_buffer_engine_image_release(cmd->output->buffer, surface);
return EINA_TRUE;
}
@ -26,5 +49,5 @@ gl_filter_blend_func_get(Evas_Filter_Command *cmd)
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
return NULL; // _gl_filter_blend;
return _gl_filter_blend;
}

View File

@ -27,46 +27,44 @@ _evas_ector_software_buffer_evas_ector_buffer_engine_image_set(Eo *obj, Evas_Ect
RGBA_Image *im = image;
EINA_SAFETY_ON_NULL_RETURN(image);
if (efl_finalized_get(obj))
{
CRI("engine_image must be set at construction time only");
return;
}
if (!im->image.data)
{
CRI("image has no pixels yet");
return;
}
EINA_SAFETY_ON_FALSE_RETURN(!efl_finalized_get(obj));
EINA_SAFETY_ON_NULL_RETURN(im->image.data);
pd->evas = efl_data_xref(evas, EVAS_CANVAS_CLASS, obj);
evas_cache_image_ref(&im->cache_entry);
pd->image = im;
ector_buffer_pixels_set(obj, im->image.data, im->cache_entry.w, im->cache_entry.h, 0, (Efl_Gfx_Colorspace) im->cache_entry.space, EINA_TRUE, 0, 0, 0, 0);
ector_buffer_pixels_set(obj, im->image.data, im->cache_entry.w, im->cache_entry.h, im->cache_entry.space, EINA_TRUE);
}
EOLIAN static void
_evas_ector_software_buffer_evas_ector_buffer_engine_image_get(Eo *obj EINA_UNUSED,
Evas_Ector_Software_Buffer_Data *pd,
Evas **evas, void **image)
EOLIAN static void *
_evas_ector_software_buffer_evas_ector_buffer_drawable_image_get(Eo *obj EINA_UNUSED,
Evas_Ector_Software_Buffer_Data *pd,
Eina_Bool update EINA_UNUSED)
{
if (!pd->evas)
{
INF("evas_ector_buffer_engine_image_set was not called on this image");
if (evas) *evas = NULL;
if (image) *image = NULL;
return;
}
if (evas) *evas = pd->evas->evas;
if (pd->evas->engine.func->gl_surface_read_pixels)
{
ERR("Invalid: requesting engine_image from a GL image from a simple SW buffer!");
if (image) *image = NULL;
return;
}
evas_cache_image_ref(&pd->image->cache_entry);
return pd->image;
}
if (image) *image = pd->image;
EOLIAN static void *
_evas_ector_software_buffer_evas_ector_buffer_render_image_get(Eo *obj EINA_UNUSED,
Evas_Ector_Software_Buffer_Data *pd,
Eina_Bool update EINA_UNUSED)
{
evas_cache_image_ref(&pd->image->cache_entry);
return pd->image;
}
EOLIAN static Eina_Bool
_evas_ector_software_buffer_evas_ector_buffer_engine_image_release(Eo *obj EINA_UNUSED,
Evas_Ector_Software_Buffer_Data *pd,
void *image)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
EINA_SAFETY_ON_FALSE_RETURN_VAL(pd->image == image, EINA_FALSE);
evas_cache_image_drop(&pd->image->cache_entry);
return EINA_TRUE;
}
EOLIAN static Eo *

View File

@ -5,6 +5,9 @@ class Evas.Ector.Software.Buffer (Ector.Software.Buffer, Evas.Ector.Buffer)
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.destructor;
Evas.Ector.Buffer.engine_image { get; set; }
Evas.Ector.Buffer.engine_image_set;
Evas.Ector.Buffer.drawable_image_get;
Evas.Ector.Buffer.render_image_get;
Evas.Ector.Buffer.engine_image_release;
}
}

View File

@ -4333,7 +4333,7 @@ eng_ector_destroy(void *data EINA_UNUSED, Ector_Surface *ector)
}
static Ector_Buffer *
eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image, Eina_Bool is_rgba_image EINA_UNUSED)
eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image)
{
Image_Entry *ie = engine_image;
Ector_Buffer *buf = NULL;
@ -4342,61 +4342,42 @@ eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image, Eina_
if (!efl_domain_current_push(EFL_ID_DOMAIN_SHARED))
return NULL;
buf = efl_add(EVAS_ECTOR_SOFTWARE_BUFFER_CLASS, NULL, evas_ector_buffer_engine_image_set(efl_added, e, ie));
buf = efl_add(EVAS_ECTOR_SOFTWARE_BUFFER_CLASS, NULL,
evas_ector_buffer_engine_image_set(efl_added, e, ie));
efl_domain_current_pop();
return buf;
}
static Ector_Buffer *
eng_ector_buffer_new(void *data EINA_UNUSED, Evas *evas, void *pixels,
int width, int height, int stride,
Efl_Gfx_Colorspace cspace, Eina_Bool writeable,
int l, int r, int t, int b,
Ector_Buffer_Flag flags EINA_UNUSED)
eng_ector_buffer_new(void *data EINA_UNUSED, Evas *evas, int width, int height,
Efl_Gfx_Colorspace cspace, Ector_Buffer_Flag flags EINA_UNUSED)
{
Ector_Buffer *buf = NULL;
int pxs = (cspace == EFL_GFX_COLORSPACE_ARGB8888) ? 4 : 1;
int iw = width + l + r;
int ih = height + t + b;
Ector_Buffer *buf;
Image_Entry *ie;
void *pixels;
int pxs;
if ((flags & (ECTOR_BUFFER_FLAG_RENDERABLE | ECTOR_BUFFER_FLAG_DRAWABLE)) == 0)
{
if (!efl_domain_current_push(EFL_ID_DOMAIN_SHARED))
return NULL;
buf = efl_add(ECTOR_SOFTWARE_BUFFER_CLASS, NULL, ector_buffer_pixels_set(efl_added, pixels, width, height, stride, cspace, writeable, l, r, t, b));
efl_domain_current_pop();
}
if (cspace == EFL_GFX_COLORSPACE_ARGB8888)
pxs = 4;
else if (cspace == EFL_GFX_COLORSPACE_GRY8)
pxs = 1;
else
{
// Create an RGBA Image as backing
Image_Entry *ie;
if (pixels)
{
// no copy
ie = evas_cache_image_data(evas_common_image_cache_get(), iw, ih,
pixels, EINA_TRUE, (Evas_Colorspace) cspace);
if (!ie) return NULL;
}
else
{
// alloc buffer
ie = evas_cache_image_copied_data(evas_common_image_cache_get(), iw, ih,
NULL, EINA_TRUE, (Evas_Colorspace) cspace);
if (!ie) return NULL;
pixels = ((RGBA_Image *) ie)->image.data;
memset(pixels, 0, iw * ih * pxs);
}
ie->borders.l = l;
ie->borders.r = r;
ie->borders.t = t;
ie->borders.b = b;
buf = eng_ector_buffer_wrap(data, evas, ie, EINA_TRUE);
evas_cache_image_drop(ie);
ERR("Unsupported colorspace: %d", (int) cspace);
return NULL;
}
// alloc buffer
ie = evas_cache_image_copied_data(evas_common_image_cache_get(), width, height,
NULL, EINA_TRUE, cspace);
if (!ie) return NULL;
pixels = ((RGBA_Image *) ie)->image.data;
memset(pixels, 0, width * height * pxs);
buf = eng_ector_buffer_wrap(data, evas, ie);
evas_cache_image_drop(ie);
return buf;
}
@ -4546,7 +4527,7 @@ _draw_thread_ector_surface_set(void *data)
y = ector_surface->y;
}
ector_buffer_pixels_set(ector_surface->ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE, 0, 0, 0, 0);
ector_buffer_pixels_set(ector_surface->ector, pixels, w, h, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
ector_surface_reference_point_set(ector_surface->ector, x, y);
eina_mempool_free(_mp_command_ector_surface, ector_surface);
@ -4591,7 +4572,7 @@ eng_ector_begin(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface
w = sf->cache_entry.w;
h = sf->cache_entry.h;
ector_buffer_pixels_set(ector, pixels, w, h, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE, 0, 0, 0, 0);
ector_buffer_pixels_set(ector, pixels, w, h, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
ector_surface_reference_point_set(ector, x, y);
}
}
@ -4613,7 +4594,7 @@ eng_ector_end(void *data EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *
}
else
{
ector_buffer_pixels_set(ector, NULL, 0, 0, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE, 0, 0, 0, 0);
ector_buffer_pixels_set(ector, NULL, 0, 0, EFL_GFX_COLORSPACE_ARGB8888, EINA_TRUE);
evas_common_cpu_end_opt();
}
}

View File

@ -269,7 +269,7 @@ _filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ARGB, &src_stride);
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ, E_ARGB, &dst_stride);
dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ | E_WRITE, E_ARGB, &dst_stride);
stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
map_w = cmd->mask->w;
@ -294,7 +294,7 @@ _filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
}
else map_fb = cmd->mask;
map_start = (uint32_t *) _buffer_map_all(map_fb->buffer, &map_len, E_READ, E_ARGB, &map_stride);
map_start = _buffer_map_all(map_fb->buffer, &map_len, E_READ, E_ARGB, &map_stride);
EINA_SAFETY_ON_FALSE_GOTO(src && dst && map_start, end);
_filter_displace_cpu_rgba_do(w, h, map_w, map_h, intensity,

View File

@ -10,7 +10,7 @@ _fill_cpu(Evas_Filter_Command *cmd)
uint32_t color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
unsigned int stride, len;
int w, h, k;
uint8_t *ptr;
uint8_t *map, *ptr;
if (!cmd->draw.clip_mode_lrtb)
{
@ -31,10 +31,10 @@ _fill_cpu(Evas_Filter_Command *cmd)
h = CLAMP(0, fb->h - y - cmd->draw.clip.b, fb->h - y);
}
ptr = _buffer_map_all(fb->buffer, &len, E_WRITE, fb->alpha_only ? E_ALPHA : E_ARGB, &stride);
if (!ptr) return EINA_FALSE;
map = _buffer_map_all(fb->buffer, &len, E_WRITE, fb->alpha_only ? E_ALPHA : E_ARGB, &stride);
if (!map) return EINA_FALSE;
ptr += y * stride;
ptr = map + y * stride;
if (fb->alpha_only)
{
for (k = 0; k < h; k++)
@ -52,7 +52,7 @@ _fill_cpu(Evas_Filter_Command *cmd)
}
}
ector_buffer_unmap(fb->buffer, ptr, len);
ector_buffer_unmap(fb->buffer, map, len);
return EINA_TRUE;
}

View File

@ -16,9 +16,9 @@ eng_filter_mask_func_get(Evas_Filter_Command *cmd)
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->buffer, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->buffer, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->buffer, NULL);
//EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->buffer, NULL);
//EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->buffer, NULL);
//EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->buffer, NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->input->w > 0) && (cmd->input->h > 0), NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL((cmd->mask->w > 0) && (cmd->mask->h > 0), NULL);
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->w == cmd->output->w, NULL);