From 856b7bdf4455663597dd78ad48f12d0a9fda0fbd Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Fri, 7 Mar 2014 01:52:11 -0300 Subject: [PATCH] evas/fb: use stride instead of width. While most framebuffes use stride = width, some may have stride bigger than width to provide better alignment. Then we must always use stride. Thanks to Arjan van de Ven, the one that spotted the issue. @fix --- src/modules/evas/engines/fb/evas_fb.h | 1 + src/modules/evas/engines/fb/evas_fb_main.c | 26 ++++++++++++++---- src/modules/evas/engines/fb/evas_outbuf.c | 32 ++++++++++++---------- 3 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/modules/evas/engines/fb/evas_fb.h b/src/modules/evas/engines/fb/evas_fb.h index 97c2cff224..20a52cf3fa 100644 --- a/src/modules/evas/engines/fb/evas_fb.h +++ b/src/modules/evas/engines/fb/evas_fb.h @@ -35,6 +35,7 @@ struct _fb_mode int fb_fd; void *mem; unsigned int mem_offset; + unsigned int stride; /* in pixels */ struct fb_var_screeninfo fb_var; }; diff --git a/src/modules/evas/engines/fb/evas_fb_main.c b/src/modules/evas/engines/fb/evas_fb_main.c index a6c66f6707..b93e44080d 100644 --- a/src/modules/evas/engines/fb/evas_fb_main.c +++ b/src/modules/evas/engines/fb/evas_fb_main.c @@ -679,7 +679,7 @@ fb_getmode(void) if (mode->depth == 8) fb_init_palette_332(mode); else fb_init_palette_linear(mode); - INF("%ux%u, bitdepth=%u (%u bits), depth=%u, refresh=%u", + INF("%ux%u, bpp=%u (%u bits), depth=%u, refresh=%u", mode->width, mode->height, mode->bpp, mode->fb_var.bits_per_pixel, mode->depth, mode->refresh); return mode; @@ -855,7 +855,7 @@ fb_postinit(FB_Mode *mode) return -1; } - DBG("%ux%u, bitdepth=%u (%u bits), depth=%u, refresh=%u, fb=%d", + DBG("%ux%u, bpp=%u (%u bits), depth=%u, refresh=%u, fb=%d", mode->width, mode->height, mode->bpp, mode->fb_var.bits_per_pixel, mode->depth, mode->refresh, fb); @@ -886,6 +886,22 @@ fb_postinit(FB_Mode *mode) fb_cleanup(); return -1; } + + mode->stride = fb_fix.line_length / mode->bpp; + if (mode->stride < mode->width) + { + CRI("stride=%u < width=%u", mode->stride, mode->width); + fb_cleanup(); + return -1; + } + if (mode->stride * mode->bpp != fb_fix.line_length) + { + CRI("FSCREENINFO line_length=%u is not multiple of bpp=%u", + fb_fix.line_length, mode->bpp); + fb_cleanup(); + return -1; + } + /* move viewport to upper left corner */ if ((mode->fb_var.xoffset != 0) || (mode->fb_var.yoffset != 0)) { @@ -918,11 +934,11 @@ fb_postinit(FB_Mode *mode) #endif mode->fb_fd = fb; - INF("%ux%u, bitdepth=%u (%u bits), depth=%u, refresh=%u, fb=%d, mem=%p, " - "mem_offset=%u, xoffset=%u, yoffset=%u", + INF("%ux%u, bpp=%u (%u bits), depth=%u, refresh=%u, fb=%d, mem=%p, " + "mem_offset=%u, stride=%u pixels, offset=%u, yoffset=%u", mode->width, mode->height, mode->bpp, mode->fb_var.bits_per_pixel, mode->depth, mode->refresh, fb, - mode->mem, mode->mem_offset, + mode->mem, mode->mem_offset, mode->stride, mode->fb_var.xoffset, mode->fb_var.yoffset); return fb; diff --git a/src/modules/evas/engines/fb/evas_outbuf.c b/src/modules/evas/engines/fb/evas_outbuf.c index 0fc7b24864..5196507084 100644 --- a/src/modules/evas/engines/fb/evas_outbuf.c +++ b/src/modules/evas/engines/fb/evas_outbuf.c @@ -74,7 +74,7 @@ _outbuf_reset(Outbuf *buf, int rot, Outbuf_Depth depth) DBG("size=%ux%u rot=%u depth=%u bitdepth=%u fb{" "width=%u, height=%u, refresh=%u, depth=%u, bpp=%u, fd=%d, " - "mem=%p, mem_offset=%u} " + "mem=%p, mem_offset=%u, stride=%u pixels} " "mask{r=%#010x, g=%#010x, b=%#010x} conv_func=%p", buf->w, buf->h, buf->rot, buf->depth, buf->priv.fb.fb->fb_var.bits_per_pixel, @@ -86,6 +86,7 @@ _outbuf_reset(Outbuf *buf, int rot, Outbuf_Depth depth) buf->priv.fb.fb->fb_fd, buf->priv.fb.fb->mem, buf->priv.fb.fb->mem_offset, + buf->priv.fb.fb->stride, buf->priv.mask.r, buf->priv.mask.g, buf->priv.mask.b, conv_func); @@ -118,11 +119,12 @@ evas_fb_outbuf_fb_setup_fb(int w, int h, int rot, Outbuf_Depth depth, int vt_no, return NULL; } fb_fd = fb_postinit(buf->priv.fb.fb); - DBG("fd=%d, mode=%ux%u, refresh=%u, depth=%u, bpp=%u, mem=%p (+%u)", + DBG("fd=%d, mode=%ux%u, refresh=%u, depth=%u, bpp=%u, mem=%p, " + "mem_offset=%u, stride=%u pixels", fb_fd, buf->priv.fb.fb->width, buf->priv.fb.fb->height, buf->priv.fb.fb->refresh, buf->priv.fb.fb->depth, buf->priv.fb.fb->bpp, buf->priv.fb.fb->mem, - buf->priv.fb.fb->mem_offset); + buf->priv.fb.fb->mem_offset, buf->priv.fb.fb->stride); if (fb_fd < 1) { fb_freemode(buf->priv.fb.fb); @@ -177,7 +179,7 @@ evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h) { data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + buf->priv.fb.fb->bpp * - (x + (y * buf->priv.fb.fb->width)); + (x + (y * buf->priv.fb.fb->stride)); conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel, buf->priv.mask.r, buf->priv.mask.g, buf->priv.mask.b, PAL_MODE_NONE, @@ -187,7 +189,7 @@ evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h) { data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + buf->priv.fb.fb->bpp * - (buf->w - x - w + ((buf->h - y - h) * buf->priv.fb.fb->width)); + (buf->w - x - w + ((buf->h - y - h) * buf->priv.fb.fb->stride)); conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel, buf->priv.mask.r, buf->priv.mask.g, buf->priv.mask.b, PAL_MODE_NONE, @@ -197,7 +199,7 @@ evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h) { data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + buf->priv.fb.fb->bpp * - (buf->h - y - h + (x * buf->priv.fb.fb->width)); + (buf->h - y - h + (x * buf->priv.fb.fb->stride)); conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel, buf->priv.mask.r, buf->priv.mask.g, buf->priv.mask.b, PAL_MODE_NONE, @@ -207,7 +209,7 @@ evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h) { data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + buf->priv.fb.fb->bpp * - (y + ((buf->w - x - w) * buf->priv.fb.fb->width)); + (y + ((buf->w - x - w) * buf->priv.fb.fb->stride)); conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel, buf->priv.mask.r, buf->priv.mask.g, buf->priv.mask.b, PAL_MODE_NONE, @@ -222,7 +224,7 @@ evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h) { conv_func(src_data, data, buf->w - w, - buf->priv.fb.fb->width - w, + buf->priv.fb.fb->stride - w, w, h, x, y, NULL); } @@ -230,7 +232,7 @@ evas_fb_outbuf_fb_update(Outbuf *buf, int x, int y, int w, int h) { conv_func(src_data, data, buf->w - w, - buf->priv.fb.fb->width - h, + buf->priv.fb.fb->stride - h, h, w, x, y, NULL); } @@ -289,7 +291,7 @@ evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, in data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + buf->priv.fb.fb->bpp * - (x + (y * buf->priv.fb.fb->width)); + (x + (y * buf->priv.fb.fb->stride)); conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel, buf->priv.mask.r, buf->priv.mask.g, @@ -301,7 +303,7 @@ evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, in data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + buf->priv.fb.fb->bpp * - (buf->w - x - w + ((buf->h - y - h) * buf->priv.fb.fb->width)); + (buf->w - x - w + ((buf->h - y - h) * buf->priv.fb.fb->stride)); conv_func = evas_common_convert_func_get(data, w, h, buf->priv.fb.fb->fb_var.bits_per_pixel, buf->priv.mask.r, buf->priv.mask.g, @@ -313,7 +315,7 @@ evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, in data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + buf->priv.fb.fb->bpp * - (buf->h - y - h + (x * buf->priv.fb.fb->width)); + (buf->h - y - h + (x * buf->priv.fb.fb->stride)); conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel, buf->priv.mask.r, buf->priv.mask.g, @@ -325,7 +327,7 @@ evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, in data = (DATA8 *)buf->priv.fb.fb->mem + buf->priv.fb.fb->mem_offset + buf->priv.fb.fb->bpp * - (y + ((buf->w - x - w) * buf->priv.fb.fb->width)); + (y + ((buf->w - x - w) * buf->priv.fb.fb->stride)); conv_func = evas_common_convert_func_get(data, h, w, buf->priv.fb.fb->fb_var.bits_per_pixel, buf->priv.mask.r, buf->priv.mask.g, @@ -341,7 +343,7 @@ evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, in { conv_func(src_data, data, 0, - buf->priv.fb.fb->width - w, + buf->priv.fb.fb->stride - w, w, h, x, y, NULL); } @@ -349,7 +351,7 @@ evas_fb_outbuf_fb_push_updated_region(Outbuf *buf, RGBA_Image *update, int x, in { conv_func(src_data, data, 0, - buf->priv.fb.fb->width - h, + buf->priv.fb.fb->stride - h, h, w, x, y, NULL); }