evas filters: Move curve to software generic (3/8)

This moves the RGBA premul/unpremul functions to static_libs/draw.
This commit is contained in:
Jean-Philippe Andre 2017-01-17 20:34:16 +09:00
parent 09ff5f419e
commit b6df13b024
12 changed files with 105 additions and 95 deletions

View File

@ -594,7 +594,6 @@ lib/evas/canvas/evas_filter_mixin.c \
lib/evas/filters/evas_filter.c \
lib/evas/filters/evas_filter_blur.c \
lib/evas/filters/evas_filter_bump.c \
lib/evas/filters/evas_filter_curve.c \
lib/evas/filters/evas_filter_displace.c \
lib/evas/filters/evas_filter_fill.c \
lib/evas/filters/evas_filter_parser.c \
@ -617,6 +616,7 @@ lib/evas/filters/blur/blur_box_rgba_neon.c
GFX_FILTER_SW_FILES = \
modules/evas/engines/software_generic/evas_engine_filter.h \
modules/evas/engines/software_generic/filters/evas_filter_blend.c \
modules/evas/engines/software_generic/filters/evas_filter_curve.c \
modules/evas/engines/software_generic/filters/evas_filter_mask.c \
$(NULL)

View File

@ -1,9 +1,6 @@
#include "evas_common_private.h"
#include "evas_convert_color.h"
#ifdef BUILD_NEON
#include <arm_neon.h>
#endif
#include "draw.h"
EAPI DATA32
evas_common_convert_ag_premul(DATA16 *data, unsigned int len)
@ -57,88 +54,13 @@ evas_common_convert_ag_unpremul(DATA16 *data, unsigned int len)
EAPI DATA32
evas_common_convert_argb_premul(DATA32 *data, unsigned int len)
{
DATA32 *de = data + len;
DATA32 nas = 0;
#ifdef BUILD_NEON
if (evas_common_cpu_has_feature(CPU_FEATURE_NEON))
{
uint8x8_t mask_0x00 = vdup_n_u8(0);
uint8x8_t mask_0x01 = vdup_n_u8(1);
uint8x8_t mask_0xff = vdup_n_u8(255);
uint8x8_t cmp;
uint64x1_t tmp;
while (data <= de - 8)
{
uint8x8x4_t rgba = vld4_u8((uint8_t *)data);
cmp = vand_u8(vorr_u8(vceq_u8(rgba.val[3], mask_0xff),
vceq_u8(rgba.val[3], mask_0x00)),
mask_0x01);
tmp = vpaddl_u32(vpaddl_u16(vpaddl_u8(cmp)));
nas += vget_lane_u32(vreinterpret_u32_u64(tmp), 0);
uint16x8x4_t lrgba;
lrgba.val[0] = vmovl_u8(rgba.val[0]);
lrgba.val[1] = vmovl_u8(rgba.val[1]);
lrgba.val[2] = vmovl_u8(rgba.val[2]);
lrgba.val[3] = vaddl_u8(rgba.val[3], mask_0x01);
rgba.val[0] = vshrn_n_u16(vmlaq_u16(lrgba.val[0], lrgba.val[0],
lrgba.val[3]), 8);
rgba.val[1] = vshrn_n_u16(vmlaq_u16(lrgba.val[1], lrgba.val[1],
lrgba.val[3]), 8);
rgba.val[2] = vshrn_n_u16(vmlaq_u16(lrgba.val[2], lrgba.val[2],
lrgba.val[3]), 8);
vst4_u8((uint8_t *)data, rgba);
data += 8;
}
}
#endif
while (data < de)
{
DATA32 a = 1 + (*data >> 24);
*data = (*data & 0xff000000) +
(((((*data) >> 8) & 0xff) * a) & 0xff00) +
(((((*data) & 0x00ff00ff) * a) >> 8) & 0x00ff00ff);
data++;
if ((a == 1) || (a == 256))
nas++;
}
return nas;
return (DATA32) efl_draw_argb_premul(data, len);
}
EAPI void
evas_common_convert_argb_unpremul(DATA32 *data, unsigned int len)
{
DATA32 *de = data + len;
DATA32 p_val = 0x00000000, p_res = 0x00000000;
while (data < de)
{
DATA32 a = (*data >> 24);
if (p_val == *data) *data = p_res;
else
{
p_val = *data;
if ((a > 0) && (a < 255))
*data = ARGB_JOIN(a,
(R_VAL(data) * 255) / a,
(G_VAL(data) * 255) / a,
(B_VAL(data) * 255) / a);
else if (a == 0)
*data = 0x00000000;
p_res = *data;
}
data++;
}
return efl_draw_argb_unpremul(data, len);
}
EAPI void

View File

@ -1541,9 +1541,6 @@ _filter_command_run(Evas_Filter_Command *cmd)
case EVAS_FILTER_MODE_BLUR:
func = evas_filter_blur_cpu_func_get(cmd);
break;
case EVAS_FILTER_MODE_CURVE:
func = evas_filter_curve_cpu_func_get(cmd);
break;
case EVAS_FILTER_MODE_DISPLACE:
func = evas_filter_displace_cpu_func_get(cmd);
break;

View File

@ -263,7 +263,6 @@ void evas_filter_context_source_set(Evas_Filter_Context *ctx
/* FIXME: CPU filters entry points. Move these to the Evas Engine itself. */
Evas_Filter_Apply_Func evas_filter_blur_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func evas_filter_bump_map_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func evas_filter_displace_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd);

View File

@ -4628,6 +4628,7 @@ _gfx_filter_func_get(Evas_Filter_Command *cmd)
switch (cmd->mode)
{
case EVAS_FILTER_MODE_BLEND: func = eng_filter_blend_func_get(cmd); break;
case EVAS_FILTER_MODE_CURVE: func = eng_filter_curve_func_get(cmd); break;
case EVAS_FILTER_MODE_MASK: func = eng_filter_mask_func_get(cmd); break;
default: return NULL;
}

View File

@ -2,8 +2,10 @@
#define EVAS_ENGINE_FILTER_H
#include "evas_filter_private.h"
#include "draw.h"
Evas_Filter_Apply_Func eng_filter_blend_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func eng_filter_curve_func_get(Evas_Filter_Command *cmd);
Evas_Filter_Apply_Func eng_filter_mask_func_get(Evas_Filter_Command *cmd);
#endif // EVAS_ENGINE_FILTER_H

View File

@ -1,6 +1,4 @@
#include "../evas_engine_filter.h"
#include "ector_buffer.h"
#include "draw.h"
// FIXME: This should all be based on ector renderer

View File

@ -1,6 +1,4 @@
#include "evas_filter.h"
#include "evas_filter_private.h"
#include "../evas_engine_filter.h"
static Eina_Bool
_filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
@ -43,7 +41,7 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
if (src != dst)
memcpy(dst, src, dst_len);
evas_data_argb_unpremul(dst, len);
efl_draw_argb_unpremul(dst, len);
// One channel (R, G or B)
if (offset >= 0)
@ -81,7 +79,7 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
C_VAL(d) = curve[C_VAL(src)];
premul:
evas_data_argb_premul(dst, len);
efl_draw_argb_premul(dst, len);
ret = EINA_TRUE;
end:
@ -118,7 +116,7 @@ end:
}
Evas_Filter_Apply_Func
evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd)
eng_filter_curve_func_get(Evas_Filter_Command *cmd)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);

View File

@ -1,7 +1,6 @@
/* Implementation of some masking functions for the software engine */
#include "../evas_engine_filter.h"
#include "draw.h"
// Naming convention: _func_engine_incolor_maskcolor_outcolor()
static Eina_Bool _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd);

View File

@ -26,6 +26,9 @@ Draw_Func_ARGB_Mix3 efl_draw_func_argb_mix3_get (Efl_Gfx_Render_Op op, uint3
Draw_Func_Alpha efl_draw_alpha_func_get (Efl_Gfx_Render_Op op, Eina_Bool has_mask);
Cspace_Convert_Func efl_draw_convert_func_get (Efl_Gfx_Colorspace origcs, Efl_Gfx_Colorspace dstcs, Eina_Bool *region_can);
int efl_draw_argb_premul(uint32_t *data, unsigned int len);
void efl_draw_argb_unpremul(uint32_t *data, unsigned int len);
/* common sw draw helpers */

View File

@ -2,6 +2,10 @@
#include "draw_private.h"
#include "../rg_etc/rg_etc1.h"
#ifdef BUILD_NEON
#include <arm_neon.h>
#endif
#if DIV_USING_BITSHIFT
# define DEFINE_DIVIDER(div) const int pow2 = _pow2_geq((div) << 10); const int numerator = (1 << pow2) / (div);
# define DIVIDE(val) (((val) * numerator) >> pow2)
@ -526,3 +530,89 @@ efl_draw_convert_func_get(Efl_Gfx_Colorspace srccs, Efl_Gfx_Colorspace dstcs,
if (region_can) *region_can = EINA_FALSE;
return NULL;
}
int
efl_draw_argb_premul(uint32_t *data, unsigned int len)
{
uint32_t *de = data + len;
int nas = 0;
#ifdef BUILD_NEON
if (eina_cpu_features_get() & EINA_CPU_NEON)
{
uint8x8_t mask_0x00 = vdup_n_u8(0);
uint8x8_t mask_0x01 = vdup_n_u8(1);
uint8x8_t mask_0xff = vdup_n_u8(255);
uint8x8_t cmp;
uint64x1_t tmp;
while (data <= de - 8)
{
uint8x8x4_t rgba = vld4_u8((uint8_t *) data);
cmp = vand_u8(vorr_u8(vceq_u8(rgba.val[3], mask_0xff),
vceq_u8(rgba.val[3], mask_0x00)),
mask_0x01);
tmp = vpaddl_u32(vpaddl_u16(vpaddl_u8(cmp)));
nas += vget_lane_u32(vreinterpret_u32_u64(tmp), 0);
uint16x8x4_t lrgba;
lrgba.val[0] = vmovl_u8(rgba.val[0]);
lrgba.val[1] = vmovl_u8(rgba.val[1]);
lrgba.val[2] = vmovl_u8(rgba.val[2]);
lrgba.val[3] = vaddl_u8(rgba.val[3], mask_0x01);
rgba.val[0] = vshrn_n_u16(vmlaq_u16(lrgba.val[0], lrgba.val[0],
lrgba.val[3]), 8);
rgba.val[1] = vshrn_n_u16(vmlaq_u16(lrgba.val[1], lrgba.val[1],
lrgba.val[3]), 8);
rgba.val[2] = vshrn_n_u16(vmlaq_u16(lrgba.val[2], lrgba.val[2],
lrgba.val[3]), 8);
vst4_u8((uint8_t *) data, rgba);
data += 8;
}
}
#endif
while (data < de)
{
uint32_t a = 1 + (*data >> 24);
*data = (*data & 0xff000000) +
(((((*data) >> 8) & 0xff) * a) & 0xff00) +
(((((*data) & 0x00ff00ff) * a) >> 8) & 0x00ff00ff);
data++;
if ((a == 1) || (a == 256))
nas++;
}
return nas;
}
void
efl_draw_argb_unpremul(uint32_t *data, unsigned int len)
{
uint32_t *de = data + len;
uint32_t p_val = 0x00000000, p_res = 0x00000000;
while (data < de)
{
uint32_t a = (*data >> 24);
if (p_val == *data) *data = p_res;
else
{
p_val = *data;
if ((a > 0) && (a < 255))
*data = DRAW_ARGB_JOIN(a,
(R_VAL(data) * 255) / a,
(G_VAL(data) * 255) / a,
(B_VAL(data) * 255) / a);
else if (a == 0)
*data = 0x00000000;
p_res = *data;
}
data++;
}
}

View File

@ -217,6 +217,7 @@ void
efl_draw_neon_init(void)
{
#ifdef BUILD_NEON
if (getenv("EVAS_CPU_NO_NEON")) return; // compat with evas env vars
if (eina_cpu_features_get() & EINA_CPU_NEON)
{
// update the comp_function table for solid color