fix 24bpp rendering problem and pixel fetch problem found in qemu/kvm.
authorCarsten Haitzler <raster@rasterman.com>
Wed, 19 Dec 2012 15:40:52 +0000 (15:40 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Wed, 19 Dec 2012 15:40:52 +0000 (15:40 +0000)
SVN revision: 81378

ChangeLog
src/lib/ecore_x/xcb/ecore_xcb_image.c
src/lib/ecore_x/xlib/ecore_x_image.c
src/lib/evas/common/evas_convert_main.c
src/lib/evas/common/evas_convert_rgb_24.c
src/modules/evas/engines/software_x11/evas_engine.h
src/modules/evas/engines/software_x11/evas_xcb_outbuf.c
src/modules/evas/engines/software_x11/evas_xlib_outbuf.c

index 4f27c87639944e29618df3d4444e607bd2fef617..a55c3047908af32da013050e826048d53c773d9d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-12-20  Carsten Haitzler (The Rasterman)
+
+        * Fixed 24bpp issue with rendering in evas. It shows itself
+        only under qemu/kvm with the cirruse driver that I have found.
+        In this case the screen is really 24bpp packed and this case
+        just never comes up on any vaguely modern gfx system.
+        * Fixed 24bpp ximage convert back from 24bpp to 32bpp in
+        ecore-x. Only shows itself in qemu/kvm.
+                
 2012-12-18  Gustavo Sverzut Barbieri (k-s)
 
        * Fixed many memory problems with ecore_evas_extn
index 8e221101b0a069fcaad585281662f47e6973194f..bce5df3a1daea9d07ab97651435564b51bc6a38b 100644 (file)
@@ -249,8 +249,10 @@ ecore_x_image_is_argb32_get(Ecore_X_Image *im)
 
    if (((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) ||
         (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR)) &&
-       (im->depth >= 24) && (vis->red_mask == 0xff0000) &&
-       (vis->green_mask == 0x00ff00) && (vis->blue_mask == 0x0000ff))
+       (im->bpp == 4) &&
+       (vis->red_mask == 0xff0000) &&
+       (vis->green_mask == 0x00ff00) && 
+       (vis->blue_mask == 0x0000ff))
      {
 #ifdef WORDS_BIGENDIAN
         if (im->xim->byte_order == XCB_IMAGE_ORDER_MSB_FIRST) return EINA_TRUE;
@@ -287,6 +289,8 @@ ecore_x_image_to_argb_convert(void            *src,
       rgb565,
       bgr565,
       rgbx555,
+      rgb888,
+      bgr888,
       argbx888,
       abgrx888,
       rgba888x,
@@ -346,40 +350,56 @@ ecore_x_image_to_argb_convert(void            *src,
    else if ((vis->_class == XCB_VISUAL_CLASS_TRUE_COLOR) ||
             (vis->_class == XCB_VISUAL_CLASS_DIRECT_COLOR))
      {
-        if ((vis->red_mask == 0x00ff0000) &&
-            (vis->green_mask == 0x0000ff00) &&
-            (vis->blue_mask == 0x000000ff))
-          mode = argbx888;
-        else if ((vis->red_mask == 0x000000ff) &&
+        if (sbpp == 24)
+          {
+             if ((vis->red_mask == 0x00ff0000) &&
                  (vis->green_mask == 0x0000ff00) &&
-                 (vis->blue_mask == 0x00ff0000))
-          mode = abgrx888;
-        else if ((vis->red_mask == 0xff000000) &&
-                 (vis->green_mask == 0x00ff0000) &&
-                 (vis->blue_mask == 0x0000ff00))
-          mode = rgba888x;
-        else if ((vis->red_mask == 0x0000ff00) &&
-                 (vis->green_mask == 0x00ff0000) &&
-                 (vis->blue_mask == 0xff000000))
-          mode = bgra888x;
-        else if ((vis->red_mask == 0x0003f000) &&
-                 (vis->green_mask == 0x00000fc0) &&
-                 (vis->blue_mask == 0x0000003f))
-          mode = argbx666;
-        else if ((vis->red_mask == 0x0000f800) &&
-                 (vis->green_mask == 0x000007e0) &&
-                 (vis->blue_mask == 0x0000001f))
-          mode = rgb565;
-        else if ((vis->red_mask == 0x0000001f) &&
-                 (vis->green_mask == 0x000007e0) &&
-                 (vis->blue_mask == 0x0000f800))
-          mode = bgr565;
-        else if ((vis->red_mask == 0x00007c00) &&
-                 (vis->green_mask == 0x000003e0) &&
-                 (vis->blue_mask == 0x0000001f))
-          mode = rgbx555;
+                 (vis->blue_mask == 0x000000ff))
+               mode = rgb888;
+             else if ((vis->red_mask == 0x000000ff) &&
+                      (vis->green_mask == 0x0000ff00) &&
+                      (vis->blue_mask == 0x00ff0000))
+               mode = bgr888;
+             else
+               return EINA_FALSE;
+          }
         else
-          return EINA_FALSE;
+          {
+             if ((vis->red_mask == 0x00ff0000) &&
+                 (vis->green_mask == 0x0000ff00) &&
+                 (vis->blue_mask == 0x000000ff))
+               mode = argbx888;
+             else if ((vis->red_mask == 0x000000ff) &&
+                      (vis->green_mask == 0x0000ff00) &&
+                      (vis->blue_mask == 0x00ff0000))
+               mode = abgrx888;
+             else if ((vis->red_mask == 0xff000000) &&
+                      (vis->green_mask == 0x00ff0000) &&
+                      (vis->blue_mask == 0x0000ff00))
+               mode = rgba888x;
+             else if ((vis->red_mask == 0x0000ff00) &&
+                      (vis->green_mask == 0x00ff0000) &&
+                      (vis->blue_mask == 0xff000000))
+               mode = bgra888x;
+             else if ((vis->red_mask == 0x0003f000) &&
+                      (vis->green_mask == 0x00000fc0) &&
+                      (vis->blue_mask == 0x0000003f))
+               mode = argbx666;
+             else if ((vis->red_mask == 0x0000f800) &&
+                      (vis->green_mask == 0x000007e0) &&
+                      (vis->blue_mask == 0x0000001f))
+               mode = rgb565;
+             else if ((vis->red_mask == 0x0000001f) &&
+                      (vis->green_mask == 0x000007e0) &&
+                      (vis->blue_mask == 0x0000f800))
+               mode = bgr565;
+             else if ((vis->red_mask == 0x00007c00) &&
+                      (vis->green_mask == 0x000003e0) &&
+                      (vis->blue_mask == 0x0000001f))
+               mode = rgbx555;
+             else
+               return EINA_FALSE;
+          }
      }
    for (row = 0; row < h; row++)
      {
@@ -461,6 +481,29 @@ ecore_x_image_to_argb_convert(void            *src,
              break;
 
            case 24:
+            s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + (x * (sbpp / 8));
+             switch (mode)
+               {
+                case rgb888:
+                  while (dp < de)
+                    {
+                       *dp = 0xff000000 | (s8[2] << 16) | (s8[1] << 8) | s8[0];
+                       s8 += 3; dp++;
+                    }
+                  break;
+                case bgr888:
+                  while (dp < de)
+                    {
+                       *dp = 0xff000000 | (s8[0] << 16) | (s8[1] << 8) | s8[2];
+                       s8 += 3; dp++;
+                    }
+                  break;
+                default:
+                  return EINA_FALSE;
+                  break;
+               }
+             break;
+             
            case 32:
              s32 = ((unsigned int *)(((unsigned char *)src) +
                                      ((y + row) * sbpl))) + x;
@@ -523,7 +566,6 @@ ecore_x_image_to_argb_convert(void            *src,
                   break;
                }
              break;
-             break;
 
            default:
              return EINA_FALSE;
index def81104a21549694d8366ef21735dd83d724505..ec1c1b84124b343b73760d563a61376a79ca4e89 100644 (file)
@@ -218,7 +218,9 @@ _ecore_x_image_shm_create(Ecore_X_Image *im)
      im->bpp = 1;
    else if (im->xim->bits_per_pixel <= 16)
      im->bpp = 2;
-   else
+   else if (im->xim->bits_per_pixel <= 24)
+     im->bpp = 3;
+   else 
      im->bpp = 4;
 }
 
@@ -358,7 +360,7 @@ ecore_x_image_is_argb32_get(Ecore_X_Image *im)
    if (!im->xim) _ecore_x_image_shm_create(im);
    if (((vis->class == TrueColor) ||
         (vis->class == DirectColor)) &&
-       (im->depth >= 24) &&
+       (im->bpp == 4) &&
        (vis->red_mask == 0xff0000) &&
        (vis->green_mask == 0x00ff00) &&
        (vis->blue_mask == 0x0000ff))
@@ -397,6 +399,8 @@ ecore_x_image_to_argb_convert(void *src,
       rgb565,
       bgr565,
       rgbx555,
+      rgb888,
+      bgr888,
       argbx888,
       abgrx888,
       rgba888x,
@@ -439,40 +443,56 @@ ecore_x_image_to_argb_convert(void *src,
    else if ((vis->class == TrueColor) ||
             (vis->class == DirectColor))
      {
-        if ((vis->red_mask == 0x00ff0000) &&
-            (vis->green_mask == 0x0000ff00) &&
-            (vis->blue_mask == 0x000000ff))
-          mode = argbx888;
-        else if ((vis->red_mask == 0x000000ff) &&
+        if (sbpp == 24)
+          {
+             if ((vis->red_mask == 0x00ff0000) &&
                  (vis->green_mask == 0x0000ff00) &&
-                 (vis->blue_mask == 0x00ff0000))
-          mode = abgrx888;
-        else if ((vis->red_mask == 0xff000000) &&
-                 (vis->green_mask == 0x00ff0000) &&
-                 (vis->blue_mask == 0x0000ff00))
-          mode = rgba888x;
-        else if ((vis->red_mask == 0x0000ff00) &&
-                 (vis->green_mask == 0x00ff0000) &&
-                 (vis->blue_mask == 0xff000000))
-          mode = bgra888x;
-        else if ((vis->red_mask == 0x0003f000) &&
-                 (vis->green_mask == 0x00000fc0) &&
-                 (vis->blue_mask == 0x0000003f))
-          mode = argbx666;
-        else if ((vis->red_mask == 0x0000f800) &&
-                 (vis->green_mask == 0x000007e0) &&
-                 (vis->blue_mask == 0x0000001f))
-          mode = rgb565;
-        else if ((vis->red_mask == 0x0000001f) &&
-                 (vis->green_mask == 0x000007e0) &&
-                 (vis->blue_mask == 0x0000f800))
-          mode = bgr565;
-        else if ((vis->red_mask == 0x00007c00) &&
-                 (vis->green_mask == 0x000003e0) &&
-                 (vis->blue_mask == 0x0000001f))
-          mode = rgbx555;
+                 (vis->blue_mask == 0x000000ff))
+               mode = rgb888;
+             else if ((vis->red_mask == 0x000000ff) &&
+                      (vis->green_mask == 0x0000ff00) &&
+                      (vis->blue_mask == 0x00ff0000))
+               mode = bgr888;
+             else
+               return EINA_FALSE;
+          }
         else
-          return EINA_FALSE;
+          {
+             if ((vis->red_mask == 0x00ff0000) &&
+                 (vis->green_mask == 0x0000ff00) &&
+                 (vis->blue_mask == 0x000000ff))
+               mode = argbx888;
+             else if ((vis->red_mask == 0x000000ff) &&
+                      (vis->green_mask == 0x0000ff00) &&
+                      (vis->blue_mask == 0x00ff0000))
+               mode = abgrx888;
+             else if ((vis->red_mask == 0xff000000) &&
+                      (vis->green_mask == 0x00ff0000) &&
+                      (vis->blue_mask == 0x0000ff00))
+               mode = rgba888x;
+             else if ((vis->red_mask == 0x0000ff00) &&
+                      (vis->green_mask == 0x00ff0000) &&
+                      (vis->blue_mask == 0xff000000))
+               mode = bgra888x;
+             else if ((vis->red_mask == 0x0003f000) &&
+                      (vis->green_mask == 0x00000fc0) &&
+                      (vis->blue_mask == 0x0000003f))
+               mode = argbx666;
+             else if ((vis->red_mask == 0x0000f800) &&
+                      (vis->green_mask == 0x000007e0) &&
+                      (vis->blue_mask == 0x0000001f))
+               mode = rgb565;
+             else if ((vis->red_mask == 0x0000001f) &&
+                      (vis->green_mask == 0x000007e0) &&
+                      (vis->blue_mask == 0x0000f800))
+               mode = bgr565;
+             else if ((vis->red_mask == 0x00007c00) &&
+                      (vis->green_mask == 0x000003e0) &&
+                      (vis->blue_mask == 0x0000001f))
+               mode = rgbx555;
+             else
+               return EINA_FALSE;
+          }
      }
    for (row = 0; row < h; row++)
      {
@@ -553,6 +573,29 @@ ecore_x_image_to_argb_convert(void *src,
              break;
 
            case 24:
+             s8 = ((unsigned char *)(((unsigned char *)src) + ((y + row) * sbpl))) + (x * (sbpp / 8));
+             switch (mode)
+               {
+                case rgb888:
+                  while (dp < de)
+                    {
+                       *dp = 0xff000000 | (s8[2] << 16) | (s8[1] << 8) | s8[0];
+                       s8 += 3; dp++;
+                    }
+                  break;
+                case bgr888:
+                  while (dp < de)
+                    {
+                       *dp = 0xff000000 | (s8[0] << 16) | (s8[1] << 8) | s8[2];
+                       s8 += 3; dp++;
+                    }
+                  break;
+                default:
+                  return EINA_FALSE;
+                  break;
+               }
+             break;
+             
            case 32:
              s32 = ((unsigned int *)(((unsigned char *)src) + ((y + row) * sbpl))) + x;
              switch (mode)
@@ -614,7 +657,6 @@ ecore_x_image_to_argb_convert(void *src,
                   break;
                }
              break;
-             break;
 
            default:
              return EINA_FALSE;
index 2be2aa27eb5811f631f224f0e02b00d29e66b661..55a2851881a348b6de254268d6797f6cdd9f2ee1 100644 (file)
@@ -438,7 +438,7 @@ evas_common_convert_func_get(DATA8 *dest, int w, int h EINA_UNUSED, int depth, D
          }
        if (depth == 24)
          {
-            if ((rmask == 0x00ff0000) && (gmask == 0x0000ff00) && (bmask == 0x000000ff))
+            if ((rmask == 0x000000ff) && (gmask == 0x0000ff00) && (bmask == 0x00ff0000))
               {
                  if (rotation == 0)
                    return evas_common_convert_rgba_to_24bpp_rgb_888;
@@ -448,7 +448,7 @@ evas_common_convert_func_get(DATA8 *dest, int w, int h EINA_UNUSED, int depth, D
                  if (rotation == 0)
                    return evas_common_convert_rgba_to_24bpp_rgb_666;
               }
-            if ((rmask == 0x000000ff) && (gmask == 0x0000ff00) && (bmask == 0x00ff0000))
+            if ((rmask == 0x00ff0000) && (gmask == 0x0000ff00) && (bmask == 0x000000ff))
               {
                  if (rotation == 0)
                    return evas_common_convert_rgba_to_24bpp_bgr_888;
index 88f3648039e4f8967f356b04934e04b110a5776e..c1d196e549d3f228a7129dea44b677caaa1a1126 100644 (file)
@@ -22,7 +22,7 @@ evas_common_convert_rgba_to_24bpp_rgb_888(DATA32 *src, DATA8 *dst, int src_jump,
             dst_ptr+=3;
          }
        src_ptr += src_jump;
-       dst_ptr += (dst_jump * 3);
+       dst_ptr += dst_jump;
      }
    return;
 }
@@ -53,7 +53,7 @@ evas_common_convert_rgba_to_24bpp_rgb_666(DATA32 *src, DATA8 *dst, int src_jump,
             dst_ptr+=3;
          }
        src_ptr += src_jump;
-       dst_ptr += (dst_jump * 3);
+       dst_ptr += dst_jump;
      }
    return;
 }
@@ -79,7 +79,7 @@ evas_common_convert_rgba_to_24bpp_bgr_888(DATA32 *src, DATA8 *dst, int src_jump,
             dst_ptr+=3;
          }
        src_ptr += src_jump;
-       dst_ptr += (dst_jump * 3);
+       dst_ptr += dst_jump;
      }
    return;
 }
index 82d2d1f57c4231ad67063a54383a122e5e4a30ae..421e43a30698d4d3031c4bd59586227f7fe1cc6d 100644 (file)
@@ -89,7 +89,7 @@ struct _Outbuf
                   Pixmap mask;
                   Visual *vis;
                   Colormap cmap;
-                  int depth, shm;
+                  int depth, imdepth, shm;
                   GC gc, gcm;
                   unsigned char swap : 1;
                   unsigned char bit_swap : 1;
@@ -104,7 +104,7 @@ struct _Outbuf
                   xcb_pixmap_t mask;
                   xcb_visualtype_t *visual;
                   xcb_colormap_t cmap;
-                  int depth, shm;
+                  int depth, imdepth, shm;
                   xcb_gcontext_t gc, gcm;
                   unsigned char swap : 1;
                   unsigned char bit_swap : 1;
index eb0dcfc2efd63b5123adac08ea7f117afbe09138..e8211836b140bd178c58b88b65c5194887096119 100644 (file)
@@ -87,7 +87,8 @@ Outbuf *
 evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_connection_t *conn, xcb_screen_t *screen, xcb_drawable_t draw, xcb_visualtype_t *vis, xcb_colormap_t cmap, int xdepth, Eina_Bool grayscale, int max_colors, xcb_drawable_t mask, Eina_Bool shape_dither, Eina_Bool alpha) 
 {
    Outbuf *buf = NULL;
-   Gfx_Func_Convert func_conv= NULL;
+   Gfx_Func_Convert func_conv = NULL;
+   Xcb_Output_Buffer *xob;
    const xcb_setup_t *setup;
 
    if (!(buf = calloc(1, sizeof(Outbuf)))) 
@@ -110,6 +111,27 @@ evas_software_xcb_outbuf_setup(int w, int h, int rot, Outbuf_Depth depth, xcb_co
    buf->priv.destination_alpha = alpha;
    buf->priv.x11.xcb.shm = evas_software_xcb_can_do_shm(conn, screen);
 
+   xob = 
+     evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
+                                         buf->priv.x11.xcb.visual, 
+                                         buf->priv.x11.xcb.depth, 
+                                         1, 1, buf->priv.x11.xcb.shm, 
+                                         NULL);
+   if (!xob) buf->priv.x11.xcb.shm = 0;
+   xob = 
+     evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
+                                         buf->priv.x11.xcb.visual, 
+                                         buf->priv.x11.xcb.depth, 
+                                         1, 1, buf->priv.x11.xcb.shm, 
+                                         NULL);
+   if (!xob) 
+     {
+        free(buf);
+        return NULL;
+     }
+   buf->priv.x11.xcb.imdepth = evas_software_xcb_output_buffer_depth(xob);
+   evas_software_xcb_output_buffer_free(xob, EINA_FALSE);
+   
    eina_array_step_set(&buf->priv.onebuf_regions, sizeof(Eina_Array), 8);
 
 #ifdef WORDS_BIGENDIAN
@@ -287,8 +309,11 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
         alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
         use_shm = buf->priv.x11.xcb.shm;
 
-        if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) && 
-            (buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff)) 
+        if ((buf->rot == 0) &&
+            (buf->priv.x11.xcb.imdepth == 32) &&
+            (buf->priv.mask.r == 0xff0000) &&
+            (buf->priv.mask.g == 0x00ff00) &&
+            (buf->priv.mask.b == 0x0000ff))
           {
              obr->xcbob = 
                evas_software_xcb_output_buffer_new(buf->priv.x11.xcb.conn, 
@@ -427,8 +452,11 @@ evas_software_xcb_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w,
 
    use_shm = buf->priv.x11.xcb.shm;
    alpha = ((buf->priv.x11.xcb.mask) || (buf->priv.destination_alpha));
-   if ((buf->rot == 0) && (buf->priv.mask.r == 0xff0000) && 
-       (buf->priv.mask.g == 0x00ff00) && (buf->priv.mask.b == 0x0000ff)) 
+   if ((buf->rot == 0) &&
+       (buf->priv.x11.xcb.imdepth == 32) &&
+       (buf->priv.mask.r == 0xff0000) && 
+       (buf->priv.mask.g == 0x00ff00) &&
+       (buf->priv.mask.b == 0x0000ff)) 
      {
         obr->xcbob = 
           _find_xcbob(buf->priv.x11.xcb.conn, buf->priv.x11.xcb.visual, 
@@ -839,13 +867,35 @@ evas_software_xcb_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, in
    if (data != (unsigned char *)src_data) 
      {
         if (buf->priv.pal)
-          func_conv(src_data, data, update->cache_entry.w - w, 
-                    (bpl / (buf->depth / 8)) - obr->w, 
-                    obr->w, obr->h, x, y, buf->priv.pal->lookup);
+          {
+             func_conv(src_data, data, update->cache_entry.w - w, 
+                       bpl - obr->w, obr->w, obr->h, x, y,
+                       buf->priv.pal->lookup);
+          }
         else
-          func_conv(src_data, data, update->cache_entry.w - w, 
-                    (bpl / (buf->depth / 8)) - obr->w, 
-                    obr->w, obr->h, x, y, NULL);
+          {
+             int pixelb = evas_software_xcb_output_buffer_depth(obr->xob) / 8;
+             int run;
+             int dstjump;
+             
+             if (pixelb == 3)
+               {
+                  run = obr->w * pixelb;
+                  dstjump = bpl - run;
+               }
+             else if ((pixelb == 2) || (pixelb == 4))
+               {
+                  run = obr->w;
+                  dstjump = (bpl / pixelb) - run;
+               }
+             else
+               {
+                  run = obr->w;
+                  dstjump = bpl - run;
+               }
+             func_conv(src_data, data, update->cache_entry.w - w, dstjump,
+                       obr->w, obr->h, x, y, NULL);
+          }
      }
 #if 1
 #else
@@ -1068,7 +1118,7 @@ _find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int
      return evas_software_xcb_output_buffer_new(conn, vis, depth, w, h, 
                                                 shm, data);
 
-   lbytes = (((w + 31) / 32) * 4);
+   lbytes = (((w + 63) / 64) * 4);
    if (depth > 1) 
      {
         bpp = (depth / 8);
@@ -1083,7 +1133,7 @@ _find_xcbob(xcb_connection_t *conn, xcb_visualtype_t *vis, int depth, int w, int
         int szdif = 0;
 
         if ((xcbob2->xim->depth != depth) || (xcbob2->visual != vis) || 
-            (xcbob2->connection != conn)) continue;
+            (xcbob2->connection != conn) || (xcbob2->w != w)) continue;
         szdif = (xcbob2->psize - sz);
         if (szdif < 0) continue;
         if (szdif == 0) 
@@ -1110,7 +1160,7 @@ have_xcbob:
    _shmpool = eina_list_remove_list(_shmpool, xl);
    xcbob->w = w;
    xcbob->h = h;
-   xcbob->bpl = lbytes;
+//   xcbob->bpl = lbytes;
    xcbob->xim->width = xcbob->w;
    xcbob->xim->height = xcbob->h;
    xcbob->xim->stride = xcbob->bpl;
index 7cc1cf0e4095ff04ebfeeb8af59289fde39edc57..866457e1eebf715a79b6d088462e6e36daa94e14 100644 (file)
@@ -52,7 +52,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
        lbytes = (((w * bpp) + 3) / 4) * 4;
      }
    else
-     lbytes = ((w + 31) / 32) * 4;
+     lbytes = ((w + 63) / 64) * 4;
    sz = lbytes * h;
    SHMPOOL_LOCK();
    EINA_LIST_FOREACH(shmpool, l, xob2)
@@ -60,7 +60,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
        int szdif;
 
        if ((xob2->xim->depth != depth) || (xob2->visual != v) ||
-           (xob2->display != d))
+           (xob2->display != d) || (xob2->w != w))
          continue;
        szdif = xob2->psize - sz;
        if (szdif < 0) continue;
@@ -88,7 +88,7 @@ _find_xob(Display *d, Visual *v, int depth, int w, int h, int shm, void *data)
    shmpool = eina_list_remove_list(shmpool, xl);
    xob->w = w;
    xob->h = h;
-   xob->bpl = lbytes;
+//   xob->bpl = lbytes;
    xob->xim->width = xob->w;
    xob->xim->height = xob->h;
    xob->xim->bytes_per_line = xob->bpl;
@@ -224,7 +224,6 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
                                                  buf->priv.x11.xlib.vis,
                                                  buf->priv.x11.xlib.depth,
                                                  1, 1, buf->priv.x11.xlib.shm, NULL);
-
       conv_func = NULL;
       if (xob)
        {
@@ -341,7 +340,8 @@ evas_software_xlib_outbuf_setup_x(int w, int h, int rot, Outbuf_Depth depth,
                                                             buf->priv.mask.b, PAL_MODE_NONE,
                                                             buf->rot);
             }
-          evas_software_xlib_x_output_buffer_free(xob, 1);
+           buf->priv.x11.xlib.imdepth = evas_software_xlib_x_output_buffer_depth(xob);
+           evas_software_xlib_x_output_buffer_free(xob, 1);
           if (!conv_func)
             {
                 ERR("At depth: %i, RGB format mask: %08x %08x %08x, "
@@ -410,6 +410,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
 
        use_shm = buf->priv.x11.xlib.shm;
        if ((buf->rot == 0) &&
+            (buf->priv.x11.xlib.imdepth == 32) &&
            (buf->priv.mask.r == 0xff0000) &&
            (buf->priv.mask.g == 0x00ff00) &&
            (buf->priv.mask.b == 0x0000ff))
@@ -565,6 +566,7 @@ evas_software_xlib_outbuf_new_region_for_update(Outbuf *buf, int x, int y, int w
    alpha = ((buf->priv.x11.xlib.mask) || (buf->priv.destination_alpha));
 
    if ((buf->rot == 0) &&
+       (buf->priv.x11.xlib.imdepth == 32) &&
        (buf->priv.mask.r == 0xff0000) &&
        (buf->priv.mask.g == 0x00ff00) &&
        (buf->priv.mask.b == 0x0000ff))
@@ -1011,21 +1013,34 @@ evas_software_xlib_outbuf_push_updated_region(Outbuf *buf, RGBA_Image *update, i
    if (buf->priv.pal)
      {
        if (data != (unsigned char *)src_data)
-         conv_func(src_data, data,
-                   update->cache_entry.w - w,
-                   bpl /
-                   ((evas_software_xlib_x_output_buffer_depth(obr->xob) /
-                     8)) - obr->w, obr->w, obr->h, x, y,
-                   buf->priv.pal->lookup);
+         conv_func(src_data, data, update->cache_entry.w - w,
+                    bpl - obr->w, obr->w, obr->h, x, y,
+                    buf->priv.pal->lookup);
      }
    else
      {
+        int pixelb = evas_software_xlib_x_output_buffer_depth(obr->xob) / 8;
+        int run;
+        int dstjump;
+        
+        if (pixelb == 3)
+          {
+             run = obr->w * pixelb;
+             dstjump = bpl - run;
+          }
+        else if ((pixelb == 2) || (pixelb == 4))
+          {
+             run = obr->w;
+             dstjump = (bpl / pixelb) - run;
+          }
+        else
+          {
+             run = obr->w;
+             dstjump = bpl - run;
+          }
        if (data != (unsigned char *)src_data)
-         conv_func(src_data, data,
-                   update->cache_entry.w - w,
-                   bpl /
-                   ((evas_software_xlib_x_output_buffer_depth(obr->xob) /
-                     8)) - obr->w, obr->w, obr->h, x, y, NULL);
+         conv_func(src_data, data, update->cache_entry.w - w, dstjump,
+                    obr->w, obr->h, x, y, NULL);
      }
 #if 1
 #else