Statistics
| Branch: | Revision:

root / hw / display / framebuffer.c @ 052e87b0

History | View | Annotate | Download (3.3 kB)

1 714fa308 pbrook
/*
2 714fa308 pbrook
 * Framebuffer device helper routines
3 714fa308 pbrook
 *
4 714fa308 pbrook
 * Copyright (c) 2009 CodeSourcery
5 714fa308 pbrook
 * Written by Paul Brook <paul@codesourcery.com>
6 714fa308 pbrook
 *
7 714fa308 pbrook
 * This code is licensed under the GNU GPLv2.
8 6b620ca3 Paolo Bonzini
 *
9 6b620ca3 Paolo Bonzini
 * Contributions after 2012-01-13 are licensed under the terms of the
10 6b620ca3 Paolo Bonzini
 * GNU GPL, version 2 or (at your option) any later version.
11 714fa308 pbrook
 */
12 714fa308 pbrook
13 714fa308 pbrook
/* TODO:
14 714fa308 pbrook
   - Do something similar for framebuffers with local ram
15 714fa308 pbrook
   - Handle rotation here instead of hacking dest_pitch
16 714fa308 pbrook
   - Use common pixel conversion routines instead of per-device drawfn
17 714fa308 pbrook
   - Remove all DisplayState knowledge from devices.
18 714fa308 pbrook
 */
19 714fa308 pbrook
20 83c9f4ca Paolo Bonzini
#include "hw/hw.h"
21 28ecbaee Paolo Bonzini
#include "ui/console.h"
22 47b43a1f Paolo Bonzini
#include "framebuffer.h"
23 714fa308 pbrook
24 714fa308 pbrook
/* Render an image from a shared memory framebuffer.  */
25 714fa308 pbrook
   
26 714fa308 pbrook
void framebuffer_update_display(
27 c78f7137 Gerd Hoffmann
    DisplaySurface *ds,
28 75c9d6c2 Avi Kivity
    MemoryRegion *address_space,
29 a8170e5e Avi Kivity
    hwaddr base,
30 714fa308 pbrook
    int cols, /* Width in pixels.  */
31 9c6bb55b Stefan Weil
    int rows, /* Height in pixels.  */
32 714fa308 pbrook
    int src_width, /* Length of source line, in bytes.  */
33 714fa308 pbrook
    int dest_row_pitch, /* Bytes between adjacent horizontal output pixels.  */
34 714fa308 pbrook
    int dest_col_pitch, /* Bytes between adjacent vertical output pixels.  */
35 714fa308 pbrook
    int invalidate, /* nonzero to redraw the whole image.  */
36 714fa308 pbrook
    drawfn fn,
37 714fa308 pbrook
    void *opaque,
38 714fa308 pbrook
    int *first_row, /* Input and output.  */
39 714fa308 pbrook
    int *last_row /* Output only */)
40 714fa308 pbrook
{
41 a8170e5e Avi Kivity
    hwaddr src_len;
42 714fa308 pbrook
    uint8_t *dest;
43 714fa308 pbrook
    uint8_t *src;
44 714fa308 pbrook
    uint8_t *src_base;
45 714fa308 pbrook
    int first, last = 0;
46 714fa308 pbrook
    int dirty;
47 714fa308 pbrook
    int i;
48 c227f099 Anthony Liguori
    ram_addr_t addr;
49 75c9d6c2 Avi Kivity
    MemoryRegionSection mem_section;
50 75c9d6c2 Avi Kivity
    MemoryRegion *mem;
51 714fa308 pbrook
52 714fa308 pbrook
    i = *first_row;
53 714fa308 pbrook
    *first_row = -1;
54 714fa308 pbrook
    src_len = src_width * rows;
55 714fa308 pbrook
56 75c9d6c2 Avi Kivity
    mem_section = memory_region_find(address_space, base, src_len);
57 052e87b0 Paolo Bonzini
    if (int128_get64(mem_section.size) != src_len ||
58 052e87b0 Paolo Bonzini
            !memory_region_is_ram(mem_section.mr)) {
59 714fa308 pbrook
        return;
60 714fa308 pbrook
    }
61 75c9d6c2 Avi Kivity
    mem = mem_section.mr;
62 75c9d6c2 Avi Kivity
    assert(mem);
63 75c9d6c2 Avi Kivity
    assert(mem_section.offset_within_address_space == base);
64 714fa308 pbrook
65 c1cd0b2c Avi Kivity
    memory_region_sync_dirty_bitmap(mem);
66 714fa308 pbrook
    src_base = cpu_physical_memory_map(base, &src_len, 0);
67 714fa308 pbrook
    /* If we can't map the framebuffer then bail.  We could try harder,
68 714fa308 pbrook
       but it's not really worth it as dirty flag tracking will probably
69 714fa308 pbrook
       already have failed above.  */
70 714fa308 pbrook
    if (!src_base)
71 714fa308 pbrook
        return;
72 714fa308 pbrook
    if (src_len != src_width * rows) {
73 714fa308 pbrook
        cpu_physical_memory_unmap(src_base, src_len, 0, 0);
74 714fa308 pbrook
        return;
75 714fa308 pbrook
    }
76 714fa308 pbrook
    src = src_base;
77 c78f7137 Gerd Hoffmann
    dest = surface_data(ds);
78 714fa308 pbrook
    if (dest_col_pitch < 0)
79 714fa308 pbrook
        dest -= dest_col_pitch * (cols - 1);
80 9312805d Vasily Khoruzhick
    if (dest_row_pitch < 0) {
81 9312805d Vasily Khoruzhick
        dest -= dest_row_pitch * (rows - 1);
82 9312805d Vasily Khoruzhick
    }
83 714fa308 pbrook
    first = -1;
84 75c9d6c2 Avi Kivity
    addr = mem_section.offset_within_region;
85 714fa308 pbrook
86 714fa308 pbrook
    addr += i * src_width;
87 714fa308 pbrook
    src += i * src_width;
88 714fa308 pbrook
    dest += i * dest_row_pitch;
89 714fa308 pbrook
90 714fa308 pbrook
    for (; i < rows; i++) {
91 d1f3dd34 Blue Swirl
        dirty = memory_region_get_dirty(mem, addr, src_width,
92 75c9d6c2 Avi Kivity
                                             DIRTY_MEMORY_VGA);
93 714fa308 pbrook
        if (dirty || invalidate) {
94 714fa308 pbrook
            fn(opaque, dest, src, cols, dest_col_pitch);
95 714fa308 pbrook
            if (first == -1)
96 714fa308 pbrook
                first = i;
97 714fa308 pbrook
            last = i;
98 714fa308 pbrook
        }
99 714fa308 pbrook
        addr += src_width;
100 714fa308 pbrook
        src += src_width;
101 714fa308 pbrook
        dest += dest_row_pitch;
102 714fa308 pbrook
    }
103 714fa308 pbrook
    cpu_physical_memory_unmap(src_base, src_len, 0, 0);
104 714fa308 pbrook
    if (first < 0) {
105 714fa308 pbrook
        return;
106 714fa308 pbrook
    }
107 75c9d6c2 Avi Kivity
    memory_region_reset_dirty(mem, mem_section.offset_within_region, src_len,
108 75c9d6c2 Avi Kivity
                              DIRTY_MEMORY_VGA);
109 714fa308 pbrook
    *first_row = first;
110 714fa308 pbrook
    *last_row = last;
111 714fa308 pbrook
}