weston/libweston/drm-formats.c
Leandro Ribeiro 0157591b34 libweston: do not forget to destroy temporary drm_format_array
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: Leandro Ribeiro <leandro.ribeiro@collabora.com>
2021-06-16 13:36:43 +00:00

518 lines
14 KiB
C

/*
* 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 <assert.h>
#include <libweston/libweston.h>
#include "libweston-internal.h"
#include "shared/weston-drm-fourcc.h"
/**
* Create and initialize a weston_drm_format_array
*
* @return The weston_drm_format_array, or NULL on failure
*/
WL_EXPORT struct weston_drm_format_array *
weston_drm_format_array_create(void)
{
struct weston_drm_format_array *formats;
formats = zalloc(sizeof(*formats));
if (!formats) {
weston_log("%s: out of memory\n", __func__);
return NULL;
}
weston_drm_format_array_init(formats);
return formats;
}
/**
* Initialize a weston_drm_format_array
*
* @param formats The weston_drm_format_array to initialize
*/
WL_EXPORT void
weston_drm_format_array_init(struct weston_drm_format_array *formats)
{
wl_array_init(&formats->arr);
}
/**
* Fini and destroy a weston_drm_format_array
*
* @param formats The weston_drm_format_array to destroy
*/
WL_EXPORT void
weston_drm_format_array_destroy(struct weston_drm_format_array *formats)
{
weston_drm_format_array_fini(formats);
free(formats);
}
/**
* Finish a weston_drm_format_array
*
* It releases the modifiers set for each format and then the
* formats array itself.
*
* @param formats The weston_drm_format_array to finish
*/
WL_EXPORT void
weston_drm_format_array_fini(struct weston_drm_format_array *formats)
{
struct weston_drm_format *fmt;
wl_array_for_each(fmt, &formats->arr)
wl_array_release(&fmt->modifiers);
wl_array_release(&formats->arr);
}
static int
add_format_and_modifiers(struct weston_drm_format_array *formats,
uint32_t format, struct wl_array *modifiers)
{
struct weston_drm_format *fmt;
int ret;
fmt = weston_drm_format_array_add_format(formats, format);
if (!fmt)
return -1;
ret = wl_array_copy(&fmt->modifiers, modifiers);
if (ret < 0) {
weston_log("%s: out of memory\n", __func__);
return -1;
}
return 0;
}
/**
* Replace the content of a weston_drm_format_array
*
* Frees the content of the array and then perform a deep copy using
* source_formats. It duplicates the array of formats and for each format it
* duplicates the modifiers set as well.
*
* @param formats The weston_drm_format_array that gets its content replaced
* @param source_formats The weston_drm_format_array to copy
* @return 0 on success, -1 on failure
*/
WL_EXPORT int
weston_drm_format_array_replace(struct weston_drm_format_array *formats,
const struct weston_drm_format_array *source_formats)
{
struct weston_drm_format *source_fmt;
int ret;
weston_drm_format_array_fini(formats);
weston_drm_format_array_init(formats);
wl_array_for_each(source_fmt, &source_formats->arr) {
ret = add_format_and_modifiers(formats, source_fmt->format,
&source_fmt->modifiers);
if (ret < 0)
return -1;
}
return 0;
}
/**
* Add format to weston_drm_format_array
*
* Adding repeated formats is considered an error.
*
* @param formats The weston_drm_format_array that receives the format
* @param format The format to add to the array
* @return The weston_drm_format, or NULL on failure
*/
WL_EXPORT struct weston_drm_format *
weston_drm_format_array_add_format(struct weston_drm_format_array *formats,
uint32_t format)
{
struct weston_drm_format *fmt;
/* We should not try to add repeated formats to an array. */
assert(!weston_drm_format_array_find_format(formats, format));
fmt = wl_array_add(&formats->arr, sizeof(*fmt));
if (!fmt) {
weston_log("%s: out of memory\n", __func__);
return NULL;
}
fmt->format = format;
wl_array_init(&fmt->modifiers);
return fmt;
}
/**
* Remove latest format added to a weston_drm_format_array
*
* Calling this function for an empty array is an error, at least one element
* must be in the array.
*
* @param formats The weston_drm_format_array from which the format is removed
*/
WL_EXPORT void
weston_drm_format_array_remove_latest_format(struct weston_drm_format_array *formats)
{
struct wl_array *array = &formats->arr;
struct weston_drm_format *fmt;
assert(array->size >= sizeof(*fmt));
array->size -= sizeof(*fmt);
fmt = array->data + array->size;
wl_array_release(&fmt->modifiers);
}
/**
* Find format in a weston_drm_format_array
*
* @param formats The weston_drm_format_array where to look for the format
* @param format The format to look for
* @return The weston_drm_format if format was found, or NULL otherwise
*/
WL_EXPORT struct weston_drm_format *
weston_drm_format_array_find_format(const struct weston_drm_format_array *formats,
uint32_t format)
{
struct weston_drm_format *fmt;
wl_array_for_each(fmt, &formats->arr)
if (fmt->format == format)
return fmt;
return NULL;
}
/**
* Compare the content of two weston_drm_format_array
*
* @param formats_A One of the weston_drm_format_array to compare
* @param formats_B The other weston_drm_format_array to compare
* @return True if both sets are equivalent, false otherwise
*/
WL_EXPORT bool
weston_drm_format_array_equal(const struct weston_drm_format_array *formats_A,
const struct weston_drm_format_array *formats_B)
{
struct weston_drm_format *fmt_A, *fmt_B;
const uint64_t *modifiers_A;
unsigned num_modifiers_A, num_modifiers_B;
unsigned int i;
if (formats_A->arr.size != formats_B->arr.size)
return false;
wl_array_for_each(fmt_A, &formats_A->arr) {
fmt_B = weston_drm_format_array_find_format(formats_B,
fmt_A->format);
if (!fmt_B)
return false;
modifiers_A = weston_drm_format_get_modifiers(fmt_A, &num_modifiers_A);
weston_drm_format_get_modifiers(fmt_B, &num_modifiers_B);
if (num_modifiers_A != num_modifiers_B)
return false;
for (i = 0; i < num_modifiers_A; i++)
if (!weston_drm_format_has_modifier(fmt_B, modifiers_A[i]))
return false;
}
return true;
}
/**
* Joins two weston_drm_format_array, keeping the result in A
*
* @param formats_A The weston_drm_format_array that receives the formats from B
* @param formats_B The weston_drm_format_array whose formats are added to A
* @return 0 on success, -1 on failure
*/
WL_EXPORT int
weston_drm_format_array_join(struct weston_drm_format_array *formats_A,
const struct weston_drm_format_array *formats_B)
{
struct weston_drm_format *fmt_A, *fmt_B;
const uint64_t *modifiers;
unsigned int num_modifiers;
unsigned int i;
int ret;
wl_array_for_each(fmt_B, &formats_B->arr) {
fmt_A = weston_drm_format_array_find_format(formats_A,
fmt_B->format);
if (!fmt_A) {
fmt_A = weston_drm_format_array_add_format(formats_A,
fmt_B->format);
if (!fmt_A)
return -1;
}
modifiers = weston_drm_format_get_modifiers(fmt_B, &num_modifiers);
for (i = 0; i < num_modifiers; i++) {
if (weston_drm_format_has_modifier(fmt_A, modifiers[i]))
continue;
ret = weston_drm_format_add_modifier(fmt_A, modifiers[i]);
if (ret < 0)
return -1;
}
}
return 0;
}
static int
modifiers_intersect(const struct weston_drm_format *fmt_A,
const struct weston_drm_format *fmt_B,
struct wl_array *modifiers_result)
{
const uint64_t *modifiers;
unsigned int num_modifiers;
uint64_t *mod;
unsigned int i;
modifiers = weston_drm_format_get_modifiers(fmt_A, &num_modifiers);
for (i = 0; i < num_modifiers; i++) {
if (!weston_drm_format_has_modifier(fmt_B, modifiers[i]))
continue;
mod = wl_array_add(modifiers_result, sizeof(modifiers[i]));
if (!mod) {
weston_log("%s: out of memory\n", __func__);
return -1;
}
*mod = modifiers[i];
}
return 0;
}
/**
* Compute the intersection between two DRM-format arrays
*
* Callers are responsible for destroying the returned array.
*
* @param formats_A One of the weston_drm_format_array
* @param formats_B The other weston_drm_format_array
* @return Array with formats and modifiers that are present
* on both A and B, or NULL on failure
*/
WL_EXPORT struct weston_drm_format_array *
weston_drm_format_array_intersect(const struct weston_drm_format_array *formats_A,
const struct weston_drm_format_array *formats_B)
{
struct weston_drm_format_array *formats_result;
struct weston_drm_format *fmt_result, *fmt_A, *fmt_B;
int ret;
formats_result = weston_drm_format_array_create();
if (!formats_result)
return NULL;
wl_array_for_each(fmt_A, &formats_A->arr) {
fmt_B = weston_drm_format_array_find_format(formats_B,
fmt_A->format);
if (!fmt_B)
continue;
fmt_result = weston_drm_format_array_add_format(formats_result,
fmt_A->format);
if (!fmt_result)
goto err;
ret = modifiers_intersect(fmt_A, fmt_B, &fmt_result->modifiers);
if (ret < 0)
goto err;
if (fmt_result->modifiers.size == 0)
weston_drm_format_array_remove_latest_format(formats_result);
}
return formats_result;
err:
weston_drm_format_array_destroy(formats_result);
return NULL;
}
static int
modifiers_subtract(const struct weston_drm_format *fmt_A,
const struct weston_drm_format *fmt_B,
struct wl_array *modifiers_result)
{
const uint64_t *modifiers;
unsigned int num_modifiers;
uint64_t *mod;
unsigned int i;
modifiers = weston_drm_format_get_modifiers(fmt_A, &num_modifiers);
for (i = 0; i < num_modifiers; i++) {
if (weston_drm_format_has_modifier(fmt_B, modifiers[i]))
continue;
mod = wl_array_add(modifiers_result, sizeof(modifiers[i]));
if (!mod) {
weston_log("%s: out of memory\n", __func__);
return -1;
}
*mod = modifiers[i];
}
return 0;
}
/**
* Compute the subtraction between two DRM-format arrays, keeping the result in A
*
* @param formats_A The minuend weston_drm_format_array
* @param formats_B The subtrahend weston_drm_format_array
* @return 0 on success, -1 on failure
*/
WL_EXPORT int
weston_drm_format_array_subtract(struct weston_drm_format_array *formats_A,
const struct weston_drm_format_array *formats_B)
{
struct weston_drm_format_array *formats_result;
struct weston_drm_format *fmt_result, *fmt_A, *fmt_B;
int ret;
formats_result = weston_drm_format_array_create();
if (!formats_result)
return -1;
wl_array_for_each(fmt_A, &formats_A->arr) {
fmt_B = weston_drm_format_array_find_format(formats_B,
fmt_A->format);
if (!fmt_B) {
ret = add_format_and_modifiers(formats_result, fmt_A->format,
&fmt_A->modifiers);
if (ret < 0)
goto err;
continue;
}
fmt_result = weston_drm_format_array_add_format(formats_result,
fmt_A->format);
if (!fmt_result)
goto err;
ret = modifiers_subtract(fmt_A, fmt_B, &fmt_result->modifiers);
if (ret < 0)
goto err;
if (fmt_result->modifiers.size == 0)
weston_drm_format_array_remove_latest_format(formats_result);
}
ret = weston_drm_format_array_replace(formats_A, formats_result);
if (ret < 0)
goto err;
weston_drm_format_array_destroy(formats_result);
return 0;
err:
weston_drm_format_array_destroy(formats_result);
return -1;
}
/**
* Add modifier to modifier set of a weston_drm_format.
*
* Adding repeated modifiers is considered an error.
*
* @param format The weston_drm_format that owns the modifier set to which
* the modifier should be added
* @param modifier The modifier to add
* @return 0 on success, -1 on failure
*/
WL_EXPORT int
weston_drm_format_add_modifier(struct weston_drm_format *format,
uint64_t modifier)
{
uint64_t *mod;
/* We should not try to add repeated modifiers to a set. */
assert(!weston_drm_format_has_modifier(format, modifier));
mod = wl_array_add(&format->modifiers, sizeof(*mod));
if (!mod) {
weston_log("%s: out of memory\n", __func__);
return -1;
}
*mod = modifier;
return 0;
}
/**
* Check if modifier set of a weston_drm_format contains a certain modifier
*
* @param format The weston_drm_format that owns the modifier set where to
* look for the modifier
* @param modifier The modifier to look for
* @return True if modifier was found, false otherwise
*/
WL_EXPORT bool
weston_drm_format_has_modifier(const struct weston_drm_format *format,
uint64_t modifier)
{
const uint64_t *modifiers;
unsigned int num_modifiers;
unsigned int i;
modifiers = weston_drm_format_get_modifiers(format, &num_modifiers);
for (i = 0; i < num_modifiers; i++)
if (modifiers[i] == modifier)
return true;
return false;
}
/**
* Get array of modifiers and modifiers count from a weston_drm_format
*
* @param format The weston_drm_format that contains the modifiers
* @param count_out Parameter that receives the modifiers count
* @return The array of modifiers
*/
WL_EXPORT const uint64_t *
weston_drm_format_get_modifiers(const struct weston_drm_format *format,
unsigned int *count_out)
{
*count_out = format->modifiers.size / sizeof(uint64_t);
return format->modifiers.data;
}