]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2009-11-30 Vladimir Serbinenko <phcoder@gmail.com>
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 30 Nov 2009 09:58:06 +0000 (10:58 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Mon, 30 Nov 2009 09:58:06 +0000 (10:58 +0100)
* video/fb/video_fb.c (grub_video_fb_scroll): Optimise by avoiding
unnecessary calls.

ChangeLog.scrollopt [new file with mode: 0644]
video/fb/video_fb.c

diff --git a/ChangeLog.scrollopt b/ChangeLog.scrollopt
new file mode 100644 (file)
index 0000000..c677a23
--- /dev/null
@@ -0,0 +1,4 @@
+2009-11-30  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * video/fb/video_fb.c (grub_video_fb_scroll): Optimise by avoiding
+       unnecessary calls.
index 5f2917da6dcb22945a22d6b229de2ecc40fe9147..15c30c23b8948ba9ef5c682fb1ce6f84f68417a0 100644 (file)
@@ -974,32 +974,83 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
     {
       /* 3. Move data in render target.  */
       struct grub_video_fbblit_info target;
-      grub_uint8_t *src;
-      grub_uint8_t *dst;
-      int j;
+      int i, j;
+      int linedelta, linelen;
 
       target.mode_info = &render_target->mode_info;
       target.data = render_target->data;
 
-      /* Check vertical direction of the move.  */
-      if (dy <= 0)
-       /* 3a. Move data upwards.  */
-       for (j = 0; j < height; j++)
-         {
-           dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j);
-           src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j);
-           grub_memmove (dst, src,
-                         width * target.mode_info->bytes_per_pixel);
-         }
+      linedelta = target.mode_info->pitch
+       - width * target.mode_info->bytes_per_pixel;
+      linelen = width * target.mode_info->bytes_per_pixel;
+#define DO_SCROLL                                                    \
+      /* Check vertical direction of the move.  */                   \
+      if (dy < 0 || (dy == 0 && dx < 0))                             \
+       {                                                            \
+         dst = (void *) grub_video_fb_get_video_ptr (&target,       \
+                                                     dst_x, dst_y); \
+         src = (void *) grub_video_fb_get_video_ptr (&target,       \
+                                                     src_x, src_y); \
+         /* 3a. Move data upwards.  */                              \
+         for (j = 0; j < height; j++)                               \
+           {                                                        \
+             for (i = 0; i < linelen; i++)                          \
+               *(dst++) = *(src++);                                 \
+             dst += linedelta;                                      \
+             src += linedelta;                                      \
+           }                                                        \
+       }                                                            \
+      else                                                           \
+       {                                                            \
+         /* 3b. Move data downwards.  */                            \
+         dst = (void *) grub_video_fb_get_video_ptr (&target,       \
+                                            dst_x + width - 1,      \
+                                            dst_y + height - 1);    \
+         src = (void *) grub_video_fb_get_video_ptr (&target,       \
+                                            src_x + width - 1,      \
+                                            src_y + height - 1);    \
+         for (j = 0; j < height; j++)                               \
+           {                                                        \
+             for (i = 0; i < linelen; i++)                          \
+               *(dst--) = *(src--);                                 \
+             dst -= linedelta;                                      \
+             src -= linedelta;                                      \
+           }                                                        \
+       }
+
+      /* If everything is aligned on 32-bit use 32-bit copy.  */
+      if ((grub_addr_t) grub_video_fb_get_video_ptr (&target, src_x, src_y)
+         % sizeof (grub_uint32_t) == 0
+         && (grub_addr_t) grub_video_fb_get_video_ptr (&target, dst_x, dst_y) 
+         % sizeof (grub_uint32_t) == 0
+         && linelen % sizeof (grub_uint32_t) == 0
+         && linedelta % sizeof (grub_uint32_t) == 0)
+       {
+         grub_uint32_t *src, *dst;
+         linelen /= sizeof (grub_uint32_t);
+         linedelta /= sizeof (grub_uint32_t);
+         DO_SCROLL
+       }
+      /* If everything is aligned on 16-bit use 16-bit copy.  */
+      else if ((grub_addr_t) grub_video_fb_get_video_ptr (&target, src_x, src_y)
+              % sizeof (grub_uint16_t) == 0
+              && (grub_addr_t) grub_video_fb_get_video_ptr (&target,
+                                                            dst_x, dst_y) 
+              % sizeof (grub_uint16_t) == 0
+              && linelen % sizeof (grub_uint16_t) == 0
+              && linedelta % sizeof (grub_uint16_t) == 0)
+       {
+         grub_uint16_t *src, *dst;
+         linelen /= sizeof (grub_uint16_t);
+         linedelta /= sizeof (grub_uint16_t);
+         DO_SCROLL
+       }
+      /* If not aligned at all use 8-bit copy.  */
       else
-       /* 3b. Move data downwards.  */
-       for (j = (height - 1); j >= 0; j--)
-         {
-           dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j);
-           src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j);
-           grub_memmove (dst, src,
-                         width * target.mode_info->bytes_per_pixel);
-         }
+       {
+         grub_uint8_t *src, *dst;
+         DO_SCROLL
+       }       
     }
 
   /* 4. Fill empty space with specified color.  In this implementation