Major rework of blit operations to use pre-multiplied colors.

I wrote the first version thinking on regular, non-pre multiplied
colors, but raster pointed out that all color data is pre-multiplied
inside Evas. I was blaming 16bpp for low quality graphics, but it
turned out that was an error with my usage.

If you experienced grayish colors when using transparency, or white
turning into black while fading out, then these should be fixed now.

Now everything looks better, brighter! :-)  Expedite shows no
performance regressions, but I'd like to see more tests on
that. Please report any issue.


SVN revision: 32037
This commit is contained in:
Gustavo Sverzut Barbieri 2007-10-10 19:22:26 +00:00
parent 616b9623ae
commit dfcde9bcaa
7 changed files with 246 additions and 214 deletions

View File

@ -12,6 +12,8 @@
((((rgb) & RGB_565_UNPACKED_MASK) | \
((rgb) & RGB_565_UNPACKED_MASK) >> 16) & 0xffff)
#define RGB_565_UNPACKED_BLEND(a, b, alpha) \
((b) + (a) - ((((b) * (alpha)) >> 5) & RGB_565_UNPACKED_MASK))
#define RGB_565_UNPACKED_BLEND_UNMUL(a, b, alpha) \
((b) + ((((a) - (b)) * (alpha)) >> 5))
#define RGB_565_FROM_COMPONENTS(r, g, b) \

View File

@ -142,29 +142,48 @@ static inline void
_soft16_convert_from_rgba_pt(const DATA32 *src, DATA16 *dst, DATA8 *alpha,
const int x, const int y)
{
DATA8 orig_r, orig_g, orig_b, orig_a, r, g, b, a, dith5, dith6, dith;
DATA8 orig_r, orig_g, orig_b, orig_a;
orig_r = R_VAL(src);
orig_g = G_VAL(src);
orig_b = B_VAL(src);
orig_a = A_VAL(src);
r = orig_r >> 3;
g = orig_g >> 2;
b = orig_b >> 3;
a = orig_a >> 3;
if (orig_a == 255)
{
DATA8 dith5, dith6, dith, r, g, b;
dith = dither_table[x & S16_DM_MSK][y & S16_DM_MSK];
dith5 = dith >> S16_DM_SHF(5);
dith6 = dith >> S16_DM_SHF(6);
dith = dither_table[x & S16_DM_MSK][y & S16_DM_MSK];
dith5 = dith >> S16_DM_SHF(5);
dith6 = dith >> S16_DM_SHF(6);
if (((orig_r - (r << 3)) >= dith5) && (r < 0x1f)) r++;
if (((orig_g - (g << 2)) >= dith6) && (g < 0x3f)) g++;
if (((orig_b - (b << 3)) >= dith5) && (b < 0x1f)) b++;
if (((orig_a - (a << 3)) >= dith5) && (a < 0x1f)) a++;
r = orig_r >> 3;
g = orig_g >> 2;
b = orig_b >> 3;
*dst = (r << 11) | (g << 5) | b;
*alpha = a;
if (((orig_r - (r << 3)) >= dith5) && (r < 0x1f)) r++;
if (((orig_g - (g << 2)) >= dith6) && (g < 0x3f)) g++;
if (((orig_b - (b << 3)) >= dith5) && (b < 0x1f)) b++;
*dst = (r << 11) | (g << 5) | b;
*alpha = 31;
}
else if (orig_a == 0)
{
*dst = 0;
*alpha = 0;
}
else
{
DATA8 r, g, b, a;
r = orig_r >> 3;
g = orig_g >> 2;
b = orig_b >> 3;
a = (orig_a >> 3) + 1;
*dst = (r << 11) | (g << 5) | b;
*alpha = a;
}
}
static inline void

View File

@ -1,4 +1,5 @@
#include "evas_soft16.h"
#include "evas_soft16_scanline_blend.c"
static inline void
_glyph_pt_mask_solid_solid(DATA16 *dst,
@ -6,15 +7,15 @@ _glyph_pt_mask_solid_solid(DATA16 *dst,
const DATA32 rgb565_unpack,
const DATA8 *mask)
{
DATA8 alpha = *mask;
DATA8 alpha = *mask >> 3;
if (alpha == 255) *dst = rgb565;
else if (alpha > 8)
if (alpha == 31) *dst = rgb565;
else if (alpha > 0)
{
DATA32 d;
d = RGB_565_UNPACK(*dst);
d = RGB_565_UNPACKED_BLEND(rgb565_unpack, d, alpha >> 3);
d = RGB_565_UNPACKED_BLEND_UNMUL(rgb565_unpack, d, alpha);
*dst = RGB_565_PACK(d);
}
}
@ -51,29 +52,24 @@ _glyph_scanline_mask_solid_solid(DATA16 *dst,
static inline void
_glyph_pt_mask_transp_solid(DATA16 *dst,
const DATA32 rgb565_unpack,
const DATA8 rel_alpha,
DATA32 rgb565_unpack,
DATA8 alpha,
const DATA8 *mask)
{
DATA32 d;
DATA8 alpha;
DATA32 a, b;
int rel_alpha;
if (*mask == 255) alpha = rel_alpha >> 3;
else if (*mask == 0) return;
else
{
/* doing multiply to avoid too much error, it's acceptable to do:
* alpha - (max_alpha - rel_alpha)
* on images because error is not that important/noticeable, but
* on texts, with many edges, it's unacceptable.
*/
alpha = (*mask * rel_alpha) >> 11;
if (alpha == 0) return;
}
rel_alpha = *mask >> 3;
alpha = (alpha * rel_alpha) >> 5;
if (alpha == 0)
return;
d = RGB_565_UNPACK(*dst);
d = RGB_565_UNPACKED_BLEND(rgb565_unpack, d, alpha);
*dst = RGB_565_PACK(d);
alpha++;
a = ((rgb565_unpack * rel_alpha) >> 5) & RGB_565_UNPACKED_MASK;
b = RGB_565_UNPACK(*dst);
b = RGB_565_UNPACKED_BLEND(a, b, alpha);
*dst = RGB_565_PACK(b);
}
static inline void
@ -143,10 +139,10 @@ _calc_ext(const Soft16_Image *dst, const RGBA_Draw_Context *dc,
}
static inline void
_glyph_scaline(Soft16_Image *dst, const DATA8 *p_mask,
const Evas_Rectangle ext, int dx, int dy, int max_x, int max_y,
int w, DATA8 alpha, const DATA16 rgb565,
const DATA32 rgb565_unpack)
_glyph_scanline(Soft16_Image *dst, const DATA8 *p_mask,
const Evas_Rectangle ext, int dx, int dy, int max_x, int max_y,
int w, DATA8 alpha, const DATA16 rgb565,
const DATA32 rgb565_unpack)
{
int size, in_x, in_w;
DATA16 *p_pixels;
@ -171,7 +167,7 @@ _glyph_scaline(Soft16_Image *dst, const DATA8 *p_mask,
if (size > 1)
{
if (alpha == 255)
if (alpha == 31)
_glyph_scanline_mask_solid_solid
(p_pixels, size, rgb565, rgb565_unpack, p_mask);
else if (alpha != 0)
@ -180,7 +176,7 @@ _glyph_scaline(Soft16_Image *dst, const DATA8 *p_mask,
}
else if (size == 1)
{
if (alpha == 255)
if (alpha == 31)
_glyph_pt_mask_solid_solid(p_pixels, rgb565, rgb565_unpack, p_mask);
else if (alpha != 0)
_glyph_pt_mask_transp_solid(p_pixels, rgb565_unpack, alpha, p_mask);
@ -201,8 +197,8 @@ _soft16_font_glyph_draw_grayscale(Soft16_Image *dst,
max_y = ext.y + ext.h;
for (i = 0; i < bh; i++, bitmap += bpitch)
_glyph_scaline(dst, bitmap, ext, x, y + i, max_x, max_y, bw,
alpha, rgb565, rgb565_unpack);
_glyph_scanline(dst, bitmap, ext, x, y + i, max_x, max_y, bw,
alpha, rgb565, rgb565_unpack);
}
static inline void
@ -244,8 +240,8 @@ _soft16_font_glyph_draw_mono(Soft16_Image *dst,
for (i = 0; i < bh; i++, bitmap += bpitch)
{
_glyph_create_mask_line(mask, bitmap, bw);
_glyph_scaline(dst, mask, ext, x, y + i, max_x, max_y, bw,
alpha, rgb565, rgb565_unpack);
_glyph_scanline(dst, mask, ext, x, y + i, max_x, max_y, bw,
alpha, rgb565, rgb565_unpack);
}
}
@ -255,17 +251,23 @@ soft16_font_glyph_draw(Soft16_Image *dst, void *data,
int x, int y)
{
const DATA8 *bitmap;
DATA8 alpha;
DATA8 alpha, r, g, b;
DATA16 rgb565;
Evas_Rectangle ext;
int bpitch, bw, bh;
alpha = A_VAL(&dc->col.col);
if (alpha < 8) return; /* precision is 5 bits, 3 bits lost */
alpha = A_VAL(&dc->col.col) >> 3;
if (alpha == 0) return; /* precision is 5 bits, 3 bits lost */
rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
G_VAL(&dc->col.col),
B_VAL(&dc->col.col));
r = R_VAL(&dc->col.col) >> 3;
g = G_VAL(&dc->col.col) >> 2;
b = B_VAL(&dc->col.col) >> 3;
if (r > alpha) r = alpha;
if (g > (alpha << 1)) g = (alpha << 1);
if (b > alpha) b = alpha;
rgb565 = (r << 11) | (g << 5) | b;
bitmap = fg->glyph_out->bitmap.buffer;
bh = fg->glyph_out->bitmap.rows;

View File

@ -111,14 +111,11 @@ _soft16_image_draw_scaled_solid_solid_mul_alpha(Soft16_Image *src,
Soft16_Image *dst,
RGBA_Draw_Context *dc,
int dst_offset, int w, int h,
int *offset_x, int *offset_y)
int *offset_x, int *offset_y,
DATA8 alpha)
{
DATA16 *dst_itr;
int y, w_align, rel_alpha;
rel_alpha = A_VAL(&dc->mul.col) >> 3;
if ((rel_alpha < 1) || (rel_alpha > 31)) return;
rel_alpha = 31 - rel_alpha;
int y, w_align;
w_align = w & ~7;
@ -141,7 +138,7 @@ _soft16_image_draw_scaled_solid_solid_mul_alpha(Soft16_Image *src,
UNROLL8({
_soft16_pt_blend_solid_solid_mul_alpha
(d, s[offset_x[x]], rel_alpha);
(d, s[offset_x[x]], alpha);
x++;
d++;
});
@ -149,7 +146,7 @@ _soft16_image_draw_scaled_solid_solid_mul_alpha(Soft16_Image *src,
for (; x < w; x++, d++)
_soft16_pt_blend_solid_solid_mul_alpha
(d, s[offset_x[x]], rel_alpha);
(d, s[offset_x[x]], alpha);
}
}
@ -158,14 +155,11 @@ _soft16_image_draw_scaled_transp_solid_mul_alpha(Soft16_Image *src,
Soft16_Image *dst,
RGBA_Draw_Context *dc,
int dst_offset, int w, int h,
int *offset_x, int *offset_y)
int *offset_x, int *offset_y,
DATA8 alpha)
{
DATA16 *dst_itr;
int y, w_align, rel_alpha;
rel_alpha = A_VAL(&dc->mul.col) >> 3;
if ((rel_alpha < 1) || (rel_alpha > 31)) return;
rel_alpha = 31 - rel_alpha;
int y, w_align;
w_align = w & ~7;
@ -193,7 +187,7 @@ _soft16_image_draw_scaled_transp_solid_mul_alpha(Soft16_Image *src,
UNROLL8({
int off_x = offset_x[x];
_soft16_pt_blend_transp_solid_mul_alpha
(d, s[off_x], a[off_x], rel_alpha);
(d, s[off_x], a[off_x], alpha);
x++;
d++;
});
@ -201,7 +195,7 @@ _soft16_image_draw_scaled_transp_solid_mul_alpha(Soft16_Image *src,
for (; x < w; x++, d++)
_soft16_pt_blend_transp_solid_mul_alpha
(d, s[offset_x[x]], a[offset_x[x]], rel_alpha);
(d, s[offset_x[x]], a[offset_x[x]], alpha);
}
}
@ -209,14 +203,14 @@ static inline void
_soft16_image_draw_scaled_mul_alpha(Soft16_Image *src, Soft16_Image *dst,
RGBA_Draw_Context *dc,
int dst_offset, int w, int h,
int *offset_x, int *offset_y)
int *offset_x, int *offset_y, DATA8 a)
{
if (src->have_alpha && (!dst->have_alpha))
_soft16_image_draw_scaled_transp_solid_mul_alpha
(src, dst, dc, dst_offset, w, h, offset_x, offset_y);
(src, dst, dc, dst_offset, w, h, offset_x, offset_y, a);
else if ((!src->have_alpha) && (!dst->have_alpha))
_soft16_image_draw_scaled_solid_solid_mul_alpha
(src, dst, dc, dst_offset, w, h, offset_x, offset_y);
(src, dst, dc, dst_offset, w, h, offset_x, offset_y, a);
else
fprintf(stderr,
"Unsupported draw of scaled images src->have_alpha=%d, "
@ -229,27 +223,18 @@ _soft16_image_draw_scaled_solid_solid_mul_color(Soft16_Image *src,
Soft16_Image *dst,
RGBA_Draw_Context *dc,
int dst_offset, int w, int h,
int *offset_x, int *offset_y)
int *offset_x, int *offset_y,
DATA8 r, DATA8 g, DATA8 b,
DATA8 alpha)
{
DATA16 *dst_itr;
int y, w_align, rel_alpha, r, g, b;
rel_alpha = A_VAL(&dc->mul.col) >> 3;
if ((rel_alpha < 1) || (rel_alpha > 31)) return;
r = R_VAL(&dc->mul.col);
g = G_VAL(&dc->mul.col);
b = B_VAL(&dc->mul.col);
/* we'll divide by 256 to make it faster, try to improve things a bit */
if (r > 127) r++;
if (g > 127) g++;
if (b > 127) b++;
int y, w_align;
w_align = w & ~7;
dst_itr = dst->pixels + dst_offset;
if (rel_alpha == 31)
if (alpha == 31)
for (y = 0; y < h; y++, dst_itr += dst->stride)
{
DATA16 *d, *s;
@ -297,7 +282,7 @@ _soft16_image_draw_scaled_solid_solid_mul_color(Soft16_Image *src,
UNROLL8({
_soft16_pt_blend_solid_solid_mul_color_transp
(d, s[offset_x[x]], rel_alpha, r, g, b);
(d, s[offset_x[x]], alpha, r, g, b);
x++;
d++;
});
@ -305,7 +290,7 @@ _soft16_image_draw_scaled_solid_solid_mul_color(Soft16_Image *src,
for (; x < w; x++, d++)
_soft16_pt_blend_solid_solid_mul_color_transp
(d, s[offset_x[x]], rel_alpha, r, g, b);
(d, s[offset_x[x]], alpha, r, g, b);
}
}
@ -314,28 +299,18 @@ _soft16_image_draw_scaled_transp_solid_mul_color(Soft16_Image *src,
Soft16_Image *dst,
RGBA_Draw_Context *dc,
int dst_offset, int w, int h,
int *offset_x, int *offset_y)
int *offset_x, int *offset_y,
DATA8 r, DATA8 g, DATA8 b,
DATA8 alpha)
{
DATA16 *dst_itr;
int y, w_align, rel_alpha, r, g, b;
rel_alpha = A_VAL(&dc->mul.col) >> 3;
if ((rel_alpha < 1) || (rel_alpha > 31)) return;
rel_alpha = 31 - rel_alpha;
r = R_VAL(&dc->mul.col);
g = G_VAL(&dc->mul.col);
b = B_VAL(&dc->mul.col);
/* we'll divide by 256 to make it faster, try to improve things a bit */
if (r > 127) r++;
if (g > 127) g++;
if (b > 127) b++;
int y, w_align;
w_align = w & ~7;
dst_itr = dst->pixels + dst_offset;
if (rel_alpha == 0)
if (alpha == 31)
for (y = 0; y < h; y++, dst_itr += dst->stride)
{
DATA16 *d, *s;
@ -393,7 +368,7 @@ _soft16_image_draw_scaled_transp_solid_mul_color(Soft16_Image *src,
UNROLL8({
int off_x = offset_x[x];
_soft16_pt_blend_transp_solid_mul_color_transp
(d, s[off_x], a[off_x], rel_alpha, r, g, b);
(d, s[off_x], a[off_x], alpha, r, g, b);
x++;
d++;
});
@ -401,7 +376,7 @@ _soft16_image_draw_scaled_transp_solid_mul_color(Soft16_Image *src,
for (; x < w; x++, d++)
_soft16_pt_blend_transp_solid_mul_color_transp
(d, s[offset_x[x]], a[offset_x[x]], rel_alpha, r, g, b);
(d, s[offset_x[x]], a[offset_x[x]], alpha, r, g, b);
}
}
@ -409,14 +384,15 @@ static inline void
_soft16_image_draw_scaled_mul_color(Soft16_Image *src, Soft16_Image *dst,
RGBA_Draw_Context *dc,
int dst_offset, int w, int h,
int *offset_x, int *offset_y)
int *offset_x, int *offset_y,
DATA8 r, DATA8 g, DATA8 b, DATA8 a)
{
if (src->have_alpha && (!dst->have_alpha))
_soft16_image_draw_scaled_transp_solid_mul_color
(src, dst, dc, dst_offset, w, h, offset_x, offset_y);
(src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a);
else if ((!src->have_alpha) && (!dst->have_alpha))
_soft16_image_draw_scaled_solid_solid_mul_color
(src, dst, dc, dst_offset, w, h, offset_x, offset_y);
(src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a);
else
fprintf(stderr,
"Unsupported draw of scaled images src->have_alpha=%d, "
@ -428,16 +404,15 @@ static inline void
_soft16_image_draw_scaled_mul(Soft16_Image *src, Soft16_Image *dst,
RGBA_Draw_Context *dc,
int dst_offset, int w, int h,
int *offset_x, int *offset_y)
int *offset_x, int *offset_y, DATA8 r, DATA8 g,
DATA8 b, DATA8 a)
{
if ((A_VAL(&dc->mul.col) == R_VAL(&dc->mul.col)) &&
(A_VAL(&dc->mul.col) == G_VAL(&dc->mul.col)) &&
(A_VAL(&dc->mul.col) == B_VAL(&dc->mul.col)))
if ((a == r) && (a == (g >> 1)) && (a == b))
_soft16_image_draw_scaled_mul_alpha
(src, dst, dc, dst_offset, w, h, offset_x, offset_y);
(src, dst, dc, dst_offset, w, h, offset_x, offset_y, a);
else
_soft16_image_draw_scaled_mul_color
(src, dst, dc, dst_offset, w, h, offset_x, offset_y);
(src, dst, dc, dst_offset, w, h, offset_x, offset_y, r, g, b, a);
}
void
@ -448,6 +423,31 @@ soft16_image_draw_scaled_sampled(Soft16_Image *src, Soft16_Image *dst,
const Evas_Rectangle cr)
{
int x, y, dst_offset, *offset_x, *offset_y;
DATA16 mul_rgb565;
DATA8 r, g, b, a;
if (!dc->mul.use)
{
r = b = a = 31;
g = 63;
mul_rgb565 = 0xffff;
}
else
{
a = A_VAL(&dc->mul.col) >> 3;
if (a == 0)
return;
r = R_VAL(&dc->mul.col) >> 3;
g = G_VAL(&dc->mul.col) >> 2;
b = B_VAL(&dc->mul.col) >> 3;
if (r > a) r = a;
if (g > (a << 1)) g = (a << 1);
if (b > a) b = a;
mul_rgb565 = (r << 11) || (g << 5) | b;
}
/* pre-calculated scale tables */
offset_x = alloca(cr.w * sizeof(*offset_x));
@ -461,10 +461,11 @@ soft16_image_draw_scaled_sampled(Soft16_Image *src, Soft16_Image *dst,
dst_offset = cr.x + (cr.y * dst->stride);
if ((!dc->mul.use) || (dc->mul.col == 0xffffffff))
if (mul_rgb565 == 0xffff)
_soft16_image_draw_scaled_no_mul
(src, dst, dc, dst_offset, cr.w, cr.h, offset_x, offset_y);
else if (dc->mul.col != 0x00000000)
else
_soft16_image_draw_scaled_mul
(src, dst, dc, dst_offset, cr.w, cr.h, offset_x, offset_y);
(src, dst, dc, dst_offset, cr.w, cr.h, offset_x, offset_y, r, g, b, a);
}

View File

@ -72,22 +72,17 @@ _soft16_image_draw_unscaled_solid_solid_mul_alpha(Soft16_Image *src,
RGBA_Draw_Context *dc,
int src_offset,
int dst_offset,
int w, int h)
int w, int h, DATA8 a)
{
DATA16 *src_itr, *dst_itr;
int y, rel_alpha;
int y;
src_itr = src->pixels + src_offset;
dst_itr = dst->pixels + dst_offset;
rel_alpha = A_VAL(&dc->mul.col) >> 3;
if ((rel_alpha < 1) || (rel_alpha > 31)) return;
rel_alpha = 31 - rel_alpha;
for (y = 0; y < h; y++)
{
_soft16_scanline_blend_solid_solid_mul_alpha(src_itr, dst_itr, w,
rel_alpha);
_soft16_scanline_blend_solid_solid_mul_alpha(src_itr, dst_itr, w, a);
src_itr += src->stride;
dst_itr += dst->stride;
}
@ -99,25 +94,21 @@ _soft16_image_draw_unscaled_transp_solid_mul_alpha(Soft16_Image *src,
RGBA_Draw_Context *dc,
int src_offset,
int dst_offset,
int w, int h)
int w, int h, DATA8 a)
{
DATA16 *src_itr, *dst_itr;
DATA8 *alpha_itr;
int y, rel_alpha;
int y;
src_itr = src->pixels + src_offset;
alpha_itr = src->alpha + src_offset;
dst_itr = dst->pixels + dst_offset;
rel_alpha = A_VAL(&dc->mul.col) >> 3;
if ((rel_alpha < 1) || (rel_alpha > 31)) return;
rel_alpha = 31 - rel_alpha;
for (y = 0; y < h; y++)
{
_soft16_scanline_blend_transp_solid_mul_alpha(src_itr, alpha_itr,
dst_itr, w, rel_alpha);
dst_itr, w, a);
src_itr += src->stride;
alpha_itr += src->stride;
dst_itr += dst->stride;
@ -128,14 +119,14 @@ static inline void
_soft16_image_draw_unscaled_mul_alpha(Soft16_Image *src, Soft16_Image *dst,
RGBA_Draw_Context *dc,
int src_offset, int dst_offset,
int width, int height)
int width, int height, DATA8 a)
{
if (src->have_alpha && (!dst->have_alpha))
_soft16_image_draw_unscaled_transp_solid_mul_alpha
(src, dst, dc, src_offset, dst_offset, width, height);
(src, dst, dc, src_offset, dst_offset, width, height, a);
else if ((!src->have_alpha) && (!dst->have_alpha))
_soft16_image_draw_unscaled_solid_solid_mul_alpha
(src, dst, dc, src_offset, dst_offset, width, height);
(src, dst, dc, src_offset, dst_offset, width, height, a);
else
fprintf(stderr,
"Unsupported draw of unscaled images src->have_alpha=%d, "
@ -149,26 +140,16 @@ _soft16_image_draw_unscaled_solid_solid_mul_color(Soft16_Image *src,
RGBA_Draw_Context *dc,
int src_offset,
int dst_offset,
int w, int h)
int w, int h, DATA8 r,
DATA8 g, DATA8 b, DATA8 a)
{
DATA16 *src_itr, *dst_itr;
int y, rel_alpha, r, g, b;
int y;
src_itr = src->pixels + src_offset;
dst_itr = dst->pixels + dst_offset;
rel_alpha = A_VAL(&dc->mul.col) >> 3;
if ((rel_alpha < 1) || (rel_alpha > 31)) return;
r = R_VAL(&dc->mul.col);
g = G_VAL(&dc->mul.col);
b = B_VAL(&dc->mul.col);
/* we'll divide by 256 to make it faster, try to improve things a bit */
if (r > 127) r++;
if (g > 127) g++;
if (b > 127) b++;
if (rel_alpha == 31)
if (a == 31)
for (y = 0; y < h; y++)
{
_soft16_scanline_blend_solid_solid_mul_color_solid
@ -180,7 +161,7 @@ _soft16_image_draw_unscaled_solid_solid_mul_color(Soft16_Image *src,
for (y = 0; y < h; y++)
{
_soft16_scanline_blend_solid_solid_mul_color_transp
(src_itr, dst_itr, w, rel_alpha, r, g, b);
(src_itr, dst_itr, w, a, r, g, b);
src_itr += src->stride;
dst_itr += dst->stride;
}
@ -192,30 +173,19 @@ _soft16_image_draw_unscaled_transp_solid_mul_color(Soft16_Image *src,
RGBA_Draw_Context *dc,
int src_offset,
int dst_offset,
int w, int h)
int w, int h, DATA8 r,
DATA8 g, DATA8 b, DATA8 a)
{
DATA16 *src_itr, *dst_itr;
DATA8 *alpha_itr;
int y, rel_alpha, r, g, b;
int y;
src_itr = src->pixels + src_offset;
alpha_itr = src->alpha + src_offset;
dst_itr = dst->pixels + dst_offset;
rel_alpha = A_VAL(&dc->mul.col) >> 3;
if ((rel_alpha < 1) || (rel_alpha > 31)) return;
rel_alpha = 31 - rel_alpha;
r = R_VAL(&dc->mul.col);
g = G_VAL(&dc->mul.col);
b = B_VAL(&dc->mul.col);
/* we'll divide by 256 to make it faster, try to improve things a bit */
if (r > 127) r++;
if (g > 127) g++;
if (b > 127) b++;
if (rel_alpha == 0)
if (a == 31)
for (y = 0; y < h; y++)
{
_soft16_scanline_blend_transp_solid_mul_color_solid
@ -228,7 +198,7 @@ _soft16_image_draw_unscaled_transp_solid_mul_color(Soft16_Image *src,
for (y = 0; y < h; y++)
{
_soft16_scanline_blend_transp_solid_mul_color_transp
(src_itr, alpha_itr, dst_itr, w, rel_alpha, r, g, b);
(src_itr, alpha_itr, dst_itr, w, a, r, g, b);
src_itr += src->stride;
alpha_itr += src->stride;
dst_itr += dst->stride;
@ -239,14 +209,15 @@ static inline void
_soft16_image_draw_unscaled_mul_color(Soft16_Image *src, Soft16_Image *dst,
RGBA_Draw_Context *dc,
int src_offset, int dst_offset,
int width, int height)
int width, int height,
DATA8 r, DATA8 g, DATA8 b, DATA8 a)
{
if (src->have_alpha && (!dst->have_alpha))
_soft16_image_draw_unscaled_transp_solid_mul_color
(src, dst, dc, src_offset, dst_offset, width, height);
_soft16_image_draw_unscaled_transp_solid_mul_color
(src, dst, dc, src_offset, dst_offset, width, height, r, g, b, a);
else if ((!src->have_alpha) && (!dst->have_alpha))
_soft16_image_draw_unscaled_solid_solid_mul_color
(src, dst, dc, src_offset, dst_offset, width, height);
_soft16_image_draw_unscaled_solid_solid_mul_color
(src, dst, dc, src_offset, dst_offset, width, height, r, g, b, a);
else
fprintf(stderr,
"Unsupported draw of unscaled images src->have_alpha=%d, "
@ -258,16 +229,16 @@ static inline void
_soft16_image_draw_unscaled_mul(Soft16_Image *src, Soft16_Image *dst,
RGBA_Draw_Context *dc,
int src_offset, int dst_offset,
int width, int height)
int width, int height, DATA8 r, DATA8 g,
DATA8 b, DATA8 a)
{
if ((A_VAL(&dc->mul.col) == R_VAL(&dc->mul.col)) &&
(A_VAL(&dc->mul.col) == G_VAL(&dc->mul.col)) &&
(A_VAL(&dc->mul.col) == B_VAL(&dc->mul.col)))
if ((a == r) && (a == (g >> 1)) && (a == b))
_soft16_image_draw_unscaled_mul_alpha(src, dst, dc, src_offset,
dst_offset, width, height);
dst_offset, width, height, a);
else
_soft16_image_draw_unscaled_mul_color(src, dst, dc, src_offset,
dst_offset, width, height);
dst_offset, width, height,
r, g, b, a);
}
void
@ -278,16 +249,42 @@ soft16_image_draw_unscaled(Soft16_Image *src, Soft16_Image *dst,
const Evas_Rectangle cr)
{
int src_offset_rows, src_offset, dst_offset;
DATA16 mul_rgb565;
DATA8 r, g, b, a;
if (!dc->mul.use)
{
r = b = a = 31;
g = 63;
mul_rgb565 = 0xffff;
}
else
{
a = A_VAL(&dc->mul.col) >> 3;
if (a == 0)
return;
r = R_VAL(&dc->mul.col) >> 3;
g = G_VAL(&dc->mul.col) >> 2;
b = B_VAL(&dc->mul.col) >> 3;
if (r > a) r = a;
if (g > (a << 1)) g = (a << 1);
if (b > a) b = a;
mul_rgb565 = (r << 11) || (g << 5) | b;
}
src_offset_rows = (cr.y - dr.y) + sr.y;
src_offset = (src_offset_rows * src->stride) + (cr.x - dr.x) + sr.x;
dst_offset = cr.x + (cr.y * dst->stride);
if ((!dc->mul.use) || (dc->mul.col == 0xffffffff))
if (mul_rgb565 == 0xffff)
_soft16_image_draw_unscaled_no_mul(src, dst, dc, src_offset, dst_offset,
cr.w, cr.h);
else if (dc->mul.col != 0x00000000)
else
_soft16_image_draw_unscaled_mul(src, dst, dc, src_offset, dst_offset,
cr.w, cr.h);
cr.w, cr.h, r, g, b, a);
}

View File

@ -42,6 +42,7 @@ _soft16_rectangle_draw_transp_solid(Soft16_Image *dst, RGBA_Draw_Context *dc,
G_VAL(&dc->col.col),
B_VAL(&dc->col.col));
rgb565 = RGB_565_UNPACK(rgb565);
alpha++;
for (i = 0; i < h; i++, dst_itr += dst->stride)
_soft16_scanline_fill_transp_solid(dst_itr, w, rgb565, alpha);

View File

@ -18,6 +18,9 @@ _soft16_pt_blend_transp_solid(DATA16 *p_dst, DATA16 src, DATA8 alpha)
else if (alpha != 0)
{
DATA32 a, b;
DATA32 dst = *p_dst;
a = RGB_565_UNPACK(src);
b = RGB_565_UNPACK(*p_dst);
b = RGB_565_UNPACKED_BLEND(a, b, alpha);
@ -103,15 +106,18 @@ _soft16_scanline_blend_solid_solid(DATA16 *src, DATA16 *dst, int size)
static inline void
_soft16_pt_blend_transp_solid_mul_alpha(DATA16 *p_dst, DATA16 src, DATA8 alpha, DATA8 rel_alpha)
{
/* rel_alpha is always > 0, so (alpha - rel_alpha) is always < 31 */
if (alpha > rel_alpha)
{
DATA32 a, b;
a = RGB_565_UNPACK(src);
b = RGB_565_UNPACK(*p_dst);
b = RGB_565_UNPACKED_BLEND(a, b, alpha - rel_alpha);
*p_dst = RGB_565_PACK(b);
}
DATA32 a, b;
alpha = (alpha * rel_alpha) >> 5;
if (alpha == 0)
return;
alpha++;
a = ((RGB_565_UNPACK(src) * rel_alpha) >> 5) & RGB_565_UNPACKED_MASK;
b = RGB_565_UNPACK(*p_dst);
b = RGB_565_UNPACKED_BLEND(a, b, alpha);
*p_dst = RGB_565_PACK(b);
}
static inline void
@ -181,7 +187,7 @@ _soft16_pt_blend_solid_solid_mul_alpha(DATA16 *p_dst, DATA16 src, DATA8 rel_alph
DATA32 a, b;
a = RGB_565_UNPACK(src);
b = RGB_565_UNPACK(*p_dst);
b = RGB_565_UNPACKED_BLEND(a, b, rel_alpha);
b = RGB_565_UNPACKED_BLEND_UNMUL(a, b, rel_alpha);
*p_dst = RGB_565_PACK(b);
}
@ -217,19 +223,23 @@ _soft16_scanline_blend_solid_solid_mul_alpha(DATA16 *src, DATA16 *dst, int size,
static inline void
_soft16_pt_blend_transp_solid_mul_color_transp(DATA16 *p_dst, DATA16 src, DATA8 alpha, DATA8 rel_alpha, DATA16 r, DATA16 g, DATA16 b)
{
/* rel_alpha is always > 0, so (alpha - rel_alpha) is always < 31 */
if (alpha > rel_alpha)
{
int r1, g1, b1;
DATA32 rgb, d;
r1 = ((((src) >> 11) & 0x1f) * r) >> 8;
g1 = ((((src) >> 5) & 0x3f) * g) >> 8;
b1 = (((src) & 0x1f) * b) >> 8;
rgb = ((r1 << 11) | (g1 << 21) | b1) & RGB_565_UNPACKED_MASK;
d = RGB_565_UNPACK(*p_dst);
d = RGB_565_UNPACKED_BLEND(rgb, d, alpha - rel_alpha);
*p_dst = RGB_565_PACK(d);
}
DATA32 rgb, d;
int r1, g1, b1;
alpha = (alpha * rel_alpha) >> 5;
if (alpha == 0)
return;
alpha++;
r1 = ((((src) >> 11) & 0x1f) * r) >> 5;
g1 = ((((src) >> 5) & 0x3f) * g) >> 6;
b1 = (((src) & 0x1f) * b) >> 5;
rgb = ((r1 << 11) | (g1 << 21) | b1) & RGB_565_UNPACKED_MASK;
d = RGB_565_UNPACK(*p_dst);
d = RGB_565_UNPACKED_BLEND(rgb, d, alpha);
*p_dst = RGB_565_PACK(d);
}
static inline void
@ -300,9 +310,9 @@ _soft16_pt_blend_solid_solid_mul_color_transp(DATA16 *p_dst, DATA16 src, DATA8 r
int r1, g1, b1;
DATA32 rgb, d;
r1 = ((((src) >> 11) & 0x1f) * r) >> 8;
g1 = ((((src) >> 5) & 0x3f) * g) >> 8;
b1 = (((src) & 0x1f) * b) >> 8;
r1 = ((((src) >> 11) & 0x1f) * r) >> 5;
g1 = ((((src) >> 5) & 0x3f) * g) >> 6;
b1 = (((src) & 0x1f) * b) >> 5;
rgb = ((r1 << 11) | (g1 << 21) | b1) & RGB_565_UNPACKED_MASK;
d = RGB_565_UNPACK(*p_dst);
@ -341,15 +351,15 @@ _soft16_scanline_blend_solid_solid_mul_color_transp(DATA16 *src, DATA16 *dst, in
* Blend operations with extra multiply color
*/
static inline void
_soft16_pt_blend_transp_solid_mul_color_solid(DATA16 *p_dst, DATA16 src, DATA8 alpha, DATA16 r, DATA16 g, DATA16 b)
_soft16_pt_blend_transp_solid_mul_color_solid(DATA16 *p_dst, DATA16 src, DATA8 alpha, DATA8 r, DATA8 g, DATA8 b)
{
int r1, g1, b1;
if (alpha == 0) return;
r1 = ((((src >> 11) & 0x1f) * r) >> 8) & 0x1f;
g1 = ((((src >> 5) & 0x3f) * g) >> 8) & 0x3f;
b1 = (((src & 0x1f) * b) >> 8) & 0x1f;
r1 = ((((src >> 11) & 0x1f) * r) >> 5) & 0x1f;
g1 = ((((src >> 5) & 0x3f) * g) >> 6) & 0x3f;
b1 = (((src & 0x1f) * b) >> 5) & 0x1f;
if (alpha == 31) *p_dst = (r1 << 11) | (g1 << 5) | b1;
else
@ -430,15 +440,15 @@ _soft16_pt_blend_solid_solid_mul_color_solid(DATA16 *p_dst, DATA16 src, DATA16 r
{
int r1, g1, b1;
r1 = ((((src >> 11) & 0x1f) * r) >> 8) & 0x1f;
g1 = ((((src >> 5) & 0x3f) * g) >> 8) & 0x3f;
b1 = (((src & 0x1f) * b) >> 8) & 0x1f;
r1 = ((((src >> 11) & 0x1f) * r) >> 5) & 0x1f;
g1 = ((((src >> 5) & 0x3f) * g) >> 6) & 0x3f;
b1 = (((src & 0x1f) * b) >> 5) & 0x1f;
*p_dst = (r1 << 11) | (g1 << 5) | b1;
}
static inline void
_soft16_scanline_blend_solid_solid_mul_color_solid(DATA16 *src, DATA16 *dst, int size, DATA16 r, DATA16 g, DATA16 b)
_soft16_scanline_blend_solid_solid_mul_color_solid(DATA16 *src, DATA16 *dst, int size, DATA8 r, DATA8 g, DATA8 b)
{
DATA16 *start, *end;