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:
parent
dc9837ea5f
commit
3e29c69a8d
2 changed files with 76 additions and 21 deletions
4
ChangeLog.scrollopt
Normal file
4
ChangeLog.scrollopt
Normal 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.
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue