GDK-DirectFB Patches



Hi,

here are a bunch of patches which improve the overall speed of GDK-DirectFB a lot
and also contain a few fixes. In our special test case the load was reduced by 70%,
speeding up tab switching 3.3 times!

The patches should be applied in the following order (probably skipping the two HACKs):

window_flip_group.patch
no_background_pixmap_fix.patch
blit_after_cairo_fix.patch
rect_clip_fix.patch
rgb16_default.patch
HACK_no_clear.patch
fast_blend.patch
opt_clip_region_and_fill_rects.patch
no_state_resets.patch
opt_temp_region_etc.patch
opt_temp_region2.patch
HACK_no_clear_area.patch


Another patch is for Cairo:

cairo_show_glyphs.patch


Each patch header has a description, here's an overview:

- window_flip_group.patch
GDK-DIRECTFB: During update processing, don't flip immediately, but accumulate a flipping region using the DirectFB
update manager and flush all Flip()s at the end of all painting. This results in a UI update In One Go [tm]!


- no_background_pixmap_fix.patch
GDK-DIRECTFB: Fix setting of NULL pixmaps resulting in a GDK_NO_BG setting. Probably GDK had an
API change at some point in time.


- blit_after_cairo_fix.patch
GDK-DIRECTFB: Fix wrong blitting flags being used by GDK after Cairo changed the state.


- rect_clip_fix.patch
GDK-DIRECTFB: Fix clipping rectangle for filling rectangles after Cairo has modified it.


- rgb16_default.patch
GDK-DIRECTFB: Use RGB16 format by default.


- HACK_no_clear.patch
GDK-DIRECTFB: Experimentally comment out the clear in gdk_window_impl_directfb_begin_paint_region().

This speeds up the test app without visual impact, but it might harm other (traditional?) apps.


- fast_blend.patch
GDK-DIRECTFB: Start with our own implementation of gdk_drawable_draw_pixbuf() based on the original.

First modifications are:
- No scratch image used, saving two copies.
- Replaced composite_565() implementation by an optimized version doing 32 bit wise I/O.

Clipping might need to be fixed.


- opt_clip_region_and_fill_rects.patch
GDK-DIRECTFB: Another small improvement by using FillRectangles() instead of FillRectangle().

Avoid a temporary memory allocation in gdk_directfb_clip_region().


- no_state_resets.patch
GDK-DIRECTFB: Don't set back states after drawing/blitting, just make sure they're correct before being used.


- opt_temp_region_etc.patch
GDK-DIRECTFB: Introduce temp_region functions and avoid temporary memory allocation in a lot of places.


- opt_temp_region2.patch
GDK-DIRECTFB: Changed remaining places where temp_region can be used. Added caching of the clip region during painting.


- HACK_no_clear_area.patch
GDK-DIRECTFB: Experimentally comment out the clear in _gdk_windowing_window_clear_area[_e] and don't invalidate in
show_window_internal().

This speeds up the test app without visual impact, but it might harm other (traditional?) apps.


- cairo_show_glyphs.patch
CAIRO-DIRECTFB: Use DirectFB for show_glyphs() even if it is unaccelerated.

The software fallback in DirectFB is well optimized.


-- 
Best regards,
  Denis Oliver Kropp

.------------------------------------------.
| DirectFB - Hardware accelerated graphics |
| http://www.directfb.org/                 |
"------------------------------------------"
GDK-DIRECTFB: Fix wrong blitting flags being used by GDK after Cairo changed the state.


diff -pur gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c	2007-07-16 21:46:15.000000000 +0200
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c	2007-11-24 19:21:01.000000000 +0100
@@ -613,6 +613,8 @@ gdk_directfb_draw_drawable (GdkDrawable 
 
   clip = gdk_directfb_clip_region (drawable, gc, &dest_rect);
 
+  impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
+
   for (i = 0; i < clip->numRects; i++)
     {
       DFBRegion reg = { clip->rects[i].x1,     clip->rects[i].y1,
@@ -853,6 +855,8 @@ gdk_directfb_draw_image (GdkDrawable *dr
 
       image_private->surface->Unlock (image_private->surface);
 
+      impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
+
       for (i = 0; i < clip->numRects; i++)
         {
           DFBRegion reg = { clip->rects[i].x1,     clip->rects[i].y1,
GDK-DIRECTFB: Start with our own implementation of gdk_drawable_draw_pixbuf() based on the original.

First modifications are:
- No scratch image used, saving two copies.
- Replaced composite_565() implementation by an optimized version doing 32 bit wise I/O.

Clipping might need to be fixed.


--- gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c	2007-11-29 04:56:27.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c	2007-11-29 04:52:42.000000000 +0100
@@ -39,6 +39,8 @@
 #include "gdkdirectfb.h"
 #include "gdkprivate-directfb.h"
 
+#include "../../gdk-pixbuf/gdk-pixbuf-private.h"
+
 #include "gdkinternals.h"
 
 
@@ -57,6 +59,66 @@
     }\
 }
 
+
+/* From DirectFB's <gfx/generix/duffs_device.h> */
+#define DUFF_1() \
+               case 1:\
+                    SET_PIXEL( D[0], S[0] );
+
+#define DUFF_2() \
+               case 3:\
+                    SET_PIXEL( D[2], S[2] );\
+               case 2:\
+                    SET_PIXEL( D[1], S[1] );\
+               DUFF_1()
+
+#define DUFF_3() \
+               case 7:\
+                    SET_PIXEL( D[6], S[6] );\
+               case 6:\
+                    SET_PIXEL( D[5], S[5] );\
+               case 5:\
+                    SET_PIXEL( D[4], S[4] );\
+               case 4:\
+                    SET_PIXEL( D[3], S[3] );\
+               DUFF_2()
+
+#define DUFF_4() \
+               case 15:\
+                    SET_PIXEL( D[14], S[14] );\
+               case 14:\
+                    SET_PIXEL( D[13], S[13] );\
+               case 13:\
+                    SET_PIXEL( D[12], S[12] );\
+               case 12:\
+                    SET_PIXEL( D[11], S[11] );\
+               case 11:\
+                    SET_PIXEL( D[10], S[10] );\
+               case 10:\
+                    SET_PIXEL( D[9], S[9] );\
+               case 9:\
+                    SET_PIXEL( D[8], S[8] );\
+               case 8:\
+                    SET_PIXEL( D[7], S[7] );\
+               DUFF_3()
+
+#define SET_PIXEL_DUFFS_DEVICE_N( D, S, w, n ) \
+do {\
+     while (w) {\
+          register int l = w & ((1 << n) - 1);\
+          switch (l) {\
+               default:\
+                    l = (1 << n);\
+                    SET_PIXEL( D[(1 << n)-1], S[(1 << n)-1] );\
+               DUFF_##n()\
+          }\
+          D += l;\
+          S += l;\
+          w -= l;\
+     }\
+} while(0)
+
+
 static GdkScreen * gdk_directfb_get_screen (GdkDrawable    *drawable);
 static void gdk_drawable_impl_directfb_class_init (GdkDrawableImplDirectFBClass *klass);
 static void gdk_directfb_draw_lines (GdkDrawable *drawable,
@@ -71,6 +133,18 @@ static gboolean  accelerated_alpha_blend
 static gpointer  parent_class               = NULL;
 static const cairo_user_data_key_t gdk_directfb_cairo_key;
 
+static void (*real_draw_pixbuf) (GdkDrawable *drawable,
+                                 GdkGC       *gc,
+                                 GdkPixbuf   *pixbuf,
+                                 gint         src_x,
+                                 gint         src_y,
+                                 gint         dest_x,
+                                 gint         dest_y,
+                                 gint         width,
+                                 gint         height,
+                                 GdkRgbDither dither,
+                                 gint         x_dither,
+                                 gint         y_dither);
 
 /**********************************************************
  * DirectFB specific implementations of generic functions *
@@ -879,6 +953,479 @@ gdk_directfb_draw_image (GdkDrawable *dr
   gdk_region_destroy (clip);
 }
 
+static void
+composite (guchar *src_buf,
+           gint    src_rowstride,
+           guchar *dest_buf,
+           gint    dest_rowstride,
+           gint    width,
+           gint    height)
+{
+  guchar *src = src_buf;
+  guchar *dest = dest_buf;
+
+  while (height--)
+    {
+      gint twidth = width;
+      guchar *p = src;
+      guchar *q = dest;
+
+      while (twidth--)
+        {
+          guchar a = p[3];
+          guint t;
+
+          t = a * p[0] + (255 - a) * q[0] + 0x80;
+          q[0] = (t + (t >> 8)) >> 8;
+          t = a * p[1] + (255 - a) * q[1] + 0x80;
+          q[1] = (t + (t >> 8)) >> 8;
+          t = a * p[2] + (255 - a) * q[2] + 0x80;
+          q[2] = (t + (t >> 8)) >> 8;
+
+          p += 4;
+          q += 3;
+        }
+      
+      src += src_rowstride;
+      dest += dest_rowstride;
+    }
+}
+
+static void
+composite_0888 (guchar      *src_buf,
+                gint         src_rowstride,
+                guchar      *dest_buf,
+                gint         dest_rowstride,
+                GdkByteOrder dest_byte_order,
+                gint         width,
+                gint         height)
+{
+  guchar *src = src_buf;
+  guchar *dest = dest_buf;
+
+  while (height--)
+    {
+      gint twidth = width;
+      guchar *p = src;
+      guchar *q = dest;
+
+      if (dest_byte_order == GDK_LSB_FIRST)
+        {
+          while (twidth--)
+            {
+              guint t;
+              
+              t = p[3] * p[2] + (255 - p[3]) * q[0] + 0x80;
+              q[0] = (t + (t >> 8)) >> 8;
+              t = p[3] * p[1] + (255 - p[3]) * q[1] + 0x80;
+              q[1] = (t + (t >> 8)) >> 8;
+              t = p[3] * p[0] + (255 - p[3]) * q[2] + 0x80;
+              q[2] = (t + (t >> 8)) >> 8;
+              p += 4;
+              q += 4;
+            }
+        }
+      else
+        {
+          while (twidth--)
+            {
+              guint t;
+              
+              t = p[3] * p[0] + (255 - p[3]) * q[1] + 0x80;
+              q[1] = (t + (t >> 8)) >> 8;
+              t = p[3] * p[1] + (255 - p[3]) * q[2] + 0x80;
+              q[2] = (t + (t >> 8)) >> 8;
+              t = p[3] * p[2] + (255 - p[3]) * q[3] + 0x80;
+              q[3] = (t + (t >> 8)) >> 8;
+              p += 4;
+              q += 4;
+            }
+        }
+      
+      src += src_rowstride;
+      dest += dest_rowstride;
+    }
+}
+
+/* change the last value to adjust the size of the device (1-4) */
+#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \
+     SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 2 )
+
+/* From DirectFB's gfx/generic/generic.c" */
+#define SET_PIXEL( D, S )                    \
+     switch (S >> 26) {                      \
+          case 0:                            \
+               break;                        \
+          case 0x3f:                         \
+               D = ((S <<  8) & 0xF800) |    \
+                   ((S >>  5) & 0x07E0) |    \
+                   ((S >> 19) & 0x001F);     \
+               break;                        \
+          default:                           \
+               D = (((( (((S<<8) & 0xf800) | ((S>>19) & 0x001f))                                    \
+                        - (D & 0xf81f)) * ((S>>26)+1) + ((D & 0xf81f)<<6)) & 0x003e07c0)            \
+                      +                                                                             \
+                    ((( ((S>>5) & 0x07e0)                                                           \
+                        - (D & 0x07e0)) * ((S>>26)+1) + ((D & 0x07e0)<<6)) & 0x0001f800)) >> 6;     \
+     }
+
+static void
+composite_565 (guchar      *src_buf,
+               gint         src_rowstride,
+               guchar      *dest_buf,
+               gint         dest_rowstride,
+               GdkByteOrder dest_byte_order,
+               gint         width,
+               gint         height)
+{
+#if 1
+     while (height--) {
+          int  w = width;
+          u16 *D = (u16*) dest_buf;
+          u32 *S = (u32*) src_buf;
+#if 1
+          if ((unsigned long)D & 2) {
+               SET_PIXEL( D[0], S[0] );
+               w--;
+               D++;
+               S++;
+          }
+
+          int  i;
+          int  w2  = w / 2;
+          u32 *D32 = (u32*) D;
+
+          for (i=0; i<w2; i++) {
+               register u32 S0 = S[(i << 1) + 0];
+               register u32 S1 = S[(i << 1) + 1];
+
+               if ((S0 >> 26) == 0x3f && (S1 >> 26) == 0x3f) {
+                    D32[i] = ((S0 <<  8) & 0x0000F800) |
+                             ((S0 >>  5) & 0x000007E0) |
+                             ((S0 >> 19) & 0x0000001F) |
+                             ((S1 << 24) & 0xF8000000) |
+                             ((S1 << 11) & 0x07E00000) |
+                             ((S1 >>  3) & 0x001F0000);
+               }
+               else {
+                    SET_PIXEL( D[(i << 1) + 0], S0 );
+                    SET_PIXEL( D[(i << 1) + 1], S1 );
+               }
+          }
+
+          if (w & 1)
+               SET_PIXEL( D[w-1], S[w-1] );
+#else
+          SET_PIXEL_DUFFS_DEVICE( D, S, w );
+#endif
+
+          dest_buf += dest_rowstride;
+          src_buf += src_rowstride;
+     }
+#else
+  guchar *src = src_buf;
+  guchar *dest = dest_buf;
+
+  while (height--)
+    {
+      gint twidth = width;
+      guchar *p = src;
+      gushort *q = (gushort *)dest;
+
+      while (twidth--)
+        {
+          guchar a = p[3];
+          guint tr, tg, tb;
+          guint tr1, tg1, tb1;
+          guint tmp = *q;
+
+#if 1
+          /* This is fast, and corresponds to what composite() above does
+           * if we converted to 8-bit first.
+           */
+          tr = (tmp & 0xf800);
+          tr1 = a * p[0] + (255 - a) * ((tr >> 8) + (tr >> 13)) + 0x80;
+          tg = (tmp & 0x07e0);
+          tg1 = a * p[1] + (255 - a) * ((tg >> 3) + (tg >> 9)) + 0x80;
+          tb = (tmp & 0x001f);
+          tb1 = a * p[2] + (255 - a) * ((tb << 3) + (tb >> 2)) + 0x80;
+
+          *q = (((tr1 + (tr1 >> 8)) & 0xf800) |
+                (((tg1 + (tg1 >> 8)) & 0xfc00) >> 5)  |
+                ((tb1 + (tb1 >> 8)) >> 11));
+#else
+          /* This version correspond to the result we get with XRENDER -
+           * a bit of precision is lost since we convert to 8 bit after premultiplying
+           * instead of at the end
+           */
+          guint tr2, tg2, tb2;
+          guint tr3, tg3, tb3;
+          
+          tr = (tmp & 0xf800);
+          tr1 = (255 - a) * ((tr >> 8) + (tr >> 13)) + 0x80;
+          tr2 = a * p[0] + 0x80;
+          tr3 = ((tr1 + (tr1 >> 8)) >> 8) + ((tr2 + (tr2 >> 8)) >> 8);
+
+          tg = (tmp & 0x07e0);
+          tg1 = (255 - a) * ((tg >> 3) + (tg >> 9)) + 0x80;
+          tg2 = a * p[0] + 0x80;
+          tg3 = ((tg1 + (tg1 >> 8)) >> 8) + ((tg2 + (tg2 >> 8)) >> 8);
+
+          tb = (tmp & 0x001f);
+          tb1 = (255 - a) * ((tb << 3) + (tb >> 2)) + 0x80;
+          tb2 = a * p[0] + 0x80;
+          tb3 = ((tb1 + (tb1 >> 8)) >> 8) + ((tb2 + (tb2 >> 8)) >> 8);
+
+          *q = (((tr3 & 0xf8) << 8) |
+                ((tg3 & 0xfc) << 3) |
+                ((tb3 >> 3)));
+#endif
+          p += 4;
+          q++;
+        }
+      
+      src += src_rowstride;
+      dest += dest_rowstride;
+    }
+#endif          
+}
+
+#undef SET_PIXEL
+#undef SET_PIXEL_DUFFS_DEVICE
+
+static void
+gdk_directfb_draw_pixbuf (GdkDrawable  *drawable,
+                          GdkGC        *gc,
+                          GdkPixbuf    *pixbuf,
+                          gint          src_x,
+                          gint          src_y,
+                          gint          dest_x,
+                          gint          dest_y,
+                          gint          width,
+                          gint          height,
+                          GdkRgbDither  dither,
+                          gint          x_dither,
+                          gint          y_dither)
+{
+  GdkPixbuf *composited = NULL;
+  gint dwidth, dheight;
+  GdkRegion *clip;
+  GdkRegion *drect;
+  GdkRectangle tmp_rect;
+
+  g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
+  g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB);
+  g_return_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4);
+  g_return_if_fail (pixbuf->bits_per_sample == 8);
+
+  g_return_if_fail (drawable != NULL);
+
+  if (width == -1) 
+    width = pixbuf->width;
+  if (height == -1)
+    height = pixbuf->height;
+
+  g_return_if_fail (width >= 0 && height >= 0);
+  g_return_if_fail (src_x >= 0 && src_x + width <= pixbuf->width);
+  g_return_if_fail (src_y >= 0 && src_y + height <= pixbuf->height);
+
+  /* Clip to the drawable; this is required for get_from_drawable() so
+   * can't be done implicitly
+   */
+  
+  if (dest_x < 0)
+    {
+      src_x -= dest_x;
+      width += dest_x;
+      dest_x = 0;
+    }
+
+  if (dest_y < 0)
+    {
+      src_y -= dest_y;
+      height += dest_y;
+      dest_y = 0;
+    }
+
+  gdk_drawable_get_size (drawable, &dwidth, &dheight);
+
+  if ((dest_x + width) > dwidth)
+    width = dwidth - dest_x;
+
+  if ((dest_y + height) > dheight)
+    height = dheight - dest_y;
+
+  if (width <= 0 || height <= 0)
+    return;
+
+  /* Clip to the clip region; this avoids getting more
+   * image data from the server than we need to.
+   */
+  
+  tmp_rect.x = dest_x;
+  tmp_rect.y = dest_y;
+  tmp_rect.width = width;
+  tmp_rect.height = height;
+
+  drect = gdk_region_rectangle (&tmp_rect);
+  clip = gdk_drawable_get_clip_region (drawable);
+
+  gdk_region_intersect (drect, clip);
+
+  gdk_region_get_clipbox (drect, &tmp_rect);
+  
+  gdk_region_destroy (drect);
+  gdk_region_destroy (clip);
+
+  if (tmp_rect.width == 0 ||
+      tmp_rect.height == 0)
+    return;
+  
+  /* Actually draw */
+  if (!gc)
+    gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
+  
+  if (pixbuf->has_alpha)
+    {
+      GdkVisual *visual = gdk_drawable_get_visual (drawable);
+      void (*composite_func) (guchar       *src_buf,
+                              gint          src_rowstride,
+                              guchar       *dest_buf,
+                              gint          dest_rowstride,
+                              GdkByteOrder  dest_byte_order,
+                              gint          width,
+                              gint          height) = NULL;
+
+      /* First we see if we have a visual-specific composition function that can composite
+       * the pixbuf data directly onto the image
+       */
+      if (visual)
+        {
+          gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (gdk_drawable_get_display (drawable),
+                                                                   visual->depth);
+          
+          if (visual->byte_order == (G_BYTE_ORDER == G_BIG_ENDIAN ? GDK_MSB_FIRST : GDK_LSB_FIRST) &&
+              visual->depth == 16 &&
+              visual->red_mask   == 0xf800 &&
+              visual->green_mask == 0x07e0 &&
+              visual->blue_mask  == 0x001f)
+            composite_func = composite_565;
+          else if (visual->depth == 24 && bits_per_pixel == 32 &&
+                   visual->red_mask   == 0xff0000 &&
+                   visual->green_mask == 0x00ff00 &&
+                   visual->blue_mask  == 0x0000ff)
+            composite_func = composite_0888;
+        }
+
+      /* We can't use our composite func if we are required to dither
+       */
+      if (composite_func && !(dither == GDK_RGB_DITHER_MAX && visual->depth != 24))
+        {
+#if 0
+          gint x0, y0;
+          for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT)
+            {
+              gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT);
+              for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH)
+                {
+                  gint xs0, ys0;
+                  
+                  gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH);
+                  
+                  GdkImage *image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable),
+                                                            width1, height1,
+                                                            gdk_drawable_get_depth (drawable), &xs0, &ys0);
+                  
+                  gdk_drawable_copy_to_image (drawable, image,
+                                              dest_x + x0, dest_y + y0,
+                                              xs0, ys0,
+                                              width1, height1);
+                  (*composite_func) (pixbuf->pixels + (src_y + y0) * pixbuf->rowstride + (src_x + x0) * 4,
+                                     pixbuf->rowstride,
+                                     (guchar*)image->mem + ys0 * image->bpl + xs0 * image->bpp,
+                                     image->bpl,
+                                     visual->byte_order,
+                                     width1, height1);
+                  gdk_draw_image (drawable, gc, image,
+                                  xs0, ys0,
+                                  dest_x + x0, dest_y + y0,
+                                  width1, height1);
+                }
+            }
+#else
+          void                    *data;
+          int                      pitch;
+          GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
+
+          if (impl->surface->Lock( impl->surface, DSLF_READ | DSLF_WRITE, &data, &pitch ) == DFB_OK) {
+               (*composite_func) (pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
+                                  pixbuf->rowstride,
+                                  data + dest_y * pitch + DFB_BYTES_PER_LINE( impl->format, dest_x ),
+                                  pitch,
+                                  visual->byte_order,
+                                  width, height);
+
+               impl->surface->Unlock( impl->surface );
+          }
+#endif          
+          goto out;
+        }
+      else
+        {
+          /* No special composition func, convert dest to 24 bit RGB data, composite against
+           * that, and convert back.
+           */
+          composited = gdk_pixbuf_get_from_drawable (NULL,
+                                                     drawable,
+                                                     NULL,
+                                                     dest_x, dest_y,
+                                                     0, 0,
+                                                     width, height);
+          
+          if (composited)
+            composite (pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
+                       pixbuf->rowstride,
+                       composited->pixels,
+                       composited->rowstride,
+                       width, height);
+        }
+    }
+
+  if (composited)
+    {
+      src_x = 0;
+      src_y = 0;
+      pixbuf = composited;
+    }
+  
+  if (pixbuf->n_channels == 4)
+    {
+      guchar *buf = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4;
+
+      gdk_draw_rgb_32_image_dithalign (drawable, gc,
+                                       dest_x, dest_y,
+                                       width, height,
+                                       dither,
+                                       buf, pixbuf->rowstride,
+                                       x_dither, y_dither);
+    }
+  else                                /* n_channels == 3 */
+    {
+      guchar *buf = pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 3;
+
+      gdk_draw_rgb_image_dithalign (drawable, gc,
+                                    dest_x, dest_y,
+                                    width, height,
+                                    dither,
+                                    buf, pixbuf->rowstride,
+                                    x_dither, y_dither);
+    }
+
+ out:
+  if (composited)
+    g_object_unref (composited);
+}
+
 static inline void
 convert_rgba_pixbuf_to_image (guint32 *src,
                               guint    src_pitch,
@@ -982,6 +1529,10 @@ gdk_drawable_impl_directfb_class_init (G
   drawable_class->_copy_to_image = _gdk_directfb_copy_to_image;
         drawable_class->get_screen = gdk_directfb_get_screen;
 
+
+  real_draw_pixbuf = drawable_class->draw_pixbuf;
+  drawable_class->draw_pixbuf = gdk_directfb_draw_pixbuf;
+
   /* check for hardware-accelerated alpha-blending */
   {
     DFBGraphicsDeviceDescription desc;
GDK-DIRECTFB: Experimentally comment out the clear in gdk_window_impl_directfb_begin_paint_region().

This speeds up the test app without visual impact, but it might harm other (traditional?) apps.


diff -pur gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkwindow-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c	2007-11-24 20:59:56.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkwindow-directfb.c	2007-11-24 20:26:01.000000000 +0100
@@ -2987,7 +2987,7 @@ gdk_window_impl_directfb_begin_paint_reg
   else
     impl->paint_region = gdk_region_copy (region);
 
-  for (i = 0; i < region->numRects; i++)
+/*  for (i = 0; i < region->numRects; i++)
     {
       GdkRegionBox *box = &region->rects[i];
 
@@ -2997,7 +2997,7 @@ gdk_window_impl_directfb_begin_paint_reg
                                         box->x2 - box->x1,
                                         box->y2 - box->y1);
                                         
-    }
+    }*/
 }
 
 static void
GDK-DIRECTFB: Experimentally comment out the clear in _gdk_windowing_window_clear_area[_e] and don't invalidate in show_window_internal().

This speeds up the test app without visual impact, but it might harm other (traditional?) apps.


diff -pur gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkwindow-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c	2007-11-29 20:22:18.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkwindow-directfb.c	2007-11-29 20:20:20.000000000 +0100
@@ -1124,7 +1124,7 @@ show_window_internal (GdkWindow *window,
           if (private->input_only)
             return;
 
-          gdk_window_invalidate_rect (window, NULL, TRUE);
+//          gdk_window_invalidate_rect (window, NULL, TRUE);
         }
     }
 
@@ -1528,7 +1528,7 @@ _gdk_windowing_window_clear_area (GdkWin
   GdkGC                   *gc = NULL;
   gint                     dx = 0;
   gint                     dy = 0;
-
+return;
   g_return_if_fail (GDK_IS_WINDOW (window));
 
   if (GDK_WINDOW_DESTROYED (window))
@@ -1603,6 +1603,7 @@ _gdk_windowing_window_clear_area_e (GdkW
   GdkRectangle  rect;
   GdkWindowObject       *private;
   GdkWindowImplDirectFB *impl;
+return;
 
   g_return_if_fail (GDK_IS_WINDOW (window));
 
GDK-DIRECTFB: Fix setting of NULL pixmaps resulting in a GDK_NO_BG setting. Probably GDK had an
API change at some point in time.


diff -pur gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkwindow-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c	2007-11-24 18:02:29.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkwindow-directfb.c	2007-11-24 17:59:40.000000000 +0100
@@ -1819,10 +1820,15 @@ gdk_window_set_back_pixmap (GdkWindow *w
     }
   else
     {
-      if (pixmap && pixmap != GDK_NO_BG && pixmap != GDK_PARENT_RELATIVE_BG)
-        g_object_ref (pixmap);
-
-      private->bg_pixmap = pixmap;
+      if (pixmap)
+        {
+          g_object_ref (pixmap);
+          private->bg_pixmap = pixmap;
+        }
+      else
+        {
+          private->bg_pixmap = GDK_NO_BG;
+        }
     }
 }
 
GDK-DIRECTFB: Don't set back states after drawing/blitting, just make sure they're correct before being used.


--- gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c	2007-11-29 06:14:37.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c	2007-11-29 06:13:04.000000000 +0100
@@ -489,6 +489,8 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
                    gc_private->values.tile)
             {
               surface = GDK_DRAWABLE_IMPL_DIRECTFB (GDK_PIXMAP_OBJECT (gc_private->values.tile)->impl)->surface;
+
+              impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
             }
         }
 
@@ -507,9 +509,6 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
               impl->surface->SetClip (impl->surface, &reg);
               impl->surface->TileBlit (impl->surface, surface, NULL, x, y);
             }
-
-          impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
-          impl->surface->SetClip (impl->surface, NULL);
         }
       else  /* normal rectangle filling */
         {
@@ -543,7 +542,6 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
           X draws the rectangle one pixel taller and wider.  */
       impl->surface->DrawRectangle (impl->surface,
                                     x, y, width , height);
-      impl->surface->SetClip (impl->surface, NULL);
     }
 }
 
@@ -603,7 +601,6 @@ gdk_directfb_draw_polygon (GdkDrawable *
                                              points[2].x, points[2].y);
 
               }
-            impl->surface->SetClip (impl->surface, NULL);
             gdk_region_destroy (clip);
 
             return;
@@ -706,7 +703,6 @@ gdk_directfb_draw_drawable (GdkDrawable 
       impl->surface->Blit (impl->surface, src_impl->surface, &rect,
                            xdest, ydest);
     }
-  impl->surface->SetClip (impl->surface, NULL);
   gdk_region_destroy (clip);
 }
 
@@ -788,8 +784,6 @@ gdk_directfb_draw_segments (GdkDrawable 
       impl->surface->DrawLines (impl->surface, (DFBRegion *)segs, nsegs);
     }
 
-  impl->surface->SetClip (impl->surface, NULL);
-
   gdk_region_destroy (clip);
 
   /* everything below can be omitted if the drawing is buffered */
@@ -896,8 +890,6 @@ gdk_directfb_draw_lines (GdkDrawable *dr
       impl->surface->DrawLines (impl->surface, lines, npoints - 1);
     }
 
-  impl->surface->SetClip (impl->surface, NULL);
-
   gdk_region_destroy (clip);
 }
 
@@ -949,7 +941,6 @@ gdk_directfb_draw_image (GdkDrawable *dr
                                image_private->surface, &src_rect,
                                xdest, ydest);
         }
-      impl->surface->SetClip (impl->surface, NULL);
 
       image_private->surface->Lock (image_private->surface, DSLF_WRITE,
                                     &image->mem, &pitch);
GDK-DIRECTFB: Another small improvement by using FillRectangles() instead of FillRectangle().

Avoid a temporary memory allocation in gdk_directfb_clip_region().


--- gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c	2007-11-29 05:52:00.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c	2007-11-29 05:49:42.000000000 +0100
@@ -279,7 +279,12 @@ gdk_directfb_clip_region (GdkDrawable  *
       GDK_WINDOW_IS_MAPPED (private->wrapper) &&
       !GDK_WINDOW_OBJECT (private->wrapper)->input_only)
     {
-      GList *cur;
+      GList     *cur;
+      GdkRegion  temp;
+
+      temp.numRects = 1;
+      temp.rects = &temp.extents;
+      temp.size = 1;
 
       for (cur = GDK_WINDOW_OBJECT (private->wrapper)->children;
            cur;
@@ -295,14 +300,12 @@ gdk_directfb_clip_region (GdkDrawable  *
 
           cur_impl = GDK_DRAWABLE_IMPL_DIRECTFB (cur_private->impl);
 
-          rect.x      = cur_private->x;
-          rect.y      = cur_private->y;
-          rect.width  = cur_impl->width;
-          rect.height = cur_impl->height;
-
-          tmpreg = gdk_region_rectangle (&rect);
-          gdk_region_subtract (clip_region, tmpreg);
-          gdk_region_destroy (tmpreg);
+          temp.extents.x1 = cur_private->x;
+          temp.extents.y1 = cur_private->y;
+          temp.extents.x2 = cur_private->x + cur_impl->width;
+          temp.extents.y2 = cur_private->y + cur_impl->height;
+
+          gdk_region_subtract (clip_region, &temp);
         }
     }
 
@@ -510,18 +513,21 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
         }
       else  /* normal rectangle filling */
         {
+          DFBRectangle rects[clip->numRects];
+
           impl->surface->SetClip (impl->surface, NULL);
 
           for (i = 0; i < clip->numRects; i++)
             {
-              DFBRegion *region = (DFBRegion *) &clip->rects[i];
+              GdkRegionBox *box = &clip->rects[i];
 
-              impl->surface->FillRectangle (impl->surface,
-                                            region->x1,
-                                            region->y1,
-                                            region->x2 - region->x1,
-                                            region->y2 - region->y1);
+              rects[i].x = box->x1;
+              rects[i].y = box->y1;
+              rects[i].w = box->x2 - box->x1;
+              rects[i].h = box->y2 - box->y1;
             }
+
+          impl->surface->FillRectangles(impl->surface, rects, clip->numRects);
         }
 
       gdk_region_destroy (clip);
GDK-DIRECTFB: Changed remaining places where temp_region can be used. Added caching of the clip region during painting.


diff -pur gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c	2007-11-29 13:11:46.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c	2007-11-29 13:04:02.000000000 +0100
@@ -220,7 +220,7 @@ gdk_directfb_get_visual (GdkDrawable *dr
 /* Calculates the real clipping region for a drawable, taking into account
  * other windows and the gc clip region.
  */
-static void
+void
 gdk_directfb_clip_region (GdkDrawable  *drawable,
                           GdkGC        *gc,
                           GdkRectangle *draw_rect,
@@ -247,15 +247,15 @@ gdk_directfb_clip_region (GdkDrawable  *
 
   temp_region_init_rectangle( ret_clip, draw_rect );
 
-  if (private->buffered && private->paint_region.numRects)
+  if (private->buffered)
     gdk_region_intersect (ret_clip, &private->paint_region);
 
   if (gc)
     {
       GdkGCDirectFB *gc_private = GDK_GC_DIRECTFB (gc);
-      GdkRegion     *region     = gc_private->clip_region;
+      GdkRegion     *region     = &gc_private->clip_region;
 
-      if (region)
+      if (region->numRects)
         {
           if (gc->clip_x_origin || gc->clip_y_origin)
             {
@@ -274,6 +274,9 @@ gdk_directfb_clip_region (GdkDrawable  *
         return;
     }
 
+  if (private->buffered)
+    return;
+
   if (GDK_IS_WINDOW (private->wrapper) &&
       GDK_WINDOW_IS_MAPPED (private->wrapper) &&
       !GDK_WINDOW_OBJECT (private->wrapper)->input_only)
@@ -761,7 +764,7 @@ gdk_directfb_draw_segments (GdkDrawable 
   GdkRegion                clip;
   gint                     i;
 
-  DFBRegion region = { segs->x1, segs->y1, segs->x2, segs->y2 };
+//  DFBRegion region = { segs->x1, segs->y1, segs->x2, segs->y2 };
 
   if (nsegs < 1)
     return;
@@ -786,7 +789,7 @@ gdk_directfb_draw_segments (GdkDrawable 
   temp_region_deinit( &clip );
 
   /* everything below can be omitted if the drawing is buffered */
-  if (impl->buffered)
+/*  if (impl->buffered)
     return;
 
   if (region.x1 > region.x2)
@@ -824,7 +827,7 @@ gdk_directfb_draw_segments (GdkDrawable 
         region.y2 = segs->y1;
       if (segs->y2 > region.y2)
         region.y2 = segs->y2;
-    }
+    }*/
 }
 
 static void
diff -pur gtk+-2.10.14/gdk/directfb/gdkgc-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkgc-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkgc-directfb.c	2007-07-16 21:46:15.000000000 +0200
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkgc-directfb.c	2007-11-29 11:26:25.000000000 +0100
@@ -111,8 +111,8 @@ gdk_gc_directfb_finalize (GObject *objec
   GdkGC         *gc      = GDK_GC (object);
   GdkGCDirectFB *private = GDK_GC_DIRECTFB (gc);
 
-  if (private->clip_region)
-    gdk_region_destroy (private->clip_region);
+  if (private->clip_region.numRects)
+    temp_region_deinit (&private->clip_region);
   if (private->values.clip_mask)
     g_object_unref (private->values.clip_mask);
   if (private->values.stipple)
@@ -260,11 +260,7 @@ gdk_directfb_gc_set_values (GdkGC       
       if (oldpm)
         g_object_unref (oldpm);
 
-      if (private->clip_region)
-        {
-          gdk_region_destroy (private->clip_region);
-          private->clip_region = NULL;
-        }
+      temp_region_reset (&private->clip_region);
     }
 
   if (values_mask & GDK_GC_SUBWINDOW)
@@ -361,17 +357,13 @@ _gdk_windowing_gc_set_clip_region (GdkGC
 
   data = GDK_GC_DIRECTFB (gc);
 
-  if (region == data->clip_region)
+  if (region == &data->clip_region)
     return;
 
-  if (data->clip_region)
-    {
-      gdk_region_destroy (data->clip_region);
-      data->clip_region = NULL;
-    }
-
   if (region)
-    data->clip_region = gdk_region_copy (region);
+       temp_region_init_copy (&data->clip_region, region);
+  else
+       temp_region_reset (&data->clip_region);
 
   gc->clip_x_origin = 0;
   gc->clip_y_origin = 0;
@@ -392,8 +384,7 @@ _gdk_windowing_gc_copy (GdkGC *dst_gc,
 
   dst_private = GDK_GC_DIRECTFB (dst_gc);
 
-  if (dst_private->clip_region)
-    gdk_region_destroy(dst_private->clip_region);
+  temp_region_reset(&dst_private->clip_region);
 
   if (dst_private->values_mask & GDK_GC_FONT)
     gdk_font_unref (dst_private->values.font);
@@ -413,8 +404,6 @@ _gdk_windowing_gc_copy (GdkGC *dst_gc,
     g_object_ref (dst_private->values.stipple);
   if (dst_private->values_mask & GDK_GC_CLIP_MASK)
     g_object_ref (dst_private->values.clip_mask);
-  if (dst_private->clip_region)
-    dst_private->clip_region = gdk_region_copy (dst_private->clip_region);
 }
 
 /**
diff -pur gtk+-2.10.14/gdk/directfb/gdkprivate-directfb.h gtk+-2.10.14-hacked/gdk/directfb/gdkprivate-directfb.h
--- gtk+-2.10.14/gdk/directfb/gdkprivate-directfb.h	2007-11-29 13:11:46.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkprivate-directfb.h	2007-11-29 12:57:40.000000000 +0100
@@ -79,6 +79,8 @@ struct _GdkDrawableImplDirectFB
   gint                    abs_x;
   gint                    abs_y;
 
+  GdkRegion               clip_region;
+
   GdkColormap            *colormap;
 
   IDirectFBSurface       *surface;
@@ -211,7 +213,7 @@ typedef struct
 {
   GdkGC             parent_instance;
 
-  GdkRegion        *clip_region;
+  GdkRegion         clip_region;
 
   GdkGCValuesMask   values_mask;
   GdkGCValues       values;
@@ -324,6 +326,10 @@ void gdk_fb_window_set_child_handler (Gd
                                       GdkWindowChildGetPos   get_pos,
                                       gpointer               user_data);
 
+void gdk_directfb_clip_region (GdkDrawable  *drawable,
+                               GdkGC        *gc,
+                               GdkRectangle *draw_rect,
+                               GdkRegion    *ret_clip);
 
 
 /* Utilities for avoiding mallocs */
@@ -395,8 +401,12 @@ temp_region_reset( GdkRegion *region )
 static inline void
 temp_region_deinit( GdkRegion *region )
 {
-     if (region->rects && region->rects != &region->extents)
+     if (region->rects && region->rects != &region->extents) {
           g_free( region->rects );
+          region->rects = NULL;
+     }
+
+     region->numRects = 0;
 }
 
 
diff -pur gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkwindow-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c	2007-11-29 13:11:46.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkwindow-directfb.c	2007-11-29 13:06:33.000000000 +0100
@@ -2963,16 +2963,29 @@ gdk_window_impl_directfb_begin_paint_reg
   g_assert (region != NULL );
   wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable);
   impl = (GdkDrawableImplDirectFB *)wimpl;
-  impl->buffered = TRUE;
-  impl->paint_depth++;
 
   if (!region)
     return;
 
-  if (impl->paint_region.numRects)
-    gdk_region_union (&impl->paint_region, region);
-  else
-    temp_region_init_copy( &impl->paint_region, region );
+  if (impl->buffered) {
+       g_assert( impl->paint_depth > 0 );
+
+       gdk_region_union (&impl->paint_region, region);
+  }
+  else {
+       g_assert( impl->paint_depth == 0 );
+
+       gdk_directfb_clip_region( GDK_DRAWABLE(paintable), NULL, NULL, &impl->clip_region );
+
+       temp_region_init_copy( &impl->paint_region, region );
+
+       impl->buffered = TRUE;
+  }
+
+  gdk_region_intersect (&impl->paint_region, &impl->clip_region);
+
+  impl->paint_depth++;
+
 
 /*  for (i = 0; i < region->numRects; i++)
     {
@@ -2996,6 +3009,8 @@ gdk_window_impl_directfb_end_paint (GdkP
 
   g_return_if_fail (impl->paint_depth > 0);
 
+  g_assert( impl->buffered );
+
   impl->paint_depth--;
 
 #ifdef NO_EXPERIMENTS
@@ -3019,6 +3034,8 @@ gdk_window_impl_directfb_end_paint (GdkP
   if (impl->paint_depth == 0) {
        impl->buffered = FALSE;
 
+       temp_region_deinit( &impl->clip_region );
+
        if (impl->paint_region.numRects) {
             GdkWindow *window = GDK_WINDOW( impl->wrapper );
 
GDK-DIRECTFB: Introduce temp_region functions and avoid temporary memory allocation in a lot of places.


diff -pur gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c	2007-11-29 11:05:37.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c	2007-11-29 10:51:35.000000000 +0100
@@ -146,6 +146,7 @@ static void (*real_draw_pixbuf) (GdkDraw
                                  gint         x_dither,
                                  gint         y_dither);
 
+
 /**********************************************************
  * DirectFB specific implementations of generic functions *
  **********************************************************/
@@ -219,18 +220,18 @@ gdk_directfb_get_visual (GdkDrawable *dr
 /* Calculates the real clipping region for a drawable, taking into account
  * other windows and the gc clip region.
  */
-static GdkRegion *
+static void
 gdk_directfb_clip_region (GdkDrawable  *drawable,
                           GdkGC        *gc,
-                          GdkRectangle *draw_rect)
+                          GdkRectangle *draw_rect,
+                          GdkRegion    *ret_clip)
 {
   GdkDrawableImplDirectFB *private;
-  GdkRegion               *clip_region;
-  GdkRegion               *tmpreg;
   GdkRectangle             rect;
 
-  g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);
-  g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_DIRECTFB (drawable), NULL);
+  g_return_if_fail (GDK_IS_DRAWABLE (drawable));
+  g_return_if_fail (GDK_IS_DRAWABLE_IMPL_DIRECTFB (drawable));
+  g_return_if_fail (ret_clip != NULL);
 
   private = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
 
@@ -244,10 +245,10 @@ gdk_directfb_clip_region (GdkDrawable  *
       draw_rect = &rect;
     }
 
-  clip_region = gdk_region_rectangle (draw_rect);
+  temp_region_init_rectangle( ret_clip, draw_rect );
 
-  if (private->buffered && private->paint_region)
-    gdk_region_intersect (clip_region, private->paint_region);
+  if (private->buffered && private->paint_region.numRects)
+    gdk_region_intersect (ret_clip, &private->paint_region);
 
   if (gc)
     {
@@ -258,21 +259,19 @@ gdk_directfb_clip_region (GdkDrawable  *
         {
           if (gc->clip_x_origin || gc->clip_y_origin)
             {
-              tmpreg = gdk_region_copy (region);
-
-              gdk_region_offset (tmpreg, gc->clip_x_origin, gc->clip_y_origin);
-              gdk_region_intersect (clip_region, tmpreg);
-              gdk_region_destroy (tmpreg);
+              gdk_region_offset (ret_clip, -gc->clip_x_origin, -gc->clip_y_origin);
+              gdk_region_intersect (ret_clip, region);
+              gdk_region_offset (ret_clip, gc->clip_x_origin, gc->clip_y_origin);
             }
           else
             {
-              gdk_region_intersect (clip_region, region);
+              gdk_region_intersect (ret_clip, region);
             }
         }
 
       if (gc_private->values_mask & GDK_GC_SUBWINDOW &&
           gc_private->values.subwindow_mode == GDK_INCLUDE_INFERIORS)
-        return clip_region;
+        return;
     }
 
   if (GDK_IS_WINDOW (private->wrapper) &&
@@ -305,11 +304,9 @@ gdk_directfb_clip_region (GdkDrawable  *
           temp.extents.x2 = cur_private->x + cur_impl->width;
           temp.extents.y2 = cur_private->y + cur_impl->height;
 
-          gdk_region_subtract (clip_region, &temp);
+          gdk_region_subtract (ret_clip, &temp);
         }
     }
-
-  return clip_region;
 }
 
 /* Drawing
@@ -405,7 +402,7 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
                               gint         height)
 {
   GdkDrawableImplDirectFB *impl;
-  GdkRegion               *clip;
+  GdkRegion                clip;
   GdkGCDirectFB           *gc_private = NULL;
   IDirectFBSurface        *surface    = NULL;
   gint  i;
@@ -469,7 +466,7 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
     {
       GdkRectangle  rect = { x, y, width, height };
 
-      clip = gdk_directfb_clip_region (drawable, gc, &rect);
+      gdk_directfb_clip_region (drawable, gc, &rect, &clip);
 
       if (gc_private && gc_private->values_mask & GDK_GC_FILL)
         {
@@ -501,10 +498,10 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
           if (gc_private->values_mask & GDK_GC_TS_Y_ORIGIN)
             y = gc_private->values.ts_y_origin;
 
-          for (i = 0; i < clip->numRects; i++)
+          for (i = 0; i < clip.numRects; i++)
             {
-              DFBRegion reg = { clip->rects[i].x1,     clip->rects[i].y1,
-                                clip->rects[i].x2, clip->rects[i].y2 };
+              DFBRegion reg = { clip.rects[i].x1,     clip.rects[i].y1,
+                                clip.rects[i].x2, clip.rects[i].y2 };
 
               impl->surface->SetClip (impl->surface, &reg);
               impl->surface->TileBlit (impl->surface, surface, NULL, x, y);
@@ -512,13 +509,13 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
         }
       else  /* normal rectangle filling */
         {
-          DFBRectangle rects[clip->numRects];
+          DFBRectangle rects[clip.numRects];
 
           impl->surface->SetClip (impl->surface, NULL);
 
-          for (i = 0; i < clip->numRects; i++)
+          for (i = 0; i < clip.numRects; i++)
             {
-              GdkRegionBox *box = &clip->rects[i];
+              GdkRegionBox *box = &clip.rects[i];
 
               rects[i].x = box->x1;
               rects[i].y = box->y1;
@@ -526,10 +523,10 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
               rects[i].h = box->y2 - box->y1;
             }
 
-          impl->surface->FillRectangles(impl->surface, rects, clip->numRects);
+          impl->surface->FillRectangles(impl->surface, rects, clip.numRects);
         }
 
-      gdk_region_destroy (clip);
+      temp_region_deinit( &clip );
     }
   else
     {
@@ -579,7 +576,7 @@ gdk_directfb_draw_polygon (GdkDrawable *
                                  points[0].y == points[npoints-1].y))
           {
             GdkDrawableImplDirectFB *impl;
-            GdkRegion               *clip;
+            GdkRegion                clip;
             gint                     i;
 
             impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
@@ -587,12 +584,12 @@ gdk_directfb_draw_polygon (GdkDrawable *
             if (!gdk_directfb_setup_for_drawing (impl, GDK_GC_DIRECTFB (gc)))
               return;
 
-            clip = gdk_directfb_clip_region (drawable, gc, NULL);
+            gdk_directfb_clip_region (drawable, gc, NULL, &clip);
 
-            for (i = 0; i < clip->numRects; i++)
+            for (i = 0; i < clip.numRects; i++)
               {
-                                DFBRegion reg = { clip->rects[i].x1,     clip->rects[i].y1, 
-                    clip->rects[i].x2 , clip->rects[i].y2  };
+                                DFBRegion reg = { clip.rects[i].x1,     clip.rects[i].y1, 
+                    clip.rects[i].x2 , clip.rects[i].y2  };
 
                 impl->surface->SetClip (impl->surface, &reg);
                 impl->surface->FillTriangle (impl->surface,
@@ -601,7 +598,8 @@ gdk_directfb_draw_polygon (GdkDrawable *
                                              points[2].x, points[2].y);
 
               }
-            gdk_region_destroy (clip);
+
+            temp_region_deinit( &clip );
 
             return;
           }
@@ -667,7 +665,7 @@ gdk_directfb_draw_drawable (GdkDrawable 
 {
   GdkDrawableImplDirectFB *impl;
   GdkDrawableImplDirectFB *src_impl;
-  GdkRegion               *clip;
+  GdkRegion                clip;
   GdkRectangle             dest_rect = { xdest,
                                          ydest,
                 xdest + width ,
@@ -690,20 +688,21 @@ gdk_directfb_draw_drawable (GdkDrawable 
   else
     return;
 
-  clip = gdk_directfb_clip_region (drawable, gc, &dest_rect);
+  gdk_directfb_clip_region (drawable, gc, &dest_rect, &clip);
 
   impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
 
-  for (i = 0; i < clip->numRects; i++)
+  for (i = 0; i < clip.numRects; i++)
     {
-      DFBRegion reg = { clip->rects[i].x1,     clip->rects[i].y1,
-                        clip->rects[i].x2 , clip->rects[i].y2 };
+      DFBRegion reg = { clip.rects[i].x1,     clip.rects[i].y1,
+                        clip.rects[i].x2 , clip.rects[i].y2 };
 
       impl->surface->SetClip (impl->surface, &reg);
       impl->surface->Blit (impl->surface, src_impl->surface, &rect,
                            xdest, ydest);
     }
-  gdk_region_destroy (clip);
+
+  temp_region_deinit( &clip );
 }
 
 static void
@@ -713,7 +712,7 @@ gdk_directfb_draw_points (GdkDrawable *d
                           gint         npoints)
 {
   GdkDrawableImplDirectFB *impl;
-  GdkRegion               *clip;
+  GdkRegion                clip;
 
   DFBRegion region = { points->x, points->y, points->x, points->y };
 
@@ -725,11 +724,11 @@ gdk_directfb_draw_points (GdkDrawable *d
   if (!gdk_directfb_setup_for_drawing (impl, GDK_GC_DIRECTFB (gc)))
     return;
 
-  clip = gdk_directfb_clip_region (drawable, gc, NULL);
+  gdk_directfb_clip_region (drawable, gc, NULL, &clip);
 
   while (npoints > 0)
     {
-      if (gdk_region_point_in (clip, points->x, points->y))
+      if (gdk_region_point_in (&clip, points->x, points->y))
         {
           impl->surface->FillRectangle (impl->surface,
                                         points->x, points->y, 1, 1);
@@ -749,7 +748,7 @@ gdk_directfb_draw_points (GdkDrawable *d
       points++;
     }
 
-  gdk_region_destroy (clip);
+  temp_region_deinit( &clip );
 }
 
 static void
@@ -759,7 +758,7 @@ gdk_directfb_draw_segments (GdkDrawable 
                             gint         nsegs)
 {
   GdkDrawableImplDirectFB *impl;
-  GdkRegion               *clip;
+  GdkRegion                clip;
   gint                     i;
 
   DFBRegion region = { segs->x1, segs->y1, segs->x2, segs->y2 };
@@ -772,19 +771,19 @@ gdk_directfb_draw_segments (GdkDrawable 
   if (!gdk_directfb_setup_for_drawing (impl, GDK_GC_DIRECTFB (gc)))
     return;
 
-  clip = gdk_directfb_clip_region (drawable, gc, NULL);
+  gdk_directfb_clip_region (drawable, gc, NULL, &clip);
 
-  for (i = 0; i < clip->numRects; i++)
+  for (i = 0; i < clip.numRects; i++)
     {
-      DFBRegion reg = { clip->rects[i].x1,   clip->rects[i].y1,
-                        clip->rects[i].x2, clip->rects[i].y2 };
+      DFBRegion reg = { clip.rects[i].x1,   clip.rects[i].y1,
+                        clip.rects[i].x2, clip.rects[i].y2 };
 
       impl->surface->SetClip (impl->surface, &reg);
 
       impl->surface->DrawLines (impl->surface, (DFBRegion *)segs, nsegs);
     }
 
-  gdk_region_destroy (clip);
+  temp_region_deinit( &clip );
 
   /* everything below can be omitted if the drawing is buffered */
   if (impl->buffered)
@@ -835,7 +834,7 @@ gdk_directfb_draw_lines (GdkDrawable *dr
                          gint         npoints)
 {
   GdkDrawableImplDirectFB *impl;
-  GdkRegion               *clip;
+  GdkRegion                clip;
   gint                     i;
 
   DFBRegion lines[npoints > 1 ? npoints - 1 : 1];
@@ -879,18 +878,18 @@ gdk_directfb_draw_lines (GdkDrawable *dr
   lines[i].x2 = points->x;
   lines[i].y2 = points->y;
 
-  clip = gdk_directfb_clip_region (drawable, gc, NULL);
+  gdk_directfb_clip_region (drawable, gc, NULL, &clip);
 
-  for (i = 0; i < clip->numRects; i++)
+  for (i = 0; i < clip.numRects; i++)
     {
-      DFBRegion reg = { clip->rects[i].x1,   clip->rects[i].y1,
-                        clip->rects[i].x2, clip->rects[i].y2 };
+      DFBRegion reg = { clip.rects[i].x1,   clip.rects[i].y1,
+                        clip.rects[i].x2, clip.rects[i].y2 };
 
       impl->surface->SetClip (impl->surface, &reg);
       impl->surface->DrawLines (impl->surface, lines, npoints - 1);
     }
 
-  gdk_region_destroy (clip);
+  temp_region_deinit( &clip );
 }
 
 static void
@@ -906,7 +905,7 @@ gdk_directfb_draw_image (GdkDrawable *dr
 {
   GdkDrawableImplDirectFB *impl;
   GdkImageDirectFB        *image_private;
-  GdkRegion               *clip;
+  GdkRegion                clip;
   GdkRectangle             dest_rect = { xdest, ydest, width, height };
 
   gint pitch = 0;
@@ -921,9 +920,9 @@ gdk_directfb_draw_image (GdkDrawable *dr
   if (!impl->surface)
     return;
 
-  clip = gdk_directfb_clip_region (drawable, gc, &dest_rect);
+  gdk_directfb_clip_region (drawable, gc, &dest_rect, &clip);
 
-  if (!gdk_region_empty (clip))
+  if (!gdk_region_empty (&clip))
     {
       DFBRectangle  src_rect = { xsrc, ysrc, width, height };
 
@@ -931,10 +930,10 @@ gdk_directfb_draw_image (GdkDrawable *dr
 
       impl->surface->SetBlittingFlags (impl->surface, DSBLIT_NOFX);
 
-      for (i = 0; i < clip->numRects; i++)
+      for (i = 0; i < clip.numRects; i++)
         {
-          DFBRegion reg = { clip->rects[i].x1,     clip->rects[i].y1,
-                            clip->rects[i].x2 , clip->rects[i].y2  };
+          DFBRegion reg = { clip.rects[i].x1,     clip.rects[i].y1,
+                            clip.rects[i].x2 , clip.rects[i].y2  };
 
           impl->surface->SetClip (impl->surface, &reg);
           impl->surface->Blit (impl->surface,
@@ -947,7 +946,7 @@ gdk_directfb_draw_image (GdkDrawable *dr
       image->bpl = pitch;
     }
 
-  gdk_region_destroy (clip);
+  temp_region_deinit( &clip );
 }
 
 static void
@@ -1075,7 +1074,6 @@ composite_565 (guchar      *src_buf,
                gint         width,
                gint         height)
 {
-#if 1
      while (height--) {
           int  w = width;
           u16 *D = (u16*) dest_buf;
@@ -1119,72 +1117,6 @@ composite_565 (guchar      *src_buf,
           dest_buf += dest_rowstride;
           src_buf += src_rowstride;
      }
-#else
-  guchar *src = src_buf;
-  guchar *dest = dest_buf;
-
-  while (height--)
-    {
-      gint twidth = width;
-      guchar *p = src;
-      gushort *q = (gushort *)dest;
-
-      while (twidth--)
-        {
-          guchar a = p[3];
-          guint tr, tg, tb;
-          guint tr1, tg1, tb1;
-          guint tmp = *q;
-
-#if 1
-          /* This is fast, and corresponds to what composite() above does
-           * if we converted to 8-bit first.
-           */
-          tr = (tmp & 0xf800);
-          tr1 = a * p[0] + (255 - a) * ((tr >> 8) + (tr >> 13)) + 0x80;
-          tg = (tmp & 0x07e0);
-          tg1 = a * p[1] + (255 - a) * ((tg >> 3) + (tg >> 9)) + 0x80;
-          tb = (tmp & 0x001f);
-          tb1 = a * p[2] + (255 - a) * ((tb << 3) + (tb >> 2)) + 0x80;
-
-          *q = (((tr1 + (tr1 >> 8)) & 0xf800) |
-                (((tg1 + (tg1 >> 8)) & 0xfc00) >> 5)  |
-                ((tb1 + (tb1 >> 8)) >> 11));
-#else
-          /* This version correspond to the result we get with XRENDER -
-           * a bit of precision is lost since we convert to 8 bit after premultiplying
-           * instead of at the end
-           */
-          guint tr2, tg2, tb2;
-          guint tr3, tg3, tb3;
-          
-          tr = (tmp & 0xf800);
-          tr1 = (255 - a) * ((tr >> 8) + (tr >> 13)) + 0x80;
-          tr2 = a * p[0] + 0x80;
-          tr3 = ((tr1 + (tr1 >> 8)) >> 8) + ((tr2 + (tr2 >> 8)) >> 8);
-
-          tg = (tmp & 0x07e0);
-          tg1 = (255 - a) * ((tg >> 3) + (tg >> 9)) + 0x80;
-          tg2 = a * p[0] + 0x80;
-          tg3 = ((tg1 + (tg1 >> 8)) >> 8) + ((tg2 + (tg2 >> 8)) >> 8);
-
-          tb = (tmp & 0x001f);
-          tb1 = (255 - a) * ((tb << 3) + (tb >> 2)) + 0x80;
-          tb2 = a * p[0] + 0x80;
-          tb3 = ((tb1 + (tb1 >> 8)) >> 8) + ((tb2 + (tb2 >> 8)) >> 8);
-
-          *q = (((tr3 & 0xf8) << 8) |
-                ((tg3 & 0xfc) << 3) |
-                ((tb3 >> 3)));
-#endif
-          p += 4;
-          q++;
-        }
-      
-      src += src_rowstride;
-      dest += dest_rowstride;
-    }
-#endif          
 }
 
 #undef SET_PIXEL
@@ -1205,10 +1137,12 @@ gdk_directfb_draw_pixbuf (GdkDrawable  *
                           gint          y_dither)
 {
   GdkPixbuf *composited = NULL;
-  gint dwidth, dheight;
+#if 0
   GdkRegion *clip;
   GdkRegion *drect;
   GdkRectangle tmp_rect;
+#endif
+  GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
 
   g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
   g_return_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB);
@@ -1244,17 +1178,16 @@ gdk_directfb_draw_pixbuf (GdkDrawable  *
       dest_y = 0;
     }
 
-  gdk_drawable_get_size (drawable, &dwidth, &dheight);
-
-  if ((dest_x + width) > dwidth)
-    width = dwidth - dest_x;
+  if ((dest_x + width) > impl->width)
+    width = impl->width - dest_x;
 
-  if ((dest_y + height) > dheight)
-    height = dheight - dest_y;
+  if ((dest_y + height) > impl->height)
+    height = impl->height - dest_y;
 
   if (width <= 0 || height <= 0)
     return;
 
+#if 0
   /* Clip to the clip region; this avoids getting more
    * image data from the server than we need to.
    */
@@ -1277,11 +1210,34 @@ gdk_directfb_draw_pixbuf (GdkDrawable  *
   if (tmp_rect.width == 0 ||
       tmp_rect.height == 0)
     return;
-  
+#endif
+
+  if (pixbuf->has_alpha && impl->format == DSPF_RGB16) {
+       void *data;
+       int   pitch;
+
+       if (impl->surface->Lock( impl->surface, DSLF_READ | DSLF_WRITE, &data, &pitch ) == DFB_OK) {
+            composite_565( pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
+                           pixbuf->rowstride,
+                           data + dest_y * pitch + dest_x * 2,
+                           pitch,
+                         #if G_BYTE_ORDER == G_BIG_ENDIAN
+                           GDK_MSB_FIRST,
+                         #else
+                           GDK_LSB_FIRST,
+                         #endif
+                           width, height );
+
+            impl->surface->Unlock( impl->surface );
+
+            return;
+       }
+  }
+
   /* Actually draw */
   if (!gc)
     gc = _gdk_drawable_get_scratch_gc (drawable, FALSE);
-  
+
   if (pixbuf->has_alpha)
     {
       GdkVisual *visual = gdk_drawable_get_visual (drawable);
@@ -1350,9 +1306,8 @@ gdk_directfb_draw_pixbuf (GdkDrawable  *
                 }
             }
 #else
-          void                    *data;
-          int                      pitch;
-          GdkDrawableImplDirectFB *impl = GDK_DRAWABLE_IMPL_DIRECTFB (drawable);
+          void *data;
+          int   pitch;
 
           if (impl->surface->Lock( impl->surface, DSLF_READ | DSLF_WRITE, &data, &pitch ) == DFB_OK) {
                (*composite_func) (pixbuf->pixels + src_y * pixbuf->rowstride + src_x * 4,
diff -pur gtk+-2.10.14/gdk/directfb/gdkprivate-directfb.h gtk+-2.10.14-hacked/gdk/directfb/gdkprivate-directfb.h
--- gtk+-2.10.14/gdk/directfb/gdkprivate-directfb.h	2007-11-29 11:05:37.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkprivate-directfb.h	2007-11-29 11:01:59.000000000 +0100
@@ -38,8 +38,11 @@
 #include "gdkinternals.h"
 #include "gdkcursor.h"
 #include "gdkdisplay-directfb.h"
+#include "gdkregion-generic.h"
 #include <cairo.h>
 
+#include <string.h>
+
 #include <directfb_util.h>
 
 
@@ -69,7 +72,7 @@ struct _GdkDrawableImplDirectFB
 
   gboolean                buffered;
 
-  GdkRegion              *paint_region;
+  GdkRegion               paint_region;
   gint                    paint_depth;
   gint                    width;
   gint                    height;
@@ -322,4 +325,79 @@ void gdk_fb_window_set_child_handler (Gd
                                       gpointer               user_data);
 
 
+
+/* Utilities for avoiding mallocs */
+
+static inline void
+temp_region_init_copy( GdkRegion       *region, 
+                       const GdkRegion *source)
+{
+  if (region != source) /*  don't want to copy to itself */
+    {  
+      if (region->size < source->numRects)
+        {
+          if (region->rects && region->rects != &region->extents)
+            g_free( region->rects );
+
+          region->rects = g_new (GdkRegionBox, source->numRects);
+          region->size  = source->numRects;
+        }
+
+      region->numRects = source->numRects;
+      region->extents  = source->extents;
+
+      memcpy( region->rects, source->rects, source->numRects * sizeof (GdkRegionBox) );
+    }
+}
+
+static inline void
+temp_region_init_rectangle( GdkRegion          *region,
+                            const GdkRectangle *rect )
+{
+     region->numRects = 1;
+     region->rects = &region->extents;
+     region->extents.x1 = rect->x;
+     region->extents.y1 = rect->y;
+     region->extents.x2 = rect->x + rect->width;
+     region->extents.y2 = rect->y + rect->height;
+     region->size = 1;
+}
+
+static inline void
+temp_region_init_rectangle_vals( GdkRegion *region,
+                                 int        x,
+                                 int        y,
+                                 int        w,
+                                 int        h )
+{
+     region->numRects = 1;
+     region->rects = &region->extents;
+     region->extents.x1 = x;
+     region->extents.y1 = y;
+     region->extents.x2 = x + w;
+     region->extents.y2 = y + h;
+     region->size = 1;
+}
+
+static inline void
+temp_region_reset( GdkRegion *region )
+{
+     if (region->size > 32 && region->rects && region->rects != &region->extents) {
+          g_free( region->rects );
+
+          region->size  = 1;
+          region->rects = &region->extents;
+     }
+
+     region->numRects = 0;
+}
+
+static inline void
+temp_region_deinit( GdkRegion *region )
+{
+     if (region->rects && region->rects != &region->extents)
+          g_free( region->rects );
+}
+
+
 #endif /* __GDK_PRIVATE_DIRECTFB_H__ */
diff -pur gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkwindow-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c	2007-11-29 11:05:37.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkwindow-directfb.c	2007-11-29 11:00:56.000000000 +0100
@@ -372,7 +372,7 @@ _gdk_windowing_window_init (void)
   private->window_type = GDK_WINDOW_ROOT;
   private->state       = 0;
   private->children    = NULL;
-  impl->drawable.paint_region   = NULL;
+//  impl->drawable.paint_region   = NULL;
   impl->gdkWindow      = _gdk_parent_root;
   impl->window           = NULL;
   impl->drawable.abs_x   = 0;
@@ -2804,9 +2804,9 @@ gdk_window_set_urgency_hint (GdkWindow *
 
 static void
 gdk_window_impl_directfb_invalidate_maybe_recurse (GdkPaintable *paintable,
-                         GdkRegion    *region,
-                         gboolean    (*child_func) (GdkWindow *, gpointer),
-                         gpointer      user_data)
+                                                   GdkRegion    *region,
+                                                   gboolean    (*child_func) (GdkWindow *, gpointer),
+                                                   gpointer      user_data)
 {
   GdkWindow *window;
   GdkWindowObject *private;
@@ -2818,7 +2818,7 @@ gdk_window_impl_directfb_invalidate_mayb
   window = wimpl->gdkWindow;
   private = (GdkWindowObject *)window;
 
-  GdkRegion *visible_region;
+  GdkRegion visible_region;
   GList *tmp_list;
 
   g_return_if_fail (window != NULL);
@@ -2830,69 +2830,65 @@ gdk_window_impl_directfb_invalidate_mayb
   if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
     return;
 
-  visible_region = gdk_drawable_get_visible_region (window);
-  gdk_region_intersect (visible_region, region);
+  temp_region_init_rectangle_vals( &visible_region, 0, 0, impl->width, impl->height );
+  gdk_region_intersect (&visible_region, region);
 
   tmp_list = private->children;
   while (tmp_list)
     {
-      GdkWindowObject *child = tmp_list->data;
+      GdkWindowObject         *child = tmp_list->data;
+      GdkDrawableImplDirectFB *cimpl = (GdkDrawableImplDirectFB *) child->impl;
       
       if (!child->input_only)
-	{
-	  GdkRegion *child_region;
-	  GdkRectangle child_rect;
-	  
-	  gdk_window_get_position ((GdkWindow *)child,
-				   &child_rect.x, &child_rect.y);
-	  gdk_drawable_get_size ((GdkDrawable *)child,
-				 &child_rect.width, &child_rect.height);
-
-	  child_region = gdk_region_rectangle (&child_rect);
-	  
-	  /* remove child area from the invalid area of the parent */
-	  if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped)
-	    gdk_region_subtract (visible_region, child_region);
-	  
-	  if (child_func && (*child_func) ((GdkWindow *)child, user_data))
-	    {
-	      gdk_region_offset (region, - child_rect.x, - child_rect.y);
-	      gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
-	      gdk_region_intersect (child_region, region);
-	      
-	      gdk_window_invalidate_maybe_recurse ((GdkWindow *)child,
-						   child_region, child_func, user_data);
-	      
-	      gdk_region_offset (region, child_rect.x, child_rect.y);
-	    }
+        {
+          GdkRegion child_region;
+          
+          temp_region_init_rectangle_vals( &child_region, child->x, child->y, cimpl->width, cimpl->height );
+          
+          /* remove child area from the invalid area of the parent */
+          if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped)
+            gdk_region_subtract (&visible_region, &child_region);
+          
+          if (child_func && (*child_func) ((GdkWindow *)child, user_data))
+            {
+              gdk_region_offset (region, - child->x, - child->y);
+              gdk_region_offset (&child_region, - child->x, - child->y);
+              gdk_region_intersect (&child_region, region);
+              
+              gdk_window_invalidate_maybe_recurse ((GdkWindow *)child,
+                                                   &child_region, child_func, user_data);
+              
+              gdk_region_offset (region, child->x, child->y);
+            }
 
-	  gdk_region_destroy (child_region);
-	}
+          temp_region_deinit( &child_region );
+        }
 
       tmp_list = tmp_list->next;
     }
   
-  if (!gdk_region_empty (visible_region))
+  if (!gdk_region_empty (&visible_region))
     {
       
       if (private->update_area)
-	{
-	  gdk_region_union (private->update_area, visible_region);
-	}
+        {
+          gdk_region_union (private->update_area, &visible_region);
+        }
       else
-	{
-	  update_windows = g_slist_prepend (update_windows, window);
-	  private->update_area = gdk_region_copy (visible_region);
-	  gdk_window_schedule_update (window);
-	}
+        {
+          update_windows = g_slist_prepend (update_windows, window);
+          private->update_area = gdk_region_copy (&visible_region);
+          gdk_window_schedule_update (window);
+        }
     }
-    gdk_region_destroy (visible_region);
+
+  temp_region_deinit( &visible_region );
 }
 
 
 static void
 gdk_window_impl_directfb_process_updates (GdkPaintable *paintable,
-                    gboolean      update_children)
+                                          gboolean      update_children)
 {
   GdkWindow *window;
   GdkWindowObject *private;
@@ -2915,58 +2911,49 @@ gdk_window_impl_directfb_process_updates
       private->update_area = NULL;
       
       if (_gdk_event_func && gdk_window_is_viewable (window))
-	{
-	  GdkRectangle window_rect;
-	  GdkRegion *expose_region;
-	  GdkRegion *window_region;
-          gint width, height;
-	  save_region = _gdk_windowing_window_queue_antiexpose (window, update_area);
+        {
+          GdkRegion *expose_region;
+          GdkRegion  window_region;
+          save_region = _gdk_windowing_window_queue_antiexpose (window, update_area);
 
-	  if (save_region)
-	    expose_region = gdk_region_copy (update_area);
-	  else
-	    expose_region = update_area;
-	  
-          gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height);
-
-	  window_rect.x = 0;
-	  window_rect.y = 0;
-	  window_rect.width = width;
-	  window_rect.height = height;
-
-	  window_region = gdk_region_rectangle (&window_rect);
-	  gdk_region_intersect (expose_region,
-				window_region);
-	  gdk_region_destroy (window_region);
-	  
-	  if (!gdk_region_empty (expose_region) &&
-	      (private->event_mask & GDK_EXPOSURE_MASK))
-	    {
-	      GdkEvent event;
-	      
-	      event.expose.type = GDK_EXPOSE;
-	      event.expose.window = g_object_ref (window);
-	      event.expose.send_event = FALSE;
-	      event.expose.count = 0;
-	      event.expose.region = expose_region;
-	      gdk_region_get_clipbox (expose_region, &event.expose.area);
-	      (*_gdk_event_func) (&event, _gdk_event_data);
-	      
-	      g_object_unref (window);
-	    }
+          if (save_region)
+            expose_region = gdk_region_copy (update_area);
+          else
+            expose_region = update_area;
+          
+          temp_region_init_rectangle_vals( &window_region, 0, 0, impl->width, impl->height );
+          gdk_region_intersect (expose_region,
+                                &window_region);
+          temp_region_deinit (&window_region);
+          
+          if (!gdk_region_empty (expose_region) &&
+              (private->event_mask & GDK_EXPOSURE_MASK))
+            {
+              GdkEvent event;
+              
+              event.expose.type = GDK_EXPOSE;
+              event.expose.window = g_object_ref (window);
+              event.expose.send_event = FALSE;
+              event.expose.count = 0;
+              event.expose.region = expose_region;
+              gdk_region_get_clipbox (expose_region, &event.expose.area);
+              (*_gdk_event_func) (&event, _gdk_event_data);
+              
+              g_object_unref (window);
+            }
 
-	  if (expose_region != update_area)
-	    gdk_region_destroy (expose_region);
-	}
+          if (expose_region != update_area)
+            gdk_region_destroy (expose_region);
+        }
       if (!save_region)
-	gdk_region_destroy (update_area);
+        gdk_region_destroy (update_area);
     }
 }
 
 
 static void
 gdk_window_impl_directfb_begin_paint_region (GdkPaintable *paintable,
-					   GdkRegion    *region)
+                                             GdkRegion    *region)
 {
   GdkDrawableImplDirectFB *impl;
   GdkWindowImplDirectFB *wimpl;
@@ -2982,10 +2969,10 @@ gdk_window_impl_directfb_begin_paint_reg
   if (!region)
     return;
 
-  if (impl->paint_region)
-    gdk_region_union (impl->paint_region, region);
+  if (impl->paint_region.numRects)
+    gdk_region_union (&impl->paint_region, region);
   else
-    impl->paint_region = gdk_region_copy (region);
+    temp_region_init_copy( &impl->paint_region, region );
 
 /*  for (i = 0; i < region->numRects; i++)
     {
@@ -3016,23 +3003,23 @@ gdk_window_impl_directfb_end_paint (GdkP
     {
       impl->buffered = FALSE;
 
-      if (impl->paint_region)
+      if (impl->paint_region.numRects)
         {
-          DFBRegion reg = { impl->paint_region->extents.x1,
-                            impl->paint_region->extents.y1,
-                            impl->paint_region->extents.x2 ,
-                            impl->paint_region->extents.y2 };
-
-          impl->surface->Flip(impl->surface, &reg,0);
-          gdk_region_destroy (impl->paint_region);
-          impl->paint_region = NULL;
+          DFBRegion reg = { impl->paint_region.extents.x1,
+                            impl->paint_region.extents.y1,
+                            impl->paint_region.extents.x2 ,
+                            impl->paint_region.extents.y2 };
+
+          impl->surface->Flip( impl->surface, &reg, 0 );
+
+          temp_region_reset( &impl->paint_region );
         }
     }
 #else
   if (impl->paint_depth == 0) {
        impl->buffered = FALSE;
 
-       if (impl->paint_region) {
+       if (impl->paint_region.numRects) {
             GdkWindow *window = GDK_WINDOW( impl->wrapper );
 
             if (GDK_IS_WINDOW(window)) {
@@ -3042,10 +3029,10 @@ gdk_window_impl_directfb_end_paint (GdkP
                       DFBRegion              reg;
                       GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (top->impl);
 
-                      reg.x1 = impl->abs_x - top->x + impl->paint_region->extents.x1;
-                      reg.y1 = impl->abs_y - top->y + impl->paint_region->extents.y1;
-                      reg.x2 = impl->abs_x - top->x + impl->paint_region->extents.x2 - 1;
-                      reg.y2 = impl->abs_y - top->y + impl->paint_region->extents.y2 - 1;
+                      reg.x1 = impl->abs_x - top->x + impl->paint_region.extents.x1;
+                      reg.y1 = impl->abs_y - top->y + impl->paint_region.extents.y1;
+                      reg.x2 = impl->abs_x - top->x + impl->paint_region.extents.x2 - 1;
+                      reg.y2 = impl->abs_y - top->y + impl->paint_region.extents.y2 - 1;
 
                       //direct_log_printf( NULL, "Adding bounding box of paint: %d,%d - %dx%d (top %p, wimpl %p)\n",
                       //                   DFB_RECTANGLE_VALS_FROM_REGION( &reg ), top, wimpl );
@@ -3054,8 +3041,7 @@ gdk_window_impl_directfb_end_paint (GdkP
                  }
             }
 
-            gdk_region_destroy (impl->paint_region);
-            impl->paint_region = NULL;
+            temp_region_reset( &impl->paint_region );
        }
   }
 #endif
GDK-DIRECTFB: Fix clipping rectangle for filling rectangles after Cairo has modified it.


diff -pur gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkdrawable-directfb.c	2007-11-24 20:04:17.000000000 +0100
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkdrawable-directfb.c	2007-11-24 19:57:18.000000000 +0100
@@ -436,6 +436,8 @@ _gdk_directfb_draw_rectangle (GdkDrawabl
         }
       else  /* normal rectangle filling */
         {
+          impl->surface->SetClip (impl->surface, NULL);
+
           for (i = 0; i < clip->numRects; i++)
             {
               DFBRegion *region = (DFBRegion *) &clip->rects[i];
GDK-DIRECTFB: Use RGB16 format by default.


diff -pur gtk+-2.10.14/gdk/directfb/gdkvisual-directfb.c gtk+-2.10.14-hacked/gdk/directfb/gdkvisual-directfb.c
--- gtk+-2.10.14/gdk/directfb/gdkvisual-directfb.c	2007-07-16 21:46:15.000000000 +0200
+++ gtk+-2.10.14-hacked/gdk/directfb/gdkvisual-directfb.c	2007-11-24 20:01:16.000000000 +0100
@@ -54,11 +54,11 @@ static GdkVisualDirectFB * gdk_directfb_
 
 static DFBSurfacePixelFormat formats[] =
 {
+  DSPF_RGB16,
   DSPF_ARGB,
   DSPF_LUT8,
   DSPF_RGB32,
   DSPF_RGB24,
-  DSPF_RGB16,
   DSPF_ARGB1555,
   DSPF_RGB332
 };
GDK-DIRECTFB: During update processing, don't flip immediately, but accumulate a flipping region using the DirectFB
update manager and flush all Flip()s at the end of all painting. This results in a UI update In One Go [tm]!


diff -pur gtk+-2.10.14/gdk/directfb/gdkprivate-directfb.h /home/dok/Pengutronix/gtk+-2.10.14-hacked4/gdk/directfb/gdkprivate-directfb.h
--- gtk+-2.10.14/gdk/directfb/gdkprivate-directfb.h	2007-07-16 21:46:15.000000000 +0200
+++ /home/dok/Pengutronix/gtk+-2.10.14-hacked4/gdk/directfb/gdkprivate-directfb.h	2007-11-24 14:48:04.000000000 +0100
@@ -40,6 +40,7 @@
 #include "gdkdisplay-directfb.h"
 #include <cairo.h>
 
+#include <directfb_util.h>
 
 
 #define GDK_TYPE_DRAWABLE_IMPL_DIRECTFB       (gdk_drawable_impl_directfb_get_type ())
@@ -151,6 +152,9 @@ struct _GdkWindowImplDirectFB
   guint8                  opacity;
 
   GdkWindowTypeHint       type_hint;
+
+  DFBUpdates              flips;
+  DFBRegion               flip_regions[4];
 };
 
 typedef struct
--- gtk+-2.10.14/gdk/directfb/gdkwindow-directfb.c	2007-07-16 21:46:15.000000000 +0200
+++ gtk+-2.10.14-hacked4b/gdk/directfb/gdkwindow-directfb.c	2007-11-24 16:37:15.000000000 +0100
@@ -46,6 +46,8 @@
 #include "cairo.h"
 #include <assert.h>
 
+#include <directfb_util.h>
+
 static GdkRegion * gdk_window_impl_directfb_get_visible_region (GdkDrawable *drawable);
 static void        gdk_window_impl_directfb_set_colormap       (GdkDrawable *drawable,
                                                                 GdkColormap *colormap);
@@ -93,6 +95,35 @@ gdk_window_directfb_process_all_updates 
       tmp_list = tmp_list->next;
     }
 
+
+#ifndef NO_EXPERIMENTS
+  tmp_list = old_update_windows;
+
+  g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
+
+  while (tmp_list) {
+       GdkWindowObject *top = GDK_WINDOW_OBJECT( gdk_window_get_toplevel( tmp_list->data ) );
+
+       if (top) {
+            GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (top->impl);
+
+            if (wimpl->flips.num_regions) {
+                 //direct_log_printf( NULL, "Flipping bounding box of paints: %d,%d - %dx%d (top %p, wimpl %p)\n",
+                 //                   DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ), top, wimpl );
+
+                 wimpl->drawable.surface->Flip( wimpl->drawable.surface, &wimpl->flips.bounding, DSFLIP_NONE );
+
+                 dfb_updates_reset( &wimpl->flips );
+            }
+       }
+
+
+       g_object_unref (tmp_list->data);
+       tmp_list = tmp_list->next;
+  }
+#endif
+
+
   g_slist_free (old_update_windows);
 
 }
@@ -313,6 +344,12 @@ create_directfb_window (GdkWindowImplDir
 
   impl->window = window;
 
+#ifndef NO_EXPERIMENTS
+  //direct_log_printf( NULL, "Initializing (window %p, wimpl %p)\n", win, impl );
+
+  dfb_updates_init( &impl->flips, impl->flip_regions, G_N_ELEMENTS(impl->flip_regions) );
+#endif
+
   return TRUE;
 }
 
@@ -2969,6 +3006,7 @@ gdk_window_impl_directfb_end_paint (GdkP
 
   impl->paint_depth--;
 
+#ifdef NO_EXPERIMENTS
   if (impl->paint_depth == 0)
     {
       impl->buffered = FALSE;
@@ -2985,6 +3023,37 @@ gdk_window_impl_directfb_end_paint (GdkP
           impl->paint_region = NULL;
         }
     }
+#else
+  if (impl->paint_depth == 0) {
+       impl->buffered = FALSE;
+
+       if (impl->paint_region) {
+            GdkWindow *window = GDK_WINDOW( impl->wrapper );
+
+            if (GDK_IS_WINDOW(window)) {
+                 GdkWindowObject *top = GDK_WINDOW_OBJECT( gdk_window_get_toplevel( window ) );
+
+                 if (top) {
+                      DFBRegion              reg;
+                      GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (top->impl);
+
+                      reg.x1 = impl->abs_x - top->x + impl->paint_region->extents.x1;
+                      reg.y1 = impl->abs_y - top->y + impl->paint_region->extents.y1;
+                      reg.x2 = impl->abs_x - top->x + impl->paint_region->extents.x2 - 1;
+                      reg.y2 = impl->abs_y - top->y + impl->paint_region->extents.y2 - 1;
+
+                      //direct_log_printf( NULL, "Adding bounding box of paint: %d,%d - %dx%d (top %p, wimpl %p)\n",
+                      //                   DFB_RECTANGLE_VALS_FROM_REGION( &reg ), top, wimpl );
+
+                      dfb_updates_add( &wimpl->flips, &reg );
+                 }
+            }
+
+            gdk_region_destroy (impl->paint_region);
+            impl->paint_region = NULL;
+       }
+  }
+#endif
 }
 
 
CAIRO-DIRECTFB: Use DirectFB for show_glyphs() even if it is unaccelerated.

The software fallback in DirectFB is well optimized.


diff -pur cairo-1.4.10/src/cairo-directfb-surface.c cairo-1.4.10-hacked/src/cairo-directfb-surface.c
--- cairo-1.4.10/src/cairo-directfb-surface.c	2007-06-27 20:00:55.000000000 +0200
+++ cairo-1.4.10-hacked/src/cairo-directfb-surface.c	2007-11-24 20:06:22.000000000 +0100
@@ -1598,7 +1598,7 @@ cairo_directfb_surface_backend_init (IDi
         cairo_directfb_surface_backend.composite_trapezoids = NULL;
 #endif
 
-#if DFB_SHOW_GLYPHS
+#if DFB_SHOW_GLYPHS && 0
     if (!(dsc.acceleration_mask & DFXL_BLIT)            ||
         !(dsc.blitting_flags & DSBLIT_COLORIZE)         ||
         !(dsc.blitting_flags & DSBLIT_BLEND_ALPHACHANNEL))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]