tests: Add internal test for the weston test screenshot capability
[platform/upstream/weston.git] / tests / internal-screenshot-test.c
1 /*
2  * Copyright © 2015 Samsung Electronics Co., Ltd
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include "config.h"
24
25 #include <unistd.h>
26 #include <stdio.h>
27 #include <string.h> /* memcpy */
28 #include <cairo.h>
29
30 #include "weston-test-client-helper.h"
31
32 char *server_parameters="--use-pixman --width=320 --height=240";
33
34 TEST(internal_screenshot)
35 {
36         struct client *client;
37         struct surface *screenshot = NULL;
38         struct surface *reference = NULL;
39         struct rectangle clip;
40         const char *fname;
41         cairo_surface_t *reference_cairo_surface;
42         cairo_status_t status;
43         bool match = false;
44         bool dump_all_images = true;
45
46         printf("Starting test\n");
47
48         /* Create the client */
49         client = create_client_and_test_surface(100, 100, 100, 100);
50         assert(client);
51         printf("Client created\n");
52
53         /* Create a surface to hold the screenshot */
54         screenshot = xzalloc(sizeof *screenshot);
55         assert(screenshot);
56
57         /* Create and attach buffer to our surface */
58         screenshot->wl_buffer = create_shm_buffer(client,
59                                                   client->output->width,
60                                                   client->output->height,
61                                                   &screenshot->data);
62         screenshot->height = client->output->height;
63         screenshot->width = client->output->width;
64         assert(screenshot->wl_buffer);
65         printf("Screenshot buffer created and attached to surface\n");
66
67         /* Take a snapshot.  Result will be in screenshot->wl_buffer. */
68         client->test->buffer_copy_done = 0;
69         weston_test_capture_screenshot(client->test->weston_test,
70                                        client->output->wl_output,
71                                        screenshot->wl_buffer);
72         printf("Capture request sent\n");
73         while (client->test->buffer_copy_done == 0)
74                 if (wl_display_dispatch(client->wl_display) < 0)
75                         break;
76         printf("Roundtrip done\n");
77
78         /* FIXME: Document somewhere the orientation the screenshot is taken
79          * and how the clip coords are interpreted, in case of scaling/transform.
80          * If we're using read_pixels() just make sure it is documented somewhere.
81          * Protocol docs in the XML, comparison function docs in Doxygen style.
82          */
83
84         /* Load reference image */
85         fname = screenshot_reference_filename("internal-screenshot", 0);
86         printf("Loading reference image %s\n", fname);
87         reference_cairo_surface = cairo_image_surface_create_from_png(fname);
88         status = cairo_surface_status(reference_cairo_surface);
89         if (status != CAIRO_STATUS_SUCCESS) {
90                 printf("Could not open %s: %s\n", fname, cairo_status_to_string(status));
91                 cairo_surface_destroy(reference_cairo_surface);
92                 assert(status != CAIRO_STATUS_SUCCESS);
93         }
94
95         /* Disguise the cairo surface in a weston test surface */
96         reference =  xzalloc(sizeof *reference);
97         reference->width = cairo_image_surface_get_width(reference_cairo_surface);
98         reference->height = cairo_image_surface_get_height(reference_cairo_surface);
99         reference->data = cairo_image_surface_get_data(reference_cairo_surface);
100
101         /* Test check_surfaces_equal()
102          * We expect this to fail since the clock will differ from when we made the reference image
103          */
104         match = check_surfaces_equal(screenshot, reference);
105         printf("Screenshot %s reference image\n", match? "equal to" : "different from");
106         assert(!match);
107
108         /* Test check_surfaces_match_in_clip()
109          * Alpha-blending and other effects can cause irrelevant discrepancies, so look only
110          * at a small portion of the solid-colored background
111          */
112         clip.x = 50;
113         clip.y = 50;
114         clip.width = 101;
115         clip.height = 101;
116         printf("Clip: %d,%d %d x %d\n", clip.x, clip.y, clip.width, clip.height);
117         match = check_surfaces_match_in_clip(screenshot, reference, &clip);
118         printf("Screenshot %s reference image in clipped area\n", match? "matches" : "doesn't match");
119         cairo_surface_destroy(reference_cairo_surface);
120         free(reference);
121
122         /* Test dumping of non-matching images */
123         if (!match || dump_all_images) {
124                 /* Write image to .png file */
125                 cairo_surface_t *surface;
126                 int bpp = 4; /* ARGB assumed */
127                 int stride = bpp * screenshot->width;
128
129                 surface = cairo_image_surface_create_for_data(screenshot->data,
130                                                               CAIRO_FORMAT_ARGB32,
131                                                               screenshot->width,
132                                                               screenshot->height,
133                                                               stride);
134
135                 printf("Writing PNG to disk\n");
136                 cairo_surface_write_to_png(surface, "clientside-screenshot.png");
137                 cairo_surface_destroy(surface);
138         }
139
140         free(screenshot);
141
142         printf("Test complete\n");
143         assert(match);
144 }