[PATCH 2/2] ephyr: Ensure stride of private framebuffer is multiple of 4

Søren Sandmann sandmann at cs.au.dk
Mon Oct 21 23:18:46 CEST 2013


From: Søren Sandmann Pedersen <ssp at redhat.com>

The fb layer of X can't deal with strides that are not a multiple of
4, so when Xephyr allocates its own framebuffer it should make sure to
align it.

This fixes crashes and rendering corruption when Xephyr runs in a
depth that is different from the host X server and its screen size is
not a multiple of 4 / depth. (This is particularly easy to trigger if
you use the -resizeable option).
---
 hw/kdrive/ephyr/hostx.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 86f3679..b547525 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -719,12 +719,14 @@ hostx_screen_init(KdScreenInfo *screen,
         return scrpriv->ximg->data;
     }
     else {
-        *bytes_per_line = width * (scrpriv->server_depth >> 3);
+        int Bpp = scrpriv->server_depth >> 3;
+        int stride = (width * Bpp + 0x3) & ~0x3;
+        
+        *bytes_per_line = stride;
         *bits_per_pixel = scrpriv->server_depth;
 
-        EPHYR_DBG("server bpp %i", scrpriv->server_depth >> 3);
-        scrpriv->fb_data =
-            malloc(width * buffer_height * (scrpriv->server_depth >> 3));
+        EPHYR_DBG("server bpp %i", Bpp);
+        scrpriv->fb_data = malloc (stride * buffer_height);
         return scrpriv->fb_data;
     }
 }
@@ -763,15 +765,14 @@ hostx_paint_rect(KdScreenInfo *screen,
 
     if (!host_depth_matches_server(scrpriv)) {
         int x, y, idx, bytes_per_pixel = (scrpriv->server_depth >> 3);
+        int stride = (scrpriv->win_width * bytes_per_pixel + 0x3) & ~0x3;
         unsigned char r, g, b;
         unsigned long host_pixel;
 
         EPHYR_DBG("Unmatched host depth scrpriv=%p\n", scrpriv);
         for (y = sy; y < sy + height; y++)
             for (x = sx; x < sx + width; x++) {
-                idx =
-                    (scrpriv->win_width * y * bytes_per_pixel) +
-                    (x * bytes_per_pixel);
+                idx = y * stride + x * bytes_per_pixel;
 
                 switch (scrpriv->server_depth) {
                 case 16:
-- 
1.7.1



More information about the xorg-devel mailing list