~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to hw/framebuffer.c

  • Committer: Bazaar Package Importer
  • Author(s): Riku Voipio, Josh Triplett, Riku Voipio
  • Date: 2009-07-29 13:28:05 UTC
  • mfrom: (1.4.1 upstream)
  • mto: (12.1.1 sid) (10.1.13 sid)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20090729132805-cau7rfexh7dawyb8
Tags: 0.10.50+git20090729-1
[ Josh Triplett ]
* Remove myself from Uploaders.

[ Riku Voipio ]
* new upstream RC version
* nuke all linux-user patches (applied upstream)
  06_exit_segfault
  12_signal_powerpc_support
  21_net_soopts
  30_syscall_ipc
  32_syscall_sysctl
  35_syscall_sockaddr
  48_signal_terminate
  55_unmux_socketcall
* nuke all other applied-upstream patches
  01_nostrip (better version upstream)
  07_i386_exec_name (can be reintroduced in debian/rules)
  50_linuxbios_isa_bios_ram (shouldn't be needed anymore)
  51_linuxbios_piix_ram_size (applied)
  56_dhcp (crap)
  60_ppc_ld (reintroduce if needed)
  64_ppc_asm_constraints (ditto)
  66_tls_ld.patch (ditto)
  81_compile_dtb.patch (applied upstream)
  82_qemu-img_decimal (ditto)
* move to git
* simplify build rules
* Correct my email address

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Framebuffer device helper routines
 
3
 *
 
4
 * Copyright (c) 2009 CodeSourcery
 
5
 * Written by Paul Brook <paul@codesourcery.com>
 
6
 *
 
7
 * This code is licensed under the GNU GPLv2.
 
8
 */
 
9
 
 
10
/* TODO:
 
11
   - Do something similar for framebuffers with local ram
 
12
   - Handle rotation here instead of hacking dest_pitch
 
13
   - Use common pixel conversion routines instead of per-device drawfn
 
14
   - Remove all DisplayState knowledge from devices.
 
15
 */
 
16
 
 
17
#include "hw.h"
 
18
#include "console.h"
 
19
#include "framebuffer.h"
 
20
 
 
21
/* Render an image from a shared memory framebuffer.  */
 
22
   
 
23
void framebuffer_update_display(
 
24
    DisplayState *ds,
 
25
    target_phys_addr_t base,
 
26
    int cols, /* Width in pixels.  */
 
27
    int rows, /* Leight in pixels.  */
 
28
    int src_width, /* Length of source line, in bytes.  */
 
29
    int dest_row_pitch, /* Bytes between adjacent horizontal output pixels.  */
 
30
    int dest_col_pitch, /* Bytes between adjacent vertical output pixels.  */
 
31
    int invalidate, /* nonzero to redraw the whole image.  */
 
32
    drawfn fn,
 
33
    void *opaque,
 
34
    int *first_row, /* Input and output.  */
 
35
    int *last_row /* Output only */)
 
36
{
 
37
    target_phys_addr_t src_len;
 
38
    uint8_t *dest;
 
39
    uint8_t *src;
 
40
    uint8_t *src_base;
 
41
    int first, last = 0;
 
42
    int dirty;
 
43
    int i;
 
44
    ram_addr_t addr;
 
45
    ram_addr_t pd;
 
46
    ram_addr_t pd2;
 
47
 
 
48
    i = *first_row;
 
49
    *first_row = -1;
 
50
    src_len = src_width * rows;
 
51
 
 
52
    cpu_physical_sync_dirty_bitmap(base, base + src_len);
 
53
    pd = cpu_get_physical_page_desc(base);
 
54
    pd2 = cpu_get_physical_page_desc(base + src_len - 1);
 
55
    /* We should reall check that this is a continuous ram region.
 
56
       Instead we just check that the first and last pages are
 
57
       both ram, and the right distance apart.  */
 
58
    if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM
 
59
        || (pd2 & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
 
60
        return;
 
61
    }
 
62
    pd = (pd & TARGET_PAGE_MASK) + (base & ~TARGET_PAGE_MASK);
 
63
    if (((pd + src_len - 1) & TARGET_PAGE_MASK) != (pd2 & TARGET_PAGE_MASK)) {
 
64
        return;
 
65
    }
 
66
 
 
67
    src_base = cpu_physical_memory_map(base, &src_len, 0);
 
68
    /* If we can't map the framebuffer then bail.  We could try harder,
 
69
       but it's not really worth it as dirty flag tracking will probably
 
70
       already have failed above.  */
 
71
    if (!src_base)
 
72
        return;
 
73
    if (src_len != src_width * rows) {
 
74
        cpu_physical_memory_unmap(src_base, src_len, 0, 0);
 
75
        return;
 
76
    }
 
77
    src = src_base;
 
78
    dest = ds_get_data(ds);
 
79
    if (dest_col_pitch < 0)
 
80
        dest -= dest_col_pitch * (cols - 1);
 
81
    first = -1;
 
82
    addr = pd;
 
83
 
 
84
    addr += i * src_width;
 
85
    src += i * src_width;
 
86
    dest += i * dest_row_pitch;
 
87
 
 
88
    for (; i < rows; i++) {
 
89
        target_phys_addr_t dirty_offset;
 
90
        dirty = 0;
 
91
        dirty_offset = 0;
 
92
        while (addr + dirty_offset < TARGET_PAGE_ALIGN(addr + src_width)) {
 
93
            dirty |= cpu_physical_memory_get_dirty(addr + dirty_offset,
 
94
                                                   VGA_DIRTY_FLAG);
 
95
            dirty_offset += TARGET_PAGE_SIZE;
 
96
        }
 
97
 
 
98
        if (dirty || invalidate) {
 
99
            fn(opaque, dest, src, cols, dest_col_pitch);
 
100
            if (first == -1)
 
101
                first = i;
 
102
            last = i;
 
103
        }
 
104
        addr += src_width;
 
105
        src += src_width;
 
106
        dest += dest_row_pitch;
 
107
    }
 
108
    cpu_physical_memory_unmap(src_base, src_len, 0, 0);
 
109
    if (first < 0) {
 
110
        return;
 
111
    }
 
112
    cpu_physical_memory_reset_dirty(pd, pd + src_len, VGA_DIRTY_FLAG);
 
113
    *first_row = first;
 
114
    *last_row = last;
 
115
    return;
 
116
}