I'm working with DirectFB on arm platform and find what in some cases
blit-colorkeyed and blit-destination colorkeyed fails with alignment
trap. The patch attache fixes it, but  unfortunatelly it reduces
perfomance for about 20% (average).

diff -ur DirectFB-0.9.24/src/gfx/generic/generic.c DirectFB-0.9.24.fixed/src/gfx/generic/generic.c
--- DirectFB-0.9.24/src/gfx/generic/generic.c	2005-09-11 19:27:37.000000000 +0400
+++ DirectFB-0.9.24.fixed/src/gfx/generic/generic.c	2006-01-26 14:01:07.394680032 +0300
@@ -453,56 +453,62 @@
 {
      int    w;
      int    l    = gfxs->length;
-     __u32 *D    = gfxs->Aop;
-     __u32 *S    = gfxs->Bop;
      __u32  Skey = gfxs->Skey;
 
-     __u32 DSkey = (Skey << 16) | Skey;
+     if (((long)gfxs->Aop)&2) { /* Destination is not aligned */
+          __u16 *D    = gfxs->Aop;
+          __u16 *S    = gfxs->Bop;
 
-     if (((long)D)&2) {         /* align */
-          __u16 *tmp = gfxs->Aop;
-          --l;
-          if ((*((__u16*)S) & 0x7FFF) != Skey)
-               *tmp = *((__u16*)S);
-
-          D = (__u32*)((__u16*)D+1);
-          S = (__u32*)((__u16*)S+1);
+          while(l) {
+               if ((*S & 0x7FFF) != Skey)
+                    *D = *S;
+               ++S;
+               ++D;
+               --l;
+          }
      }
+     else {
 
-     w = (l >> 1);
-     while (w) {
-          __u32 dpixel = *S;
-          __u16 *tmp = (__u16*)D;
-
-          if ((dpixel & 0x7FFF7FFF) != DSkey) {
-               if ((dpixel & 0x7FFF0000) != (DSkey & 0x7FFF0000)) {
-                    if ((dpixel & 0x00007FFF) != (DSkey & 0x00007FFF)) {
-                         *D = dpixel;
-                    }
-                    else {
+          __u32 *D    = gfxs->Aop;
+          __u32 *S    = gfxs->Bop;
+
+          __u32 DSkey = (Skey << 16) | Skey;
+
+          w = (l >> 1);
+          while (w) {
+               __u32 dpixel = *S;
+               __u16 *tmp = (__u16*)D;
+
+               if ((dpixel & 0x7FFF7FFF) != DSkey) {
+                    if ((dpixel & 0x7FFF0000) != (DSkey & 0x7FFF0000)) {
+                         if ((dpixel & 0x00007FFF) != (DSkey & 0x00007FFF)) {
+                              *D = dpixel;
+                         }
+                         else {
 #ifdef WORDS_BIGENDIAN
-                         tmp[0] = (__u16)(dpixel >> 16);
+                              tmp[0] = (__u16)(dpixel >> 16);
 #else
-                         tmp[1] = (__u16)(dpixel >> 16);
+                              tmp[1] = (__u16)(dpixel >> 16);
 #endif
+                         }
                     }
-               }
-               else {
+                    else {
 #ifdef WORDS_BIGENDIAN
-                    tmp[1] = (__u16)dpixel;
+                         tmp[1] = (__u16)dpixel;
 #else
-                    tmp[0] = (__u16)dpixel;
+                         tmp[0] = (__u16)dpixel;
 #endif
+                    }
                }
+               ++S;
+               ++D;
+               --w;
           }
-          ++S;
-          ++D;
-          --w;
-     }
 
-     if (l & 1) {                 /* do the last potential pixel */
-          if ((*((__u16*)S) & 0x7FFF) != Skey)
-               *((__u16*)D) = *((__u16*)S);
+          if (l & 1) {                 /* do the last potential pixel */
+               if ((*((__u16*)S) & 0x7FFF) != Skey)
+                    *((__u16*)D) = *((__u16*)S);
+          }
      }
 }
 
@@ -510,56 +516,61 @@
 static void Bop_rgb16_Kto_Aop( GenefxState *gfxs )
 {
      int    w, l = gfxs->length;
-     __u32 *D    = gfxs->Aop;
-     __u32 *S    = gfxs->Bop;
      __u32  Skey = gfxs->Skey;
+     
+     if (((long)gfxs->Aop)&2) { /* Destination is not aligned */
+          __u16 *D    = gfxs->Aop;
+          __u16 *S    = gfxs->Bop;
 
-     __u32 DSkey = (Skey << 16) | Skey;
+          while(l) {
+               if (*S != Skey)
+                    *D = *S;
+               ++S;
+               ++D;
+               --l;
+          }
+     }
+     else {
+          __u32 *D    = gfxs->Aop;
+          __u32 *S    = gfxs->Bop;
 
-     if (((long)D)&2) {         /* align */
-          __u16 *tmp = gfxs->Aop;
-          --l;
-          if (*((__u16*)S) != Skey)
-               *tmp = *((__u16*)S);
+          __u32 DSkey = (Skey << 16) | Skey;
 
-          D = (__u32*)((__u16*)D+1);
-          S = (__u32*)((__u16*)S+1);
-     }
+          w = (l >> 1);
+          while (w) {
+               __u32 dpixel = *S;
+               __u16 *tmp = (__u16*)D;
 
-     w = (l >> 1);
-     while (w) {
-          __u32 dpixel = *S;
-          __u16 *tmp = (__u16*)D;
-
-          if (dpixel != DSkey) {
-               if ((dpixel & 0xFFFF0000) != (DSkey & 0xFFFF0000)) {
-                    if ((dpixel & 0x0000FFFF) != (DSkey & 0x0000FFFF)) {
-                         *D = dpixel;
-                    }
-                    else {
+               if (dpixel != DSkey) {
+                    if ((dpixel & 0xFFFF0000) != (DSkey & 0xFFFF0000)) {
+                         if ((dpixel & 0x0000FFFF) != (DSkey & 0x0000FFFF)) {
+                              *D = dpixel;
+                         }
+                         else {
 #ifdef WORDS_BIGENDIAN
-                         tmp[0] = (__u16)(dpixel >> 16);
+                              tmp[0] = (__u16)(dpixel >> 16);
 #else
-                         tmp[1] = (__u16)(dpixel >> 16);
+                              tmp[1] = (__u16)(dpixel >> 16);
 #endif
+                         }
                     }
-               }
-               else {
+                    else {
 #ifdef WORDS_BIGENDIAN
-                    tmp[1] = (__u16)dpixel;
+                         tmp[1] = (__u16)dpixel;
 #else
-                    tmp[0] = (__u16)dpixel;
+                         tmp[0] = (__u16)dpixel;
 #endif
+                    }
                }
+               ++S;
+               ++D;
+               --w;
           }
-          ++S;
-          ++D;
-          --w;
-     }
 
-     if (l & 1) {                 /* do the last potential pixel */
-          if (*((__u16*)S) != Skey)
-               *((__u16*)D) = *((__u16*)S);
+          if (l & 1) {                 /* do the last potential pixel */
+               if (*((__u16*)S) != Skey)
+                    *((__u16*)D) = *((__u16*)S);
+          }
      }
 }
 
@@ -865,109 +876,131 @@
 static void Bop_rgb15_toK_Aop( GenefxState *gfxs )
 {
      int    w, l = gfxs->length;
-     __u32 *D    = gfxs->Aop;
-     __u32 *S    = gfxs->Bop;
-     __u32  Lkey = gfxs->Dkey;
-     __u32  Hkey = Lkey << 16;
-
-     if (((long)D)&2) {         /* align */
-          __u16 *tmp = gfxs->Aop;
-          --l;
-          if (*((__u16*)D) == Lkey)
-               *tmp = *((__u16*)S);
 
-          D = (__u32*)((__u16*)D+1);
-          S = (__u32*)((__u16*)S+1);
+     if (((long)gfxs->Aop)&2) { /* Destination is not aligned */
+          __u16 *D    = gfxs->Aop;
+          __u16 *S    = gfxs->Bop;
+          __u32  Dkey = gfxs->Dkey;
+          
+          while(l) {
+               if (*D == Dkey)
+                    *D = *S;
+               ++S;
+               ++D;
+               --l;
+          }
      }
+     else {
 
-     w = (l >> 1);
-     while (w) {
-          __u32 dpixel = *D;
-
-          if ((dpixel & 0x7FFF0000) == Hkey) {
-               if ((dpixel & 0x00007FFF) == Lkey) {
-                    *D = *S;
-               }
-               else {
-                    __u16 *tmp = (__u16*)D;
+          __u32 *D    = gfxs->Aop;
+          __u32 *S    = gfxs->Bop;
+          __u32  Lkey = gfxs->Dkey;
+          __u32  Hkey = Lkey << 16;
+
+          w = (l >> 1);
+          while (w) {
+               __u32 dpixel = *D;
+
+               if ((dpixel & 0x7FFF0000) == Hkey) {
+                    if ((dpixel & 0x00007FFF) == Lkey) {
+                         *D = *S;
+                    }
+                    else {
+                         __u16 *tmp = (__u16*)D;
 #ifdef WORDS_BIGENDIAN
-                    tmp[0] = (__u16)(*S >> 16);
+                         tmp[0] = (__u16)(*S >> 16);
 #else
-                    tmp[1] = (__u16)(*S >> 16);
+                         tmp[1] = (__u16)(*S >> 16);
 #endif
+                    }
                }
-          }
-          else if ((dpixel & 0x00007FFF) == Lkey) {
-               __u16 *tmp = (__u16*)D;
+               else if ((dpixel & 0x00007FFF) == Lkey) {
+                    __u16 *tmp = (__u16*)D;
 #ifdef WORDS_BIGENDIAN
-               tmp[1] = (__u16)*S;
+                    tmp[1] = (__u16)*S;
 #else
-               tmp[0] = (__u16)*S;
+                    tmp[0] = (__u16)*S;
 #endif
+               }
+               ++S;
+               ++D;
+               --w;
           }
-          ++S;
-          ++D;
-          --w;
-     }
 
-     if (l & 1) {                 /* do the last potential pixel */
-          if (*((__u16*)D) == Lkey)
-               *((__u16*)D) = *((__u16*)S);
+          if (l & 1) {                 /* do the last potential pixel */
+               if (*((__u16*)D) == Lkey)
+                    *((__u16*)D) = *((__u16*)S);
+          }
      }
-
 }
 
 static void Bop_rgb16_toK_Aop( GenefxState *gfxs )
 {
      int    w, l = gfxs->length;
-     __u32 *D    = gfxs->Aop;
-     __u32 *S    = gfxs->Bop;
      __u32  Dkey = gfxs->Dkey;
 
-     __u32 DDkey = (Dkey << 16) | Dkey;
+     if (((long)gfxs->Aop)&2) { /* Destination is not aligned */
+          __u16 *D    = gfxs->Aop;
+          __u16 *S    = gfxs->Bop;
+          
+          while(l) {
+               if (*D == Dkey)
+                    *D = *S;
+               ++S;
+               ++D;
+               --l;
+          }
+     }
+     else {
+
+          __u32 *D    = gfxs->Aop;
+          __u32 *S    = gfxs->Bop;
 
-     if (((long)D)&2) {         /* align */
-          __u16 *tmp = gfxs->Aop;
-          --l;
-          if (*((__u16*)D) == Dkey)
-               *tmp = *((__u16*)S);
+          __u32 DDkey = (Dkey << 16) | Dkey;
 
-          D = (__u32*)((__u16*)D+1);
-          S = (__u32*)((__u16*)S+1);
-     }
+          if (((long)D)&2) {         /* align */
+               __u16 *tmp = gfxs->Aop;
+               --l;
+               if (*((__u16*)D) == Dkey)
+                    *tmp = *((__u16*)S);
 
-     w = (l >> 1);
-     while (w) {
-          __u32 dpixel = *D;
-          __u16 *tmp = (__u16*)D;
+               D = (__u32*)((__u16*)D+1);
+               S = (__u32*)((__u16*)S+1);
+          }
 
-          if ((dpixel & 0xFFFF0000) == (DDkey & 0xFFFF0000)) {
-               if ((dpixel & 0x0000FFFF) == (DDkey & 0x0000FFFF)) {
-                    *D = *S;
-               }
-               else {
+          w = (l >> 1);
+          while (w) {
+               __u32 dpixel = *D;
+               __u16 *tmp = (__u16*)D;
+
+               if ((dpixel & 0xFFFF0000) == (DDkey & 0xFFFF0000)) {
+                    if ((dpixel & 0x0000FFFF) == (DDkey & 0x0000FFFF)) {
+                         *D = *S;
+                    }
+                    else {
 #ifdef WORDS_BIGENDIAN
-                    tmp[0] = (__u16)(*S >> 16);
+                         tmp[0] = (__u16)(*S >> 16);
 #else
-                    tmp[1] = (__u16)(*S >> 16);
+                         tmp[1] = (__u16)(*S >> 16);
 #endif
+                    }
                }
-          }
-          else if ((dpixel & 0x0000FFFF) == (DDkey & 0x0000FFFF)) {
+               else if ((dpixel & 0x0000FFFF) == (DDkey & 0x0000FFFF)) {
 #ifdef WORDS_BIGENDIAN
-               tmp[1] = (__u16)*S;
+                    tmp[1] = (__u16)*S;
 #else
-               tmp[0] = (__u16)*S;
+                    tmp[0] = (__u16)*S;
 #endif
+               }
+               ++S;
+               ++D;
+               --w;
           }
-          ++S;
-          ++D;
-          --w;
-     }
 
-     if (l & 1) {                 /* do the last potential pixel */
-          if (*((__u16*)D) == Dkey)
-               *((__u16*)D) = *((__u16*)S);
+          if (l & 1) {                 /* do the last potential pixel */
+               if (*((__u16*)D) == Dkey)
+                    *((__u16*)D) = *((__u16*)S);
+          }
      }
 }
 

_______________________________________________
directfb-dev mailing list
[email protected]
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev

Reply via email to