evas/fb: use stride instead of width.
authorGustavo Sverzut Barbieri <gustavo.barbieri@intel.com>
Fri, 7 Mar 2014 04:52:11 +0000 (01:52 -0300)
committerGustavo Sverzut Barbieri <gustavo.barbieri@intel.com>
Fri, 7 Mar 2014 05:00:11 +0000 (02:00 -0300)
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
src/modules/evas/engines/fb/evas_fb_main.c
src/modules/evas/engines/fb/evas_outbuf.c

index 97c2cff22485084cbe0b03f32ba48e7887e821cc..20a52cf3fadb0a700b1225728493c052582c34ee 100644 (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;
 };
 
index a6c66f6707868b8cfbf5a032ae5de30b53fdbf00..b93e44080ddbe99af62cf6021158b2cf8abfeb52 100644 (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;
index 0fc7b24864adcea22b3337e60660bb7540fbb7a6..5196507084d0c3f38438674a811f57b25f1bcd79 100644 (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);
               }