Annotation of qemu/hw/framebuffer.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.