Пример #1
0
static void sdl_switch(DisplayChangeListener *dcl,
                       DisplaySurface *new_surface)
{

    /* temporary hack: allows to call sdl_switch to handle scaling changes */
    if (new_surface) {
        surface = new_surface;
    }

    if (!scaling_active) {
        do_sdl_resize(surface_width(surface), surface_height(surface), 0);
    } else if (real_screen->format->BitsPerPixel !=
               surface_bits_per_pixel(surface)) {
        do_sdl_resize(real_screen->w, real_screen->h,
                      surface_bits_per_pixel(surface));
    }

    if (guest_screen != NULL) {
        SDL_FreeSurface(guest_screen);
    }
    guest_screen = SDL_CreateRGBSurfaceFrom
        (surface_data(surface),
         surface_width(surface), surface_height(surface),
         surface_bits_per_pixel(surface), surface_stride(surface),
         surface->pf.rmask, surface->pf.gmask,
         surface->pf.bmask, surface->pf.amask);
}
Пример #2
0
static void sdl_switch(DisplayChangeListener *dcl,
                       DisplaySurface *new_surface)
{
    PixelFormat pf;

    /* temporary hack: allows to call sdl_switch to handle scaling changes */
    if (new_surface) {
        surface = new_surface;
    }
    pf = qemu_pixelformat_from_pixman(surface->format);

    if (!scaling_active) {
        do_sdl_resize(surface_width(surface), surface_height(surface), 0);
    } else if (real_screen->format->BitsPerPixel !=
               surface_bits_per_pixel(surface)) {
        do_sdl_resize(real_screen->w, real_screen->h,
                      surface_bits_per_pixel(surface));
    }

    if (guest_screen != NULL) {
        SDL_FreeSurface(guest_screen);
    }

#ifdef DEBUG_SDL
    printf("SDL: Creating surface with masks: %08x %08x %08x %08x\n",
           pf.rmask, pf.gmask, pf.bmask, pf.amask);
#endif

    guest_screen = SDL_CreateRGBSurfaceFrom
        (surface_data(surface),
         surface_width(surface), surface_height(surface),
         surface_bits_per_pixel(surface), surface_stride(surface),
         pf.rmask, pf.gmask,
         pf.bmask, pf.amask);
}
Пример #3
0
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
{
    DisplaySurface *surface = qemu_console_surface(s->con);

    switch (surface_bits_per_pixel(surface)) {
        case 8:
            tc6393xb_draw_graphic8(s);
            break;
        case 15:
            tc6393xb_draw_graphic15(s);
            break;
        case 16:
            tc6393xb_draw_graphic16(s);
            break;
        case 24:
            tc6393xb_draw_graphic24(s);
            break;
        case 32:
            tc6393xb_draw_graphic32(s);
            break;
        default:
            printf("tc6393xb: unknown depth %d\n",
                   surface_bits_per_pixel(surface));
            return;
    }

    dpy_gfx_update(s->con, 0, 0, s->scr_width, s->scr_height);
}
Пример #4
0
static void g364fb_draw_graphic8(G364State *s)
{
    DisplaySurface *surface = qemu_console_surface(s->con);
    int i, w;
    uint8_t *vram;
    uint8_t *data_display, *dd;
    ram_addr_t page, page_min, page_max;
    int x, y;
    int xmin, xmax;
    int ymin, ymax;
    int xcursor, ycursor;
    unsigned int (*rgb_to_pixel)(unsigned int r, unsigned int g, unsigned int b);

    switch (surface_bits_per_pixel(surface)) {
        case 8:
            rgb_to_pixel = rgb_to_pixel8;
            w = 1;
            break;
        case 15:
            rgb_to_pixel = rgb_to_pixel15;
            w = 2;
            break;
        case 16:
            rgb_to_pixel = rgb_to_pixel16;
            w = 2;
            break;
        case 32:
            rgb_to_pixel = rgb_to_pixel32;
            w = 4;
            break;
        default:
            hw_error("g364: unknown host depth %d",
                     surface_bits_per_pixel(surface));
            return;
    }

    page = 0;
    page_min = (ram_addr_t)-1;
    page_max = 0;

    x = y = 0;
    xmin = s->width;
    xmax = 0;
    ymin = s->height;
    ymax = 0;

    if (!(s->ctla & CTLA_NO_CURSOR)) {
        xcursor = s->cursor_position >> 12;
        ycursor = s->cursor_position & 0xfff;
    } else {
Пример #5
0
static void draw_vertical_line(DisplaySurface *ds,
                               int posx, int posy1, int posy2,
                               uint32_t color)
{
    uint8_t *d;
    int y, bpp;

    bpp = (surface_bits_per_pixel(ds) + 7) >> 3;
    d = surface_data(ds) + surface_stride(ds) * posy1 + bpp * posx;
    switch(bpp) {
        case 1:
            for (y = posy1; y <= posy2; y++) {
                *((uint8_t *)d) = color;
                d += surface_stride(ds);
            }
            break;
        case 2:
            for (y = posy1; y <= posy2; y++) {
                *((uint16_t *)d) = color;
                d += surface_stride(ds);
            }
            break;
        case 4:
            for (y = posy1; y <= posy2; y++) {
                *((uint32_t *)d) = color;
                d += surface_stride(ds);
            }
            break;
    }
}
Пример #6
0
static void draw_horizontal_line(DisplaySurface *ds,
                                 int posy, int posx1, int posx2,
                                 uint32_t color)
{
    uint8_t *d;
    int x, bpp;

    bpp = (surface_bits_per_pixel(ds) + 7) >> 3;
    d = surface_data(ds) + surface_stride(ds) * posy + bpp * posx1;
    switch(bpp) {
        case 1:
            for (x = posx1; x <= posx2; x++) {
                *((uint8_t *)d) = color;
                d++;
            }
            break;
        case 2:
            for (x = posx1; x <= posx2; x++) {
                *((uint16_t *)d) = color;
                d += 2;
            }
            break;
        case 4:
            for (x = posx1; x <= posx2; x++) {
                *((uint32_t *)d) = color;
                d += 4;
            }
            break;
    }
}
Пример #7
0
static void update_palette_entries(TCXState *s, int start, int end)
{
    DisplaySurface *surface = qemu_console_surface(s->con);
    int i;

    for (i = start; i < end; i++) {
        switch (surface_bits_per_pixel(surface)) {
        default:
        case 8:
            s->palette[i] = rgb_to_pixel8(s->r[i], s->g[i], s->b[i]);
            break;
        case 15:
            s->palette[i] = rgb_to_pixel15(s->r[i], s->g[i], s->b[i]);
            break;
        case 16:
            s->palette[i] = rgb_to_pixel16(s->r[i], s->g[i], s->b[i]);
            break;
        case 32:
            if (is_surface_bgr(surface)) {
                s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
            } else {
                s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
            }
            break;
        }
    }
    if (s->depth == 24) {
        tcx24_set_dirty(s);
    } else {
        tcx_set_dirty(s);
    }
}
Пример #8
0
static void toggle_full_screen(void)
{
    int width = surface_width(surface);
    int height = surface_height(surface);
    int bpp = surface_bits_per_pixel(surface);

    gui_fullscreen = !gui_fullscreen;
    if (gui_fullscreen) {
        gui_saved_width = real_screen->w;
        gui_saved_height = real_screen->h;
        gui_saved_scaling = scaling_active;

        do_sdl_resize(width, height, bpp);
        scaling_active = 0;

        gui_saved_grab = gui_grab;
        sdl_grab_start();
    } else {
        if (gui_saved_scaling) {
            sdl_scale(gui_saved_width, gui_saved_height);
        } else {
            do_sdl_resize(width, height, 0);
        }
        if (!gui_saved_grab || !qemu_console_is_graphic(NULL)) {
            sdl_grab_end();
        }
    }
    graphic_hw_invalidate(NULL);
    graphic_hw_update(NULL);
}
Пример #9
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;
}
Пример #10
0
static void sdl_switch(DisplayChangeListener *dcl,
                       DisplaySurface *new_surface)
{
    struct sdl2_state *scon = container_of(dcl, struct sdl2_state, dcl);
    int format = 0;
    int idx = scon->idx;
    DisplaySurface *old_surface = scon->surface;

    /* temporary hack: allows to call sdl_switch to handle scaling changes */
    if (new_surface) {
        scon->surface = new_surface;
    }

    if (!new_surface && idx > 0) {
        scon->surface = NULL;
    }

    if (new_surface == NULL) {
        do_sdl_resize(scon, 0, 0, 0);
    } else {
        do_sdl_resize(scon, surface_width(scon->surface),
                      surface_height(scon->surface), 0);
    }

    if (old_surface && scon->texture) {
        SDL_DestroyTexture(scon->texture);
        scon->texture = NULL;
    }

    if (new_surface) {
        if (!scon->texture) {
            if (surface_bits_per_pixel(scon->surface) == 16) {
                format = SDL_PIXELFORMAT_RGB565;
            } else if (surface_bits_per_pixel(scon->surface) == 32) {
                format = SDL_PIXELFORMAT_ARGB8888;
            }

            scon->texture = SDL_CreateTexture(scon->real_renderer, format,
                                              SDL_TEXTUREACCESS_STREAMING,
                                              surface_width(new_surface),
                                              surface_height(new_surface));
        }
    }
}
Пример #11
0
static void jazz_led_update_display(void *opaque)
{
    LedState *s = opaque;
    DisplaySurface *surface = qemu_console_surface(s->con);
    uint8_t *d1;
    uint32_t color_segment, color_led;
    int y, bpp;

    if (s->state & REDRAW_BACKGROUND) {
        /* clear screen */
        bpp = (surface_bits_per_pixel(surface) + 7) >> 3;
        d1 = surface_data(surface);
        for (y = 0; y < surface_height(surface); y++) {
            memset(d1, 0x00, surface_width(surface) * bpp);
            d1 += surface_stride(surface);
        }
    }
Пример #12
0
/*
 * This copies data from the guest framebuffer region, into QEMU's
 * displaysurface. qemu uses 16 or 32 bpp.  In case the pv framebuffer
 * uses something else we must convert and copy, otherwise we can
 * supply the buffer directly and no thing here.
 */
static void xenfb_guest_copy(struct XenFB *xenfb, int x, int y, int w, int h)
{
    DisplaySurface *surface = qemu_console_surface(xenfb->c.con);
    int line, oops = 0;
    int bpp = surface_bits_per_pixel(surface);
    int linesize = surface_stride(surface);
    uint8_t *data = surface_data(surface);

    if (!is_buffer_shared(surface)) {
        switch (xenfb->depth) {
        case 8:
            if (bpp == 16) {
                BLT(uint8_t, uint16_t,   3, 3, 2,   5, 6, 5);
            } else if (bpp == 32) {
                BLT(uint8_t, uint32_t,   3, 3, 2,   8, 8, 8);
            } else {
                oops = 1;
            }
            break;
        case 24:
            if (bpp == 16) {
                BLT(uint32_t, uint16_t,  8, 8, 8,   5, 6, 5);
            } else if (bpp == 32) {
                BLT(uint32_t, uint32_t,  8, 8, 8,   8, 8, 8);
            } else {
                oops = 1;
            }
            break;
        default:
            oops = 1;
	}
    }
    if (oops) /* should not happen */
        xen_be_printf(&xenfb->c.xendev, 0, "%s: oops: convert %d -> %d bpp?\n",
                      __FUNCTION__, xenfb->depth, bpp);

    dpy_gfx_update(xenfb->c.con, x, y, w, h);
}
Пример #13
0
/* Load new palette for a given DMA channel, convert to internal format */
static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
{
    DisplaySurface *surface = qemu_console_surface(s->con);
    int i, n, format, r, g, b, alpha;
    uint32_t *dest;
    uint8_t *src;
    s->pal_for = LCCR4_PALFOR(s->control[4]);
    format = s->pal_for;

    switch (bpp) {
    case pxa_lcdc_2bpp:
        n = 4;
        break;
    case pxa_lcdc_4bpp:
        n = 16;
        break;
    case pxa_lcdc_8bpp:
        n = 256;
        break;
    default:
        format = 0;
        return;
    }

    src = (uint8_t *) s->dma_ch[ch].pbuffer;
    dest = (uint32_t *) s->dma_ch[ch].palette;
    alpha = r = g = b = 0;

    for (i = 0; i < n; i ++) {
        switch (format) {
        case 0: /* 16 bpp, no transparency */
            alpha = 0;
            if (s->control[0] & LCCR0_CMS) {
                r = g = b = *(uint16_t *) src & 0xff;
            }
            else {
                r = (*(uint16_t *) src & 0xf800) >> 8;
                g = (*(uint16_t *) src & 0x07e0) >> 3;
                b = (*(uint16_t *) src & 0x001f) << 3;
            }
            src += 2;
            break;
        case 1: /* 16 bpp plus transparency */
            alpha = *(uint32_t *) src & (1 << 24);
            if (s->control[0] & LCCR0_CMS)
                r = g = b = *(uint32_t *) src & 0xff;
            else {
                r = (*(uint32_t *) src & 0xf80000) >> 16;
                g = (*(uint32_t *) src & 0x00fc00) >> 8;
                b = (*(uint32_t *) src & 0x0000f8);
            }
            src += 4;
            break;
        case 2: /* 18 bpp plus transparency */
            alpha = *(uint32_t *) src & (1 << 24);
            if (s->control[0] & LCCR0_CMS)
                r = g = b = *(uint32_t *) src & 0xff;
            else {
                r = (*(uint32_t *) src & 0xfc0000) >> 16;
                g = (*(uint32_t *) src & 0x00fc00) >> 8;
                b = (*(uint32_t *) src & 0x0000fc);
            }
            src += 4;
            break;
        case 3: /* 24 bpp plus transparency */
            alpha = *(uint32_t *) src & (1 << 24);
            if (s->control[0] & LCCR0_CMS)
                r = g = b = *(uint32_t *) src & 0xff;
            else {
                r = (*(uint32_t *) src & 0xff0000) >> 16;
                g = (*(uint32_t *) src & 0x00ff00) >> 8;
                b = (*(uint32_t *) src & 0x0000ff);
            }
            src += 4;
            break;
        }
        switch (surface_bits_per_pixel(surface)) {
        case 8:
            *dest = rgb_to_pixel8(r, g, b) | alpha;
            break;
        case 15:
            *dest = rgb_to_pixel15(r, g, b) | alpha;
            break;
        case 16:
            *dest = rgb_to_pixel16(r, g, b) | alpha;
            break;
        case 24:
            *dest = rgb_to_pixel24(r, g, b) | alpha;
            break;
        case 32:
            *dest = rgb_to_pixel32(r, g, b) | alpha;
            break;
        }
        dest ++;
    }
}
Пример #14
0
/* Fixed line length 1024 allows us to do nice tricks not possible on
   VGA... */
static void tcx_update_display(void *opaque)
{
    TCXState *ts = opaque;
    DisplaySurface *surface = qemu_console_surface(ts->con);
    ram_addr_t page, page_min, page_max;
    int y, y_start, dd, ds;
    uint8_t *d, *s;
    void (*f)(TCXState *s1, uint8_t *dst, const uint8_t *src, int width);

    if (surface_bits_per_pixel(surface) == 0) {
        return;
    }

    page = 0;
    y_start = -1;
    page_min = -1;
    page_max = 0;
    d = surface_data(surface);
    s = ts->vram;
    dd = surface_stride(surface);
    ds = 1024;

    switch (surface_bits_per_pixel(surface)) {
    case 32:
        f = tcx_draw_line32;
        break;
    case 15:
    case 16:
        f = tcx_draw_line16;
        break;
    default:
    case 8:
        f = tcx_draw_line8;
        break;
    case 0:
        return;
    }

    for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE) {
        if (memory_region_get_dirty(&ts->vram_mem, page, TARGET_PAGE_SIZE,
                                    DIRTY_MEMORY_VGA)) {
            if (y_start < 0)
                y_start = y;
            if (page < page_min)
                page_min = page;
            if (page > page_max)
                page_max = page;
            f(ts, d, s, ts->width);
            d += dd;
            s += ds;
            f(ts, d, s, ts->width);
            d += dd;
            s += ds;
            f(ts, d, s, ts->width);
            d += dd;
            s += ds;
            f(ts, d, s, ts->width);
            d += dd;
            s += ds;
        } else {
            if (y_start >= 0) {
                /* flush to display */
                dpy_gfx_update(ts->con, 0, y_start,
                               ts->width, y - y_start);
                y_start = -1;
            }
            d += dd * 4;
            s += ds * 4;
        }
    }
    if (y_start >= 0) {
        /* flush to display */
        dpy_gfx_update(ts->con, 0, y_start,
                       ts->width, y - y_start);
    }
    /* reset modified pages */
    if (page_max >= page_min) {
        memory_region_reset_dirty(&ts->vram_mem,
                                  page_min,
                                  (page_max - page_min) + TARGET_PAGE_SIZE,
                                  DIRTY_MEMORY_VGA);
    }
}
Пример #15
0
static void tcx24_update_display(void *opaque)
{
    TCXState *ts = opaque;
    DisplaySurface *surface = qemu_console_surface(ts->con);
    ram_addr_t page, page_min, page_max, cpage, page24;
    int y, y_start, dd, ds;
    uint8_t *d, *s;
    uint32_t *cptr, *s24;

    if (surface_bits_per_pixel(surface) != 32) {
            return;
    }

    page = 0;
    page24 = ts->vram24_offset;
    cpage = ts->cplane_offset;
    y_start = -1;
    page_min = -1;
    page_max = 0;
    d = surface_data(surface);
    s = ts->vram;
    s24 = ts->vram24;
    cptr = ts->cplane;
    dd = surface_stride(surface);
    ds = 1024;

    for(y = 0; y < ts->height; y += 4, page += TARGET_PAGE_SIZE,
            page24 += TARGET_PAGE_SIZE, cpage += TARGET_PAGE_SIZE) {
        if (check_dirty(ts, page, page24, cpage)) {
            if (y_start < 0)
                y_start = y;
            if (page < page_min)
                page_min = page;
            if (page > page_max)
                page_max = page;
            tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
            d += dd;
            s += ds;
            cptr += ds;
            s24 += ds;
            tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
            d += dd;
            s += ds;
            cptr += ds;
            s24 += ds;
            tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
            d += dd;
            s += ds;
            cptr += ds;
            s24 += ds;
            tcx24_draw_line32(ts, d, s, ts->width, cptr, s24);
            d += dd;
            s += ds;
            cptr += ds;
            s24 += ds;
        } else {
            if (y_start >= 0) {
                /* flush to display */
                dpy_gfx_update(ts->con, 0, y_start,
                               ts->width, y - y_start);
                y_start = -1;
            }
            d += dd * 4;
            s += ds * 4;
            cptr += ds * 4;
            s24 += ds * 4;
        }
    }
    if (y_start >= 0) {
        /* flush to display */
        dpy_gfx_update(ts->con, 0, y_start,
                       ts->width, y - y_start);
    }
    /* reset modified pages */
    if (page_max >= page_min) {
        reset_dirty(ts, page_min, page_max, page24, cpage);
    }
}
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);
        }
    }
}
Пример #17
0
static void sm_lcd_update_display(void *arg)
{
    lcd_state *s = arg;

    uint8_t *d;
    uint32_t colour_on, colour_off, colour;
    int x, y, bpp;

    DisplaySurface *surface = qemu_console_surface(s->con);
    bpp = surface_bits_per_pixel(surface);
    d = surface_data(surface);


    // If vibrate is on, simply jiggle the display
    if (s->vibrate_on) {
        if (s->vibrate_offset == 0) {
            s->vibrate_offset = 2;
        }
        int bytes_per_pixel;
        switch (bpp) {
            case 8:
                bytes_per_pixel = 1;
                break;
            case 15:
            case 16:
                bytes_per_pixel = 2;
                break;
            case 32:
                bytes_per_pixel = 4;
                break;
            default:
                abort();
        }
        int total_bytes = NUM_ROWS * NUM_COLS * bytes_per_pixel
                        - abs(s->vibrate_offset) * bytes_per_pixel;
        if (s->vibrate_offset > 0) {
            memmove(d, d + s->vibrate_offset * bytes_per_pixel, total_bytes);
        } else {
            memmove(d - s->vibrate_offset * bytes_per_pixel, d, total_bytes);
        }
        s->vibrate_offset *= -1;
        dpy_gfx_update(s->con, 0, 0, NUM_COLS, NUM_ROWS);
        return;
    }

    if (!s->redraw) {
        return;
    }

    // Adjust the white level to compensate for the set brightness.
    // brightness = 0:  255 in maps to 170 out
    // brightness = 1.0: 255 in maps to 255 out
    float brightness = s->backlight_enabled ? s->brightness : 0.0;
    int max_val = 170 + (255 - 170) * brightness;

    /* set colours according to bpp */
    switch (bpp) {
    case 8:
        colour_on = rgb_to_pixel8(max_val, max_val, max_val);
        colour_off = rgb_to_pixel8(0x00, 0x00, 0x00);
        break;
    case 15:
        colour_on = rgb_to_pixel15(max_val, max_val, max_val);
        colour_off = rgb_to_pixel15(0x00, 0x00, 0x00);
        break;
    case 16:
        colour_on = rgb_to_pixel16(max_val, max_val, max_val);
        colour_off = rgb_to_pixel16(0x00, 0x00, 0x00);
    case 24:
        colour_on = rgb_to_pixel24(max_val, max_val, max_val);
        colour_off = rgb_to_pixel24(0x00, 0x00, 0x00);
        break;
    case 32:
        colour_on = rgb_to_pixel32(max_val, max_val, max_val);
        colour_off = rgb_to_pixel32(0x00, 0x00, 0x00);
        break;
    default:
        return;
    }

    for (y = 0; y < NUM_ROWS; y++) {
        for (x = 0; x < NUM_COLS; x++) {
            /* Rotate display - installed 'upside-down' in pebble. */
            int xr = NUM_COLS - 1 - x;
            int yr = NUM_ROWS - 1 - y;
            bool on = s->framebuffer[yr * NUM_COL_BYTES + xr / 8] & 1 << (xr % 8);
            colour = on ? colour_on : colour_off;
            switch(bpp) {
                case 8:
                    *((uint8_t *)d) = colour;
                    d++;
                    break;
                case 15:
                case 16:
                    *((uint16_t *)d) = colour;
                    d += 2;
                    break;
                case 24:
                    abort();
                case 32:
                    *((uint32_t *)d) = colour;
                    d += 4;
                    break;
            }
        }
    }

    dpy_gfx_update(s->con, 0, 0, NUM_COLS, NUM_ROWS);
    s->redraw = false;
}
static uint64_t goldfish_fb_read(void *opaque, hwaddr offset, unsigned size)
{
    uint64_t ret = 0;
    struct goldfish_fb_state *s = opaque;
    DisplaySurface *ds = qemu_console_surface(s->con);

#ifndef USE_ANDROID_EMU
    int android_display_bpp = surface_bits_per_pixel(ds);
#endif

    switch(offset) {
        case FB_GET_WIDTH:
            ret = surface_width(ds);
            break;

        case FB_GET_HEIGHT:
            ret = surface_height(ds);
            break;

        case FB_INT_STATUS:
            ret = s->int_status & s->int_enable;
            if(ret) {
                s->int_status &= ~ret;
                qemu_irq_lower(s->irq);
            }
            break;

        case FB_GET_PHYS_WIDTH:
            ret = pixels_to_mm( surface_width(ds), s->dpi );
            break;

        case FB_GET_PHYS_HEIGHT:
            ret = pixels_to_mm( surface_height(ds), s->dpi );
            break;

        case FB_GET_FORMAT:
            /* A kernel making this query supports high color and true color */
            switch (android_display_bpp) {   /* hw.lcd.depth */
            case 32:
            case 24:
               ret = HAL_PIXEL_FORMAT_RGBX_8888;
               break;
            case 16:
               ret = HAL_PIXEL_FORMAT_RGB_565;
               break;
            default:
               error_report("goldfish_fb_read: Bad android_display_bpp %d",
                       android_display_bpp);
               break;
            }
            s->format = ret;
            break;

        default:
            error_report("goldfish_fb_read: Bad offset 0x" TARGET_FMT_plx,
                    offset);
            break;
    }

    trace_goldfish_fb_memory_read(offset, ret);
    return ret;
}
Пример #19
0
static void cg3_update_display(void *opaque)
{
    CG3State *s = opaque;
    DisplaySurface *surface = qemu_console_surface(s->con);
    const uint8_t *pix;
    uint32_t *data;
    uint32_t dval;
    int x, y, y_start;
    unsigned int width, height;
    ram_addr_t page, page_min, page_max;

    if (surface_bits_per_pixel(surface) != 32) {
        return;
    }
    width = s->width;
    height = s->height;

    y_start = -1;
    page_min = -1;
    page_max = 0;
    page = 0;
    pix = memory_region_get_ram_ptr(&s->vram_mem);
    data = (uint32_t *)surface_data(surface);

    for (y = 0; y < height; y++) {
        int update = s->full_update;

        page = (y * width) & TARGET_PAGE_MASK;
        update |= memory_region_get_dirty(&s->vram_mem, page, page + width,
                                          DIRTY_MEMORY_VGA);
        if (update) {
            if (y_start < 0) {
                y_start = y;
            }
            if (page < page_min) {
                page_min = page;
            }
            if (page > page_max) {
                page_max = page;
            }

            for (x = 0; x < width; x++) {
                dval = *pix++;
                dval = (s->r[dval] << 16) | (s->g[dval] << 8) | s->b[dval];
                *data++ = dval;
            }
        } else {
            if (y_start >= 0) {
                dpy_gfx_update(s->con, 0, y_start, s->width, y - y_start);
                y_start = -1;
            }
            pix += width;
            data += width;
        }
    }
    s->full_update = 0;
    if (y_start >= 0) {
        dpy_gfx_update(s->con, 0, y_start, s->width, y - y_start);
    }
    if (page_max >= page_min) {
        memory_region_reset_dirty(&s->vram_mem,
                              page_min, page_max - page_min + TARGET_PAGE_SIZE,
                              DIRTY_MEMORY_VGA);
    }
    /* vsync interrupt? */
    if (s->regs[0] & CG3_CR_ENABLE_INTS) {
        s->regs[1] |= CG3_SR_PENDING_INT;
        qemu_irq_raise(s->irq);
    }
}
Пример #20
0
static void cg3_update_display(void *opaque)
{
    CG3State *s = opaque;
    DisplaySurface *surface = qemu_console_surface(s->con);
    const uint8_t *pix;
    uint32_t *data;
    uint32_t dval;
    int x, y, y_start;
    unsigned int width, height;
    ram_addr_t page;
    DirtyBitmapSnapshot *snap = NULL;

    if (surface_bits_per_pixel(surface) != 32) {
        return;
    }
    width = s->width;
    height = s->height;

    y_start = -1;
    pix = memory_region_get_ram_ptr(&s->vram_mem);
    data = (uint32_t *)surface_data(surface);

    if (!s->full_update) {
        memory_region_sync_dirty_bitmap(&s->vram_mem);
        snap = memory_region_snapshot_and_clear_dirty(&s->vram_mem, 0x0,
                                              memory_region_size(&s->vram_mem),
                                              DIRTY_MEMORY_VGA);
    }

    for (y = 0; y < height; y++) {
        int update;

        page = (ram_addr_t)y * width;

        if (s->full_update) {
            update = 1;
        } else {
            update = memory_region_snapshot_get_dirty(&s->vram_mem, snap, page,
                                                      width);
        }

        if (update) {
            if (y_start < 0) {
                y_start = y;
            }

            for (x = 0; x < width; x++) {
                dval = *pix++;
                dval = (s->r[dval] << 16) | (s->g[dval] << 8) | s->b[dval];
                *data++ = dval;
            }
        } else {
            if (y_start >= 0) {
                dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
                y_start = -1;
            }
            pix += width;
            data += width;
        }
    }
    s->full_update = 0;
    if (y_start >= 0) {
        dpy_gfx_update(s->con, 0, y_start, width, y - y_start);
    }
    /* vsync interrupt? */
    if (s->regs[0] & CG3_CR_ENABLE_INTS) {
        s->regs[1] |= CG3_SR_PENDING_INT;
        qemu_irq_raise(s->irq);
    }
    g_free(snap);
}