[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [patch] incorrect VGA initialization, can provide imag
From: |
Piotr Krysik |
Subject: |
Re: [Qemu-devel] [patch] incorrect VGA initialization, can provide image |
Date: |
Fri, 10 Sep 2004 11:34:45 -0700 (PDT) |
Update of font memory is now detected during
vga_draw_text. I also added time-to-live for
font cache to limit memory bandwidth required
for cache validation (overkill?).
Please review.
Piotrek
--- Fabrice Bellard <address@hidden> wrote:
> OK for the idea, but it is not acceptable to slow
> down the VGA write functions just to detect the
> font change. Another solution must be found.
>
> Fabrice.
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!
http://promotions.yahoo.com/new_mail
diff -ru qemu-snapshot-2004-08-04_23/hw/vga.c
qemu-snapshot-2004-08-04_23-vga-update/hw/vga.c
--- qemu-snapshot-2004-08-04_23/hw/vga.c 2004-06-26 18:12:26.000000000
+0200
+++ qemu-snapshot-2004-08-04_23-vga-update/hw/vga.c 2004-09-10
20:11:00.000000000 +0200
@@ -935,6 +935,60 @@
return full_update;
}
+/* return true if the font was modified */
+static int update_font_cache(uint8_t *font_ptr, uint8_t *vram_font_ptr)
+{
+ int full_update;
+ uint8_t *font_end;
+
+ full_update = 0;
+ font_end = font_ptr + 0x2000;
+ while (font_ptr < font_end) {
+ if (*font_ptr != *vram_font_ptr) {
+ *font_ptr = *vram_font_ptr;
+ full_update = 1;
+ }
+ font_ptr ++;
+ vram_font_ptr += 4;
+ }
+ return full_update;
+}
+
+/* return true if any of the font was modified */
+static int update_font(VGAState *s)
+{
+ int full_update;
+ uint32_t v, offset;
+
+ if (s->font_ttl > 0) {
+ s->font_ttl --;
+ return 0;
+ }
+
+ v = s->sr[3];
+ /* font A */
+ offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
+ full_update = update_font_cache(s->font[0], s->vram_ptr + offset);
+ /* font B */
+ offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
+ full_update |= update_font_cache(s->font[1], s->vram_ptr + offset);
+
+ if (full_update) {
+ s->font_ttl = s->font_age >> 1;
+ s->font_age = s->font_ttl + 1; /* age for next update */
+ } else {
+ s->font_ttl = s->font_age;
+ s->font_age += s->font_ttl; /* age for next update */
+ if (s->font_age > 16)
+ s->font_age = 16; /* limit ttl for next update */
+ }
+#if defined(DEBUG_VGA)
+ printf("vga: font cache full_update=%d age=%d ttl=%d\n",
+ full_update, s->font_age, s->font_ttl);
+#endif
+ return full_update;
+}
+
static void vga_get_offsets(VGAState *s,
uint32_t *pline_offset,
uint32_t *pstart_addr)
@@ -1062,7 +1116,7 @@
{
int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr;
int cx_min, cx_max, linesize, x_incr;
- uint32_t offset, fgcol, bgcol, v, cursor_offset;
+ uint32_t fgcol, bgcol, cursor_offset;
uint8_t *d1, *d, *src, *s1, *dest, *cursor_ptr;
const uint8_t *font_ptr, *font_base[2];
int dup9, line_offset, depth_index;
@@ -1073,22 +1127,10 @@
full_update |= update_palette16(s);
palette = s->last_palette;
-
- /* compute font data address (in plane 2) */
- v = s->sr[3];
- offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
- if (offset != s->font_offsets[0]) {
- s->font_offsets[0] = offset;
- full_update = 1;
- }
- font_base[0] = s->vram_ptr + offset;
- offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
- font_base[1] = s->vram_ptr + offset;
- if (offset != s->font_offsets[1]) {
- s->font_offsets[1] = offset;
- full_update = 1;
- }
+ full_update |= update_font(s);
+ font_base[0] = s->font[0];
+ font_base[1] = s->font[1];
full_update |= update_basic_params(s);
@@ -1176,7 +1218,7 @@
cattr = ch_attr >> 8;
#endif
font_ptr = font_base[(cattr >> 3) & 1];
- font_ptr += 32 * 4 * ch;
+ font_ptr += 32 * ch;
bgcol = palette[cattr >> 4];
fgcol = palette[cattr & 0x0f];
if (cw != 9) {
@@ -1594,6 +1636,8 @@
s->cr[0x30] = 0xe1;
#endif
s->graphic_mode = -1; /* force full update */
+ s->font_age = 0;
+ s->font_ttl = 0;
}
static CPUReadMemoryFunc *vga_mem_read[3] = {
diff -ru qemu-snapshot-2004-08-04_23/hw/vga_int.h
qemu-snapshot-2004-08-04_23-vga-update/hw/vga_int.h
--- qemu-snapshot-2004-08-04_23/hw/vga_int.h 2004-06-08 02:59:19.000000000
+0200
+++ qemu-snapshot-2004-08-04_23-vga-update/hw/vga_int.h 2004-09-10
19:29:19.000000000 +0200
@@ -109,8 +109,10 @@
VGA_STATE_COMMON_BOCHS_VBE \
/* display refresh support */ \
DisplayState *ds; \
- uint32_t font_offsets[2]; \
int graphic_mode; \
+ uint8_t font[2][0x2000]; \
+ uint8_t font_age; \
+ uint8_t font_ttl; \
uint8_t shift_control; \
uint8_t double_scan; \
uint32_t line_offset; \
diff -ru qemu-snapshot-2004-08-04_23/hw/vga_template.h
qemu-snapshot-2004-08-04_23-vga-update/hw/vga_template.h
--- qemu-snapshot-2004-08-04_23/hw/vga_template.h 2004-06-21
18:56:45.000000000 +0200
+++ qemu-snapshot-2004-08-04_23-vga-update/hw/vga_template.h 2004-09-10
17:58:31.000000000 +0200
@@ -72,7 +72,7 @@
do {
font_data = font_ptr[0];
glue(vga_draw_glyph_line_, DEPTH)(d, font_data, xorcol, bgcol);
- font_ptr += 4;
+ font_ptr ++;
d += linesize;
} while (--h);
}
@@ -92,7 +92,7 @@
glue(vga_draw_glyph_line_, DEPTH)(d + 8 * BPP,
expand4to8[font_data & 0x0f],
xorcol, bgcol);
- font_ptr += 4;
+ font_ptr ++;
d += linesize;
} while (--h);
}
@@ -141,7 +141,7 @@
else
((uint32_t *)d)[8] = bgcol;
#endif
- font_ptr += 4;
+ font_ptr ++;
d += linesize;
} while (--h);
}