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:
On Tue, Jun 7, 2011 at 8:30 AM, Jon Rafkind <workmin@xxxxxxxxxx> wrote:
Actually looks like I forgot about the memory blenders. I updated the reference implementation in src/blenders.c. I didn't understand the comment about 'NaN or Inf * 0 is not 0'. Not that I don't believe this statement but I don't see why any Nan's or Inf's should be floating around.


I wonder if returning ALLEGRO_COLOR instead of just float is noticeable in ex_blend_bench. Would be interesting seeing the returned numbers with and without the patch. Likely not much difference and even if there is, this is just the reference implementation and not always used in general.

Also, an example using the new modes would be nice, so far I'm not sure what they do - best candidate is ex_blend2, just have to add the two new values to the drop-down box.
------------------------------------------------------------------------------ EditLive Enterprise is the world's most technically advanced content authoring tool. Experience the power of Track Changes, Inline Image Editing and ensure content is compliant with Accessibility Checking. http://p.sf.net/sfu/ephox-dev2dev

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/