--- server/tests/Makefile.am | 8 ++- server/tests/test_display_base.c | 48 ++++++++++++++--- server/tests/test_display_base.h | 13 +++++ server/tests/test_display_width_stride.c | 92 ++++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+), 7 deletions(-) create mode 100644 server/tests/test_display_width_stride.c diff --git a/server/tests/Makefile.am b/server/tests/Makefile.am index e0472f3..655bc83 100644 --- a/server/tests/Makefile.am +++ b/server/tests/Makefile.am @@ -35,6 +35,7 @@ noinst_PROGRAMS = \ test_display_resolution_changes \ test_two_servers \ test_vdagent \ + test_display_width_stride \ $(NULL) test_vdagent_SOURCES = \ @@ -90,4 +91,9 @@ test_two_servers_SOURCES = \ test_two_servers.c \ $(NULL) - +test_display_width_stride_SOURCES = \ + $(COMMON_BASE) \ + test_display_base.c \ + test_display_base.h \ + test_display_width_stride.c \ + $(NULL) diff --git a/server/tests/test_display_base.c b/server/tests/test_display_base.c index 8657e91..b4c93f3 100644 --- a/server/tests/test_display_base.c +++ b/server/tests/test_display_base.c @@ -309,20 +309,36 @@ static SimpleSpiceUpdate *test_spice_create_update_copy_bits(Test *test, uint32_ return update; } -static SimpleSurfaceCmd *create_surface(int surface_id, int width, int height, uint8_t *data) +static int format_to_bpp(int format) +{ + switch (format) { + case SPICE_SURFACE_FMT_8_A: + return 1; + case SPICE_SURFACE_FMT_16_555: + case SPICE_SURFACE_FMT_16_565: + return 2; + case SPICE_SURFACE_FMT_32_xRGB: + case SPICE_SURFACE_FMT_32_ARGB: + return 4; + } + abort(); +} + +static SimpleSurfaceCmd *create_surface(int surface_id, int format, int width, int height, uint8_t *data) { SimpleSurfaceCmd *simple_cmd = calloc(sizeof(SimpleSurfaceCmd), 1); QXLSurfaceCmd *surface_cmd = &simple_cmd->surface_cmd; + int bpp = format_to_bpp(format); set_cmd(&simple_cmd->ext, QXL_CMD_SURFACE, (intptr_t)surface_cmd); simple_set_release_info(&surface_cmd->release_info, (intptr_t)simple_cmd); surface_cmd->type = QXL_SURFACE_CMD_CREATE; surface_cmd->flags = 0; // ? surface_cmd->surface_id = surface_id; - surface_cmd->u.surface_create.format = SPICE_SURFACE_FMT_32_xRGB; + surface_cmd->u.surface_create.format = format; surface_cmd->u.surface_create.width = width; surface_cmd->u.surface_create.height = height; - surface_cmd->u.surface_create.stride = -width * 4; + surface_cmd->u.surface_create.stride = -width * bpp; surface_cmd->u.surface_create.data = (intptr_t)data; return simple_cmd; } @@ -471,7 +487,10 @@ static void produce_command(Test *test) if (test->has_secondary) test->target_surface = 1; - ASSERT(test->num_commands); + if (!test->num_commands) { + usleep(1000); + return; + } command = &test->commands[test->cmd_index]; if (command->cb) { @@ -538,8 +557,17 @@ static void produce_command(Test *test) case SIMPLE_CREATE_SURFACE: { SimpleSurfaceCmd *update; test->target_surface = MAX_SURFACE_NUM - 1; - update = create_surface(test->target_surface, SURF_WIDTH, SURF_HEIGHT, - test->secondary_surface); + if (command) { + update = create_surface(command->create_surface.surface_id, + command->create_surface.format, + command->create_surface.width, + command->create_surface.height, + command->create_surface.data); + } else { + update = create_surface(test->target_surface, SPICE_SURFACE_FMT_32_xRGB, + SURF_WIDTH, SURF_HEIGHT, + test->secondary_surface); + } push_command(&update->ext); test->has_secondary = 1; break; @@ -716,7 +744,15 @@ static void set_client_capabilities(QXLInstance *qin, uint8_t client_present, uint8_t caps[58]) { + Test *test = SPICE_CONTAINEROF(qin, Test, qxl_instance); + printf("%s: present %d caps %d\n", __func__, client_present, caps[0]); + if (test->on_client_connected && client_present) { + test->on_client_connected(test); + } + if (test->on_client_disconnected && !client_present) { + test->on_client_disconnected(test); + } } QXLInterface display_sif = { diff --git a/server/tests/test_display_base.h b/server/tests/test_display_base.h index c3b9fea..d2823a7 100644 --- a/server/tests/test_display_base.h +++ b/server/tests/test_display_base.h @@ -32,6 +32,14 @@ typedef struct CommandCreatePrimary { uint32_t height; } CommandCreatePrimary; +typedef struct CommandCreateSurface { + uint32_t surface_id; + uint32_t format; + uint32_t width; + uint32_t height; + uint8_t *data; +} CommandCreateSurface; + typedef struct CommandDrawBitmap { QXLRect bbox; uint8_t *bitmap; @@ -62,6 +70,7 @@ struct Command { CommandDrawBitmap bitmap; CommandDrawSolid solid; CommandSleep sleep; + CommandCreateSurface create_surface; }; }; @@ -100,6 +109,10 @@ struct Test { int cmd_index; int target_surface; + + // callbacks + void (*on_client_connected)(Test *test); + void (*on_client_disconnected)(Test *test); }; void test_set_simple_command_list(Test *test, int *command, int num_commands); diff --git a/server/tests/test_display_width_stride.c b/server/tests/test_display_width_stride.c new file mode 100644 index 0000000..20de57a --- /dev/null +++ b/server/tests/test_display_width_stride.c @@ -0,0 +1,92 @@ +/** + * Recreate the primary surface endlessly. + */ + +#include <config.h> +#include <math.h> +#include <stdlib.h> +#include "test_display_base.h" + +SpiceTimer *ping_timer; + +void show_channels(SpiceServer *server); + +int ping_ms = 100; + +void pinger(void *opaque) +{ + Test *test = opaque; + // show_channels is not thread safe - fails if disconnections / connections occur + //show_channels(server); + + test->core->timer_start(ping_timer, ping_ms); +} + +static int g_surface_id = 1; +static uint8_t *g_surface_data; + +void set_draw_parameters(Test *test, Command *command) +{ + static int count = 17; + CommandDrawSolid *solid = &command->solid; + + solid->bbox.top = 0; + solid->bbox.left = 0; + solid->bbox.bottom = 20; + solid->bbox.right = count; + solid->surface_id = g_surface_id; + count++; +} + +void set_surface_params(Test *test, Command *command) +{ + CommandCreateSurface *create = &command->create_surface; + + // UGLY + if (g_surface_data) { + exit(0); + } + create->format = SPICE_SURFACE_FMT_8_A; + create->width = 128; + create->height = 128; + g_surface_data = realloc(g_surface_data, create->width * create->height * 1); + create->surface_id = g_surface_id; + create->data = g_surface_data; +} + +static Command commands[] = { + {SIMPLE_CREATE_SURFACE, set_surface_params}, + {SIMPLE_DRAW_SOLID, set_draw_parameters}, + {SIMPLE_DRAW_SOLID, set_draw_parameters}, + {SIMPLE_DRAW_SOLID, set_draw_parameters}, + {SIMPLE_DRAW_SOLID, set_draw_parameters}, + {SIMPLE_DRAW_SOLID, set_draw_parameters}, + {SIMPLE_DRAW_SOLID, set_draw_parameters}, + {SIMPLE_DRAW_SOLID, set_draw_parameters}, + {SIMPLE_DRAW_SOLID, set_draw_parameters}, + {SIMPLE_DRAW_SOLID, set_draw_parameters}, +}; + +void on_client_connected(Test *test) +{ + test_set_command_list(test, commands, COUNT(commands)); +} + +int main(void) +{ + SpiceCoreInterface *core; + Test *test; + + core = basic_event_loop_init(); + test = test_new(core); + test->on_client_connected = on_client_connected; + //spice_server_set_image_compression(server, SPICE_IMAGE_COMPRESS_OFF); + test_add_display_interface(test); + + ping_timer = core->timer_add(pinger, test); + core->timer_start(ping_timer, ping_ms); + + basic_event_loop_mainloop(); + + return 0; +} -- 1.8.2.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel