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
This commit is contained in:
Gustavo Sverzut Barbieri 2014-03-07 01:52:11 -03:00
parent 182eaad43d
commit 856b7bdf44
3 changed files with 39 additions and 20 deletions

View File

@ -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;
};

View File

@ -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;

View File

@ -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);
}