vga: introduce VGADisplayParams

The next patches will introduce more parameters that cause a full
refresh.  Instead of adding arguments to get_offsets and lines to
update_basic_params, do everything through a struct.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2015-01-09 10:47:33 +01:00
parent 937de9a981
commit f9b925fd41
3 changed files with 52 additions and 69 deletions

View File

@ -798,8 +798,8 @@ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
if (blit_is_unsafe(s, false)) if (blit_is_unsafe(s, false))
return 0; return 0;
return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.params.start_addr,
s->cirrus_blt_srcaddr - s->vga.start_addr, s->cirrus_blt_srcaddr - s->vga.params.start_addr,
s->cirrus_blt_width, s->cirrus_blt_height); s->cirrus_blt_width, s->cirrus_blt_height);
} }
@ -1101,30 +1101,26 @@ static void cirrus_write_bitblt(CirrusVGAState * s, unsigned reg_value)
* *
***************************************/ ***************************************/
static void cirrus_get_offsets(VGACommonState *s1, static void cirrus_get_params(VGACommonState *s1,
uint32_t *pline_offset, VGADisplayParams *params)
uint32_t *pstart_addr,
uint32_t *pline_compare)
{ {
CirrusVGAState * s = container_of(s1, CirrusVGAState, vga); CirrusVGAState * s = container_of(s1, CirrusVGAState, vga);
uint32_t start_addr, line_offset, line_compare; uint32_t line_offset;
line_offset = s->vga.cr[0x13] line_offset = s->vga.cr[0x13]
| ((s->vga.cr[0x1b] & 0x10) << 4); | ((s->vga.cr[0x1b] & 0x10) << 4);
line_offset <<= 3; line_offset <<= 3;
*pline_offset = line_offset; params->line_offset = line_offset;
start_addr = (s->vga.cr[0x0c] << 8) params->start_addr = (s->vga.cr[0x0c] << 8)
| s->vga.cr[0x0d] | s->vga.cr[0x0d]
| ((s->vga.cr[0x1b] & 0x01) << 16) | ((s->vga.cr[0x1b] & 0x01) << 16)
| ((s->vga.cr[0x1b] & 0x0c) << 15) | ((s->vga.cr[0x1b] & 0x0c) << 15)
| ((s->vga.cr[0x1d] & 0x80) << 12); | ((s->vga.cr[0x1d] & 0x80) << 12);
*pstart_addr = start_addr;
line_compare = s->vga.cr[0x18] | params->line_compare = s->vga.cr[0x18] |
((s->vga.cr[0x07] & 0x10) << 4) | ((s->vga.cr[0x07] & 0x10) << 4) |
((s->vga.cr[0x09] & 0x40) << 3); ((s->vga.cr[0x09] & 0x40) << 3);
*pline_compare = line_compare;
} }
static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s) static uint32_t cirrus_get_bpp16_depth(CirrusVGAState * s)
@ -2925,7 +2921,7 @@ void cirrus_init_common(CirrusVGAState *s, Object *owner,
s->linear_mmio_mask = s->real_vram_size - 256; s->linear_mmio_mask = s->real_vram_size - 256;
s->vga.get_bpp = cirrus_get_bpp; s->vga.get_bpp = cirrus_get_bpp;
s->vga.get_offsets = cirrus_get_offsets; s->vga.get_params = cirrus_get_params;
s->vga.get_resolution = cirrus_get_resolution; s->vga.get_resolution = cirrus_get_resolution;
s->vga.cursor_invalidate = cirrus_cursor_invalidate; s->vga.cursor_invalidate = cirrus_cursor_invalidate;
s->vga.cursor_draw_line = cirrus_cursor_draw_line; s->vga.cursor_draw_line = cirrus_cursor_draw_line;

View File

@ -1042,52 +1042,40 @@ static int update_palette256(VGACommonState *s)
return full_update; return full_update;
} }
static void vga_get_offsets(VGACommonState *s, static void vga_get_params(VGACommonState *s,
uint32_t *pline_offset, VGADisplayParams *params)
uint32_t *pstart_addr,
uint32_t *pline_compare)
{ {
uint32_t start_addr, line_offset, line_compare;
if (vbe_enabled(s)) { if (vbe_enabled(s)) {
line_offset = s->vbe_line_offset; params->line_offset = s->vbe_line_offset;
start_addr = s->vbe_start_addr; params->start_addr = s->vbe_start_addr;
line_compare = 65535; params->line_compare = 65535;
} else { } else {
/* compute line_offset in bytes */ /* compute line_offset in bytes */
line_offset = s->cr[VGA_CRTC_OFFSET]; params->line_offset = s->cr[VGA_CRTC_OFFSET] << 3;
line_offset <<= 3;
/* starting address */ /* starting address */
start_addr = s->cr[VGA_CRTC_START_LO] | params->start_addr = s->cr[VGA_CRTC_START_LO] |
(s->cr[VGA_CRTC_START_HI] << 8); (s->cr[VGA_CRTC_START_HI] << 8);
/* line compare */ /* line compare */
line_compare = s->cr[VGA_CRTC_LINE_COMPARE] | params->line_compare = s->cr[VGA_CRTC_LINE_COMPARE] |
((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) | ((s->cr[VGA_CRTC_OVERFLOW] & 0x10) << 4) |
((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3); ((s->cr[VGA_CRTC_MAX_SCAN] & 0x40) << 3);
} }
*pline_offset = line_offset;
*pstart_addr = start_addr;
*pline_compare = line_compare;
} }
/* update start_addr and line_offset. Return TRUE if modified */ /* update start_addr and line_offset. Return TRUE if modified */
static int update_basic_params(VGACommonState *s) static int update_basic_params(VGACommonState *s)
{ {
int full_update; int full_update;
uint32_t start_addr, line_offset, line_compare; VGADisplayParams current;
full_update = 0; full_update = 0;
s->get_offsets(s, &line_offset, &start_addr, &line_compare); s->get_params(s, &current);
if (line_offset != s->line_offset || if (memcmp(&current, &s->params, sizeof(current))) {
start_addr != s->start_addr || s->params = current;
line_compare != s->line_compare) {
s->line_offset = line_offset;
s->start_addr = start_addr;
s->line_compare = line_compare;
full_update = 1; full_update = 1;
} }
return full_update; return full_update;
@ -1188,7 +1176,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
} }
full_update |= update_basic_params(s); full_update |= update_basic_params(s);
line_offset = s->line_offset; line_offset = s->params.line_offset;
vga_get_text_resolution(s, &width, &height, &cw, &cheight); vga_get_text_resolution(s, &width, &height, &cw, &cheight);
if ((height * width) <= 1) { if ((height * width) <= 1) {
@ -1227,7 +1215,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
} }
cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) | cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr; s->cr[VGA_CRTC_CURSOR_LO]) - s->params.start_addr;
if (cursor_offset != s->cursor_offset || if (cursor_offset != s->cursor_offset ||
s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start || s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) { s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end) {
@ -1241,7 +1229,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
s->cursor_start = s->cr[VGA_CRTC_CURSOR_START]; s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
s->cursor_end = s->cr[VGA_CRTC_CURSOR_END]; s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
} }
cursor_ptr = s->vram_ptr + (s->start_addr + cursor_offset) * 4; cursor_ptr = s->vram_ptr + (s->params.start_addr + cursor_offset) * 4;
if (now >= s->cursor_blink_time) { if (now >= s->cursor_blink_time) {
s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2; s->cursor_blink_time = now + VGA_TEXT_CURSOR_PERIOD_MS / 2;
s->cursor_visible_phase = !s->cursor_visible_phase; s->cursor_visible_phase = !s->cursor_visible_phase;
@ -1251,7 +1239,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
linesize = surface_stride(surface); linesize = surface_stride(surface);
ch_attr_ptr = s->last_ch_attr; ch_attr_ptr = s->last_ch_attr;
line = 0; line = 0;
offset = s->start_addr * 4; offset = s->params.start_addr * 4;
for(cy = 0; cy < height; cy++) { for(cy = 0; cy < height; cy++) {
d1 = dest; d1 = dest;
src = s->vram_ptr + offset; src = s->vram_ptr + offset;
@ -1331,7 +1319,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
dest += linesize * cheight; dest += linesize * cheight;
line1 = line + cheight; line1 = line + cheight;
offset += line_offset; offset += line_offset;
if (line < s->line_compare && line1 >= s->line_compare) { if (line < s->params.line_compare && line1 >= s->params.line_compare) {
offset = 0; offset = 0;
} }
line = line1; line = line1;
@ -1461,10 +1449,10 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
disp_width = width; disp_width = width;
depth = s->get_bpp(s); depth = s->get_bpp(s);
region_start = (s->start_addr * 4); region_start = (s->params.start_addr * 4);
region_end = region_start + (ram_addr_t)s->line_offset * height; region_end = region_start + (ram_addr_t)s->params.line_offset * height;
region_end += width * depth / 8; /* scanline length */ region_end += width * depth / 8; /* scanline length */
region_end -= s->line_offset; region_end -= s->params.line_offset;
if (region_end > s->vbe_size || depth == 0 || depth == 15) { if (region_end > s->vbe_size || depth == 0 || depth == 15) {
/* /*
* We land here on: * We land here on:
@ -1529,7 +1517,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
share_surface = false; share_surface = false;
} }
if (s->line_offset != s->last_line_offset || if (s->params.line_offset != s->last_line_offset ||
disp_width != s->last_width || disp_width != s->last_width ||
height != s->last_height || height != s->last_height ||
s->last_depth != depth || s->last_depth != depth ||
@ -1540,12 +1528,12 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
s->last_scr_height = height; s->last_scr_height = height;
s->last_width = disp_width; s->last_width = disp_width;
s->last_height = height; s->last_height = height;
s->last_line_offset = s->line_offset; s->last_line_offset = s->params.line_offset;
s->last_depth = depth; s->last_depth = depth;
s->last_byteswap = byteswap; s->last_byteswap = byteswap;
full_update = 1; full_update = 1;
} }
if (surface_data(surface) != s->vram_ptr + (s->start_addr * 4) if (surface_data(surface) != s->vram_ptr + (s->params.start_addr * 4)
&& is_buffer_shared(surface)) { && is_buffer_shared(surface)) {
/* base address changed (page flip) -> shared display surfaces /* base address changed (page flip) -> shared display surfaces
* must be updated with the new base address */ * must be updated with the new base address */
@ -1555,8 +1543,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
if (full_update) { if (full_update) {
if (share_surface) { if (share_surface) {
surface = qemu_create_displaysurface_from(disp_width, surface = qemu_create_displaysurface_from(disp_width,
height, format, s->line_offset, height, format, s->params.line_offset,
s->vram_ptr + (s->start_addr * 4)); s->vram_ptr + (s->params.start_addr * 4));
dpy_gfx_replace_surface(s->con, surface); dpy_gfx_replace_surface(s->con, surface);
} else { } else {
qemu_console_resize(s->con, disp_width, height); qemu_console_resize(s->con, disp_width, height);
@ -1620,9 +1608,9 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
#if 0 #if 0
printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n", printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",
width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE], width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE],
s->line_compare, sr(s, VGA_SEQ_CLOCK_MODE)); s->params.line_compare, sr(s, VGA_SEQ_CLOCK_MODE));
#endif #endif
addr1 = (s->start_addr * 4); addr1 = (s->params.start_addr * 4);
bwidth = DIV_ROUND_UP(width * bits, 8); bwidth = DIV_ROUND_UP(width * bits, 8);
y_start = -1; y_start = -1;
d = surface_data(surface); d = surface_data(surface);
@ -1630,7 +1618,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
y1 = 0; y1 = 0;
if (!full_update) { if (!full_update) {
if (s->line_compare < height) { if (s->params.line_compare < height) {
/* split screen mode */ /* split screen mode */
region_start = 0; region_start = 0;
} }
@ -1686,14 +1674,14 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
if (!multi_run) { if (!multi_run) {
mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3; mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3;
if ((y1 & mask) == mask) if ((y1 & mask) == mask)
addr1 += s->line_offset; addr1 += s->params.line_offset;
y1++; y1++;
multi_run = multi_scan; multi_run = multi_scan;
} else { } else {
multi_run--; multi_run--;
} }
/* line compare acts on the displayed lines */ /* line compare acts on the displayed lines */
if (y == s->line_compare) if (y == s->params.line_compare)
addr1 = 0; addr1 = 0;
d += linesize; d += linesize;
} }
@ -1810,9 +1798,7 @@ void vga_common_reset(VGACommonState *s)
s->graphic_mode = -1; /* force full update */ s->graphic_mode = -1; /* force full update */
s->shift_control = 0; s->shift_control = 0;
s->double_scan = 0; s->double_scan = 0;
s->line_offset = 0; memset(&s->params, '\0', sizeof(s->params));
s->line_compare = 0;
s->start_addr = 0;
s->plane_updated = 0; s->plane_updated = 0;
s->last_cw = 0; s->last_cw = 0;
s->last_ch = 0; s->last_ch = 0;
@ -1934,7 +1920,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
/* Update "hardware" cursor */ /* Update "hardware" cursor */
cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) | cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr; s->cr[VGA_CRTC_CURSOR_LO]) - s->params.start_addr;
if (cursor_offset != s->cursor_offset || if (cursor_offset != s->cursor_offset ||
s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start || s->cr[VGA_CRTC_CURSOR_START] != s->cursor_start ||
s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) { s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
@ -1950,7 +1936,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
s->cursor_end = s->cr[VGA_CRTC_CURSOR_END]; s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
} }
src = (uint32_t *) s->vram_ptr + s->start_addr; src = (uint32_t *) s->vram_ptr + s->params.start_addr;
dst = chardata; dst = chardata;
if (full_update) { if (full_update) {
@ -2195,7 +2181,7 @@ bool vga_common_init(VGACommonState *s, Object *obj, Error **errp)
xen_register_framebuffer(&s->vram); xen_register_framebuffer(&s->vram);
s->vram_ptr = memory_region_get_ram_ptr(&s->vram); s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
s->get_bpp = vga_get_bpp; s->get_bpp = vga_get_bpp;
s->get_offsets = vga_get_offsets; s->get_params = vga_get_params;
s->get_resolution = vga_get_resolution; s->get_resolution = vga_get_resolution;
s->hw_ops = &vga_ops; s->hw_ops = &vga_ops;
switch (vga_retrace_method) { switch (vga_retrace_method) {

View File

@ -56,6 +56,12 @@ struct VGACommonState;
typedef uint8_t (* vga_retrace_fn)(struct VGACommonState *s); typedef uint8_t (* vga_retrace_fn)(struct VGACommonState *s);
typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s); typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s);
typedef struct VGADisplayParams {
uint32_t line_offset;
uint32_t start_addr;
uint32_t line_compare;
} VGADisplayParams;
typedef struct VGACommonState { typedef struct VGACommonState {
MemoryRegion *legacy_address_space; MemoryRegion *legacy_address_space;
uint8_t *vram_ptr; uint8_t *vram_ptr;
@ -90,10 +96,7 @@ typedef struct VGACommonState {
uint8_t palette[768]; uint8_t palette[768];
int32_t bank_offset; int32_t bank_offset;
int (*get_bpp)(struct VGACommonState *s); int (*get_bpp)(struct VGACommonState *s);
void (*get_offsets)(struct VGACommonState *s, void (*get_params)(struct VGACommonState *s, VGADisplayParams *params);
uint32_t *pline_offset,
uint32_t *pstart_addr,
uint32_t *pline_compare);
void (*get_resolution)(struct VGACommonState *s, void (*get_resolution)(struct VGACommonState *s,
int *pwidth, int *pwidth,
int *pheight); int *pheight);
@ -111,9 +114,7 @@ typedef struct VGACommonState {
int graphic_mode; int graphic_mode;
uint8_t shift_control; uint8_t shift_control;
uint8_t double_scan; uint8_t double_scan;
uint32_t line_offset; VGADisplayParams params;
uint32_t line_compare;
uint32_t start_addr;
uint32_t plane_updated; uint32_t plane_updated;
uint32_t last_line_offset; uint32_t last_line_offset;
uint8_t last_cw, last_ch; uint8_t last_cw, last_ch;