diff options
author | Bryce Harrington <bryce@osg.samsung.com> | 2015-09-24 14:31:44 -0700 |
---|---|---|
committer | Bryce Harrington <bryce@osg.samsung.com> | 2015-09-25 11:23:08 -0700 |
commit | 892122ed64cebb1955253ed098563b8dc5c9c899 (patch) | |
tree | f64e6a819d62c700030655914998d8d93466a40b /tests/weston-test-client-helper.c | |
parent | 89dcea9b58fa7f2fcda3108c024d699be8a334e3 (diff) | |
download | weston-892122ed64cebb1955253ed098563b8dc5c9c899.tar.gz weston-892122ed64cebb1955253ed098563b8dc5c9c899.tar.bz2 weston-892122ed64cebb1955253ed098563b8dc5c9c899.zip |
tests: Migrate screenshot code from internal test to client helpers
These routines provide test cases an ability to capture screen images
for rendering verification.
This commit is a no-change refactoring, except for making the routines
non-static. Makefile rules are also updated; most notably, this links
test clients against the cairo libraries now.
v2: Fix pointer code styling, suggested in review
Signed-off-by: Bryce Harrington <bryce@osg.samsung.com>
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
Reviewed-by: Derek Foreman <derekf@osg.samsung.com>
Diffstat (limited to 'tests/weston-test-client-helper.c')
-rw-r--r-- | tests/weston-test-client-helper.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/tests/weston-test-client-helper.c b/tests/weston-test-client-helper.c index 65a8880b..16786d9b 100644 --- a/tests/weston-test-client-helper.c +++ b/tests/weston-test-client-helper.c @@ -31,7 +31,9 @@ #include <unistd.h> #include <errno.h> #include <sys/mman.h> +#include <cairo.h> +#include "zalloc.h" #include "shared/os-compatibility.h" #include "weston-test-client-helper.h" @@ -979,3 +981,159 @@ check_surfaces_match_in_clip(const struct surface *a, const struct surface *b, c return true; } + +/** write_surface_as_png() + * + * Writes out a given weston test surface to disk as a PNG image + * using the provided filename (with path). + * + * @returns true if successfully saved file; false otherwise. + */ +bool +write_surface_as_png(const struct surface *weston_surface, const char *fname) +{ + cairo_surface_t *cairo_surface; + cairo_status_t status; + int bpp = 4; /* Assume ARGB */ + int stride = bpp * weston_surface->width; + + cairo_surface = cairo_image_surface_create_for_data(weston_surface->data, + CAIRO_FORMAT_ARGB32, + weston_surface->width, + weston_surface->height, + stride); + printf("Writing PNG to disk\n"); + status = cairo_surface_write_to_png(cairo_surface, fname); + if (status != CAIRO_STATUS_SUCCESS) { + printf("Failed to save screenshot: %s\n", + cairo_status_to_string(status)); + return false; + } + cairo_surface_destroy(cairo_surface); + return true; +} + +/** load_surface_from_png() + * + * Reads a PNG image from disk using the given filename (and path) + * and returns as a freshly allocated weston test surface. + * + * @returns weston test surface with image, which should be free'd + * when no longer used; or, NULL in case of error. + */ +struct surface * +load_surface_from_png(const char *fname) +{ + struct surface *reference; + cairo_surface_t *reference_cairo_surface; + cairo_status_t status; + size_t source_data_size; + int bpp; + int stride; + + reference_cairo_surface = cairo_image_surface_create_from_png(fname); + status = cairo_surface_status(reference_cairo_surface); + if (status != CAIRO_STATUS_SUCCESS) { + printf("Could not open %s: %s\n", fname, cairo_status_to_string(status)); + cairo_surface_destroy(reference_cairo_surface); + return NULL; + } + + /* Disguise the cairo surface in a weston test surface */ + reference = zalloc(sizeof *reference); + if (reference == NULL) { + perror("zalloc reference"); + cairo_surface_destroy(reference_cairo_surface); + return NULL; + } + reference->width = cairo_image_surface_get_width(reference_cairo_surface); + reference->height = cairo_image_surface_get_height(reference_cairo_surface); + stride = cairo_image_surface_get_stride(reference_cairo_surface); + source_data_size = stride * reference->height; + + /* Check that the file's stride matches our assumption */ + bpp = 4; + if (stride != bpp * reference->width) { + printf("Mismatched stride for screenshot reference image %s\n", fname); + cairo_surface_destroy(reference_cairo_surface); + free(reference); + return NULL; + } + + /* Allocate new buffer for our weston reference, and copy the data from + the cairo surface so we can destroy it */ + reference->data = zalloc(source_data_size); + if (reference->data == NULL) { + perror("zalloc reference data"); + cairo_surface_destroy(reference_cairo_surface); + free(reference); + return NULL; + } + memcpy(reference->data, + cairo_image_surface_get_data(reference_cairo_surface), + source_data_size); + + cairo_surface_destroy(reference_cairo_surface); + return reference; +} + +/** create_screenshot_surface() + * + * Allocates and initializes a weston test surface for use in + * storing a screenshot of the client's output. Establishes a + * shm backed wl_buffer for retrieving screenshot image data + * from the server, sized to match the client's output display. + * + * @returns stack allocated surface image, which should be + * free'd when done using it. + */ +struct surface * +create_screenshot_surface(struct client *client) +{ + struct surface *screenshot; + screenshot = zalloc(sizeof *screenshot); + if (screenshot == NULL) + return NULL; + screenshot->wl_buffer = create_shm_buffer(client, + client->output->width, + client->output->height, + &screenshot->data); + screenshot->height = client->output->height; + screenshot->width = client->output->width; + + return screenshot; +} + +/** capture_screenshot_of_output() + * + * Requests a screenshot from the server of the output that the + * client appears on. The image data returned from the server + * can be accessed from the screenshot surface's data member. + * + * @returns a new surface object, which should be free'd when no + * longer needed. + */ +struct surface * +capture_screenshot_of_output(struct client *client) +{ + struct surface *screenshot; + + /* Create a surface to hold the screenshot */ + screenshot = create_screenshot_surface(client); + + client->test->buffer_copy_done = 0; + weston_test_capture_screenshot(client->test->weston_test, + client->output->wl_output, + screenshot->wl_buffer); + while (client->test->buffer_copy_done == 0) + if (wl_display_dispatch(client->wl_display) < 0) + break; + + /* FIXME: Document somewhere the orientation the screenshot is taken + * and how the clip coords are interpreted, in case of scaling/transform. + * If we're using read_pixels() just make sure it is documented somewhere. + * Protocol docs in the XML, comparison function docs in Doxygen style. + */ + + return screenshot; +} |