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,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