static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s, hwaddr addr, int *miny, int *maxy) { DisplaySurface *surface = qemu_console_surface(s->con); int src_width, dest_width; drawfn fn = NULL; if (s->dest_width) { fn = s->line_fn[s->transp][s->bpp]; } if (!fn) { return; } src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) { src_width *= 3; } else if (s->bpp > pxa_lcdc_16bpp) { src_width *= 4; } else if (s->bpp > pxa_lcdc_8bpp) { src_width *= 2; } dest_width = s->yres * s->dest_width; *miny = 0; if (s->invalidated) { framebuffer_update_memory_section(&s->fbsection, s->sysmem, addr, s->yres, src_width); } framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres, src_width, -s->dest_width, dest_width, s->invalidated, fn, s->dma_ch[0].palette, miny, maxy); }
static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s, target_phys_addr_t addr, int *miny, int *maxy) { int src_width, dest_width; drawfn fn = NULL; if (s->dest_width) { fn = s->line_fn[s->transp][s->bpp]; } if (!fn) { return; } src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) { src_width *= 3; } else if (s->bpp > pxa_lcdc_16bpp) { src_width *= 4; } else if (s->bpp > pxa_lcdc_8bpp) { src_width *= 2; } dest_width = s->yres * s->dest_width; *miny = 0; framebuffer_update_display(s->ds, s->sysmem, addr, s->xres, s->yres, src_width, -s->dest_width, dest_width, s->invalidated, fn, s->dma_ch[0].palette, miny, maxy); }
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 pl110_update_display(void *opaque) { pl110_state *s = (pl110_state *)opaque; drawfn* fntable; drawfn fn; int dest_width; int src_width; int bpp_offset; int first; int last; if (!pl110_enabled(s)) return; switch (ds_get_bits_per_pixel(s->ds)) { case 0: return; case 8: fntable = pl110_draw_fn_8; dest_width = 1; break; case 15: fntable = pl110_draw_fn_15; dest_width = 2; break; case 16: fntable = pl110_draw_fn_16; dest_width = 2; break; case 24: fntable = pl110_draw_fn_24; dest_width = 3; break; case 32: fntable = pl110_draw_fn_32; dest_width = 4; break; default: fprintf(stderr, "pl110: Bad color depth\n"); exit(1); } if (s->cr & PL110_CR_BGR) bpp_offset = 0; else bpp_offset = 18; if (s->cr & PL110_CR_BEBO) fn = fntable[s->bpp + 6 + bpp_offset]; else if (s->cr & PL110_CR_BEPO) fn = fntable[s->bpp + 12 + bpp_offset]; else fn = fntable[s->bpp + bpp_offset]; src_width = s->cols; switch (s->bpp) { case BPP_1: src_width >>= 3; break; case BPP_2: src_width >>= 2; break; case BPP_4: src_width >>= 1; break; case BPP_8: break; case BPP_16: src_width <<= 1; break; case BPP_32: src_width <<= 2; break; } dest_width *= s->cols; first = 0; framebuffer_update_display(s->ds, s->upbase, s->cols, s->rows, src_width, dest_width, 0, s->invalidate, fn, s->pallette, &first, &last); if (first >= 0) { dpy_update(s->ds, 0, first, s->cols, last - first + 1); } s->invalidate = 0; }
static void bcm2708_fb_update(void *_opaque) { struct bcm2708_vc *vc = _opaque; drawfn* fntable; drawfn fn; int dest_width; int src_width; int bpp_offset; int first; int last; switch (ds_get_bits_per_pixel(vc->disp)) { case 0: return; case 8: fntable = pl110_draw_fn_8; dest_width = 1; break; case 15: fntable = pl110_draw_fn_15; dest_width = 2; break; case 16: fntable = pl110_draw_fn_16; dest_width = 2; break; case 24: fntable = pl110_draw_fn_24; dest_width = 3; break; case 32: fntable = pl110_draw_fn_32; dest_width = 4; break; default: fprintf(stderr, "bcm2708: Bad color depth\n"); exit(1); } bpp_offset = 0; fn = fntable[vc->fb_bpp + bpp_offset]; src_width = vc->fb.xres; switch (vc->fb_bpp) { case BPP_1: src_width >>= 3; break; case BPP_2: src_width >>= 2; break; case BPP_4: src_width >>= 1; break; case BPP_8: break; case BPP_16: case BPP_16_565: case BPP_12: src_width <<= 1; break; case BPP_32: src_width <<= 2; break; } dest_width *= vc->fb.xres; first = 0; framebuffer_update_display(vc->disp, get_system_memory(), vc->fb.base, vc->fb.xres, vc->fb.yres, src_width, dest_width, 0, vc->fb_invalidate, fn, NULL, &first, &last); if (first >= 0) { dpy_update(vc->disp, 0, first, vc->fb.xres, last - first + 1); } vc->fb_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); } } }