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.
This commit is contained in:
Jean-Philippe Andre 2015-12-11 15:44:48 +09:00
parent 7d636630cf
commit eda13b7298
7 changed files with 72 additions and 73 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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