static void vgafb_update_display(void *opaque) { MilkymistVgafbState *s = opaque; DisplaySurface *surface = qemu_console_surface(s->con); int first = 0; int last = 0; drawfn fn; if (!vgafb_enabled(s)) { return; } int dest_width = s->regs[R_HRES]; switch (surface_bits_per_pixel(surface)) { case 0: return; case 8: fn = draw_line_8; break; case 15: fn = draw_line_15; dest_width *= 2; break; case 16: fn = draw_line_16; dest_width *= 2; break; case 24: fn = draw_line_24; dest_width *= 3; break; case 32: fn = draw_line_32; dest_width *= 4; break; default: hw_error("milkymist_vgafb: bad color depth\n"); break; } framebuffer_update_display(surface, sysbus_address_space(&s->busdev), s->regs[R_BASEADDRESS] + s->fb_offset, s->regs[R_HRES], s->regs[R_VRES], s->regs[R_HRES] * 2, dest_width, 0, s->invalidate, fn, NULL, &first, &last); if (first >= 0) { dpy_gfx_update(s->con, 0, first, s->regs[R_HRES], last - first + 1); } s->invalidate = 0; }
static void goldfish_fb_update_display(void *opaque) { struct goldfish_fb_state *s = (struct goldfish_fb_state *)opaque; DisplaySurface *ds = qemu_console_surface(s->con); int full_update = 0; if (!s || !s->con || surface_bits_per_pixel(ds) == 0 || !s->fb_base) return; if((s->int_enable & FB_INT_VSYNC) && !(s->int_status & FB_INT_VSYNC)) { s->int_status |= FB_INT_VSYNC; qemu_irq_raise(s->irq); } if(s->need_update) { full_update = 1; if(s->need_int) { s->int_status |= FB_INT_BASE_UPDATE_DONE; if(s->int_enable & FB_INT_BASE_UPDATE_DONE) qemu_irq_raise(s->irq); } s->need_int = 0; s->need_update = 0; } int dest_width = surface_width(ds); int dest_height = surface_height(ds); int dest_pitch = surface_stride(ds); int ymin, ymax; #if STATS if (full_update) stats_full_updates += 1; if (++stats_counter == 120) { stats_total += stats_counter; stats_total_full_updates += stats_full_updates; trace_goldfish_fb_update_stats(stats_full_updates*100.0/stats_counter, stats_total_full_updates*100.0/stats_total ); stats_counter = 0; stats_full_updates = 0; } #endif /* STATS */ if (s->blank) { void *dst_line = surface_data(ds); memset( dst_line, 0, dest_height*dest_pitch ); ymin = 0; ymax = dest_height-1; } else { SysBusDevice *dev = SYS_BUS_DEVICE(opaque); MemoryRegion *address_space = sysbus_address_space(dev); int src_width, src_height; int dest_row_pitch, dest_col_pitch; drawfn fn; /* The source framebuffer is always read in a linear fashion, * we achieve rotation by altering the destination * step-per-pixel. */ switch (s->rotation) { case 0: /* Normal, native landscape view */ src_width = dest_width; src_height = dest_height; dest_row_pitch = surface_stride(ds); dest_col_pitch = surface_bytes_per_pixel(ds); break; case 1: /* 90 degree, portrait view */ src_width = dest_height; src_height = dest_width; dest_row_pitch = -surface_bytes_per_pixel(ds); dest_col_pitch = surface_stride(ds); break; case 2: /* 180 degree, inverted landscape view */ src_width = dest_width; src_height = dest_height; dest_row_pitch = -surface_stride(ds); dest_col_pitch = -surface_bytes_per_pixel(ds); break; case 3: /* 270 degree, mirror portrait view */ src_width = dest_height; src_height = dest_width; dest_row_pitch = surface_bytes_per_pixel(ds); dest_col_pitch = -surface_stride(ds); break; default: g_assert_not_reached(); } int source_bytes_per_pixel = 2; switch (s->format) { /* source format */ case HAL_PIXEL_FORMAT_RGB_565: source_bytes_per_pixel = 2; switch (surface_bits_per_pixel(ds)) { /* dest format */ case 8: fn = draw_line_16_8; break; case 15: fn = draw_line_16_15; break; case 16: fn = draw_line_16_16; break; case 24: fn = draw_line_16_24; break; case 32: fn = draw_line_16_32; break; default: hw_error("goldfish_fb: bad dest color depth\n"); return; } break; case HAL_PIXEL_FORMAT_RGBX_8888: source_bytes_per_pixel = 4; switch (surface_bits_per_pixel(ds)) { /* dest format */ case 8: fn = draw_line_32_8; break; case 15: fn = draw_line_32_15; break; case 16: fn = draw_line_32_16; break; case 24: fn = draw_line_32_24; break; case 32: fn = draw_line_32_32; break; default: hw_error("goldfish_fb: bad dest color depth\n"); return; } break; default: hw_error("goldfish_fb: bad source color format\n"); return; } ymin = 0; framebuffer_update_display(ds, address_space, s->fb_base, src_width, src_height, src_width * source_bytes_per_pixel, dest_row_pitch, dest_col_pitch, full_update, fn, ds, &ymin, &ymax); } ymax += 1; if (ymin >= 0) { if (s->rotation % 2) { /* In portrait mode we are drawing "sideways" so always * need to update the whole screen */ trace_goldfish_fb_update_display(0, dest_height, 0, dest_width); dpy_gfx_update(s->con, 0, 0, dest_width, dest_height); } else { trace_goldfish_fb_update_display(ymin, ymax-ymin, 0, dest_width); dpy_gfx_update(s->con, 0, ymin, dest_width, ymax-ymin); } } }