|
1 /* |
|
2 * Render Engine for framebuffer devices |
|
3 * |
|
4 * Copyright (c) 2008 CodeSourcery |
|
5 * |
|
6 * This library is free software; you can redistribute it and/or |
|
7 * modify it under the terms of the GNU Lesser General Public |
|
8 * License as published by the Free Software Foundation; either |
|
9 * version 2 of the License, or (at your option) any later version. |
|
10 * |
|
11 * This library is distributed in the hope that it will be useful, |
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
14 * Lesser General Public License for more details. |
|
15 * |
|
16 * You should have received a copy of the GNU Lesser General Public |
|
17 * License along with this library; if not, write to the Free Software |
|
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
19 */ |
|
20 |
|
21 #include "hw.h" |
|
22 //#include "console.h" |
|
23 #include "gui.h" |
|
24 #include "fb_render_engine.h" |
|
25 #include "pixel_ops.h" |
|
26 |
|
27 typedef void (*row_draw_fn)(uint32_t *, uint8_t *, const uint8_t *, int, int); |
|
28 |
|
29 enum fb_dest_bpp_mode |
|
30 { |
|
31 BPP_DEST_8, |
|
32 BPP_DEST_15, |
|
33 BPP_DEST_16, |
|
34 BPP_DEST_24, |
|
35 BPP_DEST_32 |
|
36 }; |
|
37 |
|
38 struct render_data_t { |
|
39 int base_is_in_target; |
|
40 union { |
|
41 void* base_host; |
|
42 target_phys_addr_t base_target; |
|
43 }; |
|
44 uint8_t *dest; |
|
45 uint32_t cols; |
|
46 uint32_t rows; |
|
47 uint32_t row_pitch; |
|
48 /* The following attributes refer to the guest side. |
|
49 They should be renamed once they are also variable |
|
50 at the host side. |
|
51 */ |
|
52 enum fb_pixel_order pixel_order; |
|
53 enum fb_byte_order byte_order; |
|
54 enum fb_color_order color_order; |
|
55 enum fb_src_bpp_mode src_bpp_mode; |
|
56 |
|
57 enum fb_dest_bpp_mode dest_bpp_mode; |
|
58 /* pending: |
|
59 pixel_order, byte_order, and color_order, for the dest (host). |
|
60 */ |
|
61 enum fb_rotation orientation; |
|
62 uint32_t blank : 1; |
|
63 uint32_t need_internal_update : 1; |
|
64 uint32_t raw_palette[256]; |
|
65 |
|
66 /* ====== cached internal data ===== */ |
|
67 uint32_t inter_src_row_gap; |
|
68 uint32_t bytes_per_src_row; /* Does not include padding. */ |
|
69 row_draw_fn fn; |
|
70 /* rotation info */ |
|
71 uint32_t dest_start_offset; |
|
72 uint32_t bytes_per_dest_row; |
|
73 int dest_row_step; /* in bytes */ |
|
74 int dest_col_step; /* in bytes */ |
|
75 int swap_width_height; |
|
76 /* color info */ |
|
77 uint32_t palette[256]; |
|
78 |
|
79 }; |
|
80 |
|
81 |
|
82 #define NOT_ASSIGNED -1 |
|
83 |
|
84 #include "fb_render_def.h" |
|
85 #include "fb_render_decl.h" |
|
86 |
|
87 /* getters */ |
|
88 uint32_t get_cols(const render_data *rd) |
|
89 { |
|
90 return rd->cols; |
|
91 } |
|
92 |
|
93 uint32_t get_rows(const render_data *rd) |
|
94 { |
|
95 return rd->rows; |
|
96 } |
|
97 |
|
98 uint32_t get_screen_width(const render_data *rd) |
|
99 { |
|
100 return (!rd->swap_width_height) ? rd->cols : rd->rows; |
|
101 } |
|
102 |
|
103 uint32_t get_screen_height(const render_data *rd) |
|
104 { |
|
105 return (!rd->swap_width_height) ? rd->rows : rd->cols; |
|
106 } |
|
107 |
|
108 enum fb_rotation get_orientation(const render_data *rd) |
|
109 { |
|
110 return rd->orientation; |
|
111 } |
|
112 |
|
113 void* get_fb_base_in_host(const render_data *rd) |
|
114 { |
|
115 return rd->base_is_in_target ? 0 : rd->base_host; |
|
116 } |
|
117 |
|
118 target_phys_addr_t get_fb_base_in_target(const render_data *rd) |
|
119 { |
|
120 return rd->base_is_in_target ? rd->base_target : 0; |
|
121 } |
|
122 |
|
123 uint32_t get_blank_mode(const render_data *rd) |
|
124 { |
|
125 return rd->blank; |
|
126 } |
|
127 |
|
128 enum fb_color_order get_color_order(const render_data *rd) |
|
129 { |
|
130 return rd->color_order; |
|
131 } |
|
132 |
|
133 enum fb_byte_order get_byte_order(const render_data *rd) |
|
134 { |
|
135 return rd->byte_order; |
|
136 } |
|
137 |
|
138 enum fb_pixel_order get_pixel_order(const render_data *rd) |
|
139 { |
|
140 return rd->pixel_order; |
|
141 } |
|
142 |
|
143 enum fb_src_bpp_mode get_src_bpp(const render_data *rd) |
|
144 { |
|
145 return rd->src_bpp_mode; |
|
146 } |
|
147 |
|
148 uint32_t get_row_pitch(const render_data *rd) |
|
149 { |
|
150 return rd->row_pitch; |
|
151 } |
|
152 |
|
153 uint32_t get_palette_value(const render_data *rd, uint32_t n) |
|
154 { |
|
155 return rd->raw_palette[n]; |
|
156 } |
|
157 |
|
158 |
|
159 /* setters */ |
|
160 void set_cols(render_data *rd, uint32_t cols) |
|
161 { |
|
162 rd->cols = cols; rd->need_internal_update = 1; |
|
163 } |
|
164 |
|
165 void set_rows(render_data *rd, uint32_t rows) |
|
166 { |
|
167 rd->rows = rows; rd->need_internal_update = 1; |
|
168 } |
|
169 |
|
170 void set_orientation(render_data *rd, enum fb_rotation rotation) |
|
171 { |
|
172 rd->orientation = rotation; rd->need_internal_update = 1; |
|
173 } |
|
174 |
|
175 void set_fb_base_from_host(render_data *rd, void* base) |
|
176 { |
|
177 rd->base_is_in_target = 0; |
|
178 rd->base_host = base; rd->need_internal_update = 1; |
|
179 } |
|
180 |
|
181 void set_fb_base_from_target(render_data *rd, target_phys_addr_t base) |
|
182 { |
|
183 rd->base_is_in_target = 1; |
|
184 /* ensure alignment */ |
|
185 rd->base_target = (base & (~3)); rd->need_internal_update = 1; |
|
186 } |
|
187 |
|
188 void set_blank_mode(render_data *rd, int on_off) |
|
189 { |
|
190 rd->blank = on_off; rd->need_internal_update = 1; |
|
191 } |
|
192 |
|
193 void set_pixel_order(render_data *rd, enum fb_pixel_order pixel_order) |
|
194 { |
|
195 rd->pixel_order = pixel_order; rd->need_internal_update = 1; |
|
196 } |
|
197 |
|
198 void set_byte_order(render_data *rd, enum fb_byte_order byte_order) |
|
199 { |
|
200 rd->byte_order = byte_order; rd->need_internal_update = 1; |
|
201 } |
|
202 |
|
203 void set_color_order(render_data *rd, enum fb_color_order color_order) |
|
204 { |
|
205 rd->color_order = color_order; rd->need_internal_update = 1; |
|
206 } |
|
207 |
|
208 void set_src_bpp(render_data *rd, enum fb_src_bpp_mode src_bpp_mode) |
|
209 { |
|
210 rd->src_bpp_mode = src_bpp_mode; rd->need_internal_update = 1; |
|
211 } |
|
212 |
|
213 void set_row_pitch(render_data *rd, uint32_t pitch) |
|
214 { |
|
215 rd->row_pitch = pitch & ~3; rd->need_internal_update = 1; |
|
216 } |
|
217 |
|
218 static void set_dest_bpp(render_data *rd, enum fb_dest_bpp_mode dest_bpp_mode) |
|
219 { |
|
220 rd->dest_bpp_mode = dest_bpp_mode; rd->need_internal_update = 1; |
|
221 } |
|
222 |
|
223 static void set_dest_bpp_from_ds(render_data *rd, const DisplayState *ds) |
|
224 { |
|
225 enum fb_dest_bpp_mode new_dest_bpp_mode; |
|
226 |
|
227 switch (ds_get_bits_per_pixel(ds)) { |
|
228 case 8: new_dest_bpp_mode = BPP_DEST_8; break; |
|
229 case 15: new_dest_bpp_mode = BPP_DEST_15; break; |
|
230 case 16: new_dest_bpp_mode = BPP_DEST_16; break; |
|
231 case 24: new_dest_bpp_mode = BPP_DEST_24; break; |
|
232 case 32: new_dest_bpp_mode = BPP_DEST_32; break; |
|
233 default: |
|
234 fprintf(stderr, "fb_render_engine: Bad color depth\n"); |
|
235 exit(1); |
|
236 } |
|
237 |
|
238 if (rd->dest_bpp_mode != new_dest_bpp_mode) |
|
239 set_dest_bpp(rd, new_dest_bpp_mode); |
|
240 } |
|
241 |
|
242 static void set_dest_data_from_ds(render_data *rd, const DisplayState *ds) |
|
243 { |
|
244 set_dest_bpp_from_ds(rd, ds); |
|
245 |
|
246 /* calculate row size */ |
|
247 rd->bytes_per_dest_row = ds_get_linesize(ds); |
|
248 } |
|
249 |
|
250 /* this function rounds down odd widths */ |
|
251 static uint32_t calc_bytes_per_src_row(enum fb_src_bpp_mode bpp, uint32_t cols) |
|
252 { |
|
253 uint32_t bytes_per_row = cols; |
|
254 |
|
255 switch (bpp) { |
|
256 case BPP_SRC_1: |
|
257 bytes_per_row >>= 3; |
|
258 break; |
|
259 |
|
260 case BPP_SRC_2: |
|
261 bytes_per_row >>= 2; |
|
262 break; |
|
263 |
|
264 case BPP_SRC_4: |
|
265 bytes_per_row >>= 1; |
|
266 break; |
|
267 |
|
268 case BPP_SRC_8: |
|
269 break; |
|
270 |
|
271 case BPP_SRC_15: |
|
272 case BPP_SRC_16: |
|
273 bytes_per_row <<= 1; |
|
274 break; |
|
275 |
|
276 case BPP_SRC_24: |
|
277 bytes_per_row *= 3; |
|
278 break; |
|
279 |
|
280 case BPP_SRC_32: |
|
281 bytes_per_row <<= 2; |
|
282 break; |
|
283 } |
|
284 |
|
285 if (bpp != BPP_SRC_24 && (bytes_per_row % 4) != 0) { |
|
286 fprintf(stderr, "Warning: setting an invalid width/depth combination, rounding down.\n"); |
|
287 bytes_per_row &= ~3; |
|
288 } |
|
289 |
|
290 return bytes_per_row; |
|
291 } |
|
292 |
|
293 static uint32_t calc_bytes_per_dest_row(enum fb_dest_bpp_mode bpp, uint32_t cols) |
|
294 { |
|
295 uint32_t bytes_per_row = cols; |
|
296 |
|
297 switch (bpp) { |
|
298 case BPP_DEST_8: |
|
299 break; |
|
300 case BPP_DEST_15: |
|
301 case BPP_DEST_16: |
|
302 bytes_per_row <<= 1; |
|
303 break; |
|
304 case BPP_DEST_24: |
|
305 bytes_per_row *= 3; |
|
306 break; |
|
307 case BPP_DEST_32: |
|
308 bytes_per_row <<= 2; |
|
309 break; |
|
310 } |
|
311 |
|
312 return bytes_per_row; |
|
313 } |
|
314 |
|
315 static row_draw_fn get_draw_fn(const render_data * rd) |
|
316 { |
|
317 return fb_draw_fn[rd->dest_bpp_mode][rd->color_order][rd->byte_order][rd->pixel_order][rd->src_bpp_mode]; |
|
318 } |
|
319 |
|
320 inline static void* calc_src_row_address_host(const render_data * rd, uint32_t row) |
|
321 { |
|
322 return (void*)((char*)(rd->base_host) + row * (rd->bytes_per_src_row + rd->inter_src_row_gap)); |
|
323 } |
|
324 |
|
325 inline static ram_addr_t calc_src_row_address_target(const render_data * rd, uint32_t row) |
|
326 { |
|
327 target_phys_addr_t phys; |
|
328 phys = rd->base_target + row * (rd->bytes_per_src_row + rd->inter_src_row_gap); |
|
329 return get_ram_offset_phys(phys); |
|
330 } |
|
331 |
|
332 inline static uint8_t *calc_dest_row_address(const render_data * rd, int row) |
|
333 { |
|
334 return rd->dest + rd->dest_start_offset + row * rd->dest_col_step; |
|
335 } |
|
336 |
|
337 static int is_dirty_row(const render_data * rd, uint32_t row) |
|
338 { |
|
339 int dirty; |
|
340 uint32_t addr; |
|
341 uint32_t end; |
|
342 |
|
343 addr = calc_src_row_address_target(rd, row); |
|
344 end = (addr + rd->bytes_per_src_row - 1) & TARGET_PAGE_MASK; |
|
345 addr &= TARGET_PAGE_MASK; |
|
346 |
|
347 /* Iterate over all the pages belonging to this row */ |
|
348 |
|
349 do { |
|
350 dirty = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG); |
|
351 addr += TARGET_PAGE_SIZE; |
|
352 } while (!dirty && addr <= end); |
|
353 |
|
354 return dirty; |
|
355 } |
|
356 |
|
357 static void draw_blank_row(uint8_t *dest, uint32_t bytes) |
|
358 { |
|
359 memset(dest, 0, bytes); |
|
360 } |
|
361 |
|
362 |
|
363 static void decode_rgb_for_palette(uint32_t data, unsigned int *r, unsigned int *g, unsigned int *b) |
|
364 { |
|
365 *r = (data >> 16) & 0xff; |
|
366 *g = (data >> 8) & 0xff; |
|
367 *b = data & 0xff; |
|
368 } |
|
369 |
|
370 static void update_complete_palette(render_data * rd) |
|
371 { |
|
372 int n, i; |
|
373 uint32_t raw; |
|
374 unsigned int r, g, b; |
|
375 |
|
376 switch (rd->src_bpp_mode) { |
|
377 case BPP_SRC_1: n = 2; break; |
|
378 case BPP_SRC_2: n = 4; break; |
|
379 case BPP_SRC_4: n = 16; break; |
|
380 case BPP_SRC_8: n = 256; break; |
|
381 default: return; |
|
382 } |
|
383 |
|
384 for (i=0; i<n; i++) { |
|
385 raw = rd->raw_palette[i]; |
|
386 decode_rgb_for_palette(raw, &r, &g, &b); |
|
387 switch (rd->dest_bpp_mode) { |
|
388 case BPP_DEST_8: |
|
389 rd->palette[i] = rgb_to_pixel8(r, g, b); |
|
390 break; |
|
391 case BPP_DEST_15: |
|
392 rd->palette[i] = rgb_to_pixel15(r, g, b); |
|
393 break; |
|
394 case BPP_DEST_16: |
|
395 rd->palette[i] = rgb_to_pixel16(r, g, b); |
|
396 break; |
|
397 case BPP_DEST_24: |
|
398 case BPP_DEST_32: |
|
399 rd->palette[i] = rgb_to_pixel32(r, g, b); |
|
400 break; |
|
401 } |
|
402 } |
|
403 } |
|
404 |
|
405 /* Mapping from guest (row/col) to host (x/y) coordinates. */ |
|
406 typedef struct { |
|
407 int row_x; |
|
408 int row_y; |
|
409 int col_x; |
|
410 int col_y; |
|
411 } rotation_data; |
|
412 |
|
413 static const rotation_data rotations[8] = { |
|
414 { 1, 0, 0, 1}, |
|
415 { 0, -1, 1, 0}, |
|
416 {-1, 0, 0, -1}, |
|
417 { 0, 1, -1, 0}, |
|
418 { 1, 0, 0, -1}, |
|
419 { 0, 1, 1, 0}, |
|
420 {-1, 0, 0, 1}, |
|
421 { 0, -1, -1, 0}, |
|
422 }; |
|
423 |
|
424 static void update_rotation_data(render_data *rd) |
|
425 { |
|
426 uint32_t bytes_per_dest_pixel; |
|
427 const rotation_data *r; |
|
428 |
|
429 r = &rotations[rd->orientation]; |
|
430 |
|
431 /*rd->swap_width_height = rd->orientation & 1;*/ |
|
432 |
|
433 #if 0 |
|
434 TODO DFG |
|
435 rd->bytes_per_dest_row = calc_bytes_per_dest_row(rd->dest_bpp_mode, get_screen_width(rd)); |
|
436 #endif |
|
437 bytes_per_dest_pixel = calc_bytes_per_dest_row(rd->dest_bpp_mode, get_screen_width(rd)) / get_screen_width(rd); |
|
438 |
|
439 /* Offset the start position if we are rendering backwards. */ |
|
440 rd->dest_start_offset = 0; |
|
441 if (r->row_x + r->col_x < 0) |
|
442 rd->dest_start_offset += bytes_per_dest_pixel * (get_screen_width(rd) - 1); |
|
443 /*rd->dest_start_offset += rd->bytes_per_dest_row - bytes_per_dest_pixel;*/ |
|
444 |
|
445 if (r->row_y + r->col_y < 0) |
|
446 rd->dest_start_offset += rd->bytes_per_dest_row * (get_screen_height(rd) - 1); |
|
447 |
|
448 rd->dest_row_step = rd->bytes_per_dest_row * r->row_y |
|
449 + bytes_per_dest_pixel * r->row_x; |
|
450 rd->dest_col_step = rd->bytes_per_dest_row * r->col_y |
|
451 + bytes_per_dest_pixel * r->col_x; |
|
452 } |
|
453 |
|
454 static void update_render_data(render_data *rd) |
|
455 { |
|
456 if (rd->need_internal_update) { |
|
457 rd->fn = get_draw_fn(rd); |
|
458 rd->bytes_per_src_row = calc_bytes_per_src_row(rd->src_bpp_mode, |
|
459 rd->cols); |
|
460 update_complete_palette(rd); |
|
461 if (rd->row_pitch == 0) |
|
462 rd->inter_src_row_gap = 0; |
|
463 else |
|
464 rd->inter_src_row_gap = rd->row_pitch - rd->bytes_per_src_row; |
|
465 update_rotation_data(rd); /* updates bytes_per_dest_row too */ |
|
466 rd->need_internal_update = 0; |
|
467 } |
|
468 } |
|
469 |
|
470 |
|
471 void set_palette_value(render_data *rd, uint32_t n, uint32_t value) |
|
472 { |
|
473 rd->raw_palette[n] = value; |
|
474 rd->need_internal_update = 1; |
|
475 } |
|
476 |
|
477 static void render_blank_screen(render_data * rdata) |
|
478 { |
|
479 int i; |
|
480 uint8_t* addr = rdata->dest; |
|
481 const uint32_t rows = get_screen_height(rdata); |
|
482 |
|
483 for (i = 0; i < rows; i++) { |
|
484 draw_blank_row(addr, rdata->bytes_per_dest_row); |
|
485 addr += rdata->bytes_per_dest_row; |
|
486 } |
|
487 } |
|
488 |
|
489 static void render_from_host(DisplayState *ds, const render_data *rdata) |
|
490 { |
|
491 int i; |
|
492 |
|
493 for (i = 0; i < rdata->rows; i++) { |
|
494 rdata->fn(rdata->palette, |
|
495 calc_dest_row_address(rdata, i), |
|
496 /*(uint8_t *)*/calc_src_row_address_host(rdata, i), |
|
497 rdata->cols, |
|
498 rdata->dest_row_step); |
|
499 } |
|
500 |
|
501 if (!rdata->swap_width_height) |
|
502 dpy_update(ds, 0, 0, rdata->cols, rdata->rows); |
|
503 else |
|
504 dpy_update(ds, 0, 0, rdata->rows, rdata->cols); |
|
505 |
|
506 } |
|
507 |
|
508 static void render_from_target(DisplayState *ds, const render_data *rdata, int full_update) |
|
509 { |
|
510 int first_dirty_row = NOT_ASSIGNED, last_dirty_row = 0; |
|
511 int i; |
|
512 |
|
513 for (i = 0; i < rdata->rows; i++) { |
|
514 if (full_update || is_dirty_row(rdata, i)) { |
|
515 /* FIXME: This is broken if it spans multiple RAM regions. */ |
|
516 rdata->fn(rdata->palette, |
|
517 calc_dest_row_address(rdata, i), |
|
518 host_ram_addr(calc_src_row_address_target(rdata, i)), |
|
519 rdata->cols, |
|
520 rdata->dest_row_step); |
|
521 |
|
522 if (first_dirty_row == NOT_ASSIGNED) |
|
523 first_dirty_row = i; |
|
524 last_dirty_row = i; |
|
525 } |
|
526 } |
|
527 |
|
528 if (first_dirty_row != NOT_ASSIGNED) { |
|
529 cpu_physical_memory_reset_dirty( |
|
530 calc_src_row_address_target(rdata, first_dirty_row), /* first row byte */ |
|
531 calc_src_row_address_target(rdata, last_dirty_row + 1) - 1, /* last row byte */ |
|
532 VGA_DIRTY_FLAG); |
|
533 |
|
534 if (!rdata->swap_width_height) |
|
535 dpy_update(ds, 0, first_dirty_row, rdata->cols, last_dirty_row - first_dirty_row + 1); |
|
536 else |
|
537 dpy_update(ds, first_dirty_row, 0, last_dirty_row - first_dirty_row + 1, rdata->cols); |
|
538 } |
|
539 } |
|
540 |
|
541 static int prepare_ds_for_rendering(DisplayState *ds, render_data *rdata) |
|
542 { |
|
543 rdata->swap_width_height = rdata->orientation & 1; |
|
544 |
|
545 if (ds_get_width(ds) == get_screen_width(rdata) && |
|
546 ds_get_height(ds) == get_screen_height(rdata)) |
|
547 return 1; |
|
548 else |
|
549 return gui_resize_vt(ds, get_screen_width(rdata), get_screen_height(rdata)); |
|
550 } |
|
551 |
|
552 void render(DisplayState *ds, render_data * rdata, int full_update) |
|
553 { |
|
554 if (prepare_ds_for_rendering(ds, rdata)) { |
|
555 |
|
556 rdata->dest = ds_get_data(ds); |
|
557 |
|
558 set_dest_data_from_ds(rdata, ds); |
|
559 |
|
560 rdata->need_internal_update |= full_update; |
|
561 update_render_data(rdata); |
|
562 |
|
563 if (rdata->blank) { |
|
564 render_blank_screen(rdata); |
|
565 } else { |
|
566 if (rdata->base_is_in_target) |
|
567 render_from_target(ds, rdata, full_update); |
|
568 else |
|
569 render_from_host(ds, rdata); |
|
570 } |
|
571 } |
|
572 } |
|
573 |
|
574 render_data *create_render_data() |
|
575 { |
|
576 render_data *rdata = qemu_mallocz(sizeof(render_data)); |
|
577 |
|
578 /* set some defaults */ |
|
579 |
|
580 return rdata; |
|
581 } |
|
582 |
|
583 void destroy_render_data(render_data *rd) |
|
584 { |
|
585 qemu_free(rd); |
|
586 } |
|
587 |
|
588 void qemu_put_render_data(QEMUFile *f, const render_data *s) |
|
589 { |
|
590 int i; |
|
591 |
|
592 qemu_put_be32(f, s->base_is_in_target); |
|
593 if (s->base_is_in_target) |
|
594 qemu_put_be64(f, s->base_target); |
|
595 qemu_put_be32(f, s->cols); |
|
596 qemu_put_be32(f, s->rows); |
|
597 qemu_put_be32(f, s->row_pitch); |
|
598 qemu_put_be32(f, s->pixel_order); |
|
599 qemu_put_be32(f, s->byte_order); |
|
600 qemu_put_be32(f, s->color_order); |
|
601 qemu_put_be32(f, s->src_bpp_mode); |
|
602 qemu_put_be32(f, s->orientation); |
|
603 qemu_put_be32(f, s->blank); |
|
604 for (i = 0; i < 256; i++) |
|
605 qemu_put_be32(f, s->raw_palette[i]); |
|
606 } |
|
607 |
|
608 void qemu_get_render_data(QEMUFile *f, render_data *s) |
|
609 { |
|
610 int i; |
|
611 |
|
612 s->base_is_in_target = qemu_get_be32(f); |
|
613 if (s->base_is_in_target) |
|
614 s->base_target = qemu_get_be64(f); |
|
615 s->cols = qemu_get_be32(f); |
|
616 s->rows = qemu_get_be32(f); |
|
617 s->row_pitch = qemu_get_be32(f); |
|
618 s->pixel_order = qemu_get_be32(f); |
|
619 s->byte_order = qemu_get_be32(f); |
|
620 s->color_order = qemu_get_be32(f); |
|
621 s->src_bpp_mode = qemu_get_be32(f); |
|
622 s->orientation = qemu_get_be32(f); |
|
623 s->blank = qemu_get_be32(f); |
|
624 for (i = 0; i < 256; i++) |
|
625 s->raw_palette[i] = qemu_get_be32(f); |
|
626 s->need_internal_update = 1; |
|
627 } |