This is a major refactoring of the evas filters submodule.
Use Ector.Buffer and the map/unmap methods instead of directly
accessing image buffers with RGBA_Image. RGBA_Image is still
used under the hood, for two reasons:
- Required for the final output (blend onto Evas itself)
- Required for the scaling routines
FIXME:
- Breaks proxy support (ie. all kind of texturing).
- This breaks filters support for the GL engine.
// Request rendering from the object itself (child class)
evas_filter_program_padding_get(pd->data->chain, &l, &r, &t, &b);
- eo_do(eo_obj, evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
+ eo_do(eo_obj, ok = evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
+ if (!ok) ERR("Filter input render failed.");
ENFN->context_free(ENDT, drawctx);
#endif
#include "evas_filter_private.h"
+#include <Ector.h>
+#include <software/Ector_Software.h>
+#include "evas_ector_buffer.eo.h"
#define _assert(a) if (!(a)) CRI("Failed on %s", #a);
static void _buffer_free(Evas_Filter_Buffer *fb);
static void _command_del(Evas_Filter_Context *ctx, Evas_Filter_Command *cmd);
-static RGBA_Image *_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data);
+static Ector_Buffer* _ector_buffer_create(Evas_Filter_Buffer const *fb, void *data);
#define DRAW_COLOR_SET(r, g, b, a) do { cmd->draw.R = r; cmd->draw.G = g; cmd->draw.B = b; cmd->draw.A = a; } while (0)
#define DRAW_CLIP_SET(_x, _y, _w, _h) do { cmd->draw.clip.x = _x; cmd->draw.clip.y = _y; cmd->draw.clip.w = _w; cmd->draw.clip.h = _h; } while (0)
#define DRAW_FILL_SET(fmode) do { cmd->draw.fillmode = fmode; } while (0)
-typedef struct _Evas_Filter_Thread_Command Evas_Filter_Thread_Command;
-struct _Evas_Filter_Thread_Command
+static inline void *
+_evas_image_get(Ector_Buffer *buf)
{
- Evas_Filter_Context *ctx;
- RGBA_Image *src, *mask, *dst;
- Evas_Filter_Apply_Func func;
-};
-
+ void *image = NULL;
+ if (!buf) return NULL;
+ eo_do(buf, evas_ector_buffer_engine_image_get(NULL, &image));
+ return image;
+}
/* Main functions */
* better and implement filters direcly with shaders.
*/
ctx->gl_engine = (evas->engine.func->gl_surface_read_pixels != NULL);
+ if (ctx->gl_engine)
+ {
+ // FIXME!!!
+ CRI("gl support not implemented");
+ }
return ctx;
}
}
static void
-_backing_free(Evas_Filter_Context *ctx, RGBA_Image *im)
-{
- if (!im) return;
-
- if (!ctx->gl_engine)
- {
- if (!ctx->async)
- ENFN->image_free(ENDT, im);
- else
- evas_unref_queue_image_put(ctx->evas, &im->cache_entry);
- }
- else
- {
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- evas_cache2_image_close(&im->cache_entry);
- else
-#endif
- evas_cache_image_drop(&im->cache_entry);
- }
-}
-
-static void
_filter_buffer_backing_free(Evas_Filter_Buffer *fb)
{
- if (!fb) return;
-
- _backing_free(fb->ctx, fb->backing);
- if (fb->glimage)
- fb->ENFN->image_free(fb->ENDT, fb->glimage);
- fb->backing = NULL;
- fb->glimage = NULL;
+ if (!fb || !fb->buffer) return;
+ eo_del(fb->buffer);
+ fb->buffer = NULL;
}
/* GL engine stuff: read-back from texture */
static Eina_Bool
-_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb, void *glimage)
+_filter_buffer_glimage_pixels_read(Evas_Filter_Buffer *fb EINA_UNUSED, void *glimage EINA_UNUSED)
{
+ CRI("not implemented");
+ return 0;
+
+#if 0
Eina_Bool ok;
EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_read_pixels, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(fb->ENFN->gl_surface_unlock, EINA_FALSE);
- fb->backing = _rgba_image_alloc(fb, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(fb->backing, EINA_FALSE);
+ fb->buffer = _ector_buffer_create(fb, NULL);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(fb->buffer, EINA_FALSE);
ok = fb->ENFN->gl_surface_lock(fb->ENDT, glimage);
if (!ok)
ok &= fb->ENFN->gl_surface_unlock(fb->ENDT, glimage);
return ok;
+#endif
}
/** @hidden private render proxy objects */
void
-evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj,
- Eina_Bool do_async)
+evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx EINA_UNUSED, Eo *eo_obj EINA_UNUSED,
+ Eina_Bool do_async EINA_UNUSED)
{
+ CRI("not implemented");
+ return;
+
+#if 0
Evas_Object_Protected_Data *source;
Evas_Object_Protected_Data *obj;
Evas_Filter_Buffer *fb;
fb->alpha_only = EINA_FALSE;
XDBG("Source has dimensions %dx%d (buffer %d)", fb->w, fb->h, fb->id);
}
+#endif
}
void
return fb;
}
-static RGBA_Image *
-_rgba_image_alloc(Evas_Filter_Buffer const *fb, void *data)
+static Ector_Buffer *
+_ector_buffer_create(Evas_Filter_Buffer const *fb, void *data)
{
Evas_Colorspace cspace;
- RGBA_Image *image;
- size_t sz;
+ Image_Entry *ie;
+
+ // FIXME: We still rely on evas image structs (scaling and target render)
+ // This should be fixed by implementing full support in ector
+ // Note: dropped support for cserve2, that was not needed anyway
+
+ cspace = fb->alpha_only ? E_ALPHA : E_ARGB;
+#if 0
+ // ideal code
+ return fb->ENFN->ector_buffer_new(fb->ENDT, fb->ctx->evas->evas,
+ data, fb->w, fb->h, 0,
+ cspace, EINA_TRUE, 0, 0, 0, 0,
+ ECTOR_BUFFER_FLAG_CPU_READABLE |
+ ECTOR_BUFFER_FLAG_CPU_WRITABLE);
+#endif
- cspace = fb->alpha_only ? EVAS_COLORSPACE_GRY8 : EVAS_COLORSPACE_ARGB8888;
- if (!fb->ctx->gl_engine)
+ if (data)
{
- if (!data)
- {
- image = fb->ENFN->image_new_from_copied_data
- (fb->ENDT, fb->w, fb->h, NULL, EINA_TRUE, cspace);
- }
- else
- {
- image = fb->ENFN->image_new_from_data
- (fb->ENDT, fb->w, fb->h, data, EINA_TRUE, cspace);
- }
+ // no copy
+ ie = evas_cache_image_data(evas_common_image_cache_get(), fb->w, fb->h,
+ data, EINA_TRUE, cspace);
+ if (!ie) return NULL;
}
else
{
- // FIXME: Directly calling the alloc functions since we want to use sw surfaces.
-
- if (!data)
- {
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- image = (RGBA_Image *) evas_cache2_image_copied_data
- (evas_common_image_cache2_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
- else
-#endif
- image = (RGBA_Image *) evas_cache_image_copied_data
- (evas_common_image_cache_get(), fb->w, fb->h, NULL, EINA_TRUE, cspace);
- }
- else
- {
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get())
- image = (RGBA_Image *) evas_cache2_image_data
- (evas_common_image_cache2_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
- else
-#endif
- image = (RGBA_Image *) evas_cache_image_data
- (evas_common_image_cache_get(), fb->w, fb->h, data, EINA_TRUE, cspace);
- }
+ // alloc buffer
+ ie = evas_cache_image_copied_data(evas_common_image_cache_get(), fb->w, fb->h,
+ NULL, EINA_TRUE, cspace);
+ if (!ie) return NULL;
+ data = ((RGBA_Image *) ie)->image.data;
+ memset(data, 0, fb->w * fb->h * (fb->alpha_only ? 1 : 4));
}
- if (!image) return NULL;
-
- if (fb->alpha_only)
- sz = image->cache_entry.w * image->cache_entry.h * sizeof(DATA8);
- else
- sz = image->cache_entry.w * image->cache_entry.h * sizeof(DATA32);
- if (!data) memset(image->image.data, 0, sz);
-
- return image;
+ return fb->ENFN->ector_buffer_wrap(fb->ENDT, fb->ctx->evas->evas, ie);
}
Eina_Bool
EINA_LIST_FOREACH(ctx->buffers, li, fb)
{
- if (fb->backing || fb->source || fb->glimage)
+ if (fb->buffer || fb->source || fb->glimage)
continue;
if (!fb->w && !fb->h)
continue;
}
- fb->backing = _rgba_image_alloc(fb, NULL);
- XDBG("Allocating buffer #%d of size %ux%u %s",
- fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba");
- if (!fb->backing) goto alloc_fail;
+ fb->buffer = _ector_buffer_create(fb, NULL);
+ XDBG("Allocated buffer #%d of size %ux%u %s: %p",
+ fb->id, fb->w, fb->h, fb->alpha_only ? "alpha" : "rgba", fb->buffer);
+ if (!fb->buffer) goto alloc_fail;
}
return EINA_TRUE;
if (w <= 0 || h <= 0)
return EINA_FALSE;
- EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->backing == NULL, EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(fb->buffer == NULL, EINA_FALSE);
// TODO: Check input parameters?
fb->alpha_only = alpha_only;
fb->w = w;
fb->h = h;
- fb->backing = _rgba_image_alloc(fb, data);
- return (fb->backing != NULL);
+ fb->buffer = _ector_buffer_create(fb, data);
+ return (fb->buffer != NULL);
}
-int
-evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image)
+static int
+_filter_buffer_new_from_evas_surface(Evas_Filter_Context *ctx, void *image)
{
Evas_Filter_Buffer *fb;
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
- image = ENFN->image_ref(ENDT, image);
- EINA_SAFETY_ON_NULL_RETURN_VAL(image, -1);
-
fb = calloc(1, sizeof(Evas_Filter_Buffer));
if (!fb) return -1;
fb->id = ++(ctx->last_buffer_id);
fb->ctx = ctx;
- if (!ctx->gl_engine)
- fb->backing = image;
- else
- fb->glimage = image;
+ fb->buffer = ENFN->ector_buffer_wrap(ENDT, ctx->evas->evas, image);
ENFN->image_size_get(ENDT, image, &fb->w, &fb->h);
fb->alpha_only = (ENFN->image_colorspace_get(ENDT, image)
== EVAS_COLORSPACE_GRY8);
void *
evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid)
{
- Evas_Filter_Buffer *buffer;
+ Evas_Filter_Buffer *fb;
- buffer = _filter_buffer_get(ctx, bufid);
- if (!buffer) return NULL;
+ fb = _filter_buffer_get(ctx, bufid);
+ if (!fb) return NULL;
- return buffer->backing;
+ return _evas_image_get(fb->buffer);
}
void *
{
Evas_Filter_Buffer *fb;
- EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
-
fb = _filter_buffer_get(ctx, bufid);
if (!fb) return NULL;
- if (ctx->gl_engine)
- return fb->ENFN->image_ref(fb->ENDT, fb->glimage);
- else
- return fb->ENFN->image_ref(fb->ENDT, fb->backing);
+ return fb->ENFN->image_ref(fb->ENDT, _evas_image_get(fb->buffer));
}
Eina_Bool
if (ctx->async)
evas_unref_queue_image_put(ctx->evas, stolen_buffer);
- else if (ctx->gl_engine)
- ctx->post_run.buffers_to_free =
- eina_list_append(ctx->post_run.buffers_to_free, stolen_buffer);
else
- _backing_free(ctx, stolen_buffer);
+ {
+ ctx->post_run.buffers_to_free =
+ eina_list_append(ctx->post_run.buffers_to_free, stolen_buffer);
+ }
return EINA_TRUE;
}
return -1;
}
- if (in->alpha_only != out->alpha_only)
- {
- CRI("Incompatible buffer formats");
- return -1;
- }
-
cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out);
if (!cmd) return -1;
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, EINA_FALSE);
- ctx->target.bufid = evas_filter_buffer_image_new(ctx, surface);
+ ctx->target.bufid = _filter_buffer_new_from_evas_surface(ctx, surface);
ctx->target.x = x;
ctx->target.y = y;
ctx->target.clip_use = ENFN->context_clip_get
ctx->evas->engine.func->image_free(ctx->evas->engine.data.output, ctx->target.mask);
ctx->target.mask = mask;
+#if 0
if (ctx->gl_engine)
{
// Since GL has sync rendering, draw_context is safe to keep around
XDBG("Set target as #%d (%p) and output #%d (%p, gl %p)",
ctx->target.bufid, surface, fb->id, fb->backing, fb->glimage);
}
+#endif
return EINA_TRUE;
}
_filter_target_render(Evas_Filter_Context *ctx)
{
Evas_Filter_Buffer *src, *dst;
- void *drawctx, *image, *surface;
+ void *drawctx, *image = NULL, *surface = NULL;
int cx, cy, cw, ch;
Eina_Bool use_clip = EINA_FALSE;
EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
- if (!ctx->gl_engine)
- {
- drawctx = ENFN->context_new(ENDT);
- surface = dst->backing;
- image = src->backing;
- }
- else
+#if 0
+ if (ctx->gl_engine)
{
drawctx = ctx->target.context;
surface = dst->glimage;
}
image = src->glimage;
}
+ else
+#endif
+ {
+ drawctx = ENFN->context_new(ENDT);
+ image = _evas_image_get(src->buffer);
+ surface = _evas_image_get(dst->buffer);
+ }
EINA_SAFETY_ON_NULL_RETURN_VAL(image, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(surface, EINA_FALSE);
+ // FIXME: Use ector buffer RENDERER here
+
if (ctx->target.clip_use)
{
use_clip = ENFN->context_clip_get(ENDT, drawctx, &cx, &cy, &cw, &ch);
{
Eina_Bool async_unref;
Evas_Filter_Buffer *fb;
- void *surface;
+ void *surface = NULL;
fb = _filter_buffer_get(ctx, bufid);
- if (!fb) return EINA_FALSE;
-
- surface = fb->backing;
+ surface = _evas_image_get(fb->buffer);
if (!surface) return EINA_FALSE;
if (!ctx->gl_engine)
DEBUG_TIME_END();
EINA_LIST_FREE(ctx->post_run.buffers_to_free, buffer)
- {
- if (ctx->gl_engine)
- ENFN->image_free(ENDT, buffer);
- }
+ ENFN->image_free(ENDT, buffer);
return ok;
}
#include "evas_filter.h"
#include "evas_filter_private.h"
#include "evas_blend_private.h"
+#include "ector_buffer.h"
#include "draw.h"
+// FIXME: This should all be based on ector renderer
+
// Use a better formula than R+G+B for rgba to alpha conversion (RGB to YCbCr)
#define RGBA2ALPHA_WEIGHTED 1
-typedef Eina_Bool (*image_draw_func) (void *data, void *context, void *surface, void *image, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async);
-static Eina_Bool _mapped_blend(void *data, void *drawctx, void *in, void *out, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, image_draw_func image_draw);
+typedef Eina_Bool (*draw_func) (void *data, void *context, const void *src_map, unsigned int src_stride, void *dst_map, unsigned int dst_stride, int src_x, int src_y, int src_w, int src_h, int dst_x, int dst_y, int dst_w, int dst_h, int smooth, Eina_Bool do_async);
+static Eina_Bool _mapped_blend(void *data, void *drawctx, const void *src_map, unsigned int src_stride, void *dst_map, unsigned int dst_stride, Evas_Filter_Fill_Mode fillmode, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, draw_func image_draw);
struct Filter_Blend_Draw_Context
{
Efl_Gfx_Render_Op rop;
- DATA32 color;
+ uint32_t color;
};
+#define LINELEN(stride, ptr) (stride / (sizeof(*ptr)))
+
static Eina_Bool
_image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context,
- void *surface, void *image,
+ const void *src_map, unsigned int src_stride,
+ void *dst_map, unsigned int dst_stride,
int src_x, int src_y, int src_w, int src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
int smooth EINA_UNUSED,
Eina_Bool do_async EINA_UNUSED)
{
struct Filter_Blend_Draw_Context *dc = context;
- RGBA_Image *src = image;
- RGBA_Image *dst = surface;
- DATA8* srcdata = src->image.data8;
- DATA8* dstdata = dst->image.data8;
+ const uint8_t *srcdata = src_map;
+ uint8_t *dstdata = dst_map;
Alpha_Gfx_Func func;
int y, sw, dw;
func = efl_draw_alpha_func_get(dc->rop, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
- sw = src->cache_entry.w;
- dw = dst->cache_entry.w;
+ sw = LINELEN(src_stride, srcdata);
+ dw = LINELEN(dst_stride, dstdata);
srcdata += src_y * sw;
dstdata += dst_y * dw;
static Eina_Bool
_image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context,
- void *surface, void *image,
+ const void *src_map, unsigned int src_stride,
+ void *dst_map, unsigned int dst_stride,
int src_x, int src_y, int src_w, int src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
int smooth EINA_UNUSED,
Eina_Bool do_async EINA_UNUSED)
{
struct Filter_Blend_Draw_Context *dc = context;
- RGBA_Image *src = image;
- RGBA_Image *dst = surface;
- DATA8* srcdata = src->image.data8;
- DATA32* dstdata = dst->image.data;
+ uint8_t *srcdata = (uint8_t *) src_map;
+ uint32_t *dstdata = dst_map;
RGBA_Gfx_Func func;
int y, sw, dw;
EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
- func = evas_common_gfx_func_composite_mask_color_span_get
- (dc->color, dst->cache_entry.flags.alpha, 1, dc->rop);
+ func = evas_common_gfx_func_composite_mask_color_span_get(dc->color, 1, 1, _gfx_to_evas_render_op(dc->rop));
EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
- sw = src->cache_entry.w;
- dw = dst->cache_entry.w;
+ sw = LINELEN(src_stride, srcdata);
+ dw = LINELEN(dst_stride, dstdata);
srcdata += src_y * sw;
dstdata += dst_y * dw;
}
static Eina_Bool
-_filter_blend_cpu_generic_do(Evas_Filter_Command *cmd,
- image_draw_func image_draw)
+_image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context,
+ const void *src_map, unsigned int src_stride,
+ void *dst_map, unsigned int dst_stride,
+ int src_x, int src_y, int src_w, int src_h,
+ int dst_x, int dst_y, int dst_w, int dst_h,
+ int smooth EINA_UNUSED,
+ Eina_Bool do_async EINA_UNUSED)
{
- RGBA_Image *in, *out;
- int sw, sh, dx, dy, dw, dh, sx, sy;
- struct Filter_Blend_Draw_Context dc;
-
- in = cmd->input->backing;
- out = cmd->output->backing;
- EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
-
- sx = 0;
- sy = 0;
- sw = in->cache_entry.w;
- sh = in->cache_entry.h;
+ struct Filter_Blend_Draw_Context *dc = context;
+ uint32_t *srcdata = (uint32_t *) src_map;
+ uint32_t *dstdata = dst_map;
+ RGBA_Gfx_Func func;
+ int y, sw, dw;
- dx = cmd->draw.ox;
- dy = cmd->draw.oy;
- dw = out->cache_entry.w;
- dh = out->cache_entry.h;
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
- if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
+ if (!dc->color)
return EINA_TRUE;
+ else if (dc->color == 0xFFFFFFFF)
+ func = evas_common_gfx_func_composite_pixel_span_get(1, 0, 1, 1, _gfx_to_evas_render_op(dc->rop));
+ else
+ func = evas_common_gfx_func_composite_pixel_color_span_get(1, 0, dc->color, 1, 1, _gfx_to_evas_render_op(dc->rop));
+ EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
- // Stretch if necessary.
-
- /* NOTE: As of 2014/03/11, this will happen only with RGBA buffers, since
- * only proxy sources may be scaled. So, we don't need an alpha scaling
- * algorithm just now.
- */
+ sw = LINELEN(src_stride, srcdata);
+ dw = LINELEN(dst_stride, dstdata);
- if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
+ srcdata += src_y * sw;
+ dstdata += dst_y * dw;
+ for (y = src_h; y; y--)
{
- Evas_Filter_Buffer *fb;
-
- if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
- sw = dw;
- if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
- sh = dh;
-
- BUFFERS_LOCK();
- fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, sw, sh);
- BUFFERS_UNLOCK();
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
- fb->locked = EINA_FALSE;
- in = fb->backing;
+ func(srcdata + src_x, NULL, dc->color, dstdata + dst_x, src_w);
+ srcdata += sw;
+ dstdata += dw;
}
- dc.rop = cmd->draw.rop;
- dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
- return _mapped_blend(cmd->ENDT, &dc, in, out, cmd->draw.fillmode,
- sx, sy, sw, sh, dx, dy, dw, dh, image_draw);
+ return EINA_TRUE;
}
static Eina_Bool
_image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED,
- void *surface, void *image,
+ const void *src_map, unsigned int src_stride,
+ void *dst_map, unsigned int dst_stride,
int src_x, int src_y, int src_w, int src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
int smooth EINA_UNUSED,
Eina_Bool do_async EINA_UNUSED)
{
- RGBA_Image *src = image;
- RGBA_Image *dst = surface;
- DATA32* srcdata = src->image.data;
- DATA8* dstdata = dst->image.data8;
+ uint32_t *srcdata = (uint32_t *) src_map;
+ uint8_t *dstdata = dst_map;
int x, y, sw, dw;
#if RGBA2ALPHA_WEIGHTED
const int WR = 299;
EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
- sw = src->cache_entry.w;
- dw = dst->cache_entry.w;
+ sw = LINELEN(src_stride, srcdata);
+ dw = LINELEN(dst_stride, dstdata);
srcdata += src_y * sw;
dstdata += dst_y * dw;
for (y = src_h; y; y--)
{
- DATA32 *s = srcdata + src_x;
- DATA8 *d = dstdata + dst_x;
+ uint32_t *s = srcdata + src_x;
+ uint8_t *d = dstdata + dst_x;
for (x = src_w; x; x--, d++, s++)
*d = DIVIDE((R_VAL(s) * WR) + (G_VAL(s) * WG) + (B_VAL(s) * WB));
srcdata += sw;
}
static Eina_Bool
-_image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context,
- void *surface, void *image,
- int src_x, int src_y, int src_w, int src_h,
- int dst_x, int dst_y, int dst_w, int dst_h,
- int smooth EINA_UNUSED,
- Eina_Bool do_async EINA_UNUSED)
+_filter_blend_cpu_generic_do(Evas_Filter_Command *cmd, draw_func image_draw)
{
- struct Filter_Blend_Draw_Context *dc = context;
- RGBA_Image *src = image;
- RGBA_Image *dst = surface;
- DATA32* srcdata = src->image.data;
- DATA32* dstdata = dst->image.data;
- RGBA_Gfx_Func func;
- int y, sw, dw;
+ unsigned int src_len, src_stride, dst_len, dst_stride;
+ int sw, sh, dx, dy, dw, dh, sx, sy;
+ struct Filter_Blend_Draw_Context dc;
+ Eina_Bool ret = EINA_FALSE;
+ Evas_Filter_Buffer *src_fb;
+ void *src, *dst;
- EINA_SAFETY_ON_FALSE_RETURN_VAL((src_w == dst_w) && (src_h == dst_h), EINA_FALSE);
+ sx = 0;
+ sy = 0;
+ eo_do(cmd->input->buffer, ector_buffer_size_get(&sw, &sh));
- if (!dc->color)
+ dx = cmd->draw.ox;
+ dy = cmd->draw.oy;
+ eo_do(cmd->output->buffer, ector_buffer_size_get(&dw, &dh));
+
+ if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
return EINA_TRUE;
- else if (dc->color == 0xFFFFFFFF)
- func = evas_common_gfx_func_composite_pixel_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dst->cache_entry.flags.alpha, 1, dc->rop);
- else
- func = evas_common_gfx_func_composite_pixel_color_span_get(src->cache_entry.flags.alpha, src->cache_entry.flags.alpha_sparse, dc->color, dst->cache_entry.flags.alpha, 1, dc->rop);
- EINA_SAFETY_ON_NULL_RETURN_VAL(func, EINA_FALSE);
- sw = src->cache_entry.w;
- dw = dst->cache_entry.w;
+ // Stretch if necessary.
- srcdata += src_y * sw;
- dstdata += dst_y * dw;
- for (y = src_h; y; y--)
+ /* NOTE: As of 2014/03/11, this will happen only with RGBA buffers, since
+ * only proxy sources may be scaled. So, we don't need an alpha scaling
+ * algorithm just now.
+ */
+
+ if ((sw != dw || sh != dh) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
{
- func(srcdata + src_x, NULL, dc->color, dstdata + dst_x, src_w);
- srcdata += sw;
- dstdata += dw;
+
+ if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
+ sw = dw;
+ if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
+ sh = dh;
+
+ BUFFERS_LOCK();
+ src_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->input, sw, sh);
+ BUFFERS_UNLOCK();
+
+ EINA_SAFETY_ON_NULL_GOTO(src_fb, end);
+ src_fb->locked = EINA_FALSE;
}
+ else src_fb = cmd->input;
- return EINA_TRUE;
+ src = _buffer_map_all(src_fb->buffer, &src_len, E_READ, src_fb->alpha_only ? E_ALPHA : E_ARGB, &src_stride);
+ dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &dst_stride);
+
+ dc.rop = cmd->draw.rop;
+ dc.color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+
+ ret = _mapped_blend(cmd->ENDT, &dc, src, src_stride, dst, dst_stride, cmd->draw.fillmode,
+ sx, sy, sw, sh, dx, dy, dw, dh, image_draw);
+
+end:
+ eo_do(src_fb->buffer, ector_buffer_unmap(src, src_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
+ return ret;
}
static Eina_Bool
}
static Eina_Bool
-_filter_blend_cpu_mask_rgba(Evas_Filter_Command *cmd)
+_filter_blend_cpu_alpha2rgba(Evas_Filter_Command *cmd)
{
return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha2rgba);
}
static Eina_Bool
_filter_blend_cpu_rgba(Evas_Filter_Command *cmd)
{
- RGBA_Image *in, *out;
- RGBA_Draw_Context *drawctx;
- int sw, sh, dx, dy, dw, dh, sx, sy;
- Eina_Bool ret;
-
- in = cmd->input->backing;
- out = cmd->output->backing;
- EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
-
- if (cmd->ctx->gl_engine)
- return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2rgba);
-
- sx = 0;
- sy = 0;
- sw = in->cache_entry.w;
- sh = in->cache_entry.h;
-
- dx = cmd->draw.ox;
- dy = cmd->draw.oy;
- dw = out->cache_entry.w;
- dh = out->cache_entry.h;
-
- if ((dw <= 0) || (dh <= 0) || (sw <= 0) || (sh <= 0))
- return EINA_TRUE;
-
- drawctx = cmd->ENFN->context_new(cmd->ENDT);
- cmd->ENFN->context_color_set(cmd->ENDT, drawctx, 255, 255, 255, 255);
- if ((cmd->draw.R != 255) || (cmd->draw.G != 255) || (cmd->draw.B != 255) || (cmd->draw.A != 255))
- cmd->ENFN->context_multiplier_set(cmd->ENDT, drawctx, cmd->draw.R, cmd->draw.G, cmd->draw.B, cmd->draw.A);
- else
- cmd->ENFN->context_multiplier_unset(cmd->ENDT, drawctx);
- cmd->ENFN->context_render_op_set(cmd->ENDT, drawctx, _gfx_to_evas_render_op(cmd->draw.rop));
-
- if (cmd->draw.clip_use)
- {
- cmd->ENFN->context_clip_set(cmd->ENDT, drawctx,
- cmd->draw.clip.x, cmd->draw.clip.y,
- cmd->draw.clip.w, cmd->draw.clip.h);
- cmd->ENFN->context_clip_clip(cmd->ENDT, drawctx, 0, 0,
- out->cache_entry.w, out->cache_entry.h);
- }
- else
- {
- cmd->ENFN->context_clip_set(cmd->ENDT, drawctx, 0, 0,
- out->cache_entry.w, out->cache_entry.h);
- }
-
- ret = _mapped_blend(cmd->ENDT, drawctx, in, out, cmd->draw.fillmode,
- sx, sy, sw, sh, dx, dy, dw, dh,
- cmd->ENFN->image_draw);
-
- cmd->ENFN->context_free(cmd->ENDT, drawctx);
- return ret;
+ return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2rgba);
}
static Eina_Bool
_mapped_blend(void *data, void *drawctx,
- void *in, void *out,
+ const void *src_map, unsigned int src_stride,
+ void *dst_map, unsigned int dst_stride,
Evas_Filter_Fill_Mode fillmode,
int sx, int sy,
int sw, int sh,
int dx, int dy,
int dw, int dh,
- image_draw_func image_draw)
+ draw_func image_draw)
{
int right = 0, bottom = 0, left = 0, top = 0;
int row, col, rows, cols;
XDBG("blend: %d,%d,%d,%d --> %d,%d,%d,%d (from %dx%d to %dx%d +%d,%d)",
0, 0, sw, sh, dx, dy, cols, rows, sw, sh, dw, dh, dx, dy);
}
- image_draw(data, drawctx, out, in,
+ image_draw(data, drawctx,
+ src_map, src_stride, dst_map, dst_stride,
sx, sy, cols, rows, // src
dx, dy, cols, rows, // dst
EINA_TRUE, // smooth
dst_x, dst_y, dst_w, dst_h,
sw, sh, dw, dh);
}
- image_draw(data, drawctx, out, in,
+ image_draw(data, drawctx,
+ src_map, src_stride, dst_map, dst_stride,
src_x, src_y, src_w, src_h,
dst_x, dst_y, dst_w, dst_h,
EINA_TRUE, EINA_FALSE);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL);
- if (!cmd->ctx->gl_engine || !cmd->output->glimage || cmd->output->backing)
+ if (cmd->input->alpha_only)
{
- if (cmd->input->alpha_only)
- {
- if (cmd->output->alpha_only)
- return _filter_blend_cpu_alpha;
- else
- return _filter_blend_cpu_mask_rgba;
- }
+ if (cmd->output->alpha_only)
+ return _filter_blend_cpu_alpha;
else
- {
- if (cmd->output->alpha_only)
- return _filter_blend_cpu_rgba2alpha;
- else
- return _filter_blend_cpu_rgba;
- }
+ return _filter_blend_cpu_alpha2rgba;
}
else
{
- CRI("Can't render to GL image for the moment!");
- //return _filter_blend_opengl_generic;
- return NULL;
+ if (cmd->output->alpha_only)
+ return _filter_blend_cpu_rgba2alpha;
+ else
+ return _filter_blend_cpu_rgba;
}
}
#include <math.h>
#include <time.h>
+// FIXME: Add proper stride support
+
static int
_box_blur_auto_radius(int *radii, int r)
{
#endif
static void
-_box_blur_horiz_rgba(DATA32 *src, DATA32 *dst, int* radii, int w, int h)
+_box_blur_horiz_rgba(uint32_t *src, uint32_t *dst, int* radii, int w, int h)
{
DEBUG_TIME_BEGIN();
}
static void
-_box_blur_vert_rgba(DATA32 *src, DATA32 *dst, int* radii, int w, int h)
+_box_blur_vert_rgba(uint32_t *src, uint32_t *dst, int* radii, int w, int h)
{
DEBUG_TIME_BEGIN();
DEBUG_TIME_END();
}
-static Eina_Bool
-_box_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
-{
- RGBA_Image *in, *out;
- int radii[7] = {0};
- unsigned int r;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
- r = abs(cmd->blur.dx);
- in = cmd->input->backing;
- out = cmd->output->backing;
-
- if (cmd->blur.auto_count)
- _box_blur_auto_radius(radii, r);
- else for (int k = 0; k < cmd->blur.count; k++)
- radii[k] = r;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
-
- _box_blur_horiz_rgba(in->image.data, out->image.data, radii,
- in->cache_entry.w, in->cache_entry.h);
-
- return EINA_TRUE;
-}
-
-static Eina_Bool
-_box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
-{
- RGBA_Image *in, *out;
- int radii[7] = {0};
- unsigned int r;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
- r = abs(cmd->blur.dy);
- in = cmd->input->backing;
- out = cmd->output->backing;
-
- if (cmd->blur.auto_count)
- _box_blur_auto_radius(radii, r);
- else for (int k = 0; k < cmd->blur.count; k++)
- radii[k] = r;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
-
- _box_blur_vert_rgba(in->image.data, out->image.data, radii,
- in->cache_entry.w, in->cache_entry.h);
-
- return EINA_TRUE;
-}
-
#include "./blur/blur_box_alpha_.c"
#ifdef BUILD_MMX
#include "./blur/blur_box_alpha_i386.c"
#endif
static void
-_box_blur_horiz_alpha(DATA8 *src, DATA8 *dst, int* radii, int w, int h)
+_box_blur_horiz_alpha(const DATA8 *src, DATA8 *dst, int* radii, int w, int h)
{
DEBUG_TIME_BEGIN();
}
static void
-_box_blur_vert_alpha(DATA8 *src, DATA8 *dst, int* radii, int w, int h)
+_box_blur_vert_alpha(const DATA8 *src, DATA8 *dst, int* radii, int w, int h)
{
DEBUG_TIME_BEGIN();
}
static Eina_Bool
-_box_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
+_box_blur_apply(Evas_Filter_Command *cmd, Eina_Bool vert, Eina_Bool rgba)
{
- RGBA_Image *in, *out;
+ unsigned int src_len, src_stride, dst_len, dst_stride;
+ Eina_Bool ret = EINA_TRUE;
int radii[7] = {0};
unsigned int r;
+ void *src, *dst;
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
- r = abs(cmd->blur.dx);
- in = cmd->input->backing;
- out = cmd->output->backing;
+ r = abs(vert ? cmd->blur.dy : cmd->blur.dx);
+ src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, rgba ? E_ARGB : E_ALPHA, &src_stride);
+ dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, rgba ? E_ARGB : E_ALPHA, &dst_stride);
if (cmd->blur.auto_count)
_box_blur_auto_radius(radii, r);
else for (int k = 0; k < cmd->blur.count; k++)
radii[k] = r;
- EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
+ if (src && dst)
+ {
+ if (rgba)
+ {
+ if (!vert)
+ _box_blur_horiz_rgba(src, dst, radii, cmd->input->w, cmd->input->h);
+ else
+ _box_blur_vert_rgba(src, dst, radii, cmd->input->w, cmd->input->h);
+ }
+ else
+ {
+ if (!vert)
+ _box_blur_horiz_alpha(src, dst, radii, cmd->input->w, cmd->input->h);
+ else
+ _box_blur_vert_alpha(src, dst, radii, cmd->input->w, cmd->input->h);
+ }
+ }
+ else ret = EINA_FALSE;
- _box_blur_horiz_alpha(in->image.data8, out->image.data8, radii,
- in->cache_entry.w, in->cache_entry.h);
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
- return EINA_TRUE;
+ return ret;
}
static Eina_Bool
-_box_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
+_box_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
{
- RGBA_Image *in, *out;
- int radii[7] = {0};
- unsigned int r;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
- r = abs(cmd->blur.dy);
- in = cmd->input->backing;
- out = cmd->output->backing;
-
- if (cmd->blur.auto_count)
- _box_blur_auto_radius(radii, r);
- else for (int k = 0; k < cmd->blur.count; k++)
- radii[k] = r;
+ return _box_blur_apply(cmd, 0, 0);
+}
- EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
+static Eina_Bool
+_box_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
+{
+ return _box_blur_apply(cmd, 1, 0);
+}
- _box_blur_vert_alpha(in->image.data8, out->image.data8, radii,
- in->cache_entry.w, in->cache_entry.h);
+static Eina_Bool
+_box_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
+{
+ return _box_blur_apply(cmd, 0, 1);
+}
- return EINA_TRUE;
+static Eina_Bool
+_box_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
+{
+ return _box_blur_apply(cmd, 1, 1);
}
/* Gaussian blur */
#define STEP 1
#include "./blur/blur_gaussian_alpha_.c"
-static void
-_gaussian_blur_horiz_alpha(const DATA8 *src, DATA8 *dst, int radius, int w, int h)
-{
- int *weights;
- int pow2_div = 0;
-
- weights = alloca((2 * radius + 1) * sizeof(int));
- _sin_blur_weights_get(weights, &pow2_div, radius);
-
- DEBUG_TIME_BEGIN();
- _gaussian_blur_horiz_alpha_step(src, dst, radius, w, h, w, weights, pow2_div);
- DEBUG_TIME_END();
-}
-
// Step size is w (row by row), loops = w, so STEP = 'loops'
#define FUNCTION_NAME _gaussian_blur_vert_alpha_step
#define STEP loops
#include "./blur/blur_gaussian_alpha_.c"
-static void
-_gaussian_blur_vert_alpha(const DATA8 *src, DATA8 *dst, int radius, int w, int h)
-{
- int *weights;
- int pow2_div = 0;
-
- weights = alloca((2 * radius + 1) * sizeof(int));
- _sin_blur_weights_get(weights, &pow2_div, radius);
-
- DEBUG_TIME_BEGIN();
- _gaussian_blur_vert_alpha_step(src, dst, radius, h, w, 1, weights, pow2_div);
- DEBUG_TIME_END();
-}
-
#define FUNCTION_NAME _gaussian_blur_horiz_rgba_step
#define STEP 1
#include "./blur/blur_gaussian_rgba_.c"
-static void
-_gaussian_blur_horiz_rgba(DATA32 *src, DATA32 *dst, int radius, int w, int h)
-{
- int *weights;
- int pow2_div = 0;
-
- weights = alloca((2 * radius + 1) * sizeof(int));
- _sin_blur_weights_get(weights, &pow2_div, radius);
-
- DEBUG_TIME_BEGIN();
- _gaussian_blur_horiz_rgba_step(src, dst, radius, w, h, w, weights, pow2_div);
- DEBUG_TIME_END();
-}
-
#define FUNCTION_NAME _gaussian_blur_vert_rgba_step
#define STEP loops
#include "./blur/blur_gaussian_rgba_.c"
-static void
-_gaussian_blur_vert_rgba(DATA32 *src, DATA32 *dst, int radius, int w, int h)
+static Eina_Bool
+_gaussian_blur_apply(Evas_Filter_Command *cmd, Eina_Bool vert, Eina_Bool rgba)
{
+ unsigned int src_len, src_stride, dst_len, dst_stride, radius;
+ Eina_Bool ret = EINA_TRUE;
+ int pow2_div = 0, w, h;
+ void *src, *dst;
int *weights;
- int pow2_div = 0;
+
+ radius = abs(vert ? cmd->blur.dy : cmd->blur.dx);
+ src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, rgba ? E_ARGB : E_ALPHA, &src_stride);
+ dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, rgba ? E_ARGB : E_ALPHA, &dst_stride);
+ w = cmd->input->w;
+ h = cmd->input->h;
weights = alloca((2 * radius + 1) * sizeof(int));
_sin_blur_weights_get(weights, &pow2_div, radius);
- DEBUG_TIME_BEGIN();
- _gaussian_blur_vert_rgba_step(src, dst, radius, h, w, 1, weights, pow2_div);
- DEBUG_TIME_END();
+ if (src && dst)
+ {
+ DEBUG_TIME_BEGIN();
+ if (rgba)
+ {
+ if (!vert)
+ _gaussian_blur_horiz_rgba_step(src, dst, radius, w, h, w, weights, pow2_div);
+ else
+ _gaussian_blur_vert_rgba_step(src, dst, radius, h, w, 1, weights, pow2_div);
+ }
+ else
+ {
+ if (!vert)
+ _gaussian_blur_horiz_alpha_step(src, dst, radius, w, h, w, weights, pow2_div);
+ else
+ _gaussian_blur_vert_alpha_step(src, dst, radius, h, w, 1, weights, pow2_div);
+ }
+ DEBUG_TIME_END();
+ }
+ else ret = EINA_FALSE;
+
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
+
+ return ret;
}
static Eina_Bool
_gaussian_blur_horiz_apply_alpha(Evas_Filter_Command *cmd)
{
- RGBA_Image *in, *out;
- unsigned int r;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
- r = abs(cmd->blur.dx);
- in = cmd->input->backing;
- out = cmd->output->backing;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
-
- _gaussian_blur_horiz_alpha(in->image.data8, out->image.data8, r,
- in->cache_entry.w, in->cache_entry.h);
-
- return EINA_TRUE;
+ return _gaussian_blur_apply(cmd, 0, 0);
}
static Eina_Bool
_gaussian_blur_vert_apply_alpha(Evas_Filter_Command *cmd)
{
- RGBA_Image *in, *out;
- unsigned int r;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
- r = abs(cmd->blur.dy);
- in = cmd->input->backing;
- out = cmd->output->backing;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data8, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data8, EINA_FALSE);
-
- _gaussian_blur_vert_alpha(in->image.data8, out->image.data8, r,
- in->cache_entry.w, in->cache_entry.h);
-
- return EINA_TRUE;
+ return _gaussian_blur_apply(cmd, 1, 0);
}
static Eina_Bool
_gaussian_blur_horiz_apply_rgba(Evas_Filter_Command *cmd)
{
- RGBA_Image *in, *out;
- unsigned int r;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
- r = abs(cmd->blur.dx);
- in = cmd->input->backing;
- out = cmd->output->backing;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
-
- _gaussian_blur_horiz_rgba(in->image.data, out->image.data, r,
- in->cache_entry.w, in->cache_entry.h);
-
- return EINA_TRUE;
+ return _gaussian_blur_apply(cmd, 0, 1);
}
static Eina_Bool
_gaussian_blur_vert_apply_rgba(Evas_Filter_Command *cmd)
{
- RGBA_Image *in, *out;
- unsigned int r;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
- r = abs(cmd->blur.dy);
- in = cmd->input->backing;
- out = cmd->output->backing;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(in->image.data, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out->image.data, EINA_FALSE);
-
- _gaussian_blur_vert_rgba(in->image.data, out->image.data, r,
- in->cache_entry.w, in->cache_entry.h);
-
- return EINA_TRUE;
+ return _gaussian_blur_apply(cmd, 1, 1);
}
/* Main entry point */
}
static void
-_phong_alpha_generate(DATA8 *phong, DATA8 dark, DATA8 color, DATA8 white,
+_phong_alpha_generate(uint8_t *phong, uint8_t dark, uint8_t color, uint8_t white,
float sf)
{
int x, y;
static Eina_Bool
_bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd)
{
- DATA8 *src, *map, *dst, *map_y1, *map_y2;
- DATA8 dark, color, white;
- DATA8 *phong;
+ uint8_t *src_map, *map_map, *dst_map;
+ uint8_t *src, *map, *dst, *map_y1, *map_y2;
+ uint8_t dark, color, white;
+ uint8_t *phong = NULL;
+ Eina_Bool ret = EINA_FALSE;
int x, y, w, h, lx, ly;
+ unsigned int ss, ms, ds, slen, dlen, mlen;
float xyangle, zangle, sf, lxy;
w = cmd->input->w;
h = cmd->input->h;
EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE);
- src = ((RGBA_Image *) cmd->input->backing)->image.data8;
- map = ((RGBA_Image *) cmd->mask->backing)->image.data8;
- dst = ((RGBA_Image *) cmd->output->backing)->image.data8;
- EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(map, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+ src_map = src = _buffer_map_all(cmd->input->buffer, &slen, E_READ, E_ALPHA, &ss);
+ map_map = map = _buffer_map_all(cmd->mask->buffer, &mlen, E_READ, E_ALPHA, &ms);
+ dst_map = dst = _buffer_map_all(cmd->output->buffer, &dlen, E_WRITE, E_ALPHA, &ds);
+ EINA_SAFETY_ON_FALSE_GOTO(src && dst && map, end);
xyangle = cmd->bump.xyangle;
zangle = cmd->bump.zangle;
// Generate light table
phong = malloc(256 * 256 * sizeof(*phong));
- EINA_SAFETY_ON_NULL_RETURN_VAL(phong, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_GOTO(phong, end);
_phong_alpha_generate(phong, dark, color, white, sf);
for (y = 0; y < h; y++)
src++;
}
+ ret = EINA_TRUE;
+
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, slen));
+ eo_do(cmd->mask->buffer, ector_buffer_unmap(map_map, mlen));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dlen));
free(phong);
- return EINA_TRUE;
+ return ret;
}
static Eina_Bool
_bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd)
{
- DATA8 *src, *map, *map_y1, *map_y2;
- DATA32 *dst;
- DATA32 dark, color, white, col;
- //DATA32 *phong;
- Eina_Bool compensate;
+ uint8_t *src_map, *map_map;
+ uint8_t *src, *map, *map_y1, *map_y2;
+ uint32_t *dst, *dst_map;
+ uint32_t dark, color, white, col;
+ Eina_Bool compensate, ret = EINA_FALSE;
int x, y, w, h, lx, ly, lz, gz, NL, diffusion, gzlz, gz2;
+ unsigned int ss, ms, ds, slen, dlen, mlen;
double xyangle, zangle, sf, lxy, elevation;
w = cmd->input->w;
h = cmd->input->h;
EINA_SAFETY_ON_FALSE_RETURN_VAL(w > 2 && h > 2, EINA_FALSE);
- src = ((RGBA_Image *) cmd->input->backing)->image.data8;
- map = ((RGBA_Image *) cmd->mask->backing)->image.data8;
- dst = ((RGBA_Image *) cmd->output->backing)->image.data;
- EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(map, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+ src_map = src = _buffer_map_all(cmd->input->buffer, &slen, E_READ, E_ALPHA, &ss);
+ map_map = map = _buffer_map_all(cmd->mask->buffer, &mlen, E_READ, E_ALPHA, &ms);
+ dst_map = dst = (uint32_t *) _buffer_map_all(cmd->output->buffer, &dlen, E_WRITE, E_ARGB, &ds);
+ EINA_SAFETY_ON_FALSE_GOTO(src && dst && map, end);
xyangle = cmd->bump.xyangle;
zangle = cmd->bump.zangle;
}
}
- return EINA_TRUE;
+ ret = EINA_TRUE;
+
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, slen));
+ eo_do(cmd->mask->buffer, ector_buffer_unmap(map_map, mlen));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dlen));
+ return ret;
}
static Eina_Bool
static Eina_Bool
_filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
{
- RGBA_Image *in, *out;
- DATA32 *src, *dst, *d, *s;
- DATA8 *curve;
+ unsigned int src_len, src_stride, dst_len, dst_stride;
+ void *src_map = NULL, *dst_map;
+ Eina_Bool ret = EINA_FALSE;
+ uint32_t *src, *dst, *d, *s;
+ uint8_t *curve;
int k, offset = -1, len;
-#define C_VAL(p) (((DATA8 *)(p))[offset])
+#define C_VAL(p) (((uint8_t *)(p))[offset])
+
+ // FIXME: support src_stride != dst_stride
+ // Note: potentially mapping the same region twice (read then write)
+ src_map = src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ARGB, &src_stride);
+ dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
+ EINA_SAFETY_ON_FALSE_GOTO(src && dst && (src_len == dst_len), end);
- in = cmd->input->backing;
- out = cmd->output->backing;
- EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
- src = in->image.data;
- dst = out->image.data;
- EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
curve = cmd->curve.data;
- len = in->cache_entry.w * in->cache_entry.h;
+ len = dst_len / sizeof(uint32_t);
switch (cmd->curve.channel)
{
case EVAS_FILTER_CHANNEL_RGB: break;
default:
ERR("Invalid color channel %d", (int) cmd->curve.channel);
- return EINA_FALSE;
+ goto end;
}
if (src != dst)
- memcpy(dst, src, len * sizeof(DATA32));
+ memcpy(dst, src, dst_len);
evas_data_argb_unpremul(dst, len);
// One channel (R, G or B)
premul:
evas_data_argb_premul(dst, len);
- return EINA_TRUE;
+ ret = EINA_TRUE;
+
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+ return ret;
}
static Eina_Bool
_filter_curve_cpu_alpha(Evas_Filter_Command *cmd)
{
- RGBA_Image *in, *out;
- DATA8 *src, *dst;
- DATA8 *curve;
+ unsigned int src_len, src_stride, dst_len, dst_stride;
+ uint8_t *src, *dst, *curve;
+ void *src_map, *dst_map;
+ Eina_Bool ret = EINA_FALSE;
int k;
- in = cmd->input->backing;
- out = cmd->output->backing;
- EINA_SAFETY_ON_NULL_RETURN_VAL(in, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(out, EINA_FALSE);
- src = in->image.data8;
- dst = out->image.data8;
- EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+ // FIXME: support src_stride != dst_stride
+ // Note: potentially mapping the same region twice (read then write)
+ src_map = src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
+ dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ALPHA, &dst_stride);
+ EINA_SAFETY_ON_FALSE_GOTO(src && dst && (src_len == dst_len), end);
curve = cmd->curve.data;
- for (k = in->cache_entry.w * in->cache_entry.h; k; k--)
+ for (k = src_len; k; k--)
*dst++ = curve[*src++];
- return EINA_TRUE;
+ ret = EINA_TRUE;
+
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+ return ret;
}
Evas_Filter_Apply_Func
if (cmd->input->alpha_only && cmd->output->alpha_only)
return _filter_curve_cpu_alpha;
- CRI("Incompatible image formats");
- return NULL;
+ // Rely on ector buffer's implicit conversion. not great but the command
+ // doesn't make much sense (curve requires same channel count).
+ WRN("Incompatible image formats");
+ return _filter_curve_cpu_rgba;
}
static void
_filter_displace_cpu_alpha_do(int w, int h, int map_w, int map_h, int intensity,
- DATA8 *src, DATA8 *dst, DATA32 *map_start,
+ uint8_t *src, uint8_t *dst, uint32_t *map_start,
Eina_Bool stretch, Eina_Bool smooth,
Eina_Bool blend)
{
int x, y, map_x, map_y;
const int dx = RED;
const int dy = GREEN;
- DATA8 *map;
+ uint8_t *map;
+
+ // FIXME: Add stride support
for (y = 0, map_y = 0; y < h; y++, map_y++)
{
if (map_y >= map_h) map_y = 0;
- map = (DATA8 *) (map_start + map_y * map_w);
+ map = (uint8_t *) (map_start + map_y * map_w);
for (x = 0, map_x = 0; x < w;
- x++, dst++, src++, map_x++, map += sizeof(DATA32))
+ x++, dst++, src++, map_x++, map += sizeof(uint32_t))
{
int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0;
Eina_Bool out = 0;
if (map_x >= map_w)
{
map_x = 0;
- map = (DATA8 *) (map_start + map_y * map_w);
+ map = (uint8_t *) (map_start + map_y * map_w);
}
// x
static void
_filter_displace_cpu_rgba_do(int w, int h, int map_w, int map_h, int intensity,
- DATA32 *src, DATA32 *dst, DATA32 *map_start,
+ uint32_t *src, uint32_t *dst, uint32_t *map_start,
Eina_Bool stretch, Eina_Bool smooth,
Eina_Bool blend)
{
const int dx = RED;
const int dy = GREEN;
Eina_Bool unpremul = EINA_FALSE;
- DATA8 *map;
+ uint8_t *map;
for (y = 0, map_y = 0; y < h; y++, map_y++)
{
if (map_y >= map_h) map_y = 0;
- map = (DATA8 *) (map_start + map_y * map_w);
+ map = (uint8_t *) (map_start + map_y * map_w);
for (x = 0, map_x = 0; x < w;
- x++, dst++, src++, map_x++, map += sizeof(DATA32))
+ x++, dst++, src++, map_x++, map += sizeof(uint32_t))
{
int offx = 0, offy = 0, offx_dec = 0, offy_dec = 0, val = 0;
- DATA32 col = 0;
+ uint32_t col = 0;
Eina_Bool out = 0;
// wrap (x)
if (map_x >= map_w)
{
map_x = 0;
- map = (DATA8 *) (map_start + map_y * map_w);
+ map = (uint8_t *) (map_start + map_y * map_w);
}
if (!map[ALPHA]) continue;
else
{
int R, G, B, A;
- DATA32 s00, s01, s10, s11; // indexes represent x,y
+ uint32_t s00, s01, s10, s11; // indexes represent x,y
int mul00, mul01, mul10, mul11;
mul00 = (128 - offx_dec) * (128 - offy_dec);
if (blend)
{
- DATA32 a = 256 - ALPHA_OF(col);
+ uint32_t a = 256 - ALPHA_OF(col);
*dst = col + MUL_256(a, *dst);
}
else
static Eina_Bool
_filter_displace_cpu_alpha(Evas_Filter_Command *cmd)
{
+ unsigned int src_len, src_stride, map_len, map_stride, dst_len, dst_stride;
int w, h, map_w, map_h, intensity;
- DATA8 *dst, *src;
- DATA32 *map_start;
+ uint8_t *dst, *src;
+ uint32_t *map_start;
Eina_Bool stretch, smooth, blend;
+ Evas_Filter_Buffer *map_fb;
+ Eina_Bool ret = EINA_FALSE;
w = cmd->input->w;
h = cmd->input->h;
EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
- src = ((RGBA_Image *) cmd->input->backing)->image.data8;
- map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
- dst = ((RGBA_Image *) cmd->output->backing)->image.data8;
- EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
+ src = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
+ dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_READ, E_ALPHA, &dst_stride);
stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
map_w = cmd->mask->w;
// Stretch if necessary.
if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
{
- Evas_Filter_Buffer *fb;
-
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
map_w = w;
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
map_h = h;
BUFFERS_LOCK();
- fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
+ map_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
BUFFERS_UNLOCK();
- EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
- fb->locked = EINA_FALSE;
- map_start = ((RGBA_Image *) fb->backing)->image.data;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(map_fb, EINA_FALSE);
+ map_fb->locked = EINA_FALSE;
}
+ else map_fb = cmd->mask;
+
+ map_start = (uint32_t *) _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_alpha_do(w, h, map_w, map_h, intensity,
src, dst, map_start, stretch, smooth, blend);
- return EINA_TRUE;
+ ret = EINA_TRUE;
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
+ eo_do(map_fb->buffer, ector_buffer_unmap(map_start, map_len));
+ return ret;
}
/**
static Eina_Bool
_filter_displace_cpu_rgba(Evas_Filter_Command *cmd)
{
+ unsigned int src_len, src_stride, map_len, map_stride, dst_len, dst_stride;
int w, h, map_w, map_h, intensity;
- DATA32 *dst, *src, *map_start;
+ uint32_t *dst, *src, *map_start;
Eina_Bool stretch, smooth, blend;
+ Evas_Filter_Buffer *map_fb;
+ Eina_Bool ret = EINA_FALSE;
w = cmd->input->w;
h = cmd->input->h;
EINA_SAFETY_ON_FALSE_RETURN_VAL(w == cmd->output->w, EINA_FALSE);
EINA_SAFETY_ON_FALSE_RETURN_VAL(h == cmd->output->h, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
-
- src = ((RGBA_Image *) cmd->input->backing)->image.data;
- map_start = ((RGBA_Image *) cmd->mask->backing)->image.data;
- dst = ((RGBA_Image *) cmd->output->backing)->image.data;
- EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(map_start, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(dst, 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);
stretch = cmd->displacement.flags & EVAS_FILTER_DISPLACE_STRETCH;
smooth = cmd->displacement.flags & EVAS_FILTER_DISPLACE_LINEAR;
map_w = cmd->mask->w;
// Stretch if necessary.
if ((map_w != w || map_h != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
{
- Evas_Filter_Buffer *fb;
-
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
map_w = w;
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
map_h = h;
BUFFERS_LOCK();
- fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
+ map_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, map_w, map_h);
BUFFERS_UNLOCK();
- EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
- fb->locked = EINA_FALSE;
- map_start = ((RGBA_Image *) fb->backing)->image.data;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(map_fb, EINA_FALSE);
+ map_fb->locked = EINA_FALSE;
}
+ else map_fb = cmd->mask;
+
+ map_start = (uint32_t *) _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,
src, dst, map_start, stretch, smooth, blend);
- return EINA_TRUE;
+ ret = EINA_TRUE;
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src, src_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst, dst_len));
+ eo_do(map_fb->buffer, ector_buffer_unmap(map_start, map_len));
+ return ret;
}
Evas_Filter_Apply_Func
#include "evas_filter_private.h"
+#include "draw.h"
static Eina_Bool
_fill_cpu(Evas_Filter_Command *cmd)
{
Evas_Filter_Buffer *fb = cmd->output;
- int step = fb->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
+ int step = fb->alpha_only ? sizeof(uint8_t) : sizeof(uint32_t);
int x = MAX(0, cmd->draw.clip.x);
int y = MAX(0, cmd->draw.clip.y);
- DATA8 *ptr = ((RGBA_Image *) fb->backing)->image.data8;
- int w, h, k, j;
+ 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;
if (!cmd->draw.clip_mode_lrtb)
{
h = CLAMP(0, fb->h - y - cmd->draw.clip.b, fb->h - y);
}
- ptr += y * step * fb->w;
- if ((fb->alpha_only)
- || (!cmd->draw.R && !cmd->draw.G && !cmd->draw.B && !cmd->draw.A)
- || ((cmd->draw.R == 0xff) && (cmd->draw.G == 0xff)
- && (cmd->draw.B == 0xff) && (cmd->draw.A == 0xff)))
+ ptr = _buffer_map_all(fb->buffer, &len, E_WRITE, fb->alpha_only ? E_ALPHA : E_ARGB, &stride);
+ if (!ptr) return EINA_FALSE;
+
+ ptr += y * stride;
+ if (fb->alpha_only)
{
for (k = 0; k < h; k++)
{
memset(ptr + (x * step), cmd->draw.A, step * w);
- ptr += step * fb->w;
+ ptr += stride;
}
}
else
{
- DATA32 *dst = ((DATA32 *) ptr) + x;
- DATA32 color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
for (k = 0; k < h; k++)
{
- for (j = 0; j < w; j++)
- *dst++ = color;
- dst += fb->w - w;
+ uint32_t *dst = ((uint32_t *) (ptr + (y + k) * stride)) + x;
+ draw_memset32(dst, color, w);
}
}
+ eo_do(fb->buffer, ector_buffer_unmap(ptr, len));
return EINA_TRUE;
}
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->backing, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask->backing, 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);
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input->h == cmd->output->h, NULL);
static Eina_Bool
_mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd)
{
- Alpha_Gfx_Func func;
- RGBA_Image *in, *out, *mask;
- DATA8 *src, *dst, *msk;
+ unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
Efl_Gfx_Render_Op render_op = cmd->draw.rop;
+ Evas_Filter_Buffer *msk_fb;
+ Alpha_Gfx_Func func;
+ uint8_t *src_map = NULL, *dst, *dst_map = NULL, *msk, *msk_map = NULL;
int w, h, mw, mh, x, y, my;
int stepsize, stepcount, step;
+ Eina_Bool ret = EINA_FALSE;
/* Mechanism:
* 1. Stretch mask as requested in fillmode
* FIXME: Could probably be optimized into a single op :)
*/
- in = (RGBA_Image *) cmd->input->backing;
- out = (RGBA_Image *) cmd->output->backing;
- mask = (RGBA_Image *) cmd->mask->backing;
-
w = cmd->input->w;
h = cmd->input->h;
mw = cmd->mask->w;
mh = cmd->mask->h;
- src = in->image.data8;
- dst = out->image.data8;
-
- EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
-
stepsize = MIN(mw, w);
stepcount = w / stepsize;
// Stretch if necessary.
if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
{
- Evas_Filter_Buffer *fb;
-
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
mw = w;
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
mh = h;
BUFFERS_LOCK();
- fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+ msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
BUFFERS_UNLOCK();
- EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
- fb->locked = EINA_FALSE;
- mask = fb->backing;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
+ msk_fb->locked = EINA_FALSE;
}
+ else msk_fb = cmd->mask;
- msk = mask->image.data8;
+ msk_map = msk = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ALPHA, &msk_stride);
+ dst_map = dst = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ALPHA, &dst_stride);
+ EINA_SAFETY_ON_FALSE_GOTO(dst_map && msk_map, end);
// First pass: copy to dest
- if (src != dst)
- memcpy(dst, src, w * h * sizeof(DATA8));
+ if (cmd->input->buffer != cmd->output->buffer)
+ {
+ src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, E_ALPHA, &src_stride);
+ EINA_SAFETY_ON_FALSE_GOTO(src_map, end);
+ if (dst_stride == src_stride)
+ memcpy(dst_map, src_map, dst_stride * h * sizeof(uint8_t));
+ else
+ {
+ for (y = 0; y < h; y++)
+ memcpy(dst_map + (y * dst_stride), src_map + (y * src_stride),
+ MIN(dst_stride, src_stride) * h * sizeof(uint8_t));
+ }
+ }
// Second pass: apply render op
func = efl_draw_alpha_func_get(render_op, EINA_FALSE);
- for (y = 0, my = 0; y < h; y++, my++, msk += mw)
+ for (y = 0, my = 0; y < h; y++, my++)
{
- if (my >= mh)
- {
- my = 0;
- msk = mask->image.data8;
- }
+ if (my >= mh) my = 0;
+
+ msk = msk_map + (my * msk_stride);
+ dst = dst_map + (y * dst_stride);
for (step = 0; step < stepcount; step++, dst += stepsize)
func(msk, dst, stepsize);
if (x < w)
{
func(msk, dst, w - x);
- dst += w - x;
}
}
- return EINA_TRUE;
+ ret = EINA_TRUE;
+
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+ eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+ return ret;
}
static Eina_Bool
static Eina_Bool
_mask_cpu_alpha_rgba_rgba(Evas_Filter_Command *cmd)
{
- RGBA_Gfx_Func func1, func2;
- RGBA_Image *in, *out, *mask;
- DATA8 *src;
- DATA32 *dst, *msk, *span;
+ unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
Efl_Gfx_Render_Op op = cmd->draw.rop;
- int w, h, mw, mh, y, my, r;
+ Evas_Filter_Buffer *msk_fb;
+ RGBA_Gfx_Func func1, func2;
+ uint8_t *src, *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
+ uint32_t *dst, *msk, *span;
+ int w, h, mw, mh, x, y, my;
int stepsize, stepcount, step;
- DATA32 color2;
+ Eina_Bool ret = EINA_FALSE;
+ uint32_t color;
/* Mechanism:
* 1. Stretch mask as requested in fillmode
* FIXME: Could probably be optimized into a single op :)
*/
- in = (RGBA_Image *) cmd->input->backing;
- out = (RGBA_Image *) cmd->output->backing;
- mask = (RGBA_Image *) cmd->mask->backing;
-
w = cmd->input->w;
h = cmd->input->h;
mw = cmd->mask->w;
mh = cmd->mask->h;
- src = in->image.data8;
- dst = out->image.data;
+ color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+ stepsize = MIN(mw, w);
+ stepcount = w / stepsize;
+ span = alloca(stepsize * sizeof(uint32_t));
// Stretch if necessary.
if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
{
- Evas_Filter_Buffer *fb;
-
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
mw = w;
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
mh = h;
BUFFERS_LOCK();
- fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+ msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
BUFFERS_UNLOCK();
- EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
- fb->locked = EINA_FALSE;
- mask = fb->backing;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
+ msk_fb->locked = EINA_FALSE;
}
+ else msk_fb = cmd->mask;
- color2 = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
- msk = mask->image.data;
+ src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ALPHA, &src_stride);
+ msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
+ dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
+ EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
- EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(msk, EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
-
- stepsize = MIN(mw, w);
- stepcount = w / stepsize;
- span = malloc(stepsize * sizeof(DATA32));
-
- func1 = evas_common_gfx_func_composite_pixel_mask_span_get(mask->cache_entry.flags.alpha, mask->cache_entry.flags.alpha_sparse, out->cache_entry.flags.alpha, 1, EVAS_RENDER_COPY);
- func2 = evas_common_gfx_func_composite_pixel_color_span_get(mask->cache_entry.flags.alpha, mask->cache_entry.flags.alpha_sparse, color2, out->cache_entry.flags.alpha, 1, _gfx_to_evas_render_op(op));
+ func1 = evas_common_gfx_func_composite_pixel_mask_span_get(1, 0, 1, 1, EVAS_RENDER_COPY);
+ func2 = evas_common_gfx_func_composite_pixel_color_span_get(1, 0, color, 1, 1, _gfx_to_evas_render_op(op));
// Apply mask using Gfx functions
- for (y = 0, my = 0; y < h; y++, my++, msk += mw)
+ for (y = 0, my = 0; y < h; y++, my++)
{
- if (my >= mh)
- {
- my = 0;
- msk = mask->image.data;
- }
+ if (my >= mh) my = 0;
+
+ src = src_map + (y * src_stride);
+ msk = (uint32_t *) (msk_map + (my * msk_stride));
+ dst = (uint32_t *) (dst_map + (y * dst_stride));
for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
{
- memset(span, 0, stepsize * sizeof(DATA32));
+ memset(span, 0, stepsize * sizeof(uint32_t));
func1(msk, src, 0, span, stepsize);
- func2(span, NULL, color2, dst, stepsize);
+ func2(span, NULL, color, dst, stepsize);
}
- r = w - (stepsize * stepcount);
- if (r > 0)
+ x = stepsize * stepcount;
+ if (x < w)
{
- memset(span, 0, r * sizeof(DATA32));
- func1(msk, src, 0, span, r);
- func2(span, NULL, color2, dst, r);
- dst += r;
- src += r;
+ memset(span, 0, (w - x) * sizeof(uint32_t));
+ func1(msk, src, 0, span, w - x);
+ func2(span, NULL, color, dst, w - x);
}
}
- free(span);
- return EINA_TRUE;
+ ret = EINA_TRUE;
+
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+ eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+ return ret;
}
static Eina_Bool
_mask_cpu_alpha_alpha_rgba(Evas_Filter_Command *cmd)
{
+ unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
+ uint8_t *src, *msk, *span, *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
+ Evas_Filter_Buffer *msk_fb;
RGBA_Gfx_Func func;
Alpha_Gfx_Func span_func;
- RGBA_Image *in, *out, *mask;
- DATA8 *src, *msk, *span;
- DATA32 *dst;
- DATA32 color;
+ uint32_t *dst;
+ uint32_t color;
Efl_Gfx_Render_Op op = cmd->draw.rop;
- int w, h, mw, mh, y, my, r;
+ int w, h, mw, mh, x, y, my;
int stepsize, stepcount, step;
+ Eina_Bool ret = EINA_FALSE;
/* Mechanism:
* 1. Copy mask to span buffer (1 line)
* FIXME: Could probably be optimized into a single op :)
*/
- in = (RGBA_Image *) cmd->input->backing;
- out = (RGBA_Image *) cmd->output->backing;
- mask = (RGBA_Image *) cmd->mask->backing;
-
w = cmd->input->w;
h = cmd->input->h;
mw = cmd->mask->w;
mh = cmd->mask->h;
- src = in->image.data8;
- dst = out->image.data;
color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
-
- EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
+ stepsize = MIN(mw, w);
+ stepcount = w / stepsize;
+ span = alloca(stepsize * sizeof(uint32_t));
// Stretch if necessary.
if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
{
- Evas_Filter_Buffer *fb;
-
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
mw = w;
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
mh = h;
BUFFERS_LOCK();
- fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+ msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
BUFFERS_UNLOCK();
- EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
- fb->locked = EINA_FALSE;
- mask = fb->backing;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
+ msk_fb->locked = EINA_FALSE;
}
+ else msk_fb = cmd->mask;
- msk = mask->image.data8;
- stepsize = MIN(mw, w);
- stepcount = w / stepsize;
- span = malloc(stepsize * sizeof(DATA8));
+ src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ALPHA, &src_stride);
+ msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
+ dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
+ EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
- func = evas_common_gfx_func_composite_mask_color_span_get(color, out->cache_entry.flags.alpha, 1, _gfx_to_evas_render_op(op));
+ func = evas_common_gfx_func_composite_mask_color_span_get(color, 1, 1, _gfx_to_evas_render_op(op));
span_func = efl_draw_alpha_func_get(cmd->draw.rop, EINA_TRUE);
for (y = 0, my = 0; y < h; y++, my++, msk += mw)
{
- if (my >= mh)
- {
- my = 0;
- msk = mask->image.data8;
- }
+ if (my >= mh) my = 0;
+
+ src = src_map + (y * src_stride);
+ msk = msk_map + (my * msk_stride);
+ dst = (uint32_t *) (dst_map + (y * dst_stride));
for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
{
- memcpy(span, msk, stepsize * sizeof(DATA8));
+ memcpy(span, msk, stepsize * sizeof(uint8_t));
span_func(src, span, stepsize);
func(NULL, span, color, dst, stepsize);
}
- r = w - (stepsize * stepcount);
- if (r > 0)
+ x = stepsize * stepcount;
+ if (x < w)
{
- memcpy(span, msk, r * sizeof(DATA8));
- span_func(src, span, r);
- func(NULL, span, color, dst, r);
- dst += r;
- src += r;
+ memcpy(span, msk, (w - x) * sizeof(uint8_t));
+ span_func(src, span, w - x);
+ func(NULL, span, color, dst, w -x);
}
}
- free(span);
- return EINA_TRUE;
+ ret = EINA_TRUE;
+
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+ eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+ return ret;
}
static Eina_Bool
_mask_cpu_rgba_rgba_rgba(Evas_Filter_Command *cmd)
{
+ unsigned int src_len, src_stride, msk_len, msk_stride, dst_len, dst_stride;
+ uint8_t *src_map = NULL, *msk_map = NULL, *dst_map = NULL;
Draw_Func_ARGB_Mix3 func;
- RGBA_Image *in, *out, *mask;
- DATA32 *dst, *msk, *src;
- int w, h, mw, mh, y, my, r;
+ Evas_Filter_Buffer *msk_fb;
+ uint32_t *dst, *msk, *src;
+ int w, h, mw, mh, x, y, my;
int stepsize, stepcount, step;
- DATA32 color;
+ Eina_Bool ret = EINA_FALSE;
+ uint32_t color;
/* Mechanism:
* 1. Stretch mask as requested in fillmode
* 2. Mix 3 colors
*/
- in = (RGBA_Image *) cmd->input->backing;
- out = (RGBA_Image *) cmd->output->backing;
- mask = (RGBA_Image *) cmd->mask->backing;
-
w = cmd->input->w;
h = cmd->input->h;
mw = cmd->mask->w;
mh = cmd->mask->h;
- src = in->image.data;
- dst = out->image.data;
+ color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
+ stepsize = MIN(mw, w);
+ stepcount = w / stepsize;
// Stretch if necessary.
if ((mw != w || mh != h) && (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_XY))
{
- Evas_Filter_Buffer *fb;
-
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_X)
mw = w;
if (cmd->draw.fillmode & EVAS_FILTER_FILL_MODE_STRETCH_Y)
mh = h;
BUFFERS_LOCK();
- fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
+ msk_fb = evas_filter_buffer_scaled_get(cmd->ctx, cmd->mask, mw, mh);
BUFFERS_UNLOCK();
- EINA_SAFETY_ON_NULL_RETURN_VAL(fb, EINA_FALSE);
- fb->locked = EINA_FALSE;
- mask = fb->backing;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(msk_fb, EINA_FALSE);
+ msk_fb->locked = EINA_FALSE;
}
+ else msk_fb = cmd->mask;
- color = ARGB_JOIN(cmd->draw.A, cmd->draw.R, cmd->draw.G, cmd->draw.B);
- msk = mask->image.data;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(src, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(dst, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(msk, EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN_VAL((w > 0) && (mw > 0), EINA_FALSE);
-
- stepsize = MIN(mw, w);
- stepcount = w / stepsize;
+ src_map = _buffer_map_all(cmd->input->buffer, &src_len, E_WRITE, E_ARGB, &src_stride);
+ msk_map = _buffer_map_all(msk_fb->buffer, &msk_len, E_READ, E_ARGB, &msk_stride);
+ dst_map = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, E_ARGB, &dst_stride);
+ EINA_SAFETY_ON_FALSE_GOTO(src_map && dst_map && msk_map, end);
func = efl_draw_func_argb_mix3_get(cmd->draw.rop, color);
// Apply mask using Gfx functions
- for (y = 0, my = 0; y < h; y++, my++, msk += mw)
+ for (y = 0, my = 0; y < h; y++, my++)
{
- if (my >= mh)
- {
- my = 0;
- msk = mask->image.data;
- }
+ if (my >= mh) my = 0;
+
+ src = (uint32_t *) (src_map + (y * src_stride));
+ msk = (uint32_t *) (msk_map + (my * msk_stride));
+ dst = (uint32_t *) (dst_map + (y * dst_stride));
for (step = 0; step < stepcount; step++, dst += stepsize, src += stepsize)
func(dst, src, msk, stepsize, color);
- r = w - (stepsize * stepcount);
- if (r > 0)
+ x = stepsize * stepcount;
+ if (x < w)
{
- func(dst, src, msk, r, color);
- dst += r;
- src += r;
+ func(dst, src, msk, w - x, color);
}
}
- return EINA_TRUE;
+ ret = EINA_TRUE;
+
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(src_map, src_len));
+ eo_do(msk_fb->buffer, ector_buffer_unmap(msk_map, msk_len));
+ eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dst_len));
+ return ret;
}
Evas_Object *source;
Eina_Stringshare *source_name;
- RGBA_Image *backing;
+ Ector_Generic_Buffer *buffer;
void *glimage;
int w, h;
void evas_filter_parser_shutdown(void);
+#define E_READ ECTOR_BUFFER_ACCESS_FLAG_READ
+#define E_WRITE ECTOR_BUFFER_ACCESS_FLAG_WRITE
+#define E_ALPHA EFL_GFX_COLORSPACE_GRY8
+#define E_ARGB EFL_GFX_COLORSPACE_ARGB8888
+
+static inline void *
+_buffer_map_all(Ector_Buffer *buf, unsigned int *len, Ector_Buffer_Access_Flag mode, Efl_Gfx_Colorspace cspace, unsigned int *stride)
+{
+ void *ret = NULL;
+ int w, h;
+ if (!buf) return NULL;
+ eo_do(buf, ector_buffer_size_get(&w, &h);
+ ret = ector_buffer_map(len, mode, 0, 0, w, h, cspace, stride));
+ return ret;
+}
+
#endif // EVAS_FILTER_PRIVATE_H
static Eina_Bool
_vflip_cpu(Evas_Filter_Command *cmd)
{
- size_t datasize, stride;
- DATA8 *in, *out, *span = NULL;
+ unsigned int src_len, src_stride, dst_len, dst_stride;
+ uint8_t *in, *out = NULL, *span = NULL;
int w, h, sy, dy, oy, center, t, b, objh;
int s0, s1, d0, d1;
-
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
- EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
+ Eina_Bool ret = 0;
w = cmd->input->w;
h = cmd->input->h;
- EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->w == w, EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->h == h, EINA_FALSE);
- EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->alpha_only == cmd->input->alpha_only, EINA_FALSE);
+ in = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &src_stride);
+ if (cmd->input->buffer != cmd->output->buffer)
+ out = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &dst_stride);
- in = ((RGBA_Image *) cmd->input->backing)->image.data8;
- out = ((RGBA_Image *) cmd->output->backing)->image.data8;
- datasize = cmd->input->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
- stride = w * datasize;
+ EINA_SAFETY_ON_FALSE_GOTO(cmd->output->w == w, end);
+ EINA_SAFETY_ON_FALSE_GOTO(cmd->output->h == h, end);
+ EINA_SAFETY_ON_FALSE_GOTO(src_stride <= dst_stride, end);
+ EINA_SAFETY_ON_FALSE_GOTO(cmd->output->alpha_only == cmd->input->alpha_only, end);
oy = cmd->draw.oy;
t = cmd->ctx->padt;
if (in == out)
{
- span = malloc(stride);
- if (!span) return EINA_FALSE;
+ span = alloca(src_stride);
+ if (!span) goto end;
}
for (sy = s0, dy = d0; (dy >= d1) && (sy <= s1); sy++, dy--)
{
- DATA8* src = in + stride * sy;
- DATA8* dst = out + stride * dy;
+ uint8_t* src = in + src_stride * sy;
+ uint8_t* dst = out + dst_stride * dy;
if (in == out)
{
if (src == dst) break;
- memcpy(span, dst, stride);
- memcpy(dst, src, stride);
- memcpy(src, span, stride);
+ memcpy(span, dst, src_stride);
+ memcpy(dst, src, src_stride);
+ memcpy(src, span, src_stride);
if (sy >= center) break;
}
else
- memcpy(dst, src, stride);
+ memcpy(dst, src, src_stride);
}
- free(span);
- return EINA_TRUE;
+ ret = EINA_TRUE;
+
+end:
+ eo_do(cmd->input->buffer, ector_buffer_unmap(in, src_len));
+ if (in != out) eo_do(cmd->output->buffer, ector_buffer_unmap(out, dst_len));
+ return ret;
}
Evas_Filter_Apply_Func
unsigned w, unsigned h)
{
Evas_Filter_Buffer *fb;
- Image_Entry *dstdata = NULL;
- Image_Entry *srcdata;
- void *drawctx;
+ RGBA_Image *dstim, *srcim;
+ RGBA_Draw_Context dc;
+ Eina_Bool ok;
- srcdata = evas_filter_buffer_backing_get(ctx, src->id);
- EINA_SAFETY_ON_NULL_RETURN_VAL(srcdata, NULL);
+ // only for RGBA
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(!src->alpha_only, NULL);
- if (src->alpha_only)
- {
- // There is no supporting function in Evas for alpha scaling...
- // but guess what? There is also no use case in the filters :)
- CRI("Alpha buffer scaling is not supported");
- return NULL;
- }
+ srcim = evas_filter_buffer_backing_get(ctx, src->id);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(srcim, NULL);
fb = evas_filter_temporary_buffer_get(ctx, w, h, src->alpha_only);
- if (!fb) return NULL;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(fb, NULL);
- dstdata = evas_filter_buffer_backing_get(ctx, fb->id);
- if (!dstdata)
- {
- CRI("No backing found for buffer %d", fb->id);
- return NULL;
- }
+ dstim = evas_filter_buffer_backing_get(ctx, fb->id);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(dstim, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((dstim->cache_entry.w == w) &&
+ (dstim->cache_entry.h == h), NULL);
- if ((dstdata->w != w) || (dstdata->h != h))
- {
- CRI("Buffer size mismatch: got %dx%d requested %dx%d",
- dstdata->w, dstdata->h, w, h);
- return NULL;
- }
+ memset(&dc, 0, sizeof(dc));
+ dc.sli.h = 1;
+ dc.render_op = EVAS_RENDER_COPY;
- if (ctx->gl_engine)
- {
- RGBA_Image *s = (RGBA_Image *) srcdata;
- RGBA_Image *d = (RGBA_Image *) dstdata;
- EINA_SAFETY_ON_NULL_RETURN_VAL(s->image.data, NULL);
- EINA_SAFETY_ON_NULL_RETURN_VAL(d->image.data, NULL);
+ ok = evas_common_scale_rgba_in_to_out_clip_smooth
+ (srcim, dstim, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
- if (src->w == (int) w && src->h == (int) h)
- memcpy(d->image.data, s->image.data, w * h * 4);
- else
- {
- Eina_Bool ok;
- RGBA_Draw_Context dc;
-
- memset(&dc, 0, sizeof(dc));
- dc.sli.h = 1;
- dc.render_op = EVAS_RENDER_COPY;
-
- ok = evas_common_scale_rgba_in_to_out_clip_smooth
- (s, d, &dc, 0, 0, src->w, src->h, 0, 0, w, h);
- if (!ok)
- {
- ERR("RGBA Image scaling failed.");
- return NULL;
- }
- }
- }
- else
+ if (!ok)
{
- drawctx = ENFN->context_new(ENDT);
- ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
- ENFN->context_render_op_set(ENDT, drawctx, EVAS_RENDER_COPY);
- ENFN->image_draw(ENDT, drawctx, dstdata, srcdata,
- 0, 0, src->w, src->h, // src
- 0, 0, w, h, // dst
- EINA_TRUE, // smooth
- EINA_FALSE); // Not async
- ENFN->context_free(ENDT, drawctx);
+ ERR("RGBA Image scaling failed.");
+ return NULL;
}
return fb;
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);
-int evas_filter_buffer_image_new(Evas_Filter_Context *ctx, void *image);
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);
Ector_Surface *(*ector_create) (void *data);
void (*ector_destroy) (void *data, Ector_Surface *surface);
- Ector_Buffer *(*ector_buffer_new) (void *data, Evas *e, void *engine_image); // free it with eo_del
+ Ector_Buffer *(*ector_buffer_wrap) (void *data, Evas *e, void *engine_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);
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);
}
static Ector_Buffer *
-eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image)
+eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image)
{
- Evas_GL_Image *im = engine_image;
- Ector_Buffer *buf = NULL;
-
- if (!im) return NULL;
-
#warning FIXME: implement me
- (void) e;
+ return NULL;
+}
- return buf;
+static Ector_Buffer *
+eng_ector_buffer_new(void *data EINA_UNUSED, 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)
+{
+#warning FIXME: implement me
+ return NULL;
}
static Efl_Gfx_Render_Op
ORD(ector_create);
ORD(ector_destroy);
+ ORD(ector_buffer_wrap);
ORD(ector_buffer_new);
ORD(ector_begin);
ORD(ector_renderer_draw);
eo_do(obj, ector_buffer_pixels_set(im->image.data,
im->cache_entry.w, im->cache_entry.h, 0,
- _evas_to_gfx_render_op(im->cache_entry.space),
+ im->cache_entry.space,
EINA_TRUE, 0, 0, 0, 0));
}
}
static Ector_Buffer *
-eng_ector_buffer_new(void *data EINA_UNUSED, Evas *e, void *engine_image)
+eng_ector_buffer_wrap(void *data EINA_UNUSED, Evas *e, void *engine_image)
{
Image_Entry *ie = engine_image;
Ector_Buffer *buf = NULL;
return buf;
}
+static Ector_Buffer *
+eng_ector_buffer_new(void *data EINA_UNUSED, 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 EINA_UNUSED)
+{
+ Ector_Buffer *buf = NULL;
+
+ buf = eo_add(ECTOR_SOFTWARE_BUFFER_CLASS, e,
+ ector_buffer_pixels_set(pixels, width, height, stride, cspace,
+ writeable, l, r, t, b));
+
+ return buf;
+}
+
static Efl_Gfx_Render_Op
_evas_render_op_to_ector_rop(Evas_Render_Op op)
{
NULL, // eng_texture_image_get
eng_ector_create,
eng_ector_destroy,
+ eng_ector_buffer_wrap,
eng_ector_buffer_new,
eng_ector_begin,
eng_ector_renderer_draw,