2009-11-30 Vladimir Serbinenko <phcoder@gmail.com>

* video/fb/video_fb.c (grub_video_fb_scroll): Optimise by avoiding
	unnecessary calls.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2009-11-30 10:58:06 +01:00
parent dc9837ea5f
commit 3e29c69a8d
2 changed files with 76 additions and 21 deletions

4
ChangeLog.scrollopt Normal file
View file

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

View file

@ -974,31 +974,82 @@ grub_video_fb_scroll (grub_video_color_t color, int dx, int dy)
{ {
/* 3. Move data in render target. */ /* 3. Move data in render target. */
struct grub_video_fbblit_info target; struct grub_video_fbblit_info target;
grub_uint8_t *src; int i, j;
grub_uint8_t *dst; int linedelta, linelen;
int j;
target.mode_info = &render_target->mode_info; target.mode_info = &render_target->mode_info;
target.data = render_target->data; target.data = render_target->data;
/* Check vertical direction of the move. */ linedelta = target.mode_info->pitch
if (dy <= 0) - width * target.mode_info->bytes_per_pixel;
/* 3a. Move data upwards. */ linelen = width * target.mode_info->bytes_per_pixel;
for (j = 0; j < height; j++) #define DO_SCROLL \
{ /* Check vertical direction of the move. */ \
dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j); if (dy < 0 || (dy == 0 && dx < 0)) \
src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j); { \
grub_memmove (dst, src, dst = (void *) grub_video_fb_get_video_ptr (&target, \
width * target.mode_info->bytes_per_pixel); 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; \
} \
} }
else
/* 3b. Move data downwards. */ /* If everything is aligned on 32-bit use 32-bit copy. */
for (j = (height - 1); j >= 0; j--) 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)
{ {
dst = grub_video_fb_get_video_ptr (&target, dst_x, dst_y + j); grub_uint32_t *src, *dst;
src = grub_video_fb_get_video_ptr (&target, src_x, src_y + j); linelen /= sizeof (grub_uint32_t);
grub_memmove (dst, src, linedelta /= sizeof (grub_uint32_t);
width * target.mode_info->bytes_per_pixel); 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
{
grub_uint8_t *src, *dst;
DO_SCROLL
} }
} }