Re: [AD] blender operations SRC and DST |
[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]
I changed the patch further: * altered internal/aintern_blend.h to deal with the new factors * al_blend_memory just calls _al_blend_inline now instead of having its own implementation of blending Here is ex_blend_bench before and after the patch (summary is 2-5% slowdown). I have a 1.8ghz amd processor. no change: Plain blit: 213.454 FPS Scaled blit: 213.883 FPS Rotated blit: 223.992 FPS my change: Plain blit: 201.183 FPS Scaled blit: 208.2 FPS Rotated blit: 214.747 FPS On 06/07/2011 06:57 AM, allefant wrote:
|
Index: include/allegro5/internal/aintern_blend.h =================================================================== --- include/allegro5/internal/aintern_blend.h (revision 14764) +++ include/allegro5/internal/aintern_blend.h (working copy) @@ -25,6 +25,7 @@ #ifndef _AL_NO_BLEND_INLINE_FUNC +#if 0 static _AL_ALWAYS_INLINE float get_factor(enum ALLEGRO_BLEND_MODE operation, float alpha) { @@ -37,28 +38,63 @@ ASSERT(false); return 0; /* silence warning in release build */ } +#endif +static _AL_ALWAYS_INLINE void get_factor(enum ALLEGRO_BLEND_MODE operation, const ALLEGRO_COLOR * source, const ALLEGRO_COLOR * dest, ALLEGRO_COLOR * factor) +{ + switch(operation) { + case ALLEGRO_ZERO: { + factor->r = factor->g = factor->b = factor->a = 0; + break; + } + case ALLEGRO_ONE: { + factor->r = factor->g = factor->b = factor->a = 1; + break; + } + case ALLEGRO_ALPHA: { + factor->r = factor->g = factor->b = factor->a = source->a; + break; + } + case ALLEGRO_INVERSE_ALPHA: { + factor->r = factor->g = factor->b = factor->a = 1 - source->a; + break; + } + case ALLEGRO_SRC_COLOR: { + *factor = *source; + break; + } + case ALLEGRO_DST_COLOR: { + *factor = *dest; + break; + } + default: { + ASSERT(false); + break; + } + } +} + static _AL_ALWAYS_INLINE void _al_blend_inline( const ALLEGRO_COLOR *scol, const ALLEGRO_COLOR *dcol, int op, int src_, int dst_, int aop, int asrc_, int adst_, ALLEGRO_COLOR *result) { - float src, dst, asrc, adst; + ALLEGRO_COLOR src, dst, asrc, adst; result->r = scol->r; result->g = scol->g; result->b = scol->b; result->a = scol->a; - src = get_factor(src_, result->a); - dst = get_factor(dst_, result->a); - asrc = get_factor(asrc_, result->a); - adst = get_factor(adst_, result->a); + get_factor(src_, scol, dcol, &src); + get_factor(dst_, scol, dcol, &dst); + get_factor(asrc_, scol, dcol, &asrc); + get_factor(adst_, scol, dcol, &adst); #define BLEND(c, src, dst) \ - result->c = OP(result->c * src, dcol->c * dst); + result->c = OP(result->c * src.c, dcol->c * dst.c); switch (op) { case ALLEGRO_ADD: #define OP(x, y) _ALLEGRO_MIN(1, x + y) Index: include/allegro5/bitmap.h =================================================================== --- include/allegro5/bitmap.h (revision 14764) +++ include/allegro5/bitmap.h (working copy) @@ -91,7 +91,9 @@ ALLEGRO_ZERO = 0, ALLEGRO_ONE = 1, ALLEGRO_ALPHA = 2, - ALLEGRO_INVERSE_ALPHA = 3 + ALLEGRO_INVERSE_ALPHA = 3, + ALLEGRO_SRC_COLOR = 4, + ALLEGRO_DST_COLOR = 5 }; enum ALLEGRO_BLEND_OPERATIONS { Index: src/blenders.c =================================================================== --- src/blenders.c (revision 14764) +++ src/blenders.c (working copy) @@ -18,6 +18,7 @@ #include "allegro5/allegro.h" #include "allegro5/internal/aintern.h" #include "allegro5/internal/aintern_bitmap.h" +#include "allegro5/internal/aintern_blend.h" #include "allegro5/internal/aintern_display.h" #include <string.h> @@ -25,17 +26,41 @@ #define MAX _ALLEGRO_MAX -static float get_factor(int operation, float alpha) +/* +static void get_factor(int operation, ALLEGRO_COLOR * source, ALLEGRO_COLOR * dest, ALLEGRO_COLOR * factor) { switch(operation) { - case ALLEGRO_ZERO: return 0; - case ALLEGRO_ONE: return 1; - case ALLEGRO_ALPHA: return alpha; - case ALLEGRO_INVERSE_ALPHA: return 1 - alpha; + case ALLEGRO_ZERO: { + factor->r = factor->g = factor->b = factor->a = 0; + break; + } + case ALLEGRO_ONE: { + factor->r = factor->g = factor->b = factor->a = 1; + break; + } + case ALLEGRO_ALPHA: { + factor->r = factor->g = factor->b = factor->a = source->a; + break; + } + case ALLEGRO_INVERSE_ALPHA: { + factor->r = factor->g = factor->b = factor->a = 1 - source->a; + break; + } + case ALLEGRO_SRC_COLOR: { + *factor = *source; + break; + } + case ALLEGRO_DST_COLOR: { + *factor = *dest; + break; + } + default: { + ASSERT(false); + break; + } } - ASSERT(false); - return 0; /* silence warning in release build */ } +*/ // FIXME: un-optimized reference implementation @@ -43,34 +68,48 @@ ALLEGRO_BITMAP *dest, int dx, int dy, ALLEGRO_COLOR *result) { - float src, dst, asrc, adst; - int op, src_, dst_, aop, asrc_, adst_; ALLEGRO_COLOR dcol; + int op, src_blend, dest_blend, alpha_op, alpha_src_blend, alpha_dest_blend; + dcol = al_get_pixel(dest, dx, dy); + al_get_separate_blender(&op, &src_blend, &dest_blend, + &alpha_op, &alpha_src_blend, &alpha_dest_blend); + _al_blend_inline(scol, &dcol, + op, src_blend, dest_blend, + alpha_op, alpha_src_blend, alpha_dest_blend, + result); + +#if 0 + ALLEGRO_COLOR src_factor, dest_factor; + ALLEGRO_COLOR alpha_src_factor, alpha_dest_factor; + int op, src_blend, dest_blend, alpha_op, alpha_src_blend, alpha_dest_blend; + ALLEGRO_COLOR dcol; + dcol = al_get_pixel(dest, dx, dy); - al_get_separate_blender(&op, &src_, &dst_, &aop, &asrc_, &adst_); + al_get_separate_blender(&op, &src_blend, &dest_blend, &alpha_op, &alpha_src_blend, &alpha_dest_blend); result->r = scol->r; result->g = scol->g; result->b = scol->b; result->a = scol->a; - src = get_factor(src_, result->a); - dst = get_factor(dst_, result->a); - asrc = get_factor(asrc_, result->a); - adst = get_factor(adst_, result->a); + get_factor(src_blend, scol, &dcol, &src_factor); + get_factor(dest_blend, scol, &dcol, &dest_factor); + get_factor(alpha_src_blend, scol, &dcol, &alpha_src_factor); + get_factor(alpha_dest_blend, scol, &dcol, &alpha_dest_factor); // FIXME: Better not do all those checks for each pixel but already // at the caller. // Note: Multiplying NaN or Inf with 0 doesn't give 0. - if (dst == 0) { + /* + if (dest == 0) { if (src == 0 || op == ALLEGRO_DEST_MINUS_SRC) { result->r = 0; result->g = 0; result->b = 0; } else { - result->r = result->r * src; - result->g = result->g * src; - result->b = result->b * src; + result->r = result->r * src_factor.r; + result->g = result->g * src_factor.g; + result->b = result->b * src_factor.b; } } else if (src == 0) { if (op == ALLEGRO_SRC_MINUS_DEST) { @@ -79,40 +118,46 @@ result->b = 0; } else { - result->r = dcol.r * dst; - result->g = dcol.g * dst; - result->b = dcol.b * dst; + result->r = dcol.r * dest_factor.r; + result->g = dcol.g * dest_factor.g; + result->b = dcol.b * dest_factor.b; } - } else if (op == ALLEGRO_ADD) { - result->r = MIN(1, result->r * src + dcol.r * dst); - result->g = MIN(1, result->g * src + dcol.g * dst); - result->b = MIN(1, result->b * src + dcol.b * dst); + } else + */ + if (op == ALLEGRO_ADD) { + result->r = MIN(1, result->r * src_factor.r + dcol.r * dest_factor.r); + result->g = MIN(1, result->g * src_factor.g + dcol.g * dest_factor.g); + result->b = MIN(1, result->b * src_factor.b + dcol.b * dest_factor.b); } else if (op == ALLEGRO_SRC_MINUS_DEST) { - result->r = MAX(0, result->r * src - dcol.r * dst); - result->g = MAX(0, result->g * src - dcol.g * dst); - result->b = MAX(0, result->b * src - dcol.b * dst); + result->r = MAX(0, result->r * src_factor.r - dcol.r * dest_factor.r); + result->g = MAX(0, result->g * src_factor.g - dcol.g * dest_factor.g); + result->b = MAX(0, result->b * src_factor.b - dcol.b * dest_factor.b); } else if (op == ALLEGRO_DEST_MINUS_SRC) { - result->r = MAX(0, dcol.r * dst - result->r * src); - result->g = MAX(0, dcol.g * dst - result->g * src); - result->b = MAX(0, dcol.b * dst - result->b * src); + result->r = MAX(0, dcol.r * dest_factor.r - result->r * src_factor.r); + result->g = MAX(0, dcol.g * dest_factor.g - result->g * src_factor.g); + result->b = MAX(0, dcol.b * dest_factor.b - result->b * src_factor.b); } + /* if (adst == 0) if (asrc == 0 || aop == ALLEGRO_DEST_MINUS_SRC) result->a = 0; else - result->a = result->a * asrc; + result->a = result->a * alpha_src_factor.a; else if (asrc == 0) if (aop == ALLEGRO_SRC_MINUS_DEST) result->a = 0; else - result->a = dcol.a * adst; - else if (aop == ALLEGRO_ADD) - result->a = MIN(1, result->a * asrc + dcol.a * adst); - else if (aop == ALLEGRO_SRC_MINUS_DEST) - result->a = MAX(0, result->a * asrc - dcol.a * adst); - else if (aop == ALLEGRO_DEST_MINUS_SRC) - result->a = MAX(0, dcol.a * adst - result->a * asrc); + result->a = dcol.a * alpha_dest_factor.a; + else + */ + if (alpha_op == ALLEGRO_ADD) + result->a = MIN(1, result->a * alpha_src_factor.a + dcol.a * alpha_dest_factor.a); + else if (alpha_op == ALLEGRO_SRC_MINUS_DEST) + result->a = MAX(0, result->a * alpha_src_factor.a - dcol.a * alpha_dest_factor.a); + else if (alpha_op == ALLEGRO_DEST_MINUS_SRC) + result->a = MAX(0, dcol.a * alpha_dest_factor.a - result->a * alpha_src_factor.a); +#endif } Index: src/opengl/ogl_bitmap.c =================================================================== --- src/opengl/ogl_bitmap.c (revision 14764) +++ src/opengl/ogl_bitmap.c (working copy) @@ -173,8 +173,9 @@ static INLINE bool setup_blending(ALLEGRO_DISPLAY *ogl_disp) { int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha; - const int blend_modes[4] = { - GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA + const int blend_modes[6] = { + GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, + GL_SRC_COLOR, GL_DST_COLOR }; const int blend_equations[3] = { GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT Index: src/win/d3d_disp.cpp =================================================================== --- src/win/d3d_disp.cpp (revision 14764) +++ src/win/d3d_disp.cpp (working copy) @@ -2049,20 +2049,24 @@ static int d3d_al_blender_to_d3d(int al_mode) { - int num_modes = 4; + int num_modes = 6; int allegro_modes[] = { ALLEGRO_ZERO, ALLEGRO_ONE, ALLEGRO_ALPHA, - ALLEGRO_INVERSE_ALPHA + ALLEGRO_INVERSE_ALPHA, + ALLEGRO_SRC_COLOR, + ALLEGRO_DST_COLOR }; int d3d_modes[] = { D3DBLEND_ZERO, D3DBLEND_ONE, D3DBLEND_SRCALPHA, - D3DBLEND_INVSRCALPHA + D3DBLEND_INVSRCALPHA, + D3DBLEND_SRCCOLOR, + D3DBLEND_DESTCCOLOR }; int i;
Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |