From fb9089d4f57bc1c70a4672f802b0858c6a8da0c7 Mon Sep 17 00:00:00 2001 From: Bryce Harrington Date: Tue, 4 Nov 2014 16:39:38 -0800 Subject: [PATCH] tests: Add internal test for the weston test screenshot capability This also serves as a proof of concept of the screen capture functionality and as a demo for snapshot-based rendering verification. Implements screenshot saving clientside in the test itself. This also demonstrates use of test-specific configuration files, in this case to disable fadein animations and background images. Signed-off-by: Bryce Harrington Reviewed-By: Derek Foreman --- Makefile.am | 20 ++- tests/internal-screenshot-test.c | 144 +++++++++++++++++++++ tests/internal-screenshot.ini | 3 + tests/reference/internal-screenshot-00.png | Bin 0 -> 5149 bytes 4 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 tests/internal-screenshot-test.c create mode 100644 tests/internal-screenshot.ini create mode 100644 tests/reference/internal-screenshot-00.png diff --git a/Makefile.am b/Makefile.am index 543c7369..e860e0e7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -941,7 +941,10 @@ libshared_cairo_la_SOURCES = \ # tests subdirectory # -TESTS = $(shared_tests) $(module_tests) $(weston_tests) $(ivi_tests) +TESTS = $(internal_tests) $(shared_tests) $(module_tests) $(weston_tests) $(ivi_tests) + +internal_tests = \ + internal-screenshot.weston shared_tests = \ config-parser.test \ @@ -988,6 +991,7 @@ noinst_LTLIBRARIES += \ noinst_PROGRAMS += \ $(setbacklight) \ + $(internal_tests) \ $(shared_tests) \ $(weston_tests) \ $(ivi_tests) \ @@ -1040,6 +1044,20 @@ nodist_libtest_client_la_SOURCES = \ libtest_client_la_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) libtest_client_la_LIBADD = $(TEST_CLIENT_LIBS) libshared.la libtest-runner.la + +# +# Internal tests - tests functionality of the testsuite itself +# + +internal_screenshot_weston_SOURCES = tests/internal-screenshot-test.c +internal_screenshot_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) $(CAIRO_CFLAGS) +internal_screenshot_weston_LDADD = libtest-client.la $(CAIRO_LIBS) + + +# +# Weston Tests +# + bad_buffer_weston_SOURCES = tests/bad-buffer-test.c bad_buffer_weston_CFLAGS = $(AM_CFLAGS) $(TEST_CLIENT_CFLAGS) bad_buffer_weston_LDADD = libtest-client.la diff --git a/tests/internal-screenshot-test.c b/tests/internal-screenshot-test.c new file mode 100644 index 00000000..27b1547c --- /dev/null +++ b/tests/internal-screenshot-test.c @@ -0,0 +1,144 @@ +/* + * Copyright © 2015 Samsung Electronics Co., Ltd + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "config.h" + +#include +#include +#include /* memcpy */ +#include + +#include "weston-test-client-helper.h" + +char *server_parameters="--use-pixman --width=320 --height=240"; + +TEST(internal_screenshot) +{ + struct client *client; + struct surface *screenshot = NULL; + struct surface *reference = NULL; + struct rectangle clip; + const char *fname; + cairo_surface_t *reference_cairo_surface; + cairo_status_t status; + bool match = false; + bool dump_all_images = true; + + printf("Starting test\n"); + + /* Create the client */ + client = create_client_and_test_surface(100, 100, 100, 100); + assert(client); + printf("Client created\n"); + + /* Create a surface to hold the screenshot */ + screenshot = xzalloc(sizeof *screenshot); + assert(screenshot); + + /* Create and attach buffer to our surface */ + 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; + assert(screenshot->wl_buffer); + printf("Screenshot buffer created and attached to surface\n"); + + /* Take a snapshot. Result will be in screenshot->wl_buffer. */ + client->test->buffer_copy_done = 0; + weston_test_capture_screenshot(client->test->weston_test, + client->output->wl_output, + screenshot->wl_buffer); + printf("Capture request sent\n"); + while (client->test->buffer_copy_done == 0) + if (wl_display_dispatch(client->wl_display) < 0) + break; + printf("Roundtrip done\n"); + + /* 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. + */ + + /* Load reference image */ + fname = screenshot_reference_filename("internal-screenshot", 0); + printf("Loading reference image %s\n", fname); + 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); + assert(status != CAIRO_STATUS_SUCCESS); + } + + /* Disguise the cairo surface in a weston test surface */ + reference = xzalloc(sizeof *reference); + reference->width = cairo_image_surface_get_width(reference_cairo_surface); + reference->height = cairo_image_surface_get_height(reference_cairo_surface); + reference->data = cairo_image_surface_get_data(reference_cairo_surface); + + /* Test check_surfaces_equal() + * We expect this to fail since the clock will differ from when we made the reference image + */ + match = check_surfaces_equal(screenshot, reference); + printf("Screenshot %s reference image\n", match? "equal to" : "different from"); + assert(!match); + + /* Test check_surfaces_match_in_clip() + * Alpha-blending and other effects can cause irrelevant discrepancies, so look only + * at a small portion of the solid-colored background + */ + clip.x = 50; + clip.y = 50; + clip.width = 101; + clip.height = 101; + printf("Clip: %d,%d %d x %d\n", clip.x, clip.y, clip.width, clip.height); + match = check_surfaces_match_in_clip(screenshot, reference, &clip); + printf("Screenshot %s reference image in clipped area\n", match? "matches" : "doesn't match"); + cairo_surface_destroy(reference_cairo_surface); + free(reference); + + /* Test dumping of non-matching images */ + if (!match || dump_all_images) { + /* Write image to .png file */ + cairo_surface_t *surface; + int bpp = 4; /* ARGB assumed */ + int stride = bpp * screenshot->width; + + surface = cairo_image_surface_create_for_data(screenshot->data, + CAIRO_FORMAT_ARGB32, + screenshot->width, + screenshot->height, + stride); + + printf("Writing PNG to disk\n"); + cairo_surface_write_to_png(surface, "clientside-screenshot.png"); + cairo_surface_destroy(surface); + } + + free(screenshot); + + printf("Test complete\n"); + assert(match); +} diff --git a/tests/internal-screenshot.ini b/tests/internal-screenshot.ini new file mode 100644 index 00000000..abc046e9 --- /dev/null +++ b/tests/internal-screenshot.ini @@ -0,0 +1,3 @@ +[shell] +startup-animation=none +background-color=0xCC336699 diff --git a/tests/reference/internal-screenshot-00.png b/tests/reference/internal-screenshot-00.png new file mode 100644 index 0000000000000000000000000000000000000000..5dc79576345241122f9aba308c93e5e9c7797fbd GIT binary patch literal 5149 zcmd^D_fr$jwns%o0kNQTupmecozUc>qVffT8j&85NJ0$+q!WUoA`n3YL248=p$MTD zL+=nE(mMe{F@)ZeP%i%Pez@;1xbxoGoh`FFvu94*b3PFdLHBvi2%TYLW8*P=aQ87A z+p&KgtyejZAB_j5GCD^ShlA1myKIMl+m|YQ92?uk9>cr(PyADt#sX~2d=6UHRxFo8 zV$F_`#$R+OCQ6(%Z&YphQD-dQdBf1ix;VMH*voxHQc75bj<I3jPp({+v}_LZ1s&o*zS@$q_`GmZD74?I7HZ^-=n$7cs+Nm)`)k%hQ zFL%w2NQc=I`serzVneQyyk?8l2iaRc@1aQOcC>GGB5B?oXyuObgW$me)FdrRy7%vT$H2!=}not);y=}f;t10}9I#ik0hZ`N zS-5s7RgaN!IRFt}rl3KDHO+h3N&i$wuDvR2UoYeb_~$G%4il=LBqUaa^usl37=!BT z-B(%QQb>De`%rZjngTI{zX^Y%z*t=xYoPIimP}d5JJ0dk8W1xw!ge5}V7Kw*Okw5X z6f!KkD^i^0U;ox@zEGu0taBH!)dO0(?lP9&wgx?V%siO+Y&O38dN^)x)g1zYO+}#E ztZM|dp4Y1J_qF880a)uvcPyPxdw{Sm%1J}=qU0la$LAblNzh22WJku)=-c(Yn0Yl^ zg-*IrVx%oX1Hf5#b!!|^Mq2W%7#E8frFkhetD1oM*n{amzOR&8$+-(L=rzfwv`W3> z&5NA|hBCA^rC!7Y{-$rZvk)bVJ`*3!J4hsPC*R3>q;U_tEJx0rAbc*%&zQdso4s)GpKAMN|)7}(& z_oq2G=)b>8gVW)d3IgAQyuxpMh3dFi&i7GpR zm5@58S>SSoA@wZo24C8(&lONo=6U2Nx>Axc7bPtYTQtAKr#P@3f0#LA23vp~Y+ySbNDwC!+ zGUP{9yu7%EwlqE|m2S0&7R}WV1L&m`@`CovT7dVw#E)f=_6HT2gMgII%i{&_vmXrF z#PqvZmj2n#LZhnk6|vMe?KHYN!m?y8Mb}c3<<(WKz7qE8RsE@vlIpqYo>^b44obbO zwZsKF-L6LG;Q2G}!`BbfaivLuzTU7@kd{Ze&AdzUsJ_a1JHWu8qSw-E_6!wB9EVK3 zNYEz9%E-v1g7%}7aLz)sp zZPIqAlJ(nljE?xmwz%o{PtkSu)oZ%~9U-{DErKTLX-!re;I8VhoH{z1s&MHNElgbp z@z4_D>-n2-YQ}HA;{j-Ne<>Movipg=d{{|(-GWESDQ;mQ{>OUHS*F@~L62*Zl}>!z zl7#Qc@|TBgAt`G=f2084oaN@0yLmI;BKO$Kmz`F{oV>gQ%9TdFD_<;&<}$jkaAq9Y zI))=|*savUORMcqn`jq||pud8CFVUVkLK1e5> zE*d2OwIkRLeuaj^c<36L;ul7Vqw_|I>lp=J%OgA~Wx-g_yv)rfU!m(HkJ7503EbBZ zj8Y=03em7bZI1q=dkIs}GRueq z)I?}p4Yo;zcg^YU&DU}92P?WV`|#M{%>>Mpwl@yDr>SxEsy-RF>(!QyI`vPNXg}HE zKsghg*d+=HbWV0EMBd&StwOtu7tSnB8R2;qAgcq7ZQvtfkJ}0aNO0DN@xBmHda>Fy z^W?oVvr#w(Ex7kyFun*hnS6~iNoHqf57b#+q_zY+@{HG(z|L$jDj_kWv+E2A z%LKvb+A^@$2%>0MWH_rz{yTDQ_9L|=IzF)ca%ajLcBW5EKr5oY^~o^q%+ta9x7 zFC$|&wB@X^q&C!z)m8lZH9KJxUgG7a#vO#7=(yT&?^7bARL$vt)nq!KP9K4P(f8sO zRGx{8IY4IZdM%{isX<%CAi5#=Fe)&89zC?(%SG0cI_P1%Zz)P}xtPCBvi-yMi0|Z4 zpIR+&i&i3#`A4qw*(=^WPEdx~3qg&~@kGjz3T+?@zg11l)-+e$k=r&C6_tAs-5??N zV_D9EB7pL$#{*M~V&fUVd}yiFvfz)7MRoNXI#9W5*QQ%zubc4`#)escV|E48;-g3K znX+m67FO=_%8OqxGTK^oScZ_K8O_=z-58B~{OjHh&~FZIxgMY+_N_Zp`hv>mvtn9- zn?q|-_jHmASB6kKrO{DQIf1*57&BlRC{b2bwb<*Q2M>NXMVafBR{CcFrKIkkGl3m) zU<%^k>%wX-5}Jg)*icHk?tbjceFqj#N87FET+WXfVeeqXYPhp_x4H!IX29rNPD9fM zM#(RrZNGcJYyOgAbMP&@t~QnIMN%Ldd6&3N)=`s@_VJn(y!!*i;>Cz=e3vksCu998 zY>q{Wi2ZHtCM5b673buZ1*~b zb&k|?{(Nk)Mz~Tla;ysd3!kaDG6HB8fXZpQmr2Oh>A$28qTKVD<{(~Pt}0gED#M$i z6Lj!OdUYAJQ_`+_uq)8Cr~+zfa*xMO@I!N?;SrsrKV z{3vJFQB&*5&-DGrkZiNN?AAO4zBqj{?!8h%LIIqXv9q_hjlEDt1CJqg!o>k;O3=5~ zJ-#pz)f5xnTfghBL}KNvX>0xos0!Hj;&2Q`V8zo2EE(+{?03h6*ew``bAE(6oR(?d zD!27LB+B6VZDkbXWrcs&PE!hr&qcw5Vc@Ut$XIJ4m3$`CUK!8B3I&4R&nB_Ku;CcfH^;_t=yL%VcPJn|_T z?`eYjP39E;s)=mZqT!#NDe42_8i=uS+q>4`)?I+|S^?H>7$Z!4SsPJ*x2W~k<^q}P zZInTiL1LsJR7v-n9cpd(nJLICKGFOMFeWiEXT4whxB_-M+jB0pL+zycwEr4*rDG&1 zIX2PGsl-Z*;avk6Cq@gYEdTn}ywUHQrWOrf`WtBpgY-`lSP8>I3F*S0GTFE+V{j7A zCHbe!$7@D~GjS3G3EGKB*U3>CO;lO8lbno@A5AEs;f1acU$EJ&~ZrKhO3#R(_Tp2K;F)XbAEZ>lzx!u#9`3QZwknM43GS zUNU;8TkO~$79mH1N`l_U#ONUv)t)tEJIW50kJnV(px*>gHuqydc<-g;PaJf$19xMG z#|yn+h>+fP+e|KvNMDo3fn7ldxilgUF2Y7PL@vqEm-2^oSF<=Iv_99CD+B2vH? z2V#O8GP7GT1SuO!n$msd~dTVnOjvUZrjx;a}7HQ$)DC!pbZnx;1JSSasB}ha> ziW4RbHfvr>s9kjd%v3-Ak`<{|-o1jGcg@Z=O{@Z$(hN+%K#*cT*P4yA>M3C9*v_X%cdk2?u@5=|KIM+;N3sDipBu zz=;blwt%$1tfpmOLyC}vjgLOQSyLP+xD;i4Xvz{eE