From 4c880348455dbff8c6e1a6b72ee86b923d242a1e Mon Sep 17 00:00:00 2001 From: Yonit Halperin Date: Wed, 2 May 2012 14:30:12 +0300 Subject: server/tests/test_display_streaming: include tests for clip and sized frames CC: Alon Levy --- server/tests/test_display_streaming.c | 197 +++++++++++++++++++++++++++++++--- 1 file changed, 181 insertions(+), 16 deletions(-) (limited to 'server/tests/test_display_streaming.c') diff --git a/server/tests/test_display_streaming.c b/server/tests/test_display_streaming.c index b4fe0136..f3958000 100644 --- a/server/tests/test_display_streaming.c +++ b/server/tests/test_display_streaming.c @@ -9,40 +9,197 @@ #include #include #include +#include +#include #include "test_display_base.h" static int sized; +static int render_last_frame; -void create_update(Command *command) +void create_overlay(Command *command , int width, int height) { - static int count = 0; - CommandDrawSolid *cmd = &command->solid; + CommandDrawBitmap *cmd = &command->bitmap; + uint32_t *dst; + cmd->surface_id = 0; cmd->bbox.left = 0; - cmd->bbox.right = test_get_width(); cmd->bbox.top = 0; - cmd->color = 0xffff00 + ((count * 10) % 256); - assert(test_get_height() > 50); - cmd->bbox.bottom = test_get_height() - 50; - if (count < 20) { - } else if (sized && count % 5 == 0) { - cmd->bbox.bottom = test_get_height(); - cmd->color = 0xff; + cmd->bbox.right = width; + cmd->bbox.bottom = height; + + cmd->num_clip_rects = 0; + cmd->bitmap = malloc(width * height * 4 ); + dst = (uint32_t *)cmd->bitmap; + for (int i = 0; i < width * height; i++, dst++) { + *dst = 0x8B008B; } + +} + +#define NUM_COMMANDS 2000 +#define SIZED_INTERVAL 100 +#define OVERLAY_FRAME 500 +#define OVERLAY_WIDTH 200 +#define OVERLAY_HEIGHT 200 + +/* + * Create a frame in a stream that displays a row that moves + * from the top to the bottom repeatedly. + * Upon the OVERLAY_FRAME-th, a drawable is created on top of a part of the stream, + * and from then on, all the stream frames has a clipping that keeps this drawable + * visible, and in addition a clipping_factor is subtracted from the right limit of their clipping. + * If sized=TRUE, a higher frame than the original stream height is created every SIZED_INTERVAL. + * The sized frames can be distinguished by a change in the color of the top and bottom limits of the + * surface. + */ +void create_clipped_frame(Command *command, int clipping_factor) +{ + static int count = 0; + CommandDrawBitmap *cmd = &command->bitmap; + int max_height = test_get_height(); + int width = test_get_width(); + int height; + int cur_line, end_line; + uint32_t *dst; + count++; - printf("%d %d\n", count, cmd->bbox.bottom); + if (count == NUM_COMMANDS) { + count = 0; + } + if (count == OVERLAY_FRAME) { + create_overlay(command, OVERLAY_WIDTH, OVERLAY_HEIGHT); + return; + } + + cmd->surface_id = 0; + + cmd->bbox.left = 0; + cmd->bbox.right = width; + assert(max_height > 600); + cmd->bbox.top = 50; + cmd->bbox.bottom = max_height - 50; + height = cmd->bbox.bottom - cmd->bbox.top; + cur_line = (height/30)*(count % 30); + end_line = cur_line + (height/30); + if (end_line >= height || height - end_line < 8) { + end_line = height; + } + + if (sized && count % SIZED_INTERVAL == 0) { + + cmd->bbox.top = 0; + cmd->bbox.bottom = max_height; + height = max_height; + cur_line += 50; + end_line += 50; + } + + cmd->bitmap = malloc(width*height*4); + memset(cmd->bitmap, 0xff, width*height*4); + dst = (uint32_t *)(cmd->bitmap + cur_line*width*4); + for (cur_line; cur_line < end_line; cur_line++) { + int col; + for (col = 0; col < width; col++, dst++) { + *dst = 0x00FF00; + } + } + if (sized && count % SIZED_INTERVAL == 0) { + int i; + uint32_t color = 0xffffff & rand(); + + dst = (uint32_t *)cmd->bitmap; + + for (i = 0; i < 50*width; i++, dst++) { + *dst = color; + } + + dst = ((uint32_t *)(cmd->bitmap + (height - 50)*4*width)); + + for (i = 0; i < 50*width; i++, dst++) { + *dst = color; + } + } + + if (count < OVERLAY_FRAME) { + cmd->num_clip_rects = 0; + } else { + cmd->num_clip_rects = 2; + cmd->clip_rects = calloc(sizeof(QXLRect), 2); + cmd->clip_rects[0].left = OVERLAY_WIDTH; + cmd->clip_rects[0].top = cmd->bbox.top; + cmd->clip_rects[0].right = cmd->bbox.right - clipping_factor; + cmd->clip_rects[0].bottom = OVERLAY_HEIGHT; + cmd->clip_rects[1].left = cmd->bbox.left; + cmd->clip_rects[1].top = OVERLAY_HEIGHT; + cmd->clip_rects[1].right = cmd->bbox.right - clipping_factor; + cmd->clip_rects[1].bottom = cmd->bbox.bottom; + } +} + +void create_frame1(Command *command) +{ + create_clipped_frame(command, 0); +} + +void create_frame2(Command *command) +{ + create_clipped_frame(command, 200); +} + +typedef void (*create_frame_cb)(Command *command); + + +/* + * The test contains two types of streams. The first stream doesn't + * have a clipping besides the on that the display the overlay drawable. + * Expected result: If render_last_frame=false, the last frame should + * be sent losslessly. Otherwise, red_update_area should be called, and the + * stream is upgraded by a screenshot. + * + * In the second test, the stream clip changes in the middle (becomes smaller). + * Expected result: red_update_area should is, and the + * stream is upgraded by a screenshot (including lossy areas that belong to old frames + * and were never covered by a lossless drawable). + * + */ +static void get_stream_commands(Command *commands, int num_commands, + create_frame_cb cb) +{ + int i; + + commands[0].command = DESTROY_PRIMARY; + commands[1].command = CREATE_PRIMARY; + commands[1].create_primary.width = 1280; + commands[1].create_primary.height = 1024; + commands[num_commands - 1].command = SLEEP; + commands[num_commands - 1].sleep.secs = 20; + + for (i = 2; i < num_commands - 1; i++) { + commands[i].command = SIMPLE_DRAW_BITMAP; + commands[i].cb = cb; + } + if (render_last_frame) { + commands[num_commands - 2].command = SIMPLE_UPDATE; + } } -static Command commands[] = { - {SIMPLE_DRAW_SOLID, create_update}, -}; +static void get_commands(Command **commands, int *num_commands) +{ + *num_commands = NUM_COMMANDS * 2; + *commands = calloc(sizeof(Command), *num_commands); + + get_stream_commands(*commands, NUM_COMMANDS, create_frame1); + get_stream_commands((*commands) + NUM_COMMANDS, NUM_COMMANDS, create_frame2); +} SpiceCoreInterface *core; SpiceServer *server; int main(int argc, char **argv) { + Command *commands; + int num_commands; int i; spice_test_config_parse_args(argc, argv); sized = 0; @@ -50,12 +207,20 @@ int main(int argc, char **argv) if (strcmp(argv[i], "sized") == 0) { sized = 1; } + /* render last frame */ + if (strcmp(argv[i], "render") == 0) { + render_last_frame = 1; + } } + srand(time(NULL)); + // todo: add args list of test numbers with explenations core = basic_event_loop_init(); server = test_init(core); spice_server_set_streaming_video(server, SPICE_STREAM_VIDEO_ALL); test_add_display_interface(server); - test_set_command_list(commands, COUNT(commands)); + get_commands(&commands, &num_commands); + test_set_command_list(commands, num_commands); basic_event_loop_mainloop(); + free(commands); return 0; } -- cgit