aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-02-13 19:00:12 -0800
committerH. Peter Anvin <hpa@zytor.com>2008-02-13 19:00:12 -0800
commitbc1081b746cc3a224470567990364bf62162b405 (patch)
treec713af8aa792ab2f66a0ef88a56e08a46cde84e1
parent2079650b3e6dbe302fe27e5256fd412894c2f4b9 (diff)
downloadsyslinux-bc1081b746cc3a224470567990364bf62162b405.tar.gz
syslinux-bc1081b746cc3a224470567990364bf62162b405.tar.xz
syslinux-bc1081b746cc3a224470567990364bf62162b405.zip
VESA: move pixel formatting into __vesacon_copy_to_screen()syslinux-3.62-pre5
Make pixel formatting an integral part of __vesacon_copy_to_screen(). In order to cut down on the dispatch overhead, make the formatting functions contain the pixel loop, so we only do indirect dispatch twice per pixel row - once for the formatting and once for copying to the screen.
-rw-r--r--com32/lib/Makefile2
-rw-r--r--com32/lib/sys/vesa/background.c9
-rw-r--r--com32/lib/sys/vesa/drawtxt.c10
-rw-r--r--com32/lib/sys/vesa/fmtpixel.c (renamed from com32/lib/sys/vesa/fmtpixel.h)95
-rw-r--r--com32/lib/sys/vesa/initvesa.c1
-rw-r--r--com32/lib/sys/vesa/screencpy.c29
-rw-r--r--com32/lib/sys/vesa/video.h9
7 files changed, 85 insertions, 70 deletions
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index cd0cebd9..cb330242 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -43,7 +43,7 @@ LIBOBJS = \
\
sys/vesacon_write.o sys/vesaserial_write.o \
sys/vesa/initvesa.o sys/vesa/drawtxt.o sys/vesa/background.o \
- sys/vesa/alphatbl.o sys/vesa/screencpy.o \
+ sys/vesa/alphatbl.o sys/vesa/screencpy.o sys/vesa/fmtpixel.o \
\
pci/cfgtype.o pci/scan.o \
pci/readb.o pci/readw.o pci/readl.o pci/readbios.o \
diff --git a/com32/lib/sys/vesa/background.c b/com32/lib/sys/vesa/background.c
index d7a0d019..5794db2e 100644
--- a/com32/lib/sys/vesa/background.c
+++ b/com32/lib/sys/vesa/background.c
@@ -35,7 +35,6 @@
#include <minmax.h>
#include "vesa.h"
#include "video.h"
-#include "fmtpixel.h"
static size_t filesize(FILE *fp)
{
@@ -52,18 +51,12 @@ static size_t filesize(FILE *fp)
aligned dwords. */
static void draw_background_line(int line, int start, int npixels)
{
- uint8_t line_buf[VIDEO_X_SIZE*4], *lbp;
uint32_t *bgptr = &__vesacon_background[line][start];
unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
- enum vesa_pixel_format pixel_format = __vesacon_pixel_format;
uint8_t *fbptr = (uint8_t *)__vesa_info.mi.lfb_ptr +
line*__vesa_info.mi.logical_scan + start*bytes_per_pixel;
- lbp = line_buf;
- while (npixels--)
- lbp = format_pixel(lbp, *bgptr++, pixel_format);
-
- __vesacon_copy_to_screen(fbptr, line_buf, lbp-line_buf);
+ __vesacon_copy_to_screen(fbptr, bgptr, npixels);
}
/* This draws the border, then redraws the text area */
diff --git a/com32/lib/sys/vesa/drawtxt.c b/com32/lib/sys/vesa/drawtxt.c
index 9e222ecc..023c3646 100644
--- a/com32/lib/sys/vesa/drawtxt.c
+++ b/com32/lib/sys/vesa/drawtxt.c
@@ -29,7 +29,6 @@
#include <colortbl.h>
#include "vesa.h"
#include "video.h"
-#include "fmtpixel.h"
#include "fill.h"
/*
@@ -84,7 +83,7 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols)
struct vesa_char *rowptr, *rowsptr, *cptr, *csptr;
unsigned int bytes_per_pixel = __vesacon_bytes_per_pixel;
unsigned long pixel_offset;
- uint8_t row_buffer[VIDEO_X_SIZE*4], *rowbufptr;
+ uint32_t row_buffer[VIDEO_X_SIZE], *rowbufptr;
uint8_t *fbrowptr;
uint8_t sha;
@@ -174,14 +173,11 @@ static void vesacon_update_characters(int row, int col, int nrows, int ncols)
color &= 0x3f3f3f;
}
- rowbufptr = format_pixel(rowbufptr, color, __vesacon_pixel_format);
+ *rowbufptr++ = color;
}
/* Copy to frame buffer */
- /* Note that the dword_count is rounded down, not up. That's because
- the row_buffer includes a spillover pixel. */
- __vesacon_copy_to_screen(fbrowptr, row_buffer,
- (rowbufptr-row_buffer) & ~3);
+ __vesacon_copy_to_screen(fbrowptr, row_buffer, rowbufptr-row_buffer);
bgrowptr += VIDEO_X_SIZE;
fbrowptr += __vesa_info.mi.logical_scan;
diff --git a/com32/lib/sys/vesa/fmtpixel.h b/com32/lib/sys/vesa/fmtpixel.c
index dcde0109..74c79ef1 100644
--- a/com32/lib/sys/vesa/fmtpixel.h
+++ b/com32/lib/sys/vesa/fmtpixel.c
@@ -26,63 +26,76 @@
* ----------------------------------------------------------------------- */
/*
- * fmtpixel.h
+ * fmtpixel.c
*
- * Inline function to format a single pixel
+ * Functions to format a single pixel
*/
-#ifndef LIB_SYS_VESA_FMTPIXEL_H
-#define LIB_SYS_VESA_FMTPIXEL_H
-
#include <inttypes.h>
#include "video.h"
/* Format a pixel and return the advanced pointer.
THIS FUNCTION IS ALLOWED TO WRITE BEYOND THE END OF THE PIXEL. */
-static inline __attribute__((always_inline))
- void *format_pixel(void *ptr, uint32_t bgra, enum vesa_pixel_format fmt)
+static inline uint32_t *copy_dword(uint32_t *dst, const uint32_t *src,
+ size_t dword_count)
{
- switch (fmt) {
- case PXF_BGRA32:
- *(uint32_t *)ptr = bgra;
- ptr = (uint32_t *)ptr + 1;
- break;
-
- case PXF_BGR24:
- *(uint32_t *)ptr = bgra;
- ptr = (uint8_t *)ptr + 3;
- break;
+ asm volatile("cld; rep; movsl"
+ : "+D" (dst), "+S" (src), "+c" (dword_count));
+ return dst; /* Updated destination pointer */
+}
- case PXF_LE_RGB16_565:
- {
- uint16_t pxv =
- ((bgra >> 3) & 0x1f) +
- ((bgra >> (2+8-5)) & (0x3f << 5)) +
- ((bgra >> (3+16-11)) & (0x1f << 11));
+static void *format_pxf_bgra32(void *ptr, const uint32_t *p, size_t n)
+{
+ return copy_dword(ptr, p, n);
+}
- *(uint16_t *)ptr = pxv;
- ptr = (uint16_t *)ptr + 1;
- }
- break;
+static void *format_pxf_bgr24(void *ptr, const uint32_t *p, size_t n)
+{
+ char *q = ptr;
- case PXF_LE_RGB15_555:
- {
- uint16_t pxv =
- ((bgra >> 3) & 0x1f) +
- ((bgra >> (2+8-5)) & (0x1f << 5)) +
- ((bgra >> (3+16-10)) & (0x1f << 10));
+ while (n--) {
+ *(uint32_t *)q = *p++;
+ q += 3;
+ }
+ return q;
+}
- *(uint16_t *)ptr = pxv;
- ptr = (uint16_t *)ptr + 1;
- }
- break;
+static void *format_pxf_le_rgb16_565(void *ptr, const uint32_t *p, size_t n)
+{
+ uint32_t bgra;
+ uint16_t *q = ptr;
- case PXF_NONE: /* Shuts up gcc */
- break;
+ while (n--) {
+ bgra = *p++;
+ *q++ =
+ ((bgra >> 3) & 0x1f) +
+ ((bgra >> (2+8-5)) & (0x3f << 5)) +
+ ((bgra >> (3+16-11)) & (0x1f << 11));
}
+ return q;
+}
- return ptr;
+static void *format_pxf_le_rgb15_555(void *ptr, const uint32_t *p, size_t n)
+{
+ uint32_t bgra;
+ uint16_t *q = ptr;
+
+ while (n--) {
+ bgra = *p++;
+ *q++ =
+ ((bgra >> 3) & 0x1f) +
+ ((bgra >> (2+8-5)) & (0x1f << 5)) +
+ ((bgra >> (3+16-10)) & (0x1f << 10));
+ }
+ return q;
}
-#endif /* LIB_SYS_VESA_FMTPIXEL_H */
+__vesacon_format_pixels_t __vesacon_format_pixels;
+
+const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE] = {
+ [PXF_BGRA32] = format_pxf_bgra32,
+ [PXF_BGR24] = format_pxf_bgr24,
+ [PXF_LE_RGB16_565] = format_pxf_le_rgb16_565,
+ [PXF_LE_RGB15_555] = format_pxf_le_rgb15_555,
+};
diff --git a/com32/lib/sys/vesa/initvesa.c b/com32/lib/sys/vesa/initvesa.c
index d5aa9ba7..b5aba989 100644
--- a/com32/lib/sys/vesa/initvesa.c
+++ b/com32/lib/sys/vesa/initvesa.c
@@ -236,6 +236,7 @@ static int vesacon_set_mode(void)
mi = &__vesa_info.mi;
mode = bestmode;
__vesacon_bytes_per_pixel = (mi->bpp+7) >> 3;
+ __vesacon_format_pixels = __vesacon_format_pixels_list[bestpxf];
/* Download the SYSLINUX- or BIOS-provided font */
rm.eax.w[0] = 0x0018; /* Query custom font */
diff --git a/com32/lib/sys/vesa/screencpy.c b/com32/lib/sys/vesa/screencpy.c
index a8be4306..f526de5a 100644
--- a/com32/lib/sys/vesa/screencpy.c
+++ b/com32/lib/sys/vesa/screencpy.c
@@ -42,7 +42,7 @@ static struct win_info {
} wi;
static void *
-vesacon_copy_to_paged_screen(void *dst, const void *src, size_t len);
+memcpy_to_paged_screen(void *dst, const void *src, size_t len);
static inline int __constfunc ilog2(unsigned int x)
{
@@ -50,15 +50,17 @@ static inline int __constfunc ilog2(unsigned int x)
return x;
}
+static void * (*memcpy_to_screen)(void *, const void *, size_t);
+
void __vesacon_init_copy_to_screen(void)
{
struct vesa_mode_info * const mi = &__vesa_info.mi;
int winn;
if (mi->mode_attr & 0x0080) {
- __vesacon_copy_to_screen = memcpy; /* Really easy... */
+ memcpy_to_screen = memcpy;
} else {
- __vesacon_copy_to_screen = vesacon_copy_to_paged_screen;
+ memcpy_to_screen = memcpy_to_paged_screen;
mi->lfb_ptr = 0; /* Zero-base this */
wi.win_pos = -1; /* Undefined position */
@@ -76,8 +78,17 @@ void __vesacon_init_copy_to_screen(void)
}
}
+void __vesacon_copy_to_screen(void *dst, const uint32_t *src, size_t npixels)
+{
+ size_t bytes = npixels * __vesacon_bytes_per_pixel;
+ char rowbuf[bytes+4];
+
+ __vesacon_format_pixels(rowbuf, src, npixels);
+ memcpy_to_screen(dst, rowbuf, bytes);
+}
+
static void *
-vesacon_copy_to_paged_screen(void *dst, const void *src, size_t len)
+memcpy_to_paged_screen(void *dst, const void *src, size_t len)
{
size_t win_pos, win_off;
size_t win_size = wi.win_size;
@@ -86,18 +97,16 @@ vesacon_copy_to_paged_screen(void *dst, const void *src, size_t len)
size_t l;
size_t d = (size_t)dst;
const char *s = src;
- com32sys_t ireg;
-
- memset(&ireg, 0, sizeof ireg);
- ireg.eax.w[0] = 0x4F05; /* VBE Window Control */
- /* BH = 0 -> Set memory window */
- ireg.ebx.b[0] = wi.win_num;
while (len) {
win_off = d & omask;
win_pos = d & ~omask;
if (win_pos != wi.win_pos) {
+ com32sys_t ireg;
+ memset(&ireg, 0, sizeof ireg);
+ ireg.eax.w[0] = 0x4F05;
+ ireg.ebx.b[0] = wi.win_num;
ireg.edx.w[0] = win_pos >> wi.win_gshift;
__intcall(0x10, &ireg, NULL);
wi.win_pos = win_pos;
diff --git a/com32/lib/sys/vesa/video.h b/com32/lib/sys/vesa/video.h
index 699d4e9a..39052087 100644
--- a/com32/lib/sys/vesa/video.h
+++ b/com32/lib/sys/vesa/video.h
@@ -58,12 +58,15 @@ enum vesa_pixel_format {
PXF_LE_RGB15_555, /* 15-bit littleendian 5:5:5 RGB */
PXF_NONE
};
+extern enum vesa_pixel_format __vesacon_pixel_format;
+extern unsigned int __vesacon_bytes_per_pixel;
+typedef void * (*__vesacon_format_pixels_t)(void *, const uint32_t *, size_t);
+extern __vesacon_format_pixels_t __vesacon_format_pixels;
+extern const __vesacon_format_pixels_t __vesacon_format_pixels_list[PXF_NONE];
extern struct vesa_char *__vesacon_text_display;
extern int __vesacon_font_height, __vesacon_text_rows;
-extern enum vesa_pixel_format __vesacon_pixel_format;
-extern unsigned int __vesacon_bytes_per_pixel;
extern uint8_t __vesacon_graphics_font[FONT_MAX_CHARS][FONT_MAX_HEIGHT];
extern uint32_t __vesacon_background[VIDEO_Y_SIZE][VIDEO_X_SIZE];
extern uint32_t __vesacon_shadowfb[VIDEO_Y_SIZE][VIDEO_X_SIZE];
@@ -81,7 +84,7 @@ void __vesacon_write_char(int, int, uint8_t, attr_t);
void __vesacon_redraw_text(void);
void __vesacon_doit(void);
void __vesacon_set_cursor(int, int, int);
-void * (*__vesacon_copy_to_screen)(void *, const void *, size_t);
+void __vesacon_copy_to_screen(void *, const uint32_t *, size_t);
void __vesacon_init_copy_to_screen(void);
#endif /* LIB_SYS_VESA_VIDEO_H */