From eda13b729851605615032a4af400de9b820e2d63 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Fri, 11 Dec 2015 15:44:48 +0900 Subject: [PATCH] Evas filters: Relax limitations about colorspaces Since Ector Buffer implicitly converts colorspaces, we can allow more commands to work even if they are suboptimal. Now all filters should support any combinaison of input, map/mask and output colorspaces. --- src/lib/evas/filters/evas_filter.c | 26 ++++++++++++++----- src/lib/evas/filters/evas_filter_blend.c | 24 ++++++++--------- src/lib/evas/filters/evas_filter_blur.c | 14 +++++----- src/lib/evas/filters/evas_filter_bump.c | 27 ++++--------------- src/lib/evas/filters/evas_filter_displace.c | 9 +------ src/lib/evas/filters/evas_filter_mask.c | 39 ++++++++++++++++++---------- src/lib/evas/filters/evas_filter_transform.c | 6 ++--- 7 files changed, 72 insertions(+), 73 deletions(-) diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index a050374..b3068d7 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -649,6 +649,9 @@ evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *drawctx, goto fail; } + if (!in->alpha_only && out->alpha_only) + DBG("Different color formats, implicit conversion may be slow"); + if (in == out) out->dirty = EINA_FALSE; blend = (out->dirty && !out->transient); @@ -1049,10 +1052,8 @@ evas_filter_command_curve_add(Evas_Filter_Context *ctx, } if (in->alpha_only != out->alpha_only) - { - ERR("Incompatible formats for color curves"); - return -1; - } + WRN("Incompatible formats for color curves, implicit conversion will be " + "slow and may not produce the desired output."); copy = malloc(256 * sizeof(DATA8)); if (!copy) return -1; @@ -1098,9 +1099,12 @@ evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, } if (in->alpha_only != out->alpha_only) + DBG("Different color formats, implicit conversion may be slow"); + + if (map->alpha_only) { - ERR("Incompatible formats for displacement map"); - return -1; + WRN("Displacement map is not an RGBA buffer, X and Y axes will be " + "displaced together."); } if (in == out) @@ -1205,6 +1209,13 @@ evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, return -1; } + if (!bumpmap->alpha_only) + DBG("Bump map is not an Alpha buffer, implicit conversion may be slow"); + + // FIXME: Boo! + if (!in->alpha_only) + WRN("RGBA bump map support is not implemented! This will trigger conversion."); + // FIXME: Must ensure in != out if (in == out) CRI("Not acceptable"); if (bumpmap == out) CRI("Not acceptable"); @@ -1251,6 +1262,9 @@ evas_filter_command_transform_add(Evas_Filter_Context *ctx, return -1; } + if (in->alpha_only != out->alpha_only) + DBG("Incompatible buffer formats, will trigger implicit conversion."); + cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out); if (!cmd) return -1; diff --git a/src/lib/evas/filters/evas_filter_blend.c b/src/lib/evas/filters/evas_filter_blend.c index 153e568..344a7c0 100644 --- a/src/lib/evas/filters/evas_filter_blend.c +++ b/src/lib/evas/filters/evas_filter_blend.c @@ -21,7 +21,7 @@ struct Filter_Blend_Draw_Context #define LINELEN(stride, ptr) (stride / (sizeof(*ptr))) static Eina_Bool -_image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context, +_image_draw_cpu_alpha_alpha(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, @@ -56,7 +56,7 @@ _image_draw_cpu_alpha2alpha(void *data EINA_UNUSED, void *context, } static Eina_Bool -_image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context, +_image_draw_cpu_alpha_rgba(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, @@ -91,7 +91,7 @@ _image_draw_cpu_alpha2rgba(void *data EINA_UNUSED, void *context, } static Eina_Bool -_image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context, +_image_draw_cpu_rgba_rgba(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, @@ -131,7 +131,7 @@ _image_draw_cpu_rgba2rgba(void *data EINA_UNUSED, void *context, } static Eina_Bool -_image_draw_cpu_rgba2alpha(void *data EINA_UNUSED, void *context EINA_UNUSED, +_image_draw_cpu_rgba_alpha(void *data EINA_UNUSED, void *context EINA_UNUSED, 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, @@ -236,25 +236,25 @@ end: static Eina_Bool _filter_blend_cpu_alpha(Evas_Filter_Command *cmd) { - return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha2alpha); + return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha_alpha); } static Eina_Bool -_filter_blend_cpu_alpha2rgba(Evas_Filter_Command *cmd) +_filter_blend_cpu_alpha_rgba(Evas_Filter_Command *cmd) { - return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha2rgba); + return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_alpha_rgba); } static Eina_Bool -_filter_blend_cpu_rgba2alpha(Evas_Filter_Command *cmd) +_filter_blend_cpu_rgba_alpha(Evas_Filter_Command *cmd) { - return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2alpha); + return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba_alpha); } static Eina_Bool _filter_blend_cpu_rgba(Evas_Filter_Command *cmd) { - return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba2rgba); + return _filter_blend_cpu_generic_do(cmd, _image_draw_cpu_rgba_rgba); } static Eina_Bool @@ -447,12 +447,12 @@ evas_filter_blend_cpu_func_get(Evas_Filter_Command *cmd) if (cmd->output->alpha_only) return _filter_blend_cpu_alpha; else - return _filter_blend_cpu_alpha2rgba; + return _filter_blend_cpu_alpha_rgba; } else { if (cmd->output->alpha_only) - return _filter_blend_cpu_rgba2alpha; + return _filter_blend_cpu_rgba_alpha; else return _filter_blend_cpu_rgba; } diff --git a/src/lib/evas/filters/evas_filter_blur.c b/src/lib/evas/filters/evas_filter_blur.c index 9cf851f..3eb59d4 100644 --- a/src/lib/evas/filters/evas_filter_blur.c +++ b/src/lib/evas/filters/evas_filter_blur.c @@ -390,39 +390,37 @@ evas_filter_blur_cpu_func_get(Evas_Filter_Command *cmd) switch (cmd->blur.type) { case EVAS_FILTER_BLUR_BOX: - if (!cmd->input->alpha_only && !cmd->output->alpha_only) + if (!cmd->output->alpha_only) { if (cmd->blur.dx) return _box_blur_horiz_apply_rgba; else if (cmd->blur.dy) return _box_blur_vert_apply_rgba; } - else if (cmd->input->alpha_only && cmd->output->alpha_only) + else { if (cmd->blur.dx) return _box_blur_horiz_apply_alpha; else if (cmd->blur.dy) return _box_blur_vert_apply_alpha; } - CRI("Unsupported operation: mixing RGBA and Alpha surfaces."); - return NULL; + case EVAS_FILTER_BLUR_GAUSSIAN: - if (!cmd->input->alpha_only && !cmd->output->alpha_only) + if (!cmd->output->alpha_only) { if (cmd->blur.dx) return _gaussian_blur_horiz_apply_rgba; else if (cmd->blur.dy) return _gaussian_blur_vert_apply_rgba; } - else if (cmd->input->alpha_only && cmd->output->alpha_only) + else { if (cmd->blur.dx) return _gaussian_blur_horiz_apply_alpha; else if (cmd->blur.dy) return _gaussian_blur_vert_apply_alpha; } - CRI("Unsupported operation: mixing RGBA and Alpha surfaces."); - return NULL; + default: CRI("Unsupported blur type %d", cmd->blur.type); return NULL; diff --git a/src/lib/evas/filters/evas_filter_bump.c b/src/lib/evas/filters/evas_filter_bump.c index e93f1ad..f89ec3c 100644 --- a/src/lib/evas/filters/evas_filter_bump.c +++ b/src/lib/evas/filters/evas_filter_bump.c @@ -14,7 +14,6 @@ static Eina_Bool _bump_map_cpu_alpha_alpha(Evas_Filter_Command *cmd); static Eina_Bool _bump_map_cpu_alpha_rgba(Evas_Filter_Command *cmd); -static Eina_Bool _bump_map_cpu_rgba_rgba(Evas_Filter_Command *cmd); Evas_Filter_Apply_Func evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd) @@ -25,11 +24,7 @@ evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd) EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->mask, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL); - EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->input != cmd->output, NULL); - EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->mask->alpha_only, NULL); - EINA_SAFETY_ON_FALSE_RETURN_VAL((!cmd->output->alpha_only) - || cmd->input->alpha_only, NULL); w = cmd->input->w; h = cmd->input->h; @@ -38,15 +33,12 @@ evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd) EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->mask->w == w, NULL); EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->mask->h == h, NULL); - if (cmd->input->alpha_only) - { - if (cmd->output->alpha_only) - return _bump_map_cpu_alpha_alpha; - else - return _bump_map_cpu_alpha_rgba; - } + // FIXME: Bump map support is not implemented for RGBA input! + + if (cmd->output->alpha_only) + return _bump_map_cpu_alpha_alpha; else - return _bump_map_cpu_rgba_rgba; + return _bump_map_cpu_alpha_rgba; } static void @@ -417,12 +409,3 @@ end: eo_do(cmd->output->buffer, ector_buffer_unmap(dst_map, dlen)); return ret; } - -static Eina_Bool -_bump_map_cpu_rgba_rgba(Evas_Filter_Command *cmd) -{ - (void) cmd; - - CRI("Not implemented yet."); - return EINA_FALSE; -} diff --git a/src/lib/evas/filters/evas_filter_displace.c b/src/lib/evas/filters/evas_filter_displace.c index 1513a91..5722c7b 100644 --- a/src/lib/evas/filters/evas_filter_displace.c +++ b/src/lib/evas/filters/evas_filter_displace.c @@ -316,15 +316,8 @@ evas_filter_displace_cpu_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_FALSE_RETURN_VAL(!cmd->mask->alpha_only, NULL); - if (cmd->input->alpha_only != cmd->output->alpha_only) - { - CRI("Invalid color formats"); - return NULL; - } - - if (cmd->input->alpha_only) + if (cmd->output->alpha_only) return _filter_displace_cpu_alpha; else return _filter_displace_cpu_rgba; diff --git a/src/lib/evas/filters/evas_filter_mask.c b/src/lib/evas/filters/evas_filter_mask.c index d8d6dda..949caa9 100644 --- a/src/lib/evas/filters/evas_filter_mask.c +++ b/src/lib/evas/filters/evas_filter_mask.c @@ -28,26 +28,37 @@ evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd) if (cmd->input->alpha_only) { - if (cmd->mask->alpha_only && cmd->output->alpha_only) - return _mask_cpu_alpha_alpha_alpha; - else if (!cmd->mask->alpha_only && !cmd->output->alpha_only) + if (cmd->output->alpha_only) + { + if (cmd->mask->alpha_only) + { + DBG("Input and output are Alpha but mask is RGBA. This is not " + "optimal (implicit conversion and loss of color)."); + } + return _mask_cpu_alpha_alpha_alpha; + } + else if (!cmd->mask->alpha_only) return _mask_cpu_alpha_rgba_rgba; - else if (cmd->mask->alpha_only && !cmd->output->alpha_only) + else return _mask_cpu_alpha_alpha_rgba; } else { - if (cmd->mask->alpha_only && !cmd->output->alpha_only) - return _mask_cpu_rgba_alpha_rgba; - else if (!cmd->mask->alpha_only && !cmd->output->alpha_only) - return _mask_cpu_rgba_rgba_rgba; + if (!cmd->output->alpha_only) + { + // rgba -> rgba + if (cmd->mask->alpha_only) + return _mask_cpu_rgba_alpha_rgba; + else + return _mask_cpu_rgba_rgba_rgba; + } + else + { + // rgba -> alpha + DBG("Input is RGBA but output is Alpha, losing colors."); + return _mask_cpu_alpha_alpha_alpha; + } } - - CRI("If input or mask is RGBA, then output must also be RGBA: %s [%s] %s", - cmd->input->alpha_only ? "alpha" : "rgba", - cmd->mask->alpha_only ? "alpha" : "rgba", - cmd->output->alpha_only ? "alpha" : "rgba"); - return NULL; } static Eina_Bool diff --git a/src/lib/evas/filters/evas_filter_transform.c b/src/lib/evas/filters/evas_filter_transform.c index fd05d5c..5f262ee 100644 --- a/src/lib/evas/filters/evas_filter_transform.c +++ b/src/lib/evas/filters/evas_filter_transform.c @@ -13,19 +13,19 @@ _vflip_cpu(Evas_Filter_Command *cmd) 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; + Efl_Gfx_Colorspace cspace = cmd->output->alpha_only ? E_ALPHA : E_ARGB; int s0, s1, d0, d1; Eina_Bool ret = 0; w = cmd->input->w; h = cmd->input->h; - in = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, cmd->output->alpha_only ? E_ALPHA : E_ARGB, &src_stride); + in = _buffer_map_all(cmd->input->buffer, &src_len, E_READ, cspace, &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); + out = _buffer_map_all(cmd->output->buffer, &dst_len, E_WRITE, cspace, &dst_stride); 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; -- 2.7.4