Commit 714fa308a3f86e1dc55021ff1282c1afe6954d3d
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
Showing
10 changed files
with
253 additions
and
231 deletions
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; | ... | ... |