Annotation of qemu/hw/framebuffer.c, revision 1.1.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.