Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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;
}
Example #4
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;
}
Example #5
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);
        }
    }
}