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

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.
        !             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: }

unix.superglobalmegacorp.com

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