From 623c4147650d0404cfbea0f9b7df66dc7d928e00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Mon, 21 Oct 2013 17:11:56 -0400 Subject: [PATCH] ephyr: Ensure stride of private framebuffer is multiple of 4 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). Reviewed-by: Eric Anholt Signed-off-by: Soren Sandmann Reviewed-by: Adam Jackson --- hw/kdrive/ephyr/hostx.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index 6020e8d63..ee9ae455c 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -721,12 +721,14 @@ hostx_screen_init(KdScreenInfo *screen, return scrpriv->ximg->data; } else { - *bytes_per_line = width * (scrpriv->server_depth >> 3); + int bytes_per_pixel = scrpriv->server_depth >> 3; + int stride = (width * bytes_per_pixel + 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", bytes_per_pixel); + scrpriv->fb_data = malloc (stride * buffer_height); return scrpriv->fb_data; } } @@ -765,15 +767,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: