Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mvaldina/weston
  • ant8me/weston
  • JaredHu/weston
  • drawat/weston
  • bnieuwenhuizen/weston
  • Robyn.marie/weston
  • dwrobel/weston
  • yjheo/weston
  • dos/weston
  • longjunyu2/weston
  • soerenmeier/weston
  • igor.torrente/weston
  • luckyziv/weston
  • qyliss/weston
  • tantan/weston
  • wengxt/weston
  • mroussin/weston
  • n3rdopolis/weston
  • xiangxuy/weston
  • RAOF/weston
  • afrantzis/weston
  • lujin/weston
  • jayjona42/weston
  • ascent/weston
  • inzamam.15/weston
  • bbara93/weston
  • adoan/weston
  • Vivalavina/weston
  • iason.paraskevopoulos/weston
  • phnaharris/weston
  • mforney/weston
  • linkmauve/weston
  • xexaxo/weston
  • rajendraprasadkj/weston
  • xeechou/weston
  • learning/weston
  • agners/weston
  • ianr/weston
  • eucan/weston
  • heemin.lee/weston
  • nniro/weston
  • PaulKocialkowski/weston
  • NaveenKumar/weston
  • msisov/weston
  • ollieparanoid/weston
  • pH5/weston
  • dbaker/weston
  • gtristan/weston
  • khosokawa/weston
  • lubosz/weston
  • Fahien/weston
  • m.tretter/weston
  • valpackett/weston
  • marimeireles/weston
  • afd/weston
  • lk1025/weston
  • marler8997/weston
  • jianglei121381/weston
  • flakylawww/weston
  • ayaka/weston
  • bbeckett/weston
  • rdp.effort/weston
  • Ganjing0224/weston
  • jcline/weston
  • bl4ckb0ne/weston
  • Bastian-Krause/weston
  • fifi899173/weston
  • jpewhacker/weston
  • yuanye100/weston
  • t-8ch/weston
  • HarshaMM/weston
  • david.turner/weston
  • wismill/weston
  • rsmith/weston
  • rohanjulka19/weston
  • shadeslayer/weston
  • sjoerd/weston
  • barry.song/weston
  • petervdperk/weston
  • renjiayuan1314/weston
  • HeYong/weston
  • bluesirhl/weston
  • macpijan/weston
  • andreinonea/weston
  • vanfanel/weston
  • mstoeckl/weston
  • chewi/weston
  • shierote/weston
  • tmaillart1/weston
  • jh-hsd/weston
  • bgjdarm/weston
  • anurup_m/weston
  • lucaweiss/weston
  • dima/weston
  • marysaka/weston
  • daissi/weston
  • vnguyentrong/weston
  • enocknyaega/weston
  • kang-sooyeon/weston
  • tpetazzoni/weston
  • mihlenfeldt/weston
  • rgallaispou/weston
  • chienpv/weston
  • kraj/weston
  • stolk/weston
  • Emantor/weston
  • kusma/weston
  • bmkimg/weston
  • 9531718244loco/weston
  • Ts/weston
  • kennylevinsen/weston
  • eyelash/weston
  • Igortorrente/weston
  • pleasurefish/weston
  • ahe/weston
  • ekurzinger/weston
  • pochu/weston
  • saavedra.pablo/weston
  • borneoa/weston
  • JimmyOhn/weston
  • ShivakumarVH/weston
  • Cwiiis/weston
  • romangg/weston
  • zubzub/weston
  • askebm/weston
  • ewtoombs/weston
  • wolf._.lael666/weston
  • dr3020187/weston
  • kxing/weston_hpd
  • filip-hejsek/weston
  • xndcn/weston
  • therealkenc/weston
  • C0rn3j/weston
  • tmaillart/weston
  • leandrohrb/weston
  • snow/weston
  • marex/weston
  • bnlrnz/weston
  • zhourunsheng2008/weston
  • zhouliang/weston
  • isinyaaa/weston
  • JeffyCN/weston
  • tzimmermann/weston
  • christian-rauch/weston
  • krh/weston
  • Rigo-V/weston
  • archiesix/weston
  • cwjo/weston
  • hedone21/weston
  • liyi42/weston
  • uniontechWu/weston
  • justdoGIT/weston
  • ajax/weston
  • pmenzel/weston
  • mominurisiamm887/weston
  • denix0/weston
  • ivyl/weston
  • fallahmahid.mahdi/weston
  • Alvarito050506/weston
  • obbardc/weston
  • joantolo/weston
  • zumbi/weston
  • doubleagent3276/weston
  • leoli/weston
  • dude/weston
  • cardenasvitealejandro/weston
  • ljia5/weston
  • Trigger.Huang/weston
  • swick/weston
  • Wladmis/weston
  • vyivel/weston
  • orbitcowboy/weston
  • AIDEA775/weston
  • maos20008/weston
  • mvicomoya/weston
  • bbrezillon/weston
  • wujiansun/weston
  • Benjamin_Loison/weston
  • rhelmot/weston
  • rgonzalez/weston
  • ekapllaj/weston
  • Shugyousha/weston
  • carbn/weston
  • derekf/weston
  • gyeyoung976/weston
  • dhobsong/weston
  • jeri.li/weston
  • mtey/weston
  • etom/weston
  • azeps/weston
  • champagneg/weston
  • makepost/weston
  • trem/weston
  • hwentland/weston
  • Ambyjkl/weston
  • YDinhVan/weston
  • pixellon/weston
  • daniels/weston
  • OctopusET/weston
  • emersion/weston
  • gilvbp/weston
  • yadneshk/weston
  • mvlad/weston
  • wayland/weston
  • phreer/weston
  • diegonieto/weston
  • vliaskov/weston
  • Vivek/weston
  • sami/weston
  • creiter/weston
  • luigi.santivetti/weston
  • aknautiyal/weston
  • martinetd/weston
  • 5HT/weston
  • yayowd/qimm
  • khangtb/weston
  • Laplac2/weston
  • pritbisw/weston
  • molinari/weston
  • vvavrychuk/weston
  • zzyiwei/weston
  • vanvugt/weston
  • pq/weston
  • qaqsw24/weston
  • gfxstrand/weston
  • alex.kanavin/weston
  • pinchyguey45/weston
  • davidre/weston
  • bigbear1385/weston
  • zzag/weston
  • benh/weston
  • harpreetbasra1313/weston
  • phomes/weston
  • rmader/weston
  • Heartyharts/weston
  • arandomhuman/weston
  • kchibisov/weston
  • hwti/weston
  • abhinavk/weston
  • vitalyp/weston
  • pedestrianlove/weston
  • sardemff7/weston
  • Ivaniku/tayland
  • JoseExposito/weston
  • zeerd/weston
  • jadahl/weston
  • sophia/weston
  • mol/weston
  • rawoul/weston
  • maxice8/weston
  • whot/weston
  • Qingwu-Li/weston
  • lfrb/weston
  • heftig/weston
  • Calandracas/weston
  • SergioGDR/weston
  • Foreal/weston
  • ghishadow/weston
  • puhui/weston
  • dmitry.batrak1/weston
  • fanbaby6/weston
  • chiragkhurana/weston
  • amaksoft/weston
  • surban/weston
  • smit-mayani/weston
  • jwillikers/weston
  • meshki022/weston
  • pritamabiswas/weston
  • antonino/weston
  • k77951586/weston
  • ChaoGuo/weston
  • ColinKinloch/weston
  • paraaz4959/weston
  • ivan.nikolaenko/weston
  • adarshgm/weston
  • ericruei/weston
  • harishkrupo/weston
  • VKadasani/weston
  • jameshilliard/weston
  • davidedmundson/weston
  • strassek/weston
  • flto/weston
  • Kishore409/weston
  • ktullavik/weston
  • Eugeniy.Paltsev/weston
  • sameer.lattannavar/weston
  • jesstindean85/weston
  • ashie/weston
  • Zamundaaa/weston
  • jlindgren90/weston
  • LARathbone/weston
  • g0hl1n/weston
  • matth/weston
  • nicolesager7/weston
  • hitong602/weston
  • Rpegusus2233/weston
  • bentiss/weston
  • hthiery/weston
  • thewayoftherob/weston
  • ofourdan/weston
  • enunes/weston
  • tomek/weston
  • bugaevc/weston
  • eero-t/weston
304 results
Show changes
Commits on Source (36)
  • Leandro Ribeiro's avatar
    libweston: do not forget to destroy temporary drm_format_array · 0157591b
    Leandro Ribeiro authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Leak found running drm-formats-test with ASan:
    
    ==58755==ERROR: LeakSanitizer: detected memory leaks
    
    Direct leak of 24 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x7fae744dbe3a in zalloc ../include/libweston/zalloc.h:38
        #2 0x7fae744dbe4e in weston_drm_format_array_create ../libweston/drm-formats.c:44
        #3 0x7fae744dd2a2 in weston_drm_format_array_subtract ../libweston/drm-formats.c:410
        #4 0x55723c67bed5 in subtract_arrays ../tests/drm-formats-test.c:487
        #5 0x55723c67b6bb in wrapsubtract_arrays ../tests/drm-formats-test.c:467
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Direct leak of 24 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x7fae744dbe3a in zalloc ../include/libweston/zalloc.h:38
        #2 0x7fae744dbe4e in weston_drm_format_array_create ../libweston/drm-formats.c:44
        #3 0x7fae744dd2a2 in weston_drm_format_array_subtract ../libweston/drm-formats.c:410
        #4 0x55723c67deca in subtract_arrays_modifier_invalid ../tests/drm-formats-test.c:613
        #5 0x55723c67da3d in wrapsubtract_arrays_modifier_invalid ../tests/drm-formats-test.c:593
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Direct leak of 24 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x7fae744dbe3a in zalloc ../include/libweston/zalloc.h:38
        #2 0x7fae744dbe4e in weston_drm_format_array_create ../libweston/drm-formats.c:44
        #3 0x7fae744dd2a2 in weston_drm_format_array_subtract ../libweston/drm-formats.c:410
        #4 0x55723c67c9c0 in subtract_arrays_same_content ../tests/drm-formats-test.c:521
        #5 0x55723c67c55b in wrapsubtract_arrays_same_content ../tests/drm-formats-test.c:504
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Direct leak of 24 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x7fae744dbe3a in zalloc ../include/libweston/zalloc.h:38
        #2 0x7fae744dbe4e in weston_drm_format_array_create ../libweston/drm-formats.c:44
        #3 0x7fae744dd2a2 in weston_drm_format_array_subtract ../libweston/drm-formats.c:410
        #4 0x55723c67d1b7 in subtract_arrays_exclusive_formats ../tests/drm-formats-test.c:552
        #5 0x55723c67cb23 in wrapsubtract_arrays_exclusive_formats ../tests/drm-formats-test.c:529
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Direct leak of 24 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x7fae744dbe3a in zalloc ../include/libweston/zalloc.h:38
        #2 0x7fae744dbe4e in weston_drm_format_array_create ../libweston/drm-formats.c:44
        #3 0x7fae744dd2a2 in weston_drm_format_array_subtract ../libweston/drm-formats.c:410
        #4 0x55723c67d8d5 in subtract_arrays_exclusive_modifiers ../tests/drm-formats-test.c:584
        #5 0x55723c67d31d in wrapsubtract_arrays_exclusive_modifiers ../tests/drm-formats-test.c:561
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Indirect leak of 320 byte(s) in 5 object(s) allocated from:
        #0 0x7fae74658279 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
        #1 0x7fae74473bc3 in wl_array_add (/usr/lib/libwayland-client.so.0+0xabc3)
        #2 0x7fae74473c10 in wl_array_copy (/usr/lib/libwayland-client.so.0+0xac10)
        #3 0x7fae744dbfe0 in add_format_and_modifiers ../libweston/drm-formats.c:108
        #4 0x7fae744dd389 in weston_drm_format_array_subtract ../libweston/drm-formats.c:418
        #5 0x55723c67d1b7 in subtract_arrays_exclusive_formats ../tests/drm-formats-test.c:552
        #6 0x55723c67cb23 in wrapsubtract_arrays_exclusive_formats ../tests/drm-formats-test.c:529
        #7 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #8 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #9 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #10 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #11 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #12 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #13 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #14 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #15 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Indirect leak of 256 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658652 in __interceptor_realloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:164
        #1 0x7fae74473b76 in wl_array_add (/usr/lib/libwayland-client.so.0+0xab76)
        #2 0x7fae744dc19f in weston_drm_format_array_add_format ../libweston/drm-formats.c:166
        #3 0x7fae744dbfb7 in add_format_and_modifiers ../libweston/drm-formats.c:104
        #4 0x7fae744dd389 in weston_drm_format_array_subtract ../libweston/drm-formats.c:418
        #5 0x55723c67d1b7 in subtract_arrays_exclusive_formats ../tests/drm-formats-test.c:552
        #6 0x55723c67cb23 in wrapsubtract_arrays_exclusive_formats ../tests/drm-formats-test.c:529
        #7 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #8 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #9 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #10 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #11 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #12 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #13 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #14 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #15 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Indirect leak of 256 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658652 in __interceptor_realloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:164
        #1 0x7fae74473b76 in wl_array_add (/usr/lib/libwayland-client.so.0+0xab76)
        #2 0x7fae744dc19f in weston_drm_format_array_add_format ../libweston/drm-formats.c:166
        #3 0x7fae744dd3de in weston_drm_format_array_subtract ../libweston/drm-formats.c:426
        #4 0x55723c67bed5 in subtract_arrays ../tests/drm-formats-test.c:487
        #5 0x55723c67b6bb in wrapsubtract_arrays ../tests/drm-formats-test.c:467
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Indirect leak of 128 byte(s) in 2 object(s) allocated from:
        #0 0x7fae74658279 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
        #1 0x7fae74473bc3 in wl_array_add (/usr/lib/libwayland-client.so.0+0xabc3)
        #2 0x7fae74473c10 in wl_array_copy (/usr/lib/libwayland-client.so.0+0xac10)
        #3 0x7fae744dbfe0 in add_format_and_modifiers ../libweston/drm-formats.c:108
        #4 0x7fae744dd389 in weston_drm_format_array_subtract ../libweston/drm-formats.c:418
        #5 0x55723c67bed5 in subtract_arrays ../tests/drm-formats-test.c:487
        #6 0x55723c67b6bb in wrapsubtract_arrays ../tests/drm-formats-test.c:467
        #7 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #8 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #9 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #10 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #11 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #12 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #13 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #14 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #15 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Indirect leak of 96 byte(s) in 3 object(s) allocated from:
        #0 0x7fae74658652 in __interceptor_realloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:164
        #1 0x7fae74473b76 in wl_array_add (/usr/lib/libwayland-client.so.0+0xab76)
        #2 0x7fae744dd142 in modifiers_subtract ../libweston/drm-formats.c:384
        #3 0x7fae744dd408 in weston_drm_format_array_subtract ../libweston/drm-formats.c:431
        #4 0x55723c67bed5 in subtract_arrays ../tests/drm-formats-test.c:487
        #5 0x55723c67b6bb in wrapsubtract_arrays ../tests/drm-formats-test.c:467
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Indirect leak of 64 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658652 in __interceptor_realloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:164
        #1 0x7fae74473b76 in wl_array_add (/usr/lib/libwayland-client.so.0+0xab76)
        #2 0x7fae744dd142 in modifiers_subtract ../libweston/drm-formats.c:384
        #3 0x7fae744dd408 in weston_drm_format_array_subtract ../libweston/drm-formats.c:431
        #4 0x55723c67d8d5 in subtract_arrays_exclusive_modifiers ../tests/drm-formats-test.c:584
        #5 0x55723c67d31d in wrapsubtract_arrays_exclusive_modifiers ../tests/drm-formats-test.c:561
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Indirect leak of 32 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658279 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
        #1 0x7fae74473bc3 in wl_array_add (/usr/lib/libwayland-client.so.0+0xabc3)
        #2 0x7fae744dc19f in weston_drm_format_array_add_format ../libweston/drm-formats.c:166
        #3 0x7fae744dd3de in weston_drm_format_array_subtract ../libweston/drm-formats.c:426
        #4 0x55723c67d8d5 in subtract_arrays_exclusive_modifiers ../tests/drm-formats-test.c:584
        #5 0x55723c67d31d in wrapsubtract_arrays_exclusive_modifiers ../tests/drm-formats-test.c:561
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Indirect leak of 32 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658279 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
        #1 0x7fae74473bc3 in wl_array_add (/usr/lib/libwayland-client.so.0+0xabc3)
        #2 0x7fae744dc19f in weston_drm_format_array_add_format ../libweston/drm-formats.c:166
        #3 0x7fae744dd3de in weston_drm_format_array_subtract ../libweston/drm-formats.c:426
        #4 0x55723c67deca in subtract_arrays_modifier_invalid ../tests/drm-formats-test.c:613
        #5 0x55723c67da3d in wrapsubtract_arrays_modifier_invalid ../tests/drm-formats-test.c:593
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Indirect leak of 32 byte(s) in 1 object(s) allocated from:
        #0 0x7fae74658279 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
        #1 0x7fae74473bc3 in wl_array_add (/usr/lib/libwayland-client.so.0+0xabc3)
        #2 0x7fae744dc19f in weston_drm_format_array_add_format ../libweston/drm-formats.c:166
        #3 0x7fae744dd3de in weston_drm_format_array_subtract ../libweston/drm-formats.c:426
        #4 0x55723c67c9c0 in subtract_arrays_same_content ../tests/drm-formats-test.c:521
        #5 0x55723c67c55b in wrapsubtract_arrays_same_content ../tests/drm-formats-test.c:504
        #6 0x55723c67e9a9 in run_test ../tests/weston-test-runner.c:162
        #7 0x55723c67f0af in run_case ../tests/weston-test-runner.c:277
        #8 0x55723c67ee48 in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x55723c67f358 in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x55723c680381 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x55723c6803b1 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x55723c680844 in main ../tests/weston-test-runner.c:661
        #13 0x7fae742c4b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x55723c67442d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Signed-off-by: default avatarLeandro Ribeiro <leandro.ribeiro@collabora.com>
    0157591b
  • Leandro Ribeiro's avatar
    tests: fix leaks in drm-formats-test · 7c547e49
    Leandro Ribeiro authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Leak found running drm-formats-test with ASan:
    
    ==59454==ERROR: LeakSanitizer: detected memory leaks
    
    Direct leak of 24 byte(s) in 1 object(s) allocated from:
        #0 0x7f5302ff2459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x7f5302e75e3a in zalloc ../include/libweston/zalloc.h:38
        #2 0x7f5302e75e4e in weston_drm_format_array_create ../libweston/drm-formats.c:44
        #3 0x7f5302e76e33 in weston_drm_format_array_intersect ../libweston/drm-formats.c:340
        #4 0x559dc2d3c69f in intersect_arrays_same_content ../tests/drm-formats-test.c:391
        #5 0x559dc2d3c317 in wrapintersect_arrays_same_content ../tests/drm-formats-test.c:376
        #6 0x559dc2d409ec in run_test ../tests/weston-test-runner.c:162
        #7 0x559dc2d410f2 in run_case ../tests/weston-test-runner.c:277
        #8 0x559dc2d40e8b in for_each_test_case ../tests/weston-test-runner.c:235
        #9 0x559dc2d4139b in testsuite_run ../tests/weston-test-runner.c:311
        #10 0x559dc2d423c4 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #11 0x559dc2d423f4 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #12 0x559dc2d42887 in main ../tests/weston-test-runner.c:661
        #13 0x7f5302c5eb24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #14 0x559dc2d3642d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Direct leak of 24 byte(s) in 1 object(s) allocated from:
        #0 0x7f5302ff2459 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:154
        #1 0x7f5302e75e3a in zalloc ../include/libweston/zalloc.h:38
        #2 0x7f5302e75e4e in weston_drm_format_array_create ../libweston/drm-formats.c:44
        #3 0x559dc2d3bc7b in intersect_arrays ../tests/drm-formats-test.c:352
        #4 0x559dc2d3b678 in wrapintersect_arrays ../tests/drm-formats-test.c:339
        #5 0x559dc2d409ec in run_test ../tests/weston-test-runner.c:162
        #6 0x559dc2d410f2 in run_case ../tests/weston-test-runner.c:277
        #7 0x559dc2d40e8b in for_each_test_case ../tests/weston-test-runner.c:235
        #8 0x559dc2d4139b in testsuite_run ../tests/weston-test-runner.c:311
        #9 0x559dc2d423c4 in weston_test_harness_execute_standalone ../tests/weston-test-runner.c:572
        #10 0x559dc2d423f4 in fixture_setup_run_ ../tests/weston-test-runner.c:610
        #11 0x559dc2d42887 in main ../tests/weston-test-runner.c:661
        #12 0x7f5302c5eb24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
        #13 0x559dc2d3642d in _start (/home/lele/weston/build/tests/test-drm-formats+0x642d)
    
    Signed-off-by: default avatarLeandro Ribeiro <leandro.ribeiro@collabora.com>
    7c547e49
  • Pekka Paalanen's avatar
    tests: fix leak in events · d3acfd3b
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Fixes all the ASan reported leaks in this test.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    d3acfd3b
  • Pekka Paalanen's avatar
    tests: fix leaks in internal-screenshot-test · ca59c8e8
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Fixes all the ASan reported leaks in this test.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    ca59c8e8
  • Pekka Paalanen's avatar
    tests: fix leaks in ivi-layout-test-client · fda3696e
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Everything here was systematically leaking client and iviapp.
    
    Discovered by ASan on ./tests/test-ivi-layout-client
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    fda3696e
  • Pekka Paalanen's avatar
    tests: add destroy listener in ivi-layout test plugin · 2dcc79f5
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Fixes ASan reported leak:
    
    Direct leak of 136 byte(s) in 1 object(s) allocated from:
        #0 0x7ff60173c518 in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9518)
        #1 0x7ff5fcfed3fa in zalloc ../../git/weston/include/libweston/zalloc.h:38
        #2 0x7ff5fcfed8bf in wet_module_init ../../git/weston/tests/ivi-layout-test-plugin.c:196
        #3 0x7ff60161bd81 in wet_load_module ../../git/weston/compositor/main.c:941
        #4 0x7ff60161c165 in load_modules ../../git/weston/compositor/main.c:1012
        #5 0x7ff60162ced9 in wet_main ../../git/weston/compositor/main.c:3441
        #6 0x559a98fd7d4c in execute_compositor ../../git/weston/tests/weston-test-fixture-compositor.c:432
        #7 0x559a98fdb780 in weston_test_harness_execute_as_client ../../git/weston/tests/weston-test-runner.c:528
        #8 0x559a98fcbc48 in fixture_setup ../../git/weston/tests/ivi-layout-test-client.c:48
        #9 0x559a98fcbcca in fixture_setup_run_ ../../git/weston/tests/ivi-layout-test-client.c:50
        #10 0x559a98fdbd35 in main ../../git/weston/tests/weston-test-runner.c:661
        #11 0x7ff60129109a in __libc_start_main ../csu/libc-start.c:308
        #12 0x559a98fcb769 in _start (/home/pq/build/weston-meson/tests/test-ivi-layout-client+0xd769)
    
    This also plugs the leak on wl_global_create() error path, though it
    cannot really be tested.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    2dcc79f5
  • Pekka Paalanen's avatar
    ivi-shell: destroy desktop · 32aedb9f
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Fixes ASan reported leaks:
    
    Direct leak of 88 byte(s) in 1 object(s) allocated from:
        #0 0x7fcdc7382518 in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9518)
        #1 0x7fcdc2d902f3 in zalloc ../../git/weston/include/libweston/zalloc.h:38
        #2 0x7fcdc2d91cc2 in weston_desktop_xwayland_init ../../git/weston/libweston-desktop/xwayland.c:410
        #3 0x7fcdc2d89aef in weston_desktop_create ../../git/weston/libweston-desktop/libweston-desktop.c:87
        #4 0x7fcdc2db7300 in wet_shell_init ../../git/weston/ivi-shell/ivi-shell.c:642
        #5 0x7fcdc7261de5 in wet_load_shell ../../git/weston/compositor/main.c:956
        #6 0x7fcdc7272baa in wet_main ../../git/weston/compositor/main.c:3410
        #7 0x55e12a669e29 in execute_compositor ../../git/weston/tests/weston-test-fixture-compositor.c:432
        #8 0x55e12a66d85d in weston_test_harness_execute_as_client ../../git/weston/tests/weston-test-runner.c:528
        #9 0x55e12a65dc48 in fixture_setup ../../git/weston/tests/ivi-layout-test-client.c:48
        #10 0x55e12a65dcca in fixture_setup_run_ ../../git/weston/tests/ivi-layout-test-client.c:50
        #11 0x55e12a66de12 in main ../../git/weston/tests/weston-test-runner.c:661
        #12 0x7fcdc6ed709a in __libc_start_main ../csu/libc-start.c:308
        #13 0x55e12a65d769 in _start (/home/pq/build/weston-meson/tests/test-ivi-layout-client+0xd769)
    
    Indirect leak of 152 byte(s) in 1 object(s) allocated from:
        #0 0x7fcdc7382518 in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9518)
        #1 0x7fcdc2d89811 in zalloc ../../git/weston/include/libweston/zalloc.h:38
        #2 0x7fcdc2d8992d in weston_desktop_create ../../git/weston/libweston-desktop/libweston-desktop.c:65
        #3 0x7fcdc2db7300 in wet_shell_init ../../git/weston/ivi-shell/ivi-shell.c:642
        #4 0x7fcdc7261de5 in wet_load_shell ../../git/weston/compositor/main.c:956
        #5 0x7fcdc7272baa in wet_main ../../git/weston/compositor/main.c:3410
        #6 0x55e12a669e29 in execute_compositor ../../git/weston/tests/weston-test-fixture-compositor.c:432
        #7 0x55e12a66d85d in weston_test_harness_execute_as_client ../../git/weston/tests/weston-test-runner.c:528
        #8 0x55e12a65dc48 in fixture_setup ../../git/weston/tests/ivi-layout-test-client.c:48
        #9 0x55e12a65dcca in fixture_setup_run_ ../../git/weston/tests/ivi-layout-test-client.c:50
        #10 0x55e12a66de12 in main ../../git/weston/tests/weston-test-runner.c:661
        #11 0x7fcdc6ed709a in __libc_start_main ../csu/libc-start.c:308
        #12 0x55e12a65d769 in _start (/home/pq/build/weston-meson/tests/test-ivi-layout-client+0xd769)
    
    Indirect leak of 72 byte(s) in 1 object(s) allocated from:
        #0 0x7fcdc7382518 in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9518)
        #1 0x7fcdc2d8a5ae in zalloc ../../git/weston/include/libweston/zalloc.h:38
        #2 0x7fcdc2d8a89e in weston_desktop_client_create ../../git/weston/libweston-desktop/client.c:108
        #3 0x7fcdc2d91d2a in weston_desktop_xwayland_init ../../git/weston/libweston-desktop/xwayland.c:415
        #4 0x7fcdc2d89aef in weston_desktop_create ../../git/weston/libweston-desktop/libweston-desktop.c:87
        #5 0x7fcdc2db7300 in wet_shell_init ../../git/weston/ivi-shell/ivi-shell.c:642
        #6 0x7fcdc7261de5 in wet_load_shell ../../git/weston/compositor/main.c:956
        #7 0x7fcdc7272baa in wet_main ../../git/weston/compositor/main.c:3410
        #8 0x55e12a669e29 in execute_compositor ../../git/weston/tests/weston-test-fixture-compositor.c:432
        #9 0x55e12a66d85d in weston_test_harness_execute_as_client ../../git/weston/tests/weston-test-runner.c:528
        #10 0x55e12a65dc48 in fixture_setup ../../git/weston/tests/ivi-layout-test-client.c:48
        #11 0x55e12a65dcca in fixture_setup_run_ ../../git/weston/tests/ivi-layout-test-client.c:50
        #12 0x55e12a66de12 in main ../../git/weston/tests/weston-test-runner.c:661
        #13 0x7fcdc6ed709a in __libc_start_main ../csu/libc-start.c:308
        #14 0x55e12a65d769 in _start (/home/pq/build/weston-meson/tests/test-ivi-layout-client+0xd769)
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    32aedb9f
  • Pekka Paalanen's avatar
    tests: fix leak in ivi-shell-app-test · b64d4114
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Found by ASan.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    b64d4114
  • Pekka Paalanen's avatar
    compositor: fix leaking log_scopes · 2516e330
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Found by ASan:
    
    Direct leak of 30 byte(s) in 1 object(s) allocated from:
        #0 0x7f4dcf029810 in strdup (/lib/x86_64-linux-gnu/libasan.so.5+0x3a810)
        #1 0x7f4dcefd2143 in handle_option ../../git/weston/shared/option-parser.c:56
        #2 0x7f4dcefd2473 in long_option ../../git/weston/shared/option-parser.c:84
        #3 0x7f4dcefd2bb6 in parse_options ../../git/weston/shared/option-parser.c:175
        #4 0x7f4dcefc7b0d in wet_main ../../git/weston/compositor/main.c:3229
        #5 0x5593dfa38ffd in execute_compositor ../../git/weston/tests/weston-test-fixture-compositor.c:432
        #6 0x5593dfa3ca69 in weston_test_harness_execute_as_client ../../git/weston/tests/weston-test-runner.c:528
        #7 0x5593dfa2e511 in fixture_setup ../../git/weston/tests/ivi-shell-app-test.c:139
        #8 0x5593dfa2e596 in fixture_setup_run_ ../../git/weston/tests/ivi-shell-app-test.c:141
        #9 0x5593dfa3d01e in main ../../git/weston/tests/weston-test-runner.c:661
        #10 0x7f4dcec2d09a in __libc_start_main ../csu/libc-start.c:308
        #11 0x5593dfa2d769 in _start (/home/pq/build/weston-meson/tests/test-ivi-shell-app+0xd769)
    
    when running
    
    	ASAN_OPTIONS=fast_unwind_on_malloc=0,malloc_context_size=50 \
    	LSAN_OPTIONS=suppressions=/home/pq/git/weston/.gitlab-ci/leak-sanitizer.supp \
    	./tests/test-ivi-shell-app
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    2516e330
  • Pekka Paalanen's avatar
    tests: destroy client in keyboard-test · ef8d6520
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Fixes all the leaks reported by ASan in this test.
    
    The manual keyboard release in
    keyboard_timestamps_stop_after_client_releases_wl_keyboard is slightly
    awkward as we need to open-code a part of input_destroy() to avoid
    double-freeing keyboard->wl_keyboard.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    ef8d6520
  • Pekka Paalanen's avatar
    tests: destroy client in pointer-test · 689e8b3c
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Fixes all the leaks reported by ASan in this test.
    
    The manual pointer release in
    pointer_timestamps_stop_after_client_releases_wl_pointer is slightly
    awkward as we need to open-code a part of input_destroy() to avoid
    double-freeing pointer->wl_pointer.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    689e8b3c
  • Pekka Paalanen's avatar
    tests: fix leak in surface_commit_color() in pointer-shot · ee1c1778
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Found by ASan, several leaks like:
    
    Direct leak of 48 byte(s) in 2 object(s) allocated from:
        #0 0x7f35fdc9c518 in calloc (/lib/x86_64-linux-gnu/libasan.so.5+0xe9518)
        #1 0x55a77d6a4c6a in zalloc ../../git/weston/include/libweston/zalloc.h:38
        #2 0x55a77d6a748e in create_shm_buffer ../../git/weston/tests/weston-test-client-helper.c:459
        #3 0x55a77d6a78cd in create_shm_buffer_a8r8g8b8 ../../git/weston/tests/weston-test-client-helper.c:499
        #4 0x55a77d6a4145 in surface_commit_color ../../git/weston/tests/pointer-shot-test.c:89
        #5 0x55a77d6a4542 in pointer_cursor_retains_committed_buffer_after_reenter ../../git/weston/tests/pointer-shot-test.c:135
        #6 0x55a77d6a4207 in wrappointer_cursor_retains_committed_buffer_after_reenter ../../git/weston/tests/pointer-shot-test.c:98
        #7 0x55a77d6b15c2 in run_test ../../git/weston/tests/weston-test-runner.c:162
        #8 0x55a77d6b1c63 in run_case ../../git/weston/tests/weston-test-runner.c:277
        #9 0x55a77d6b1a09 in for_each_test_case ../../git/weston/tests/weston-test-runner.c:235
        #10 0x55a77d6b1eeb in testsuite_run ../../git/weston/tests/weston-test-runner.c:311
        #11 0x7f35f9510b6b in client_thread_routine ../../git/weston/tests/weston-test.c:479
        #12 0x7f35fd7a4fa2 in start_thread /build/glibc-vjB4T1/glibc-2.28/nptl/pthread_create.c:486
        #13 0x7f35fd8c64ce in clone (/lib/x86_64-linux-gnu/libc.so.6+0xf94ce)
    
    Now this test has no more leaks.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    ee1c1778
  • Pekka Paalanen's avatar
    tests: fix leaks in presentation-test · 1600431e
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Fixes all leaks found by ASan.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    1600431e
  • Pekka Paalanen's avatar
    gl-renderer: add shader bit input_is_premult · 4d5b2f34
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Add a new shader requirements bit input_is_premult which says whether
    the texture sampling results in premultiplied alpha or not. Currently
    this can be deduced fully from the shader texture variant, but in the
    future there might a protocol extension to explicitly control it. Hence
    the need for a new bit.
    
    yuva2rgba() is changed to produce straight alpha always. This makes
    sample_input_texture() sometimes produce straight or premultiplied
    alpha. The input_is_premult bit needs to match sample_input_texture()
    behavior. Doing this should save three multiplications in the shader for
    straight alpha formats.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    4d5b2f34
  • Pekka Paalanen's avatar
    gl-renderer: fragment shader precision to high · 391f513c
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Always when supported, make the fragment shader default floating point
    precision high. The medium precision is roughly like half-floats, which
    can be surprisingly bad. High precision does not reach even normal
    32-bit float precision (by specification), but it's better. GL ES
    implementations are allowed to exceed the minimum precision requirements
    given in the specification.
    
    This is an advance attempt to avoid nasty surprises from poor shader
    precision.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    391f513c
  • Pekka Paalanen's avatar
    gl-renderer: implement SHADER_COLOR_CURVE_LUT_3x1D · 9a6a4e70
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    This adds shader support for using a three-channel one-dimensional
    look-up table for de/encoding input colors. This operation will be useful
    for applying EOTF or its inverse, in other words, gamma curves. It will
    also be useful in optimizing a following 3D LUT tap distribution once
    support for 3D LUT is added.
    
    Even though called three-channel and one-dimensional, it is actually
    implemented as a one-channel two-dimensional texture with four rows.
    Each row corresponds to a source color channel except the fourth one is
    unused. The reason for having the fourth row is to get texture
    coordinates in 1/8 steps instead of 1/6 steps. 1/6 may would not be
    exact in floating- or fixed-point arithmetic and might perhaps risk
    unintended results from bilinear texture filtering when we want linear
    filtering only in x but not in y texture coordinates. I may be paranoid.
    
    The LUT is applied on source colors after they have been converted to
    straight RGB. It cannot be applied with pre-multiplied alpha. A LUT can
    be used for both applying EOTF to go from source color space to blending
    color space, and EOTF^-1 to go from blending space to output
    (electrical) space. However, this type of LUT cannot do color space
    conversions.
    
    For now, this feature is hardcoded to off everywhere, to be enabled in
    following patches.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    9a6a4e70
  • Pekka Paalanen's avatar
    gl-renderer: implement 3 x 1D LUT color pre-curve · 92f2367e
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    This makes weston_color_transform object be able to express
    three-channel one-dimensional look-up table transformations. They are
    useful for applying EOTF and EOTF^-1 mapping, or, gamma curves. They
    will also be useful in optimizing a following 3D LUT tap distribution
    once support for 3D LUT is added.
    
    The code added here translates from the lut_3x1d fill_in() interface to
    a GL texture to be used with SHADER_COLOR_CURVE_LUT_3x1D for
    weston_surfaces.
    
    It demonstrates how renderer data is attached to weston_color_transform
    and cached.
    
    GL_OES_texture_float_linear is required to be able to use bilinear
    texture filtering with 32-bit floating-point textures, used for the LUT.
    
    As the size of the LUT depends on what implements it, lut_3x1d fill_in()
    interface is a callback to the color management component to ask for an
    arbitrary size. For GL-renderer this is not important as it can easily
    realize any LUT size, but when DRM-backend wants to offload the EOTF^-1
    mapping to KMS (GAMMA_LUT), the LUT size comes from KMS.
    
    Nothing actually implements lut_3x1d fill_in() yet, that will come in a
    later patch.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    92f2367e
  • Pekka Paalanen's avatar
    gl-renderer: color transform censor fill and triangle fan · d7eca407
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Use the sRGB to blending color space transformation for the censoring
    color fill and triangle fan debug drawings.
    
    This removes the assert that the output's blending space is (non-linear)
    sRGB.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    d7eca407
  • Pekka Paalanen's avatar
    gl-renderer: color transform output borders · e7b43ba3
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Use the sRGB to output color space transformation when blitting the
    borders (decorations) into an output window (nested compositor).
    
    Nested output does not need to be sRGB anymore, as far as the
    decorations are concerned.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    e7b43ba3
  • Pekka Paalanen's avatar
    gl-renderer: color transform in blit_shadow_to_output() · b12d4fcb
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Use the blending to output color space transformation when blitting from
    the shadow to a framebuffer.
    
    This allows the blending and output color spaces to differ as long as
    shadow is used, in case a backend does not off-load the color
    transformation.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    b12d4fcb
  • Pekka Paalanen's avatar
    color-lcms: use sRGB EOTF · 7c13c4a4
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Initialize LittleCMS and use it to generate the sRGB EOTF and inverse
    curves. Use these curves to define the blending color space as optical
    (linear) sRGB by assuming that both content and output color spaces are
    sRGB.
    
    As a consequence, this causes Weston to do "gamma correct blending", as
    in, blend in light linear space which should avoid distorting colors in
    alpha gradients, when color-lcms is active.
    
    This makes use of the 3x1D LUT support added in gl-renderer earlier, and
    shows how the color manager is responsible for re-using existing color
    transformation objects.
    
    Co-authored-by: default avatarVitaly Prosyak <vitaly.prosyak@amd.com>
    Signed-off-by: default avatarVitaly Prosyak <vitaly.prosyak@amd.com>
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    7c13c4a4
  • Pekka Paalanen's avatar
    tests/alpha-blending: refactor into get_middle_row() · 129bef50
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Refactor the alpha-blending test to allow using all three images
    foreground, background, and screenshot in a future new verification
    function.
    
    This is a pure refactoring, no change in behavior.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    129bef50
  • Pekka Paalanen's avatar
    tests/alpha-blending: reference blending · e70aa1fd
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Instead of checking just the monotonicity of the blending results, this
    changes the alpha-blending test to compute the reference blend result
    itself and then comparing to the compositor result. This way we can be
    sure that the compositor implements the exact correct formula and not
    something that just looks nice, as verifying the reference images are
    actually correct is hard.
    
    The reference image is renamed to follow the fact that this is not
    primarily a monotonicity test anymore. The reference image is also
    redundant, but I think it has documentary value.
    
    The #if 0'd block of code was very useful in figuring out blending
    errors in a future test case, so it is included here. I have a feeling
    we are going to need it again.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    e70aa1fd
  • Pekka Paalanen's avatar
    tests/alpha-blending: add sRGB linear light case · 35cae567
    Pekka Paalanen authored and Pekka Paalanen's avatar Pekka Paalanen committed
    Now that GL-renderer and color manager implement linear light blending
    for sRGB EOTF, add a test case to verify the result is expected.
    
    As noted in test comments, this new tests is quite powerful in ensuring
    the whole linear light pipeline is working correctly with 1D LUTs in
    GL-renderer. This test will even catch smashing source_lut.scale = 1.0f
    and source_lut.offset = 0.0f which would result in wrong texture sample
    positions for LUT data.
    
    As the assumption is that by default content and outputs are in sRGB
    color space, this test should not need fix-ups or become stale when more
    color management features are implemented.
    
    The sRGB EOTF can be found in:
    http://www.color.org/sRGB.pdf (beware, typos)
    https://www.w3.org/Graphics/Color/srgb
    https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html#TRANSFER_SRGB
    
    
    
    Note on AMD Polaris 11 error threshold: this is quite likely due to
    using fp16 format shadow framebuffer and GCN fp32 to fp16 conversion
    instruction rounding mode. When using fp32 shadow framebuffer, the error
    glitch is not present and the threshold could be significantly lower.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    35cae567
  • Pekka Paalanen's avatar
    tests: clean up in roles-test · fc26bdb2
    Pekka Paalanen authored
    
    This fixes all ASan reported leaks in this test.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    fc26bdb2
  • Pekka Paalanen's avatar
    tests: fix all leaks in subsurface-test · ecbf1dba
    Pekka Paalanen authored
    
    Fix all ASan reported leaks in this test.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    ecbf1dba
  • Pekka Paalanen's avatar
    tests: reduce subsurface-test verbosity · c021e2f9
    Pekka Paalanen authored
    
    Not printing these will drop 7980 lines or roughly 350 kB from the test
    logs. Now I don't have scroll through them all, and I don't have to
    watch them if I run this test manually.
    
    These prints were useful when developing the test, but we don't need
    them printed in CI all the time. Printing the final count should be
    enough.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    c021e2f9
  • Pekka Paalanen's avatar
    tests: fix some leaks in subsurface-shot-test · 9cf9121b
    Pekka Paalanen authored
    
    Fix all ASan reported leaks in this test when running on AMD Mesa
    driver.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    9cf9121b
  • Pekka Paalanen's avatar
    tests: fix all leaks in linux-explicit-synchronization-test · 4f515a1d
    Pekka Paalanen authored
    
    Fix all ASan reported leaks in this test.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    4f515a1d
  • Pekka Paalanen's avatar
    tests: fix all leaks in surface-test · b9826762
    Pekka Paalanen authored
    
    Fixes all ASan reported leaks.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    b9826762
  • Pekka Paalanen's avatar
    tests: fix all leaks in surface-global-test · 54ea691b
    Pekka Paalanen authored
    
    Fix all ASan reported leaks.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    54ea691b
  • Pekka Paalanen's avatar
    tests: fix all leaks in text-test · 56a8d69b
    Pekka Paalanen authored
    
    Fix all ASan reported leaks.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    56a8d69b
  • Pekka Paalanen's avatar
    tests: fix all leaks in touch-test · a01299a5
    Pekka Paalanen authored
    
    Fixes all ASan reported leaks.
    
    The manual touch release is slightly awkward as we need to open-code a
    part of input_destroy() to avoid double-freeing pointer->wl_touch.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    a01299a5
  • Pekka Paalanen's avatar
    tests: free pixman image in yuv-buffer-test · f6acdc5d
    Pekka Paalanen authored
    
    Fixes all ASan reported leaks in this test when using AMD Mesa driver.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    f6acdc5d
  • Pekka Paalanen's avatar
    tests: fix all leaks in devices-test · 591fa3b9
    Pekka Paalanen authored
    This fixes all ASan reported leaks in this test.
    
    This test program has several tests named *_multiple that just run
    another test function 30 times. Previously without cleanup all the
    created clients would be left lingering, but now they are torn down. Ths
    might cause a change in test behaviour, although that was never the
    intention:
    
    > It is intentional to run it so many times, but it is not intentional
    > to run a hundred clients at a time.  The problem is that currently we
    > have no destroy function for client.  However, the clients do not run
    > simultaneously but serially, so the effect should be the same as if
    > we'd destroy them (after the client finishes its body, it just 'is'
    > and does nothing until the process exits)
    
    - the original review discussion in
    https://lists.freedesktop.org/archives/wayland-devel/2015-March/020957.html
    
    
    
    The intention for the repeat testing is that as the Weston instance
    remains from test to another, each test needs to undo its changes to the
    devices. Failing to correcntly undo would accumulate devices.
    
    Signed-off-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
    591fa3b9
  • Marius Vlad's avatar
    backend-drm: Clean-up minor leak when destroying the DRM-backend · 7a44ee7f
    Marius Vlad authored and Pekka Paalanen's avatar Pekka Paalanen committed
    
    Fixes a minor leak due to launcher-libseatd:
    
    Direct leak of 32 byte(s) in 1 object(s) allocated from:
        #0 0x7f15664e5037 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.6+0xaa037)
        #1 0x7f156305c59f in zalloc ../include/libweston/zalloc.h:38
        #2 0x7f156305c99b in seat_open_device ../libweston/launcher-libseat.c:114
        #3 0x7f1563056341 in weston_launcher_open ../libweston/launcher-util.c:79
        #4 0x7f156302f1e2 in drm_device_is_kms ../libweston/backend-drm/drm.c:2616
        #5 0x7f156302f751 in find_primary_gpu ../libweston/backend-drm/drm.c:2715
        #6 0x7f15630309a5 in drm_backend_create ../libweston/backend-drm/drm.c:2970
        #7 0x7f15630317ab in weston_backend_init ../libweston/backend-drm/drm.c:3162
        #8 0x7f1566025b61 in weston_compositor_load_backend ../libweston/compositor.c:8201
        #9 0x7f156640cb9e in load_drm_backend ../compositor/main.c:2596
        #10 0x7f156641193c in load_backend ../compositor/main.c:3079
        #11 0x7f1566413cc3 in wet_main ../compositor/main.c:3356
        #12 0x562ba484b179 in main ../compositor/executable.c:33
        #13 0x7f156624fcc9 in __libc_start_main ../csu/libc-start.c:308
    
    But also use the launcher interface to actually close the DRM fd, in
    mirror to what weston_launcher_open() does.
    
    Signed-off-by: default avatarMarius Vlad <marius.vlad@collabora.com>
    7a44ee7f
Showing
with 1031 additions and 78 deletions
......@@ -3493,6 +3493,7 @@ out_display:
free(socket_name);
free(option_modules);
free(log);
free(log_scopes);
free(modules);
return ret;
......
......@@ -346,6 +346,8 @@ shell_destroy(struct wl_listener *listener, void *data)
wl_list_remove(&shell->destroy_listener.link);
wl_list_remove(&shell->wake_listener.link);
weston_desktop_destroy(shell->desktop);
wl_list_for_each_safe(ivisurf, next, &shell->ivi_surface_list, link) {
if (ivisurf->layout_surface != NULL)
layout_surface_cleanup(ivisurf);
......
......@@ -2515,9 +2515,9 @@ drm_destroy(struct weston_compositor *ec)
udev_monitor_unref(b->udev_monitor);
udev_unref(b->udev);
weston_launcher_close(ec->launcher, b->drm.fd);
weston_launcher_destroy(ec->launcher);
close(b->drm.fd);
free(b->drm.filename);
free(b);
}
......
/*
* Copyright 2021 Collabora, Ltd.
* Copyright 2021 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
......@@ -25,8 +26,7 @@
#include "config.h"
#include <lcms2.h>
#include <assert.h>
#include <libweston/libweston.h>
#include "color.h"
......@@ -36,6 +36,9 @@
static void
cmlcms_destroy_color_transform(struct weston_color_transform *xform_base)
{
struct cmlcms_color_transform *xform = get_xform(xform_base);
cmlcms_color_transform_destroy(xform);
}
static bool
......@@ -44,8 +47,21 @@ cmlcms_get_surface_color_transform(struct weston_color_manager *cm_base,
struct weston_output *output,
struct weston_surface_color_transform *surf_xform)
{
/* Identity transform */
surf_xform->transform = NULL;
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
struct cmlcms_color_transform_search_param param = {
/*
* Assumes both content and output color spaces are sRGB SDR.
* This defines the blending space as optical sRGB SDR.
*/
.type = CMLCMS_TYPE_EOTF_sRGB,
};
struct cmlcms_color_transform *xform;
xform = cmlcms_color_transform_get(cm, &param);
if (!xform)
return false;
surf_xform->transform = &xform->base;
surf_xform->identity_pipeline = true;
return true;
......@@ -56,9 +72,21 @@ cmlcms_get_output_color_transform(struct weston_color_manager *cm_base,
struct weston_output *output,
struct weston_color_transform **xform_out)
{
/* Identity transform */
*xform_out = NULL;
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
struct cmlcms_color_transform_search_param param = {
/*
* Assumes blending space is optical sRGB SDR and
* output color space is sRGB SDR.
*/
.type = CMLCMS_TYPE_EOTF_sRGB_INV,
};
struct cmlcms_color_transform *xform;
xform = cmlcms_color_transform_get(cm, &param);
if (!xform)
return false;
*xform_out = &xform->base;
return true;
}
......@@ -67,6 +95,7 @@ cmlcms_get_sRGB_to_output_color_transform(struct weston_color_manager *cm_base,
struct weston_output *output,
struct weston_color_transform **xform_out)
{
/* Assumes output color space is sRGB SDR */
/* Identity transform */
*xform_out = NULL;
......@@ -78,29 +107,61 @@ cmlcms_get_sRGB_to_blend_color_transform(struct weston_color_manager *cm_base,
struct weston_output *output,
struct weston_color_transform **xform_out)
{
/* Identity transform */
*xform_out = NULL;
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
struct cmlcms_color_transform_search_param param = {
/* Assumes blending space is optical sRGB SDR */
.type = CMLCMS_TYPE_EOTF_sRGB,
};
struct cmlcms_color_transform *xform;
xform = cmlcms_color_transform_get(cm, &param);
if (!xform)
return false;
*xform_out = &xform->base;
return true;
}
static void
lcms_error_logger(cmsContext context_id,
cmsUInt32Number error_code,
const char *text)
{
weston_log("LittleCMS error: %s\n", text);
}
static bool
cmlcms_init(struct weston_color_manager *cm_base)
{
if (!(cm_base->compositor->capabilities & WESTON_CAP_COLOR_OPS)) {
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
if (!(cm->base.compositor->capabilities & WESTON_CAP_COLOR_OPS)) {
weston_log("color-lcms: error: color operations capability missing. Is GL-renderer not in use?\n");
return false;
}
cm->lcms_ctx = cmsCreateContext(NULL, cm);
if (!cm->lcms_ctx) {
weston_log("color-lcms error: creating LittCMS context failed.\n");
return false;
}
cmsSetLogErrorHandlerTHR(cm->lcms_ctx, lcms_error_logger);
weston_log("LittleCMS %d initialized.\n", cmsGetEncodedCMMversion());
return true;
}
static void
cmlcms_destroy(struct weston_color_manager *cm_base)
{
struct weston_color_manager_lcms *cmlcms = get_cmlcms(cm_base);
struct weston_color_manager_lcms *cm = get_cmlcms(cm_base);
free(cmlcms);
assert(wl_list_empty(&cm->color_transform_list));
cmsDeleteContext(cm->lcms_ctx);
free(cm);
}
WL_EXPORT struct weston_color_manager *
......@@ -126,5 +187,7 @@ weston_color_manager_create(struct weston_compositor *compositor)
cm->base.get_sRGB_to_blend_color_transform =
cmlcms_get_sRGB_to_blend_color_transform;
wl_list_init(&cm->color_transform_list);
return &cm->base;
}
/*
* Copyright 2021 Collabora, Ltd.
* Copyright 2021 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
......@@ -26,6 +27,7 @@
#ifndef WESTON_COLOR_LCMS_H
#define WESTON_COLOR_LCMS_H
#include <lcms2.h>
#include <libweston/libweston.h>
#include "color.h"
......@@ -33,6 +35,9 @@
struct weston_color_manager_lcms {
struct weston_color_manager base;
cmsContext lcms_ctx;
struct wl_list color_transform_list; /* cmlcms_color_transform::link */
};
static inline struct weston_color_manager_lcms *
......@@ -41,4 +46,43 @@ get_cmlcms(struct weston_color_manager *cm_base)
return container_of(cm_base, struct weston_color_manager_lcms, base);
}
/*
* Perhaps a placeholder, until we get actual color spaces involved and
* see how this would work better.
*/
enum cmlcms_color_transform_type {
CMLCMS_TYPE_EOTF_sRGB = 0,
CMLCMS_TYPE_EOTF_sRGB_INV,
CMLCMS_TYPE__END,
};
struct cmlcms_color_transform_search_param {
enum cmlcms_color_transform_type type;
};
struct cmlcms_color_transform {
struct weston_color_transform base;
/* weston_color_manager_lcms::color_transform_list */
struct wl_list link;
struct cmlcms_color_transform_search_param search_key;
/* for EOTF types */
cmsToneCurve *curve;
};
static inline struct cmlcms_color_transform *
get_xform(struct weston_color_transform *xform_base)
{
return container_of(xform_base, struct cmlcms_color_transform, base);
}
struct cmlcms_color_transform *
cmlcms_color_transform_get(struct weston_color_manager_lcms *cm,
const struct cmlcms_color_transform_search_param *param);
void
cmlcms_color_transform_destroy(struct cmlcms_color_transform *xform);
#endif /* WESTON_COLOR_LCMS_H */
/*
* Copyright 2021 Collabora, Ltd.
* Copyright 2021 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "config.h"
#include <assert.h>
#include <libweston/libweston.h>
#include "color.h"
#include "color-lcms.h"
#include "shared/helpers.h"
/* Arguments to cmsBuildParametricToneCurve() */
struct tone_curve_def {
cmsInt32Number cmstype;
cmsFloat64Number params[5];
};
/*
* LCMS uses the required number of 'params' based on 'cmstype', the parametric
* tone curve number. LCMS honors negative 'cmstype' as inverse function.
* These are LCMS built-in parametric tone curves.
*/
static const struct tone_curve_def predefined_eotf_curves[] = {
[CMLCMS_TYPE_EOTF_sRGB] = {
.cmstype = 4,
.params = { 2.4, 1. / 1.055, 0.055 / 1.055, 1. / 12.92, 0.04045 },
},
[CMLCMS_TYPE_EOTF_sRGB_INV] = {
.cmstype = -4,
.params = { 2.4, 1. / 1.055, 0.055 / 1.055, 1. / 12.92, 0.04045 },
},
};
static void
cmlcms_fill_in_tone_curve(struct weston_color_transform *xform_base,
float *values, unsigned len)
{
struct cmlcms_color_transform *xform = get_xform(xform_base);
float *R_lut = values;
float *G_lut = R_lut + len;
float *B_lut = G_lut + len;
unsigned i;
cmsFloat32Number x, y;
assert(xform->curve != NULL);
assert(len > 1);
for (i = 0; i < len; i++) {
x = (double)i / (len - 1);
y = cmsEvalToneCurveFloat(xform->curve, x);
R_lut[i] = y;
G_lut[i] = y;
B_lut[i] = y;
}
}
void
cmlcms_color_transform_destroy(struct cmlcms_color_transform *xform)
{
wl_list_remove(&xform->link);
if (xform->curve)
cmsFreeToneCurve(xform->curve);
free(xform);
}
static struct cmlcms_color_transform *
cmlcms_color_transform_create(struct weston_color_manager_lcms *cm,
const struct cmlcms_color_transform_search_param *param)
{
struct cmlcms_color_transform *xform;
const struct tone_curve_def *tonedef;
if (param->type < 0 || param->type >= CMLCMS_TYPE__END) {
weston_log("color-lcms error: bad color transform type in %s.\n",
__func__);
return NULL;
}
tonedef = &predefined_eotf_curves[param->type];
xform = zalloc(sizeof *xform);
if (!xform)
return NULL;
xform->curve = cmsBuildParametricToneCurve(cm->lcms_ctx,
tonedef->cmstype,
tonedef->params);
if (xform->curve == NULL) {
weston_log("color-lcms error: failed to build parametric tone curve.\n");
free(xform);
return NULL;
}
weston_color_transform_init(&xform->base, &cm->base);
xform->search_key = *param;
xform->base.pre_curve.type = WESTON_COLOR_CURVE_TYPE_LUT_3x1D;
xform->base.pre_curve.u.lut_3x1d.fill_in = cmlcms_fill_in_tone_curve;
xform->base.pre_curve.u.lut_3x1d.optimal_len = 256;
wl_list_insert(&cm->color_transform_list, &xform->link);
return xform;
}
static bool
transform_matches_params(const struct cmlcms_color_transform *xform,
const struct cmlcms_color_transform_search_param *param)
{
if (xform->search_key.type != param->type)
return false;
return true;
}
struct cmlcms_color_transform *
cmlcms_color_transform_get(struct weston_color_manager_lcms *cm,
const struct cmlcms_color_transform_search_param *param)
{
struct cmlcms_color_transform *xform;
wl_list_for_each(xform, &cm->color_transform_list, link) {
if (transform_matches_params(xform, param)) {
weston_color_transform_ref(&xform->base);
return xform;
}
}
xform = cmlcms_color_transform_create(cm, param);
if (!xform)
weston_log("color-lcms error: failed to create a color transformation.\n");
return xform;
}
......@@ -9,6 +9,7 @@ endif
srcs_color_lcms = [
'color-lcms.c',
'color-transform.c',
]
deps_color_lcms = [
......
......@@ -40,7 +40,28 @@ enum weston_color_curve_type {
/** LUT_3x1D parameters */
struct weston_color_curve_lut_3x1d {
/* To be defined */
/**
* Approximate a color curve with three 1D LUTs
*
* A 1D LUT is a mapping from [0.0, 1.0] to arbitrary values. The first
* element in the LUT corresponds to input value 0.0, and the last
* element corresponds to input value 1.0. The step from one element
* to the next in input space is 1.0 / (len - 1). When input value is
* between two elements, linear interpolation should be used.
*
* This function fills in the given array with the LUT values.
*
* \param xform This color transformation object.
* \param len The number of elements in each 1D LUT.
* \param values Array of 3 x len elements. First R channel
* LUT, immediately followed by G channel LUT, and then B channel LUT.
*/
void
(*fill_in)(struct weston_color_transform *xform,
float *values, unsigned len);
/** Optimal 1D LUT length for storage vs. precision */
unsigned optimal_len;
};
/**
......
......@@ -440,6 +440,7 @@ weston_drm_format_array_subtract(struct weston_drm_format_array *formats_A,
if (ret < 0)
goto err;
weston_drm_format_array_destroy(formats_result);
return 0;
err:
......
......@@ -42,18 +42,30 @@
#define SHADER_VARIANT_SOLID 7
#define SHADER_VARIANT_EXTERNAL 8
/* enum gl_shader_color_curve */
#define SHADER_COLOR_CURVE_IDENTITY 0
#define SHADER_COLOR_CURVE_LUT_3x1D 1
#if DEF_VARIANT == SHADER_VARIANT_EXTERNAL
#extension GL_OES_EGL_image_external : require
#endif
precision mediump float;
#ifdef GL_FRAGMENT_PRECISION_HIGH
#define HIGHPRECISION highp
#else
#define HIGHPRECISION mediump
#endif
precision HIGHPRECISION float;
/*
* These undeclared identifiers will be #defined by a runtime generated code
* snippet.
*/
compile_const int c_variant = DEF_VARIANT;
compile_const bool c_input_is_premult = DEF_INPUT_IS_PREMULT;
compile_const bool c_green_tint = DEF_GREEN_TINT;
compile_const int c_color_pre_curve = DEF_COLOR_PRE_CURVE;
vec4
yuva2rgba(vec4 yuva)
......@@ -79,7 +91,6 @@ yuva2rgba(vec4 yuva)
color_out.g = Y - 0.39176229 * su - 0.81296764 * sv;
color_out.b = Y + 2.01723214 * su;
color_out.rgb *= yuva.w;
color_out.a = yuva.w;
return color_out;
......@@ -96,6 +107,8 @@ uniform sampler2D tex1;
uniform sampler2D tex2;
uniform float alpha;
uniform vec4 unicolor;
uniform HIGHPRECISION sampler2D color_pre_curve_lut_2d;
uniform HIGHPRECISION vec2 color_pre_curve_lut_scale_offset;
vec4
sample_input_texture()
......@@ -141,16 +154,82 @@ sample_input_texture()
return yuva2rgba(yuva);
}
/*
* Texture coordinates go from 0.0 to 1.0 corresponding to texture edges.
* When we do LUT look-ups with linear filtering, the correct range to sample
* from is not from edge to edge, but center of first texel to center of last
* texel. This follows because with LUTs, you have the exact end points given,
* you never extrapolate but only interpolate.
* The scale and offset are precomputed to achieve this mapping.
*/
float
lut_texcoord(float x, vec2 scale_offset)
{
return x * scale_offset.s + scale_offset.t;
}
/*
* Sample a 1D LUT which is a single row of a 2D texture. The 2D texture has
* four rows so that the centers of texels have precise y-coordinates.
*/
float
sample_color_pre_curve_lut_2d(float x, compile_const int row)
{
float tx = lut_texcoord(x, color_pre_curve_lut_scale_offset);
return texture2D(color_pre_curve_lut_2d,
vec2(tx, (float(row) + 0.5) / 4.0)).x;
}
vec3
color_pre_curve(vec3 color)
{
vec3 ret;
if (c_color_pre_curve == SHADER_COLOR_CURVE_IDENTITY) {
return color;
} else if (c_color_pre_curve == SHADER_COLOR_CURVE_LUT_3x1D) {
ret.r = sample_color_pre_curve_lut_2d(color.r, 0);
ret.g = sample_color_pre_curve_lut_2d(color.g, 1);
ret.b = sample_color_pre_curve_lut_2d(color.b, 2);
return ret;
} else {
/* Never reached, bad c_color_pre_curve. */
return vec3(1.0, 0.3, 1.0);
}
}
vec4
color_pipeline(vec4 color)
{
/* View alpha (opacity) */
color.a *= alpha;
color.rgb = color_pre_curve(color.rgb);
return color;
}
void
main()
{
vec4 color;
/* Electrical (non-linear) RGBA values, pre-multiplied */
/* Electrical (non-linear) RGBA values, may be premult or not */
color = sample_input_texture();
/* View alpha (opacity) */
color *= alpha;
/* Ensure straight alpha */
if (c_input_is_premult) {
if (color.a == 0.0)
color.rgb = vec3(0, 0, 0);
else
color.rgb *= 1.0 / color.a;
}
color = color_pipeline(color);
/* pre-multiply for blending */
color.rgb *= color.a;
if (c_green_tint)
color = vec4(0.0, 0.3, 0.0, 0.2) + color * 0.8;
......
......@@ -50,6 +50,12 @@ enum gl_shader_texture_variant {
SHADER_VARIANT_EXTERNAL,
};
/* Keep the following in sync with fragment.glsl. */
enum gl_shader_color_curve {
SHADER_COLOR_CURVE_IDENTITY = 0,
SHADER_COLOR_CURVE_LUT_3x1D,
};
/** GL shader requirements key
*
* This structure is used as a binary blob key for building and searching
......@@ -62,19 +68,22 @@ enum gl_shader_texture_variant {
struct gl_shader_requirements
{
unsigned variant:4; /* enum gl_shader_texture_variant */
bool input_is_premult:1;
bool green_tint:1;
unsigned color_pre_curve:1; /* enum gl_shader_color_curve */
/*
* The total size of all bitfields plus pad_bits_ must fill up exactly
* how many bytes the compiler allocates for them together.
*/
unsigned pad_bits_:27;
unsigned pad_bits_:25;
};
static_assert(sizeof(struct gl_shader_requirements) ==
4 /* total bitfield size in bytes */,
"struct gl_shader_requirements must not contain implicit padding");
struct gl_shader;
struct weston_color_transform;
#define GL_SHADER_INPUT_TEX_MAX 3
struct gl_shader_config {
......@@ -85,6 +94,8 @@ struct gl_shader_config {
GLfloat unicolor[4];
GLint input_tex_filter; /* GL_NEAREST or GL_LINEAR */
GLuint input_tex[GL_SHADER_INPUT_TEX_MAX];
GLuint color_pre_curve_lut_tex;
GLfloat color_pre_curve_lut_scale_offset[2];
};
struct gl_renderer {
......@@ -202,6 +213,9 @@ gl_renderer_setup_egl_extensions(struct weston_compositor *ec);
GLenum
gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v);
bool
gl_shader_texture_variant_can_be_premult(enum gl_shader_texture_variant v);
void
gl_shader_destroy(struct gl_renderer *gr, struct gl_shader *shader);
......@@ -221,4 +235,8 @@ gl_renderer_use_program(struct gl_renderer *gr,
struct weston_log_scope *
gl_shader_scope_create(struct gl_renderer *gr);
bool
gl_shader_config_set_color_transform(struct gl_shader_config *sconf,
struct weston_color_transform *xform);
#endif /* GL_RENDERER_INTERNAL_H */
......@@ -718,6 +718,7 @@ gl_renderer_send_shader_error(struct weston_view *view)
static void
triangle_fan_debug(struct gl_renderer *gr,
const struct gl_shader_config *sconf,
struct weston_output *output,
int first, int count)
{
int i;
......@@ -738,12 +739,20 @@ triangle_fan_debug(struct gl_renderer *gr,
alt = (struct gl_shader_config) {
.req = {
.variant = SHADER_VARIANT_SOLID,
.input_is_premult = true,
},
.projection = sconf->projection,
.view_alpha = 1.0f,
.unicolor = { col[0], col[1], col[2], col[3] },
};
if (!gl_shader_config_set_color_transform(&alt,
output->from_sRGB_to_blend)) {
weston_log("GL-renderer: %s failed to generate a color transformation.\n",
__func__);
return;
}
gl_renderer_use_program(gr, &alt);
nelems = (count - 1 + count - 2) * 2;
......@@ -771,6 +780,7 @@ triangle_fan_debug(struct gl_renderer *gr,
static void
repaint_region(struct gl_renderer *gr,
struct weston_view *ev,
struct weston_output *output,
pixman_region32_t *region,
pixman_region32_t *surf_region,
const struct gl_shader_config *sconf)
......@@ -808,7 +818,7 @@ repaint_region(struct gl_renderer *gr,
for (i = 0, first = 0; i < nfans; i++) {
glDrawArrays(GL_TRIANGLE_FAN, first, vtxcnt[i]);
if (gr->fan_debug)
triangle_fan_debug(gr, sconf, first, vtxcnt[i]);
triangle_fan_debug(gr, sconf, output, first, vtxcnt[i]);
first += vtxcnt[i];
}
......@@ -908,6 +918,28 @@ ensure_surface_buffer_is_ready(struct gl_renderer *gr,
return (wait_ret == EGL_TRUE && destroy_ret == EGL_TRUE) ? 0 : -1;
}
static void
censor_override(struct gl_shader_config *sconf,
struct weston_output *output)
{
struct gl_shader_config alt = {
.req = {
.variant = SHADER_VARIANT_SOLID,
.input_is_premult = true,
},
.projection = sconf->projection,
.view_alpha = sconf->view_alpha,
.unicolor = { 0.40, 0.0, 0.0, 1.0 },
};
if (!gl_shader_config_set_color_transform(&alt,
output->from_sRGB_to_blend)) {
weston_log("GL-renderer: %s failed to generate a color transformation.\n",
__func__);
}
*sconf = alt;
}
/* Checks if a view needs to be censored on an output
* Checks for 2 types of censor requirements
......@@ -922,14 +954,6 @@ maybe_censor_override(struct gl_shader_config *sconf,
struct weston_output *output,
struct weston_view *ev)
{
const struct gl_shader_config alt = {
.req = {
.variant = SHADER_VARIANT_SOLID,
},
.projection = sconf->projection,
.view_alpha = sconf->view_alpha,
.unicolor = { 0.40, 0.0, 0.0, 1.0 },
};
struct gl_surface_state *gs = get_surface_state(ev->surface);
bool recording_censor =
(output->disable_planes > 0) &&
......@@ -939,7 +963,7 @@ maybe_censor_override(struct gl_shader_config *sconf,
(ev->surface->desired_protection > output->current_protection);
if (gs->direct_display) {
*sconf = alt;
censor_override(sconf, output);
return;
}
......@@ -950,7 +974,7 @@ maybe_censor_override(struct gl_shader_config *sconf,
return;
if (recording_censor || unprotected_censor)
*sconf = alt;
censor_override(sconf, output);
}
static void
......@@ -960,6 +984,8 @@ gl_shader_config_set_input_textures(struct gl_shader_config *sconf,
int i;
sconf->req.variant = gs->shader_variant;
sconf->req.input_is_premult =
gl_shader_texture_variant_can_be_premult(gs->shader_variant);
for (i = 0; i < 4; i++)
sconf->unicolor[i] = gs->color[i];
......@@ -981,7 +1007,6 @@ gl_shader_config_init_for_paint_node(struct gl_shader_config *sconf,
if (!pnode->surf_xform_valid)
return false;
assert(pnode->surf_xform.transform == NULL);
*sconf = (struct gl_shader_config) {
.projection = go->output_matrix,
......@@ -991,6 +1016,11 @@ gl_shader_config_init_for_paint_node(struct gl_shader_config *sconf,
gl_shader_config_set_input_textures(sconf, gs);
if (!gl_shader_config_set_color_transform(sconf, pnode->surf_xform.transform)) {
weston_log("GL-renderer: failed to generate a color transformation.\n");
return false;
}
return true;
}
......@@ -1034,9 +1064,6 @@ draw_paint_node(struct weston_paint_node *pnode,
else
filter = GL_NEAREST;
/* for triangle_fan_debug(), maybe_censor_override() */
assert(pnode->output->from_sRGB_to_blend == NULL);
if (!gl_shader_config_init_for_paint_node(&sconf, pnode, filter))
goto out;
......@@ -1077,13 +1104,15 @@ draw_paint_node(struct weston_paint_node *pnode,
else
glDisable(GL_BLEND);
repaint_region(gr, pnode->view, &repaint, &surface_opaque, &alt);
repaint_region(gr, pnode->view, pnode->output,
&repaint, &surface_opaque, &alt);
gs->used_in_output_repaint = true;
}
if (pixman_region32_not_empty(&surface_blend)) {
glEnable(GL_BLEND);
repaint_region(gr, pnode->view, &repaint, &surface_blend, &sconf);
repaint_region(gr, pnode->view, pnode->output,
&repaint, &surface_blend, &sconf);
gs->used_in_output_repaint = true;
}
......@@ -1264,6 +1293,7 @@ draw_output_borders(struct weston_output *output,
struct gl_shader_config sconf = {
.req = {
.variant = SHADER_VARIANT_RGBA,
.input_is_premult = true,
},
.view_alpha = 1.0f,
};
......@@ -1275,7 +1305,10 @@ draw_output_borders(struct weston_output *output,
if (border_status == BORDER_STATUS_CLEAN)
return; /* Clean. Nothing to do. */
assert(output->from_sRGB_to_output == NULL);
if (!gl_shader_config_set_color_transform(&sconf, output->from_sRGB_to_output)) {
weston_log("GL-renderer: %s failed to generate a color transformation.\n", __func__);
return;
}
top = &go->borders[GL_RENDERER_BORDER_TOP];
bottom = &go->borders[GL_RENDERER_BORDER_BOTTOM];
......@@ -1485,9 +1518,10 @@ blit_shadow_to_output(struct weston_output *output,
pixman_region32_t *output_damage)
{
struct gl_output_state *go = get_output_state(output);
const struct gl_shader_config sconf = {
struct gl_shader_config sconf = {
.req = {
.variant = SHADER_VARIANT_RGBA,
.input_is_premult = true,
},
.projection = {
.d = { /* transpose */
......@@ -1512,7 +1546,10 @@ blit_shadow_to_output(struct weston_output *output,
pixman_region32_t translated_damage;
GLfloat verts[4 * 2];
assert(output->from_blend_to_output == NULL);
if (!gl_shader_config_set_color_transform(&sconf, output->from_blend_to_output)) {
weston_log("GL-renderer: %s failed to generate a color transformation.\n", __func__);
return;
}
pixman_region32_init(&translated_damage);
......@@ -1577,7 +1614,7 @@ gl_renderer_repaint_output(struct weston_output *output,
struct weston_paint_node *pnode;
assert(output->from_blend_to_output_by_backend ||
output->from_blend_to_output == NULL);
output->from_blend_to_output == NULL || shadow_exists(go));
if (use_output(output) < 0)
return;
......@@ -3821,6 +3858,7 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
gr->has_egl_image_external = true;
if (gr->gl_version >= gr_gl_version(3, 0) &&
weston_check_egl_extension(extensions, "GL_OES_texture_float_linear") &&
weston_check_egl_extension(extensions, "GL_EXT_color_buffer_half_float")) {
gr->gl_supports_color_transforms = true;
}
......
/*
* Copyright 2021 Collabora, Ltd.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "config.h"
#include <GLES3/gl3.h>
#include <GLES2/gl2ext.h>
#include <assert.h>
#include <libweston/libweston.h>
#include "color.h"
#include "gl-renderer.h"
#include "gl-renderer-internal.h"
#include "shared/weston-egl-ext.h"
struct gl_renderer_color_curve {
enum gl_shader_color_curve type;
GLuint tex;
float scale;
float offset;
};
struct gl_renderer_color_transform {
struct weston_color_transform *owner;
struct wl_listener destroy_listener;
struct gl_renderer_color_curve pre_curve;
};
static void
gl_renderer_color_curve_fini(struct gl_renderer_color_curve *gl_curve)
{
if (gl_curve->tex)
glDeleteTextures(1, &gl_curve->tex);
}
static void
gl_renderer_color_transform_destroy(struct gl_renderer_color_transform *gl_xform)
{
gl_renderer_color_curve_fini(&gl_xform->pre_curve);
wl_list_remove(&gl_xform->destroy_listener.link);
free(gl_xform);
}
static void
color_transform_destroy_handler(struct wl_listener *l, void *data)
{
struct gl_renderer_color_transform *gl_xform;
gl_xform = wl_container_of(l, gl_xform, destroy_listener);
assert(gl_xform->owner == data);
gl_renderer_color_transform_destroy(gl_xform);
}
static struct gl_renderer_color_transform *
gl_renderer_color_transform_create(struct weston_color_transform *xform)
{
struct gl_renderer_color_transform *gl_xform;
gl_xform = zalloc(sizeof *gl_xform);
if (!gl_xform)
return NULL;
gl_xform->owner = xform;
gl_xform->destroy_listener.notify = color_transform_destroy_handler;
wl_signal_add(&xform->destroy_signal, &gl_xform->destroy_listener);
return gl_xform;
}
static struct gl_renderer_color_transform *
gl_renderer_color_transform_get(struct weston_color_transform *xform)
{
struct wl_listener *l;
l = wl_signal_get(&xform->destroy_signal,
color_transform_destroy_handler);
if (!l)
return NULL;
return container_of(l, struct gl_renderer_color_transform,
destroy_listener);
}
static bool
gl_color_curve_lut_3x1d(struct gl_renderer_color_curve *gl_curve,
const struct weston_color_curve *curve,
struct weston_color_transform *xform)
{
const unsigned lut_len = curve->u.lut_3x1d.optimal_len;
const unsigned nr_rows = 4;
GLuint tex;
float *lut;
/*
* Four rows, see fragment.glsl sample_color_pre_curve_lut_2d().
* The fourth row is unused in fragment.glsl color_pre_curve().
*/
lut = calloc(lut_len * nr_rows, sizeof *lut);
if (!lut)
return false;
curve->u.lut_3x1d.fill_in(xform, lut, lut_len);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ALIGNMENT, sizeof (float));
glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS_EXT, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, lut_len, nr_rows, 0,
GL_RED_EXT, GL_FLOAT, lut);
glBindTexture(GL_TEXTURE_2D, 0);
free(lut);
gl_curve->type = SHADER_COLOR_CURVE_LUT_3x1D;
gl_curve->tex = tex;
gl_curve->scale = (float)(lut_len - 1) / lut_len;
gl_curve->offset = 0.5f / lut_len;
return true;
}
static const struct gl_renderer_color_transform *
gl_renderer_color_transform_from(struct weston_color_transform *xform)
{
static const struct gl_renderer_color_transform no_op_gl_xform = {
.pre_curve.type = SHADER_COLOR_CURVE_IDENTITY,
.pre_curve.tex = 0,
.pre_curve.scale = 0.0f,
.pre_curve.offset = 0.0f,
};
struct gl_renderer_color_transform *gl_xform;
bool ok = false;
/* Identity transformation */
if (!xform)
return &no_op_gl_xform;
/* Cached transformation */
gl_xform = gl_renderer_color_transform_get(xform);
if (gl_xform)
return gl_xform;
/* New transformation */
gl_xform = gl_renderer_color_transform_create(xform);
if (!gl_xform)
return NULL;
switch (xform->pre_curve.type) {
case WESTON_COLOR_CURVE_TYPE_IDENTITY:
gl_xform->pre_curve = no_op_gl_xform.pre_curve;
ok = true;
break;
case WESTON_COLOR_CURVE_TYPE_LUT_3x1D:
ok = gl_color_curve_lut_3x1d(&gl_xform->pre_curve,
&xform->pre_curve, xform);
break;
}
if (!ok) {
gl_renderer_color_transform_destroy(gl_xform);
return NULL;
}
return gl_xform;
}
bool
gl_shader_config_set_color_transform(struct gl_shader_config *sconf,
struct weston_color_transform *xform)
{
const struct gl_renderer_color_transform *gl_xform;
gl_xform = gl_renderer_color_transform_from(xform);
if (!gl_xform)
return false;
sconf->req.color_pre_curve = gl_xform->pre_curve.type;
sconf->color_pre_curve_lut_tex = gl_xform->pre_curve.tex;
sconf->color_pre_curve_lut_scale_offset[0] = gl_xform->pre_curve.scale;
sconf->color_pre_curve_lut_scale_offset[1] = gl_xform->pre_curve.offset;
return true;
}
......@@ -58,6 +58,8 @@ struct gl_shader {
GLint tex_uniforms[3];
GLint alpha_uniform;
GLint color_uniform;
GLint color_pre_curve_lut_2d_uniform;
GLint color_pre_curve_lut_scale_offset_uniform;
struct wl_list link; /* gl_renderer::shader_list */
struct timespec last_used;
};
......@@ -82,6 +84,19 @@ gl_shader_texture_variant_to_string(enum gl_shader_texture_variant v)
return "!?!?"; /* never reached */
}
static const char *
gl_shader_color_curve_to_string(enum gl_shader_color_curve kind)
{
switch (kind) {
#define CASERET(x) case x: return #x;
CASERET(SHADER_COLOR_CURVE_IDENTITY)
CASERET(SHADER_COLOR_CURVE_LUT_3x1D)
#undef CASERET
}
return "!?!?"; /* never reached */
}
static void
dump_program_with_line_numbers(int count, const char **sources)
{
......@@ -147,8 +162,10 @@ create_shader_description_string(const struct gl_shader_requirements *req)
int size;
char *str;
size = asprintf(&str, "%s %cgreen",
size = asprintf(&str, "%s %s %cinput_is_premult %cgreen",
gl_shader_texture_variant_to_string(req->variant),
gl_shader_color_curve_to_string(req->color_pre_curve),
req->input_is_premult ? '+' : '-',
req->green_tint ? '+' : '-');
if (size < 0)
return NULL;
......@@ -163,8 +180,12 @@ create_shader_config_string(const struct gl_shader_requirements *req)
size = asprintf(&str,
"#define DEF_GREEN_TINT %s\n"
"#define DEF_INPUT_IS_PREMULT %s\n"
"#define DEF_COLOR_PRE_CURVE %s\n"
"#define DEF_VARIANT %s\n",
req->green_tint ? "true" : "false",
req->input_is_premult ? "true" : "false",
gl_shader_color_curve_to_string(req->color_pre_curve),
gl_shader_texture_variant_to_string(req->variant));
if (size < 0)
return NULL;
......@@ -242,6 +263,10 @@ gl_shader_create(struct gl_renderer *gr,
shader->alpha_uniform = glGetUniformLocation(shader->program, "alpha");
shader->color_uniform = glGetUniformLocation(shader->program,
"unicolor");
shader->color_pre_curve_lut_2d_uniform =
glGetUniformLocation(shader->program, "color_pre_curve_lut_2d");
shader->color_pre_curve_lut_scale_offset_uniform =
glGetUniformLocation(shader->program, "color_pre_curve_lut_scale_offset");
free(conf);
......@@ -349,6 +374,8 @@ gl_renderer_create_fallback_shader(struct gl_renderer *gr)
{
static const struct gl_shader_requirements fallback_requirements = {
.variant = SHADER_VARIANT_SOLID,
.input_is_premult = true,
.color_pre_curve = SHADER_COLOR_CURVE_IDENTITY,
};
struct gl_shader *shader;
......@@ -415,6 +442,25 @@ gl_renderer_garbage_collect_programs(struct gl_renderer *gr)
}
}
bool
gl_shader_texture_variant_can_be_premult(enum gl_shader_texture_variant v)
{
switch (v) {
case SHADER_VARIANT_SOLID:
case SHADER_VARIANT_RGBA:
case SHADER_VARIANT_EXTERNAL:
return true;
case SHADER_VARIANT_NONE:
case SHADER_VARIANT_RGBX:
case SHADER_VARIANT_Y_U_V:
case SHADER_VARIANT_Y_UV:
case SHADER_VARIANT_Y_XUXV:
case SHADER_VARIANT_XYUV:
return false;
}
return true;
}
GLenum
gl_shader_texture_variant_get_target(enum gl_shader_texture_variant v)
{
......@@ -450,6 +496,25 @@ gl_shader_load_config(struct gl_shader *shader,
glTexParameteri(in_tgt, GL_TEXTURE_MIN_FILTER, in_filter);
glTexParameteri(in_tgt, GL_TEXTURE_MAG_FILTER, in_filter);
}
/* Fixed texture unit for color_pre_curve LUT */
i = GL_SHADER_INPUT_TEX_MAX;
glActiveTexture(GL_TEXTURE0 + i);
switch (sconf->req.color_pre_curve) {
case SHADER_COLOR_CURVE_IDENTITY:
assert(sconf->color_pre_curve_lut_tex == 0);
break;
case SHADER_COLOR_CURVE_LUT_3x1D:
assert(sconf->color_pre_curve_lut_tex != 0);
assert(shader->color_pre_curve_lut_2d_uniform != -1);
assert(shader->color_pre_curve_lut_scale_offset_uniform != -1);
glBindTexture(GL_TEXTURE_2D, sconf->color_pre_curve_lut_tex);
glUniform1i(shader->color_pre_curve_lut_2d_uniform, i);
glUniform2fv(shader->color_pre_curve_lut_scale_offset_uniform,
1, sconf->color_pre_curve_lut_scale_offset);
break;
}
}
bool
......
......@@ -23,6 +23,7 @@ srcs_renderer_gl = [
fragment_glsl,
'gl-renderer.c',
'gl-shaders.c',
'gl-shader-config-color-transformation.c',
linux_dmabuf_unstable_v1_protocol_c,
linux_dmabuf_unstable_v1_server_protocol_h,
vertex_glsl,
......
......@@ -25,9 +25,7 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <math.h>
#include "weston-test-client-helper.h"
#include "weston-test-fixture-compositor.h"
......@@ -35,6 +33,7 @@
struct setup_args {
struct fixture_metadata meta;
enum renderer_type renderer;
bool color_management;
};
static const int ALPHA_STEPS = 256;
......@@ -43,12 +42,19 @@ static const int BLOCK_WIDTH = 3;
static const struct setup_args my_setup_args[] = {
{
.renderer = RENDERER_PIXMAN,
.color_management = false,
.meta.name = "pixman"
},
{
.renderer = RENDERER_GL,
.color_management = false,
.meta.name = "GL"
},
{
.renderer = RENDERER_GL,
.color_management = true,
.meta.name = "GL sRGB EOTF"
},
};
static enum test_result_code
......@@ -62,6 +68,12 @@ fixture_setup(struct weston_test_harness *harness, const struct setup_args *arg)
setup.height = 16;
setup.shell = SHELL_TEST_DESKTOP;
if (arg->color_management) {
weston_ini_setup(&setup,
cfgln("[core]"),
cfgln("color-management=true"));
}
return weston_test_harness_execute_as_client(harness, &setup);
}
DECLARE_FIXTURE_SETUP_WITH_ARG(fixture_setup, my_setup_args, meta);
......@@ -125,6 +137,170 @@ fill_alpha_pattern(struct buffer *buf)
}
}
struct color_float {
float r, g, b, a;
};
static struct color_float
a8r8g8b8_to_float(uint32_t v)
{
struct color_float cf;
cf.a = ((v >> 24) & 0xff) / 255.f;
cf.r = ((v >> 16) & 0xff) / 255.f;
cf.g = ((v >> 8) & 0xff) / 255.f;
cf.b = ((v >> 0) & 0xff) / 255.f;
return cf;
}
static void
unpremult_float(struct color_float *cf)
{
if (cf->a == 0.0f) {
cf->r = 0.0f;
cf->g = 0.0f;
cf->b = 0.0f;
} else {
cf->r /= cf->a;
cf->g /= cf->a;
cf->b /= cf->a;
}
}
static float
sRGB_EOTF(float e)
{
assert(e >= 0.0f);
assert(e <= 1.0f);
if (e <= 0.04045)
return e / 12.92;
else
return pow((e + 0.055) / 1.055, 2.4);
}
static void
sRGB_linearize(struct color_float *cf)
{
cf->r = sRGB_EOTF(cf->r);
cf->g = sRGB_EOTF(cf->g);
cf->b = sRGB_EOTF(cf->b);
}
static float
sRGB_EOTF_inv(float o)
{
assert(o >= 0.0f);
assert(o <= 1.0f);
if (o <= 0.04045 / 12.92)
return o * 12.92;
else
return pow(o, 1.0 / 2.4) * 1.055 - 0.055;
}
static void
sRGB_delinearize(struct color_float *cf)
{
cf->r = sRGB_EOTF_inv(cf->r);
cf->g = sRGB_EOTF_inv(cf->g);
cf->b = sRGB_EOTF_inv(cf->b);
}
static bool
compare_float(float ref, float dst, int x, const char *chan, float *max_diff)
{
#if 0
/*
* This file can be loaded in Octave for visualization.
*
* S = load('compare_float_dump.txt');
*
* rvec = S(S(:,1)==114, 2:3);
* gvec = S(S(:,1)==103, 2:3);
* bvec = S(S(:,1)==98, 2:3);
*
* figure
* subplot(3, 1, 1);
* plot(rvec(:,1), rvec(:,2) .* 255, 'r');
* subplot(3, 1, 2);
* plot(gvec(:,1), gvec(:,2) .* 255, 'g');
* subplot(3, 1, 3);
* plot(bvec(:,1), bvec(:,2) .* 255, 'b');
*/
static FILE *fp = NULL;
if (!fp)
fp = fopen("compare_float_dump.txt", "w");
fprintf(fp, "%d %d %f\n", chan[0], x, dst - ref);
fflush(fp);
#endif
float diff = fabsf(ref - dst);
if (diff > *max_diff)
*max_diff = diff;
/*
* Allow for +/- 1.5 code points of error in non-linear 8-bit channel
* value. This is necessary for the BLEND_LINEAR case.
*
* With llvmpipe, we could go as low as +/- 0.65 code points of error
* and still pass.
*
* AMD Polaris 11 would be ok with +/- 1.0 code points error threshold
* if not for one particular case of blending (a=254, r=0) into r=255,
* which results in error of 1.29 code points.
*/
if (diff < 1.5f / 255.f)
return true;
testlog("x=%d %s: ref %f != dst %f, delta %f\n",
x, chan, ref, dst, dst - ref);
return false;
}
enum blend_space {
BLEND_NONLINEAR,
BLEND_LINEAR,
};
static bool
verify_sRGB_blend_a8r8g8b8(uint32_t bg32, uint32_t fg32, uint32_t dst32,
int x, struct color_float *max_diff,
enum blend_space space)
{
struct color_float bg = a8r8g8b8_to_float(bg32);
struct color_float fg = a8r8g8b8_to_float(fg32);
struct color_float dst = a8r8g8b8_to_float(dst32);
struct color_float ref;
bool ok = true;
unpremult_float(&bg);
unpremult_float(&fg);
unpremult_float(&dst);
if (space == BLEND_LINEAR) {
sRGB_linearize(&bg);
sRGB_linearize(&fg);
}
ref.r = (1.0f - fg.a) * bg.r + fg.a * fg.r;
ref.g = (1.0f - fg.a) * bg.g + fg.a * fg.g;
ref.b = (1.0f - fg.a) * bg.b + fg.a * fg.b;
if (space == BLEND_LINEAR)
sRGB_delinearize(&ref);
ok = compare_float(ref.r, dst.r, x, "r", &max_diff->r) && ok;
ok = compare_float(ref.g, dst.g, x, "g", &max_diff->g) && ok;
ok = compare_float(ref.b, dst.b, x, "b", &max_diff->b) && ok;
return ok;
}
static uint8_t
red(uint32_t v)
{
......@@ -155,27 +331,45 @@ pixels_monotonic(const uint32_t *row, int x)
return ret;
}
static bool
check_blend_pattern(struct buffer *shot)
static void *
get_middle_row(struct buffer *buf)
{
bool ret = true;
const int y = (BLOCK_WIDTH - 1) / 2; /* middle row */
int x;
void *pixels;
int stride_bytes;
uint32_t *row;
assert(pixman_image_get_width(shot->image) >= BLOCK_WIDTH * ALPHA_STEPS);
assert(pixman_image_get_height(shot->image) >= BLOCK_WIDTH);
assert(pixman_image_get_width(buf->image) >= BLOCK_WIDTH * ALPHA_STEPS);
assert(pixman_image_get_height(buf->image) >= BLOCK_WIDTH);
pixels = pixman_image_get_data(shot->image);
stride_bytes = pixman_image_get_stride(shot->image);
row = pixels + y * stride_bytes;
pixels = pixman_image_get_data(buf->image);
stride_bytes = pixman_image_get_stride(buf->image);
return pixels + y * stride_bytes;
}
static bool
check_blend_pattern(struct buffer *bg, struct buffer *fg, struct buffer *shot,
enum blend_space space)
{
uint32_t *bg_row = get_middle_row(bg);
uint32_t *fg_row = get_middle_row(fg);
uint32_t *shot_row = get_middle_row(shot);
struct color_float max_diff = { 0.0f, 0.0f, 0.0f, 0.0f };
bool ret = true;
int x;
for (x = 0; x < BLOCK_WIDTH * ALPHA_STEPS - 1; x++)
if (!pixels_monotonic(row, x))
for (x = 0; x < BLOCK_WIDTH * ALPHA_STEPS - 1; x++) {
if (!pixels_monotonic(shot_row, x))
ret = false;
if (!verify_sRGB_blend_a8r8g8b8(bg_row[x], fg_row[x],
shot_row[x], x, &max_diff,
space))
ret = false;
}
testlog("%s max diff: r=%f, g=%f, b=%f\n",
__func__, max_diff.r, max_diff.g, max_diff.b);
return ret;
}
......@@ -196,8 +390,26 @@ check_blend_pattern(struct buffer *shot)
* - red goes from 1.0 to 0.0, monotonic
* - green is not monotonic
* - blue goes from 0.0 to 1.0, monotonic
*
* This test has two modes: BLEND_NONLINEAR and BLEND_LINEAR.
*
* BLEND_NONLINEAR does blending with pixel values as is, which are non-linear,
* and therefore result in "physically incorrect" blending result. Yet, people
* have accustomed to seeing this effect. This mode hits pipeline_premult()
* in fragment.glsl.
*
* BLEND_LINEAR has sRGB encoded pixels (non-linear). These are converted to
* linear light (optical) values, blended, and converted back to non-linear
* (electrical) values. This results in "physically more correct" blending
* result for some value of "physical". This mode hits pipeline_straight()
* in fragment.glsl, and tests even more things:
* - gl-renderer implementation of 1D LUT is correct
* - color-lcms instantiates the correct sRGB EOTF and inverse LUTs
* - color space conversions do not happen when both content and output are
* using their default color spaces
* - blending through gl-renderer shadow framebuffer
*/
TEST(alpha_blend_monotonic)
TEST(alpha_blend)
{
const int width = BLOCK_WIDTH * ALPHA_STEPS;
const int height = BLOCK_WIDTH;
......@@ -207,38 +419,51 @@ TEST(alpha_blend_monotonic)
.blue = 0x0000,
.alpha = 0xffff
};
const struct setup_args *args;
struct client *client;
struct buffer *buf;
struct buffer *bg;
struct buffer *fg;
struct wl_subcompositor *subco;
struct wl_surface *surf;
struct wl_subsurface *sub;
struct buffer *shot;
bool match;
int seq_no;
enum blend_space space;
args = &my_setup_args[get_test_fixture_index()];
if (args->color_management) {
seq_no = 1;
space = BLEND_LINEAR;
} else {
seq_no = 0;
space = BLEND_NONLINEAR;
}
client = create_client();
subco = bind_to_singleton_global(client, &wl_subcompositor_interface, 1);
/* background window content */
buf = create_shm_buffer_a8r8g8b8(client, width, height);
fill_image_with_color(buf->image, &background_color);
bg = create_shm_buffer_a8r8g8b8(client, width, height);
fill_image_with_color(bg->image, &background_color);
/* background window, main surface */
client->surface = create_test_surface(client);
client->surface->width = width;
client->surface->height = height;
client->surface->buffer = buf; /* pass ownership */
client->surface->buffer = bg; /* pass ownership */
set_opaque_rect(client, client->surface,
&(struct rectangle){ 0, 0, width, height });
/* foreground blended content */
buf = create_shm_buffer_a8r8g8b8(client, width, height);
fill_alpha_pattern(buf);
fg = create_shm_buffer_a8r8g8b8(client, width, height);
fill_alpha_pattern(fg);
/* foreground window, sub-surface */
surf = wl_compositor_create_surface(client->wl_compositor);
sub = wl_subcompositor_get_subsurface(subco, surf, client->surface->wl_surface);
/* sub-surface defaults to position 0, 0, top-most, synchronized */
wl_surface_attach(surf, buf->proxy, 0, 0);
wl_surface_attach(surf, fg->proxy, 0, 0);
wl_surface_damage(surf, 0, 0, width, height);
wl_surface_commit(surf);
......@@ -247,15 +472,15 @@ TEST(alpha_blend_monotonic)
shot = capture_screenshot_of_output(client);
assert(shot);
match = verify_image(shot, "alpha_blend_monotonic", 0, NULL, 0);
match = verify_image(shot, "alpha_blend", seq_no, NULL, seq_no);
assert(check_blend_pattern(bg, fg, shot, space));
assert(match);
assert(check_blend_pattern(shot));
buffer_destroy(shot);
wl_subsurface_destroy(sub);
wl_surface_destroy(surf);
buffer_destroy(buf);
buffer_destroy(fg);
wl_subcompositor_destroy(subco);
client_destroy(client);
client_destroy(client); /* destroys bg */
}
......@@ -106,6 +106,8 @@ TEST(seat_capabilities_test)
assert(cl->input->pointer);
assert(cl->input->keyboard);
assert(cl->input->touch);
client_destroy(cl);
}
#define COUNT 15
......@@ -144,6 +146,8 @@ TEST(multiple_device_add_and_remove)
assert(cl->input->pointer);
assert(cl->input->keyboard);
assert(cl->input->touch);
client_destroy(cl);
}
TEST(device_release_before_destroy)
......@@ -181,6 +185,8 @@ TEST(device_release_before_destroy)
client_roundtrip(cl);
assert(cl->input->caps == WL_SEAT_CAPABILITY_ALL);
client_destroy(cl);
}
TEST(device_release_before_destroy_multiple)
......@@ -190,12 +196,6 @@ TEST(device_release_before_destroy_multiple)
/* if weston crashed during this test, then there is
* some inconsistency */
for (i = 0; i < 30; ++i) {
/* Fifty times run the previous test. This will create
* fifty clients, because we don't have any
* way how to destroy them (worth of adding!). Only one
* client will run at a time though and so should have no
* effect on the result of the test (after the client
* finishes its body, it just 'is' and does nothing). */
device_release_before_destroy();
}
}
......@@ -237,6 +237,8 @@ TEST(device_release_after_destroy)
client_roundtrip(cl);
assert(cl->input->caps == WL_SEAT_CAPABILITY_ALL);
client_destroy(cl);
}
TEST(device_release_after_destroy_multiple)
......@@ -310,6 +312,8 @@ TEST(get_device_after_destroy)
client_roundtrip(cl);
assert(cl->input->caps == WL_SEAT_CAPABILITY_ALL);
client_destroy(cl);
}
TEST(get_device_after_destroy_multiple)
......@@ -331,6 +335,8 @@ TEST(seats_have_names)
wl_list_for_each(input, &cl->inputs, link) {
assert(input->seat_name);
}
client_destroy(cl);
}
TEST(seat_destroy_and_recreate)
......@@ -353,4 +359,6 @@ TEST(seat_destroy_and_recreate)
assert(cl->input->pointer);
assert(cl->input->keyboard);
assert(cl->input->touch);
client_destroy(cl);
}
......@@ -349,11 +349,9 @@ TEST(intersect_arrays)
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
format_array_C = weston_drm_format_array_create();
format_array_result = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
assert(format_array_C);
assert(format_array_result);
ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
......@@ -393,7 +391,7 @@ TEST(intersect_arrays_same_content)
assert(format_array_result);
assert(format_array_result->arr.size == 0);
weston_drm_format_array_fini(format_array_result);
weston_drm_format_array_destroy(format_array_result);
/* DRM-format arrays A and B have the same content, so the intersection
* should be equal to them. */
......
......@@ -108,6 +108,8 @@ TEST(test_surface_output)
/* visible */
check_client_move(client, x, --y);
assert(output_contains_client(client));
client_destroy(client);
}
static void
......@@ -176,4 +178,9 @@ TEST(buffer_release)
assert(buf1_released == 0);
assert(buf2_released == 1);
assert(buf3_released == 1);
buffer_destroy(buf1);
buffer_destroy(buf2);
buffer_destroy(buf3);
client_destroy(client);
}
......@@ -91,7 +91,7 @@ TEST(internal_screenshot)
pixman_image_t *reference_bad = NULL;
pixman_image_t *diffimg;
struct rectangle clip;
const char *fname;
char *fname;
bool match = false;
bool dump_all_images = true;
......@@ -135,12 +135,14 @@ TEST(internal_screenshot)
testlog("Loading good reference image %s\n", fname);
reference_good = load_image_from_png(fname);
assert(reference_good);
free(fname);
/* Load bad reference image */
fname = screenshot_reference_filename("internal-screenshot-bad", 0);
testlog("Loading bad reference image %s\n", fname);
reference_bad = load_image_from_png(fname);
assert(reference_bad);
free(fname);
/* Test check_images_match() without a clip.
* We expect this to fail since we use a bad reference image
......@@ -166,6 +168,7 @@ TEST(internal_screenshot)
fname = screenshot_output_filename("internal-screenshot-error", 0);
write_image_as_png(diffimg, fname);
pixman_image_unref(diffimg);
free(fname);
}
pixman_image_unref(reference_good);
......@@ -173,10 +176,14 @@ TEST(internal_screenshot)
if (!match || dump_all_images) {
fname = screenshot_output_filename("internal-screenshot", 0);
write_image_as_png(screenshot->image, fname);
free(fname);
}
buffer_destroy(screenshot);
testlog("Test complete\n");
assert(match);
buffer_destroy(buf);
client_destroy(client);
}