Commit 714fa308a3f86e1dc55021ff1282c1afe6954d3d

Authored by pbrook
1 parent 602dafcf

Implement and use shared memory framebuffer device rendering reoutine.

Use DMA mapping API.

Signed-off-by: Paul Brook <paul@codesourcery.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6965 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -672,6 +672,7 @@ OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o
672 672 OBJS+= tsc2005.o bt-hci-csr.o
673 673 OBJS+= mst_fpga.o mainstone.o
674 674 OBJS+= musicpal.o pflash_cfi02.o
  675 +OBJS+= framebuffer.o
675 676 CPPFLAGS += -DHAS_AUDIO
676 677 endif
677 678 ifeq ($(TARGET_BASE_ARCH), sh4)
... ...
hw/framebuffer.c 0 → 100644
  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 +#include "kvm.h"
  21 +
  22 +/* Render an image from a shared memory framebuffer. */
  23 +
  24 +void framebuffer_update_display(
  25 + DisplayState *ds,
  26 + target_phys_addr_t base,
  27 + int cols, /* Width in pixels. */
  28 + int rows, /* Leight in pixels. */
  29 + int src_width, /* Length of source line, in bytes. */
  30 + int dest_row_pitch, /* Bytes between adjacent horizontal output pixels. */
  31 + int dest_col_pitch, /* Bytes between adjacent vertical output pixels. */
  32 + int invalidate, /* nonzero to redraw the whole image. */
  33 + drawfn fn,
  34 + void *opaque,
  35 + int *first_row, /* Input and output. */
  36 + int *last_row /* Output only */)
  37 +{
  38 + target_phys_addr_t src_len;
  39 + uint8_t *dest;
  40 + uint8_t *src;
  41 + uint8_t *src_base;
  42 + int first, last = 0;
  43 + int dirty;
  44 + int i;
  45 + ram_addr_t addr;
  46 + ram_addr_t pd;
  47 + ram_addr_t pd2;
  48 +
  49 + i = *first_row;
  50 + *first_row = -1;
  51 + src_len = src_width * rows;
  52 +
  53 + if (kvm_enabled()) {
  54 + kvm_physical_sync_dirty_bitmap(base, src_len);
  55 + }
  56 + pd = cpu_get_physical_page_desc(base);
  57 + pd2 = cpu_get_physical_page_desc(base + src_len - 1);
  58 + /* We should reall check that this is a continuous ram region.
  59 + Instead we just check that the first and last pages are
  60 + both ram, and the right distance apart. */
  61 + if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM
  62 + || (pd2 & ~TARGET_PAGE_MASK) > IO_MEM_ROM) {
  63 + return;
  64 + }
  65 + pd = (pd & TARGET_PAGE_MASK) + (base & ~TARGET_PAGE_MASK);
  66 + if (((pd + src_len - 1) & TARGET_PAGE_MASK) != (pd2 & TARGET_PAGE_MASK)) {
  67 + return;
  68 + }
  69 +
  70 + src_base = cpu_physical_memory_map(base, &src_len, 0);
  71 + /* If we can't map the framebuffer then bail. We could try harder,
  72 + but it's not really worth it as dirty flag tracking will probably
  73 + already have failed above. */
  74 + if (!src_base)
  75 + return;
  76 + if (src_len != src_width * rows) {
  77 + cpu_physical_memory_unmap(src_base, src_len, 0, 0);
  78 + return;
  79 + }
  80 + src = src_base;
  81 + dest = ds_get_data(ds);
  82 + if (dest_col_pitch < 0)
  83 + dest -= dest_col_pitch * (cols - 1);
  84 + first = -1;
  85 + addr = pd;
  86 +
  87 + addr += i * src_width;
  88 + src += i * src_width;
  89 + dest += i * dest_row_pitch;
  90 +
  91 + for (; i < rows; i++) {
  92 + target_phys_addr_t dirty_offset;
  93 + dirty = 0;
  94 + dirty_offset = 0;
  95 + while (addr + dirty_offset < TARGET_PAGE_ALIGN(addr + src_width)) {
  96 + dirty |= cpu_physical_memory_get_dirty(addr + dirty_offset,
  97 + VGA_DIRTY_FLAG);
  98 + dirty_offset += TARGET_PAGE_SIZE;
  99 + }
  100 +
  101 + if (dirty || invalidate) {
  102 + fn(opaque, dest, src, cols, dest_col_pitch);
  103 + if (first == -1)
  104 + first = i;
  105 + last = i;
  106 + }
  107 + addr += src_width;
  108 + src += src_width;
  109 + dest += dest_row_pitch;
  110 + }
  111 + cpu_physical_memory_unmap(src_base, src_len, 0, 0);
  112 + if (first < 0) {
  113 + return;
  114 + }
  115 + cpu_physical_memory_reset_dirty(pd, pd + src_len, VGA_DIRTY_FLAG);
  116 + *first_row = first;
  117 + *last_row = last;
  118 + return;
  119 +}
... ...
hw/framebuffer.h 0 → 100644
  1 +#ifndef QEMU_FRAMEBUFFER_H
  2 +#define QEMU_FRAMEBUFFER_H
  3 +
  4 +/* Framebuffer device helper routines. */
  5 +
  6 +typedef void (*drawfn)(void *, uint8_t *, const uint8_t *, int, int);
  7 +
  8 +void framebuffer_update_display(
  9 + DisplayState *ds,
  10 + target_phys_addr_t base,
  11 + int cols,
  12 + int rows,
  13 + int src_width,
  14 + int dest_row_pitch,
  15 + int dest_col_pitch,
  16 + int invalidate,
  17 + drawfn fn,
  18 + void *opaque,
  19 + int *first_row,
  20 + int *last_row);
  21 +
  22 +#endif
... ...
hw/omap.h
... ... @@ -490,7 +490,7 @@ struct omap_dma_lcd_channel_s {
490 490 int dual;
491 491  
492 492 int current_frame;
493   - ram_addr_t phys_framebuffer[2];
  493 + target_phys_addr_t phys_framebuffer[2];
494 494 qemu_irq irq;
495 495 struct omap_mpu_state_s *mpu;
496 496 } *omap_dma_get_lcdch(struct soc_dma_s *s);
... ...
hw/omap_lcd_template.h
... ... @@ -43,9 +43,10 @@
43 43 /*
44 44 * 2-bit colour
45 45 */
46   -static void glue(draw_line2_, DEPTH)(
47   - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal)
  46 +static void glue(draw_line2_, DEPTH)(void *opaque,
  47 + uint8_t *d, const uint8_t *s, int width, int deststep)
48 48 {
  49 + uint16_t *pal = opaque;
49 50 uint8_t v, r, g, b;
50 51  
51 52 do {
... ... @@ -81,9 +82,10 @@ static void glue(draw_line2_, DEPTH)(
81 82 /*
82 83 * 4-bit colour
83 84 */
84   -static void glue(draw_line4_, DEPTH)(
85   - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal)
  85 +static void glue(draw_line4_, DEPTH)(void *opaque,
  86 + uint8_t *d, const uint8_t *s, int width, int deststep)
86 87 {
  88 + uint16_t *pal = opaque;
87 89 uint8_t v, r, g, b;
88 90  
89 91 do {
... ... @@ -107,9 +109,10 @@ static void glue(draw_line4_, DEPTH)(
107 109 /*
108 110 * 8-bit colour
109 111 */
110   -static void glue(draw_line8_, DEPTH)(
111   - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal)
  112 +static void glue(draw_line8_, DEPTH)(void *opaque,
  113 + uint8_t *d, const uint8_t *s, int width, int deststep)
112 114 {
  115 + uint16_t *pal = opaque;
113 116 uint8_t v, r, g, b;
114 117  
115 118 do {
... ... @@ -126,8 +129,8 @@ static void glue(draw_line8_, DEPTH)(
126 129 /*
127 130 * 12-bit colour
128 131 */
129   -static void glue(draw_line12_, DEPTH)(
130   - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal)
  132 +static void glue(draw_line12_, DEPTH)(void *opaque,
  133 + uint8_t *d, const uint8_t *s, int width, int deststep)
131 134 {
132 135 uint16_t v;
133 136 uint8_t r, g, b;
... ... @@ -146,8 +149,8 @@ static void glue(draw_line12_, DEPTH)(
146 149 /*
147 150 * 16-bit colour
148 151 */
149   -static void glue(draw_line16_, DEPTH)(
150   - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal)
  152 +static void glue(draw_line16_, DEPTH)(void *opaque,
  153 + uint8_t *d, const uint8_t *s, int width, int deststep)
151 154 {
152 155 #if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
153 156 memcpy(d, s, width * 2);
... ...
hw/omap_lcdc.c
... ... @@ -20,6 +20,7 @@
20 20 #include "hw.h"
21 21 #include "console.h"
22 22 #include "omap.h"
  23 +#include "framebuffer.h"
23 24  
24 25 struct omap_lcd_panel_s {
25 26 qemu_irq irq;
... ... @@ -68,8 +69,7 @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
68 69  
69 70 #include "pixel_ops.h"
70 71  
71   -typedef void draw_line_func(
72   - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal);
  72 +#define draw_line_func drawfn
73 73  
74 74 #define DEPTH 8
75 75 #include "omap_lcd_template.h"
... ... @@ -80,31 +80,31 @@ typedef void draw_line_func(
80 80 #define DEPTH 32
81 81 #include "omap_lcd_template.h"
82 82  
83   -static draw_line_func *draw_line_table2[33] = {
  83 +static draw_line_func draw_line_table2[33] = {
84 84 [0 ... 32] = 0,
85 85 [8] = draw_line2_8,
86 86 [15] = draw_line2_15,
87 87 [16] = draw_line2_16,
88 88 [32] = draw_line2_32,
89   -}, *draw_line_table4[33] = {
  89 +}, draw_line_table4[33] = {
90 90 [0 ... 32] = 0,
91 91 [8] = draw_line4_8,
92 92 [15] = draw_line4_15,
93 93 [16] = draw_line4_16,
94 94 [32] = draw_line4_32,
95   -}, *draw_line_table8[33] = {
  95 +}, draw_line_table8[33] = {
96 96 [0 ... 32] = 0,
97 97 [8] = draw_line8_8,
98 98 [15] = draw_line8_15,
99 99 [16] = draw_line8_16,
100 100 [32] = draw_line8_32,
101   -}, *draw_line_table12[33] = {
  101 +}, draw_line_table12[33] = {
102 102 [0 ... 32] = 0,
103 103 [8] = draw_line12_8,
104 104 [15] = draw_line12_15,
105 105 [16] = draw_line12_16,
106 106 [32] = draw_line12_32,
107   -}, *draw_line_table16[33] = {
  107 +}, draw_line_table16[33] = {
108 108 [0 ... 32] = 0,
109 109 [8] = draw_line16_8,
110 110 [15] = draw_line16_15,
... ... @@ -115,11 +115,10 @@ static draw_line_func *draw_line_table2[33] = {
115 115 static void omap_update_display(void *opaque)
116 116 {
117 117 struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
118   - draw_line_func *draw_line;
119   - int size, dirty[2], minline, maxline, height;
120   - int line, width, linesize, step, bpp, frame_offset;
121   - ram_addr_t frame_base, scanline, newline, x;
122   - uint8_t *s, *d;
  118 + draw_line_func draw_line;
  119 + int size, height, first, last;
  120 + int width, linesize, step, bpp, frame_offset;
  121 + target_phys_addr_t frame_base;
123 122  
124 123 if (!omap_lcd || omap_lcd->plm == 1 ||
125 124 !omap_lcd->enable || !ds_get_bits_per_pixel(omap_lcd->state))
... ... @@ -127,9 +126,9 @@ static void omap_update_display(void *opaque)
127 126  
128 127 frame_offset = 0;
129 128 if (omap_lcd->plm != 2) {
130   - memcpy(omap_lcd->palette, phys_ram_base +
131   - omap_lcd->dma->phys_framebuffer[
132   - omap_lcd->dma->current_frame], 0x200);
  129 + cpu_physical_memory_read(omap_lcd->dma->phys_framebuffer[
  130 + omap_lcd->dma->current_frame],
  131 + (void *)omap_lcd->palette, 0x200);
133 132 switch (omap_lcd->palette[0] >> 12 & 7) {
134 133 case 3 ... 7:
135 134 frame_offset += 0x200;
... ... @@ -202,49 +201,28 @@ static void omap_update_display(void *opaque)
202 201 if (!ds_get_bits_per_pixel(omap_lcd->state))
203 202 return;
204 203  
205   - line = 0;
  204 + first = 0;
206 205 height = omap_lcd->height;
207 206 if (omap_lcd->subpanel & (1 << 31)) {
208 207 if (omap_lcd->subpanel & (1 << 29))
209   - line = (omap_lcd->subpanel >> 16) & 0x3ff;
  208 + first = (omap_lcd->subpanel >> 16) & 0x3ff;
210 209 else
211 210 height = (omap_lcd->subpanel >> 16) & 0x3ff;
212 211 /* TODO: fill the rest of the panel with DPD */
213 212 }
  213 +
214 214 step = width * bpp >> 3;
215   - scanline = frame_base + step * line;
216   - s = (uint8_t *) (phys_ram_base + scanline);
217   - d = ds_get_data(omap_lcd->state);
218 215 linesize = ds_get_linesize(omap_lcd->state);
219   -
220   - dirty[0] = dirty[1] =
221   - cpu_physical_memory_get_dirty(scanline, VGA_DIRTY_FLAG);
222   - minline = height;
223   - maxline = line;
224   - for (; line < height; line ++) {
225   - newline = scanline + step;
226   - for (x = scanline + TARGET_PAGE_SIZE; x < newline;
227   - x += TARGET_PAGE_SIZE) {
228   - dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
229   - dirty[0] |= dirty[1];
230   - }
231   - if (dirty[0] || omap_lcd->invalidate) {
232   - draw_line(d, s, width, omap_lcd->palette);
233   - if (line < minline)
234   - minline = line;
235   - maxline = line + 1;
236   - }
237   - scanline = newline;
238   - dirty[0] = dirty[1];
239   - s += step;
240   - d += linesize;
241   - }
242   -
243   - if (maxline >= minline) {
244   - dpy_update(omap_lcd->state, 0, minline, width, maxline);
245   - cpu_physical_memory_reset_dirty(frame_base + step * minline,
246   - frame_base + step * maxline, VGA_DIRTY_FLAG);
  216 + framebuffer_update_display(omap_lcd->state,
  217 + frame_base, width, height,
  218 + step, linesize, 0,
  219 + omap_lcd->invalidate,
  220 + draw_line, omap_lcd->palette,
  221 + &first, &last);
  222 + if (first >= 0) {
  223 + dpy_update(omap_lcd->state, 0, first, width, last - first + 1);
247 224 }
  225 + omap_lcd->invalidate = 0;
248 226 }
249 227  
250 228 static int ppm_save(const char *filename, uint8_t *data,
... ... @@ -336,25 +314,13 @@ static void omap_lcd_update(struct omap_lcd_panel_s *s) {
336 314 return;
337 315 }
338 316  
339   - if (s->dma->src == imif) {
340   - /* Framebuffers are in SRAM */
341   - s->dma->phys_framebuffer[0] = s->imif_base +
342   - s->dma->src_f1_top - OMAP_IMIF_BASE;
343   -
344   - s->dma->phys_framebuffer[1] = s->imif_base +
345   - s->dma->src_f2_top - OMAP_IMIF_BASE;
346   - } else {
347   - /* Framebuffers are in RAM */
348   - s->dma->phys_framebuffer[0] = s->emiff_base +
349   - s->dma->src_f1_top - OMAP_EMIFF_BASE;
350   -
351   - s->dma->phys_framebuffer[1] = s->emiff_base +
352   - s->dma->src_f2_top - OMAP_EMIFF_BASE;
353   - }
  317 + s->dma->phys_framebuffer[0] = s->dma->src_f1_top;
  318 + s->dma->phys_framebuffer[1] = s->dma->src_f2_top;
354 319  
355 320 if (s->plm != 2 && !s->palette_done) {
356   - memcpy(s->palette, phys_ram_base +
357   - s->dma->phys_framebuffer[s->dma->current_frame], 0x200);
  321 + cpu_physical_memory_read(
  322 + s->dma->phys_framebuffer[s->dma->current_frame],
  323 + (void *)s->palette, 0x200);
358 324 s->palette_done = 1;
359 325 omap_lcd_interrupts(s);
360 326 }
... ...
hw/pl110.c
... ... @@ -10,6 +10,7 @@
10 10 #include "hw.h"
11 11 #include "primecell.h"
12 12 #include "console.h"
  13 +#include "framebuffer.h"
13 14  
14 15 #define PL110_CR_EN 0x001
15 16 #define PL110_CR_BGR 0x100
... ... @@ -61,8 +62,6 @@ static const unsigned char pl110_versatile_id[] =
61 62  
62 63 #include "pixel_ops.h"
63 64  
64   -typedef void (*drawfn)(uint32_t *, uint8_t *, const uint8_t *, int);
65   -
66 65 #define BITS 8
67 66 #include "pl110_template.h"
68 67 #define BITS 15
... ... @@ -84,17 +83,11 @@ static void pl110_update_display(void *opaque)
84 83 pl110_state *s = (pl110_state *)opaque;
85 84 drawfn* fntable;
86 85 drawfn fn;
87   - uint32_t *pallette;
88   - uint32_t addr;
89   - uint32_t base;
90 86 int dest_width;
91 87 int src_width;
92   - uint8_t *dest;
93   - uint8_t *src;
94   - int first, last = 0;
95   - int dirty, new_dirty;
96   - int i;
97 88 int bpp_offset;
  89 + int first;
  90 + int last;
98 91  
99 92 if (!pl110_enabled(s))
100 93 return;
... ... @@ -159,47 +152,17 @@ static void pl110_update_display(void *opaque)
159 152 break;
160 153 }
161 154 dest_width *= s->cols;
162   - pallette = s->pallette;
163   - base = s->upbase;
164   - /* HACK: Arm aliases physical memory at 0x80000000. */
165   - if (base > 0x80000000)
166   - base -= 0x80000000;
167   - src = phys_ram_base + base;
168   - dest = ds_get_data(s->ds);
169   - first = -1;
170   - addr = base;
171   -
172   - dirty = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG);
173   - new_dirty = dirty;
174   - for (i = 0; i < s->rows; i++) {
175   - if ((addr & ~TARGET_PAGE_MASK) + src_width >= TARGET_PAGE_SIZE) {
176   - uint32_t tmp;
177   - new_dirty = 0;
178   - for (tmp = 0; tmp < src_width; tmp += TARGET_PAGE_SIZE) {
179   - new_dirty |= cpu_physical_memory_get_dirty(addr + tmp,
180   - VGA_DIRTY_FLAG);
181   - }
182   - }
183   -
184   - if (dirty || new_dirty || s->invalidate) {
185   - fn(pallette, dest, src, s->cols);
186   - if (first == -1)
187   - first = i;
188   - last = i;
189   - }
190   - dirty = new_dirty;
191   - addr += src_width;
192   - dest += dest_width;
193   - src += src_width;
  155 + first = 0;
  156 + framebuffer_update_display(s->ds,
  157 + s->upbase, s->cols, s->rows,
  158 + src_width, dest_width, 0,
  159 + s->invalidate,
  160 + fn, s->pallette,
  161 + &first, &last);
  162 + if (first >= 0) {
  163 + dpy_update(s->ds, 0, first, s->cols, last - first + 1);
194 164 }
195   - if (first < 0)
196   - return;
197   -
198 165 s->invalidate = 0;
199   - cpu_physical_memory_reset_dirty(base + first * src_width,
200   - base + (last + 1) * src_width,
201   - VGA_DIRTY_FLAG);
202   - dpy_update(s->ds, 0, first, s->cols, last - first + 1);
203 166 }
204 167  
205 168 static void pl110_invalidate_display(void * opaque)
... ...
hw/pl110_template.h
... ... @@ -115,8 +115,9 @@ static drawfn glue(pl110_draw_fn_,BITS)[36] =
115 115 #define FN_4(x, y) FN_2(x, y) FN_2(x+2, y)
116 116 #define FN_8(y) FN_4(0, y) FN_4(4, y)
117 117  
118   -static void glue(pl110_draw_line1_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  118 +static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
119 119 {
  120 + uint32_t *pallette = opaque;
120 121 uint32_t data;
121 122 while (width > 0) {
122 123 data = *(uint32_t *)src;
... ... @@ -142,8 +143,9 @@ static void glue(pl110_draw_line1_,NAME)(uint32_t *pallette, uint8_t *d, const u
142 143 }
143 144 }
144 145  
145   -static void glue(pl110_draw_line2_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  146 +static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
146 147 {
  148 + uint32_t *pallette = opaque;
147 149 uint32_t data;
148 150 while (width > 0) {
149 151 data = *(uint32_t *)src;
... ... @@ -169,8 +171,9 @@ static void glue(pl110_draw_line2_,NAME)(uint32_t *pallette, uint8_t *d, const u
169 171 }
170 172 }
171 173  
172   -static void glue(pl110_draw_line4_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  174 +static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
173 175 {
  176 + uint32_t *pallette = opaque;
174 177 uint32_t data;
175 178 while (width > 0) {
176 179 data = *(uint32_t *)src;
... ... @@ -196,8 +199,9 @@ static void glue(pl110_draw_line4_,NAME)(uint32_t *pallette, uint8_t *d, const u
196 199 }
197 200 }
198 201  
199   -static void glue(pl110_draw_line8_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  202 +static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
200 203 {
  204 + uint32_t *pallette = opaque;
201 205 uint32_t data;
202 206 while (width > 0) {
203 207 data = *(uint32_t *)src;
... ... @@ -219,7 +223,7 @@ static void glue(pl110_draw_line8_,NAME)(uint32_t *pallette, uint8_t *d, const u
219 223 }
220 224 }
221 225  
222   -static void glue(pl110_draw_line16_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  226 +static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
223 227 {
224 228 uint32_t data;
225 229 unsigned int r, g, b;
... ... @@ -265,7 +269,7 @@ static void glue(pl110_draw_line16_,NAME)(uint32_t *pallette, uint8_t *d, const
265 269 }
266 270 }
267 271  
268   -static void glue(pl110_draw_line32_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width)
  272 +static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
269 273 {
270 274 uint32_t data;
271 275 unsigned int r, g, b;
... ...
hw/pxa2xx_lcd.c
... ... @@ -13,8 +13,7 @@
13 13 #include "pixel_ops.h"
14 14 /* FIXME: For graphic_rotate. Should probably be done in common code. */
15 15 #include "sysemu.h"
16   -
17   -typedef void (*drawfn)(uint32_t *, uint8_t *, const uint8_t *, int, int);
  16 +#include "framebuffer.h"
18 17  
19 18 struct pxa2xx_lcdc_s {
20 19 qemu_irq irq;
... ... @@ -56,7 +55,7 @@ struct pxa2xx_lcdc_s {
56 55 int up;
57 56 uint8_t palette[1024];
58 57 uint8_t pbuffer[1024];
59   - void (*redraw)(struct pxa2xx_lcdc_s *s, uint8_t *fb,
  58 + void (*redraw)(struct pxa2xx_lcdc_s *s, target_phys_addr_t addr,
60 59 int *miny, int *maxy);
61 60  
62 61 target_phys_addr_t descriptor;
... ... @@ -669,18 +668,15 @@ static void pxa2xx_palette_parse(struct pxa2xx_lcdc_s *s, int ch, int bpp)
669 668 }
670 669  
671 670 static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s,
672   - uint8_t *fb, int *miny, int *maxy)
  671 + target_phys_addr_t addr, int *miny, int *maxy)
673 672 {
674   - int y, src_width, dest_width, dirty[2];
675   - uint8_t *src, *dest;
676   - ram_addr_t x, addr, new_addr, start, end;
  673 + int src_width, dest_width;
677 674 drawfn fn = 0;
678 675 if (s->dest_width)
679 676 fn = s->line_fn[s->transp][s->bpp];
680 677 if (!fn)
681 678 return;
682 679  
683   - src = fb;
684 680 src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
685 681 if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
686 682 src_width *= 3;
... ... @@ -689,54 +685,25 @@ static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s,
689 685 else if (s->bpp > pxa_lcdc_8bpp)
690 686 src_width *= 2;
691 687  
692   - dest = ds_get_data(s->ds);
693 688 dest_width = s->xres * s->dest_width;
694   -
695   - addr = (ram_addr_t) (fb - phys_ram_base);
696   - start = addr + s->yres * src_width;
697   - end = addr;
698   - dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG);
699   - for (y = 0; y < s->yres; y ++) {
700   - new_addr = addr + src_width;
701   - for (x = addr + TARGET_PAGE_SIZE; x < new_addr;
702   - x += TARGET_PAGE_SIZE) {
703   - dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
704   - dirty[0] |= dirty[1];
705   - }
706   - if (dirty[0] || s->invalidated) {
707   - fn((uint32_t *) s->dma_ch[0].palette,
708   - dest, src, s->xres, s->dest_width);
709   - if (addr < start)
710   - start = addr;
711   - end = new_addr;
712   - if (y < *miny)
713   - *miny = y;
714   - if (y >= *maxy)
715   - *maxy = y + 1;
716   - }
717   - addr = new_addr;
718   - dirty[0] = dirty[1];
719   - src += src_width;
720   - dest += dest_width;
721   - }
722   -
723   - if (end > start)
724   - cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG);
  689 + *miny = 0;
  690 + framebuffer_update_display(s->ds,
  691 + addr, s->xres, s->yres,
  692 + src_width, dest_width, s->dest_width,
  693 + s->invalidated,
  694 + fn, s->dma_ch[0].palette, miny, maxy);
725 695 }
726 696  
727 697 static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s,
728   - uint8_t *fb, int *miny, int *maxy)
  698 + target_phys_addr_t addr, int *miny, int *maxy)
729 699 {
730   - int y, src_width, dest_width, dirty[2];
731   - uint8_t *src, *dest;
732   - ram_addr_t x, addr, new_addr, start, end;
  700 + int src_width, dest_width;
733 701 drawfn fn = 0;
734 702 if (s->dest_width)
735 703 fn = s->line_fn[s->transp][s->bpp];
736 704 if (!fn)
737 705 return;
738 706  
739   - src = fb;
740 707 src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */
741 708 if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
742 709 src_width *= 3;
... ... @@ -746,38 +713,13 @@ static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s,
746 713 src_width *= 2;
747 714  
748 715 dest_width = s->yres * s->dest_width;
749   - dest = ds_get_data(s->ds) + dest_width * (s->xres - 1);
750   -
751   - addr = (ram_addr_t) (fb - phys_ram_base);
752   - start = addr + s->yres * src_width;
753   - end = addr;
754   - x = addr + TARGET_PAGE_SIZE;
755   - dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(start, VGA_DIRTY_FLAG);
756   - for (y = 0; y < s->yres; y ++) {
757   - new_addr = addr + src_width;
758   - for (; x < new_addr; x += TARGET_PAGE_SIZE) {
759   - dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
760   - dirty[0] |= dirty[1];
761   - }
762   - if (dirty[0] || s->invalidated) {
763   - fn((uint32_t *) s->dma_ch[0].palette,
764   - dest, src, s->xres, -dest_width);
765   - if (addr < start)
766   - start = addr;
767   - end = new_addr;
768   - if (y < *miny)
769   - *miny = y;
770   - if (y >= *maxy)
771   - *maxy = y + 1;
772   - }
773   - addr = new_addr;
774   - dirty[0] = dirty[1];
775   - src += src_width;
776   - dest += s->dest_width;
777   - }
778   -
779   - if (end > start)
780   - cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG);
  716 + *miny = 0;
  717 + framebuffer_update_display(s->ds,
  718 + addr, s->xres, s->yres,
  719 + src_width, s->dest_width, -dest_width,
  720 + s->invalidated,
  721 + fn, s->dma_ch[0].palette,
  722 + miny, maxy);
781 723 }
782 724  
783 725 static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s)
... ... @@ -803,7 +745,6 @@ static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s)
803 745 static void pxa2xx_update_display(void *opaque)
804 746 {
805 747 struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
806   - uint8_t *fb;
807 748 target_phys_addr_t fbptr;
808 749 int miny, maxy;
809 750 int ch;
... ... @@ -829,13 +770,11 @@ static void pxa2xx_update_display(void *opaque)
829 770 pxa2xx_dma_ber_set(s, ch);
830 771 continue;
831 772 }
832   - fbptr -= PXA2XX_SDRAM_BASE;
833   - fb = phys_ram_base + fbptr;
834 773  
835 774 if (s->dma_ch[ch].command & LDCMD_PAL) {
836   - memcpy(s->dma_ch[ch].pbuffer, fb,
837   - MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
838   - sizeof(s->dma_ch[ch].pbuffer)));
  775 + cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer,
  776 + MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
  777 + sizeof(s->dma_ch[ch].pbuffer)));
839 778 pxa2xx_palette_parse(s, ch, s->bpp);
840 779 } else {
841 780 /* Do we need to reparse palette */
... ... @@ -845,7 +784,7 @@ static void pxa2xx_update_display(void *opaque)
845 784 /* ACK frame start */
846 785 pxa2xx_dma_sof_set(s, ch);
847 786  
848   - s->dma_ch[ch].redraw(s, fb, &miny, &maxy);
  787 + s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy);
849 788 s->invalidated = 0;
850 789  
851 790 /* ACK frame completed */
... ... @@ -859,10 +798,12 @@ static void pxa2xx_update_display(void *opaque)
859 798 s->status[0] |= LCSR0_LDD;
860 799 }
861 800  
862   - if (s->orientation)
863   - dpy_update(s->ds, miny, 0, maxy, s->xres);
864   - else
865   - dpy_update(s->ds, 0, miny, s->xres, maxy);
  801 + if (miny >= 0) {
  802 + if (s->orientation)
  803 + dpy_update(s->ds, miny, 0, maxy, s->xres);
  804 + else
  805 + dpy_update(s->ds, 0, miny, s->xres, maxy);
  806 + }
866 807 pxa2xx_lcdc_int_update(s);
867 808  
868 809 qemu_irq_raise(s->vsync_cb);
... ...
hw/pxa2xx_template.h
... ... @@ -30,9 +30,10 @@
30 30 #define FN_2(x) FN(x + 1) FN(x)
31 31 #define FN_4(x) FN_2(x + 2) FN_2(x)
32 32  
33   -static void glue(pxa2xx_draw_line2_, BITS)(uint32_t *palette,
  33 +static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
34 34 uint8_t *dest, const uint8_t *src, int width, int deststep)
35 35 {
  36 + uint32_t *palette = opaque;
36 37 uint32_t data;
37 38 while (width > 0) {
38 39 data = *(uint32_t *) src;
... ... @@ -54,9 +55,10 @@ static void glue(pxa2xx_draw_line2_, BITS)(uint32_t *palette,
54 55 }
55 56 }
56 57  
57   -static void glue(pxa2xx_draw_line4_, BITS)(uint32_t *palette,
  58 +static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
58 59 uint8_t *dest, const uint8_t *src, int width, int deststep)
59 60 {
  61 + uint32_t *palette = opaque;
60 62 uint32_t data;
61 63 while (width > 0) {
62 64 data = *(uint32_t *) src;
... ... @@ -78,9 +80,10 @@ static void glue(pxa2xx_draw_line4_, BITS)(uint32_t *palette,
78 80 }
79 81 }
80 82  
81   -static void glue(pxa2xx_draw_line8_, BITS)(uint32_t *palette,
  83 +static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
82 84 uint8_t *dest, const uint8_t *src, int width, int deststep)
83 85 {
  86 + uint32_t *palette = opaque;
84 87 uint32_t data;
85 88 while (width > 0) {
86 89 data = *(uint32_t *) src;
... ... @@ -102,7 +105,7 @@ static void glue(pxa2xx_draw_line8_, BITS)(uint32_t *palette,
102 105 }
103 106 }
104 107  
105   -static void glue(pxa2xx_draw_line16_, BITS)(uint32_t *palette,
  108 +static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
106 109 uint8_t *dest, const uint8_t *src, int width, int deststep)
107 110 {
108 111 uint32_t data;
... ... @@ -130,7 +133,7 @@ static void glue(pxa2xx_draw_line16_, BITS)(uint32_t *palette,
130 133 }
131 134 }
132 135  
133   -static void glue(pxa2xx_draw_line16t_, BITS)(uint32_t *palette,
  136 +static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
134 137 uint8_t *dest, const uint8_t *src, int width, int deststep)
135 138 {
136 139 uint32_t data;
... ... @@ -166,7 +169,7 @@ static void glue(pxa2xx_draw_line16t_, BITS)(uint32_t *palette,
166 169 }
167 170 }
168 171  
169   -static void glue(pxa2xx_draw_line18_, BITS)(uint32_t *palette,
  172 +static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
170 173 uint8_t *dest, const uint8_t *src, int width, int deststep)
171 174 {
172 175 uint32_t data;
... ... @@ -188,7 +191,7 @@ static void glue(pxa2xx_draw_line18_, BITS)(uint32_t *palette,
188 191 }
189 192  
190 193 /* The wicked packed format */
191   -static void glue(pxa2xx_draw_line18p_, BITS)(uint32_t *palette,
  194 +static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
192 195 uint8_t *dest, const uint8_t *src, int width, int deststep)
193 196 {
194 197 uint32_t data[3];
... ... @@ -236,7 +239,7 @@ static void glue(pxa2xx_draw_line18p_, BITS)(uint32_t *palette,
236 239 }
237 240 }
238 241  
239   -static void glue(pxa2xx_draw_line19_, BITS)(uint32_t *palette,
  242 +static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
240 243 uint8_t *dest, const uint8_t *src, int width, int deststep)
241 244 {
242 245 uint32_t data;
... ... @@ -262,7 +265,7 @@ static void glue(pxa2xx_draw_line19_, BITS)(uint32_t *palette,
262 265 }
263 266  
264 267 /* The wicked packed format */
265   -static void glue(pxa2xx_draw_line19p_, BITS)(uint32_t *palette,
  268 +static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
266 269 uint8_t *dest, const uint8_t *src, int width, int deststep)
267 270 {
268 271 uint32_t data[3];
... ... @@ -326,7 +329,7 @@ static void glue(pxa2xx_draw_line19p_, BITS)(uint32_t *palette,
326 329 }
327 330 }
328 331  
329   -static void glue(pxa2xx_draw_line24_, BITS)(uint32_t *palette,
  332 +static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
330 333 uint8_t *dest, const uint8_t *src, int width, int deststep)
331 334 {
332 335 uint32_t data;
... ... @@ -347,7 +350,7 @@ static void glue(pxa2xx_draw_line24_, BITS)(uint32_t *palette,
347 350 }
348 351 }
349 352  
350   -static void glue(pxa2xx_draw_line24t_, BITS)(uint32_t *palette,
  353 +static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
351 354 uint8_t *dest, const uint8_t *src, int width, int deststep)
352 355 {
353 356 uint32_t data;
... ... @@ -372,7 +375,7 @@ static void glue(pxa2xx_draw_line24t_, BITS)(uint32_t *palette,
372 375 }
373 376 }
374 377  
375   -static void glue(pxa2xx_draw_line25_, BITS)(uint32_t *palette,
  378 +static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
376 379 uint8_t *dest, const uint8_t *src, int width, int deststep)
377 380 {
378 381 uint32_t data;
... ...