symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/fb_render_engine.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 }