forked from enlightenment/efl
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:
parent
09ff5f419e
commit
b6df13b024
|
@ -594,7 +594,6 @@ lib/evas/canvas/evas_filter_mixin.c \
|
||||||
lib/evas/filters/evas_filter.c \
|
lib/evas/filters/evas_filter.c \
|
||||||
lib/evas/filters/evas_filter_blur.c \
|
lib/evas/filters/evas_filter_blur.c \
|
||||||
lib/evas/filters/evas_filter_bump.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_displace.c \
|
||||||
lib/evas/filters/evas_filter_fill.c \
|
lib/evas/filters/evas_filter_fill.c \
|
||||||
lib/evas/filters/evas_filter_parser.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 = \
|
GFX_FILTER_SW_FILES = \
|
||||||
modules/evas/engines/software_generic/evas_engine_filter.h \
|
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_blend.c \
|
||||||
|
modules/evas/engines/software_generic/filters/evas_filter_curve.c \
|
||||||
modules/evas/engines/software_generic/filters/evas_filter_mask.c \
|
modules/evas/engines/software_generic/filters/evas_filter_mask.c \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
#include "evas_common_private.h"
|
#include "evas_common_private.h"
|
||||||
#include "evas_convert_color.h"
|
#include "evas_convert_color.h"
|
||||||
|
#include "draw.h"
|
||||||
#ifdef BUILD_NEON
|
|
||||||
#include <arm_neon.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EAPI DATA32
|
EAPI DATA32
|
||||||
evas_common_convert_ag_premul(DATA16 *data, unsigned int len)
|
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
|
EAPI DATA32
|
||||||
evas_common_convert_argb_premul(DATA32 *data, unsigned int len)
|
evas_common_convert_argb_premul(DATA32 *data, unsigned int len)
|
||||||
{
|
{
|
||||||
DATA32 *de = data + len;
|
return (DATA32) efl_draw_argb_premul(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
evas_common_convert_argb_unpremul(DATA32 *data, unsigned int len)
|
evas_common_convert_argb_unpremul(DATA32 *data, unsigned int len)
|
||||||
{
|
{
|
||||||
DATA32 *de = data + len;
|
return efl_draw_argb_unpremul(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++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
|
|
|
@ -1541,9 +1541,6 @@ _filter_command_run(Evas_Filter_Command *cmd)
|
||||||
case EVAS_FILTER_MODE_BLUR:
|
case EVAS_FILTER_MODE_BLUR:
|
||||||
func = evas_filter_blur_cpu_func_get(cmd);
|
func = evas_filter_blur_cpu_func_get(cmd);
|
||||||
break;
|
break;
|
||||||
case EVAS_FILTER_MODE_CURVE:
|
|
||||||
func = evas_filter_curve_cpu_func_get(cmd);
|
|
||||||
break;
|
|
||||||
case EVAS_FILTER_MODE_DISPLACE:
|
case EVAS_FILTER_MODE_DISPLACE:
|
||||||
func = evas_filter_displace_cpu_func_get(cmd);
|
func = evas_filter_displace_cpu_func_get(cmd);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -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. */
|
/* 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_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_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_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_fill_cpu_func_get(Evas_Filter_Command *cmd);
|
||||||
Evas_Filter_Apply_Func evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd);
|
Evas_Filter_Apply_Func evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd);
|
||||||
|
|
|
@ -4628,6 +4628,7 @@ _gfx_filter_func_get(Evas_Filter_Command *cmd)
|
||||||
switch (cmd->mode)
|
switch (cmd->mode)
|
||||||
{
|
{
|
||||||
case EVAS_FILTER_MODE_BLEND: func = eng_filter_blend_func_get(cmd); break;
|
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;
|
case EVAS_FILTER_MODE_MASK: func = eng_filter_mask_func_get(cmd); break;
|
||||||
default: return NULL;
|
default: return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
#define EVAS_ENGINE_FILTER_H
|
#define EVAS_ENGINE_FILTER_H
|
||||||
|
|
||||||
#include "evas_filter_private.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_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);
|
Evas_Filter_Apply_Func eng_filter_mask_func_get(Evas_Filter_Command *cmd);
|
||||||
|
|
||||||
#endif // EVAS_ENGINE_FILTER_H
|
#endif // EVAS_ENGINE_FILTER_H
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
#include "../evas_engine_filter.h"
|
#include "../evas_engine_filter.h"
|
||||||
#include "ector_buffer.h"
|
|
||||||
#include "draw.h"
|
|
||||||
|
|
||||||
// FIXME: This should all be based on ector renderer
|
// FIXME: This should all be based on ector renderer
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
#include "evas_filter.h"
|
#include "../evas_engine_filter.h"
|
||||||
#include "evas_filter_private.h"
|
|
||||||
|
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
|
_filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
|
||||||
|
@ -43,7 +41,7 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
|
||||||
|
|
||||||
if (src != dst)
|
if (src != dst)
|
||||||
memcpy(dst, src, dst_len);
|
memcpy(dst, src, dst_len);
|
||||||
evas_data_argb_unpremul(dst, len);
|
efl_draw_argb_unpremul(dst, len);
|
||||||
|
|
||||||
// One channel (R, G or B)
|
// One channel (R, G or B)
|
||||||
if (offset >= 0)
|
if (offset >= 0)
|
||||||
|
@ -81,7 +79,7 @@ _filter_curve_cpu_rgba(Evas_Filter_Command *cmd)
|
||||||
C_VAL(d) = curve[C_VAL(src)];
|
C_VAL(d) = curve[C_VAL(src)];
|
||||||
|
|
||||||
premul:
|
premul:
|
||||||
evas_data_argb_premul(dst, len);
|
efl_draw_argb_premul(dst, len);
|
||||||
ret = EINA_TRUE;
|
ret = EINA_TRUE;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -118,7 +116,7 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
Evas_Filter_Apply_Func
|
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, NULL);
|
||||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
|
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, NULL);
|
|
@ -1,7 +1,6 @@
|
||||||
/* Implementation of some masking functions for the software engine */
|
/* Implementation of some masking functions for the software engine */
|
||||||
|
|
||||||
#include "../evas_engine_filter.h"
|
#include "../evas_engine_filter.h"
|
||||||
#include "draw.h"
|
|
||||||
|
|
||||||
// Naming convention: _func_engine_incolor_maskcolor_outcolor()
|
// Naming convention: _func_engine_incolor_maskcolor_outcolor()
|
||||||
static Eina_Bool _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd);
|
static Eina_Bool _mask_cpu_alpha_alpha_alpha(Evas_Filter_Command *cmd);
|
||||||
|
|
|
@ -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);
|
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);
|
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 */
|
/* common sw draw helpers */
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
#include "draw_private.h"
|
#include "draw_private.h"
|
||||||
#include "../rg_etc/rg_etc1.h"
|
#include "../rg_etc/rg_etc1.h"
|
||||||
|
|
||||||
|
#ifdef BUILD_NEON
|
||||||
|
#include <arm_neon.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if DIV_USING_BITSHIFT
|
#if DIV_USING_BITSHIFT
|
||||||
# define DEFINE_DIVIDER(div) const int pow2 = _pow2_geq((div) << 10); const int numerator = (1 << pow2) / (div);
|
# define DEFINE_DIVIDER(div) const int pow2 = _pow2_geq((div) << 10); const int numerator = (1 << pow2) / (div);
|
||||||
# define DIVIDE(val) (((val) * numerator) >> pow2)
|
# 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;
|
if (region_can) *region_can = EINA_FALSE;
|
||||||
return NULL;
|
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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -217,6 +217,7 @@ void
|
||||||
efl_draw_neon_init(void)
|
efl_draw_neon_init(void)
|
||||||
{
|
{
|
||||||
#ifdef BUILD_NEON
|
#ifdef BUILD_NEON
|
||||||
|
if (getenv("EVAS_CPU_NO_NEON")) return; // compat with evas env vars
|
||||||
if (eina_cpu_features_get() & EINA_CPU_NEON)
|
if (eina_cpu_features_get() & EINA_CPU_NEON)
|
||||||
{
|
{
|
||||||
// update the comp_function table for solid color
|
// update the comp_function table for solid color
|
||||||
|
|
Loading…
Reference in New Issue