You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
weston/tests/drm-formats-test.c

620 lines
26 KiB

/*
* 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"
#include "weston-test-client-helper.h"
#include "weston-test-fixture-compositor.h"
/* Add multiple formats to weston_drm_format_array and add the same set of
* modifiers to each format. */
#define ADD_FORMATS_AND_MODS(dest, formats, mods) \
do { \
unsigned int i; \
for (i = 0; i < ARRAY_LENGTH(formats); i++) \
format_array_add_format_and_modifiers(dest, (formats)[i], \
mods, ARRAY_LENGTH(mods)); \
} while (0)
/* Same as ADD_FORMATS_AND_MODS, but add the formats in reverse order. */
#define ADD_FORMATS_AND_MODS_REVERSE(dest, formats, mods) \
do { \
int i; \
for (i = ARRAY_LENGTH(formats) - 1; i >= 0; i--) \
format_array_add_format_and_modifiers(dest, (formats)[i], \
mods, ARRAY_LENGTH(mods)); \
} while (0)
static void
format_array_add_format_and_modifiers(struct weston_drm_format_array *formats,
uint32_t format, uint64_t *modifiers,
unsigned int num_modifiers)
{
struct weston_drm_format *fmt;
unsigned int i;
int ret;
fmt = weston_drm_format_array_add_format(formats, format);
assert(fmt);
for (i = 0; i < num_modifiers; i++) {
ret = weston_drm_format_add_modifier(fmt, modifiers[i]);
assert(ret == 0);
}
}
TEST(basic_operations)
{
struct weston_drm_format_array *format_array;
struct weston_drm_format *fmt;
uint32_t formats[] = {1, 2, 3, 4, 5};
uint64_t modifiers[] = {11, 12, 13, 14, 15};
unsigned int i, j;
format_array = weston_drm_format_array_create();
assert(format_array);
ADD_FORMATS_AND_MODS(format_array, formats, modifiers);
for (i = 0; i < ARRAY_LENGTH(formats); i++) {
fmt = weston_drm_format_array_find_format(format_array, formats[i]);
assert(fmt && fmt->format == formats[i]);
for (j = 0; j < ARRAY_LENGTH(modifiers); j++)
assert(weston_drm_format_has_modifier(fmt, modifiers[j]));
}
weston_drm_format_array_destroy(format_array);
}
TEST(compare_arrays_same_content)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
uint32_t formats[] = {1, 2, 3, 4, 5};
uint64_t modifiers[] = {11, 12, 13, 14, 15};
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
/* Both are empty arrays, so they have the same content. */
assert(weston_drm_format_array_equal(format_array_A, format_array_B));
/* Test non-empty arrays with same content. */
ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
ADD_FORMATS_AND_MODS(format_array_B, formats, modifiers);
assert(weston_drm_format_array_equal(format_array_A, format_array_B));
/* Test non-empty arrays with same content, but add elements to B in
* reverse order. This is important as in the future we may keep
* DRM-format arrays ordered to improve performance. */
weston_drm_format_array_fini(format_array_B);
weston_drm_format_array_init(format_array_B);
ADD_FORMATS_AND_MODS_REVERSE(format_array_B, formats, modifiers);
assert(weston_drm_format_array_equal(format_array_A, format_array_B));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
}
TEST(compare_arrays_exclusive_content)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
uint32_t formats_A[] = {1, 2, 3, 4, 5};
uint32_t formats_B[] = {6, 7, 8, 9, 10};
uint64_t modifiers_A[] = {11, 12, 13, 14, 15};
uint64_t modifiers_B[] = {16, 17, 18, 19, 20};
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
/* Arrays with formats that are mutually exclusive. */
ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
assert(!weston_drm_format_array_equal(format_array_A, format_array_B));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
}
TEST(replace_array)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
uint32_t formats[] = {1, 2, 3, 4, 5};
uint64_t modifiers[] = {11, 12, 13, 14, 15};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
/* Replace content of B with the content of A, so they should
* have the same content. */
ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
ret = weston_drm_format_array_replace(format_array_B, format_array_A);
assert(ret == 0);
assert(weston_drm_format_array_equal(format_array_A, format_array_B));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
}
TEST(remove_from_array)
{
struct weston_drm_format_array *format_array_A, *format_array_B, *format_array_C;
uint32_t formats_A[] = {1, 2, 3, 4, 5};
uint32_t formats_B[] = {1, 2, 3, 4};
uint32_t formats_C[] = {1, 2, 3, 4, 6};
uint64_t modifiers[] = {11, 12, 13, 14, 15};
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
format_array_C = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
assert(format_array_C);
/* After removing latest added format from array A, it should
* be equal to B. */
ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers);
ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers);
weston_drm_format_array_remove_latest_format(format_array_A);
assert(weston_drm_format_array_equal(format_array_A, format_array_B));
/* Add 6 to the format array A, so it should be equal to C. */
ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){6}, modifiers);
ADD_FORMATS_AND_MODS(format_array_C, formats_C, modifiers);
assert(weston_drm_format_array_equal(format_array_A, format_array_C));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_C);
}
TEST(join_arrays)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
struct weston_drm_format_array *format_array_C;
uint32_t formats_A[] = {1, 2, 6, 9, 10};
uint32_t formats_B[] = {2, 5, 7, 9, 10};
uint64_t modifiers_A[] = {1, 2, 3, 4, 7};
uint64_t modifiers_B[] = {0, 2, 3, 5, 6};
uint64_t modifiers_join[] = {0, 1, 2, 3, 4, 5, 6, 7};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
format_array_C = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
assert(format_array_C);
ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
ret = weston_drm_format_array_join(format_array_A, format_array_B);
assert(ret == 0);
/* The result of the joint (which is saved in A) should have
* the same content as C. */
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){1}, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){2}, modifiers_join);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){5}, modifiers_B);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){6}, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){7}, modifiers_B);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){9}, modifiers_join);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){10}, modifiers_join);
assert(weston_drm_format_array_equal(format_array_A, format_array_C));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_C);
}
TEST(join_arrays_same_content)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
uint32_t formats[] = {1, 2, 3, 4, 5};
uint64_t modifiers[] = {11, 12, 13, 14, 15};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
/* Joint of empty arrays must be empty. */
ret = weston_drm_format_array_join(format_array_A, format_array_B);
assert(ret == 0);
assert(format_array_A->arr.size == 0);
/* Join B, which is empty, with A, which is non-empty. The joint (which
* is saved in B) should have the same content as A. */
ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
ret = weston_drm_format_array_join(format_array_B, format_array_A);
assert(ret == 0);
assert(weston_drm_format_array_equal(format_array_A, format_array_B));
/* Now A and B are non-empty and have the same content. The joint (which
* is saved in A) should not change its content. */
ret = weston_drm_format_array_join(format_array_A, format_array_B);
assert(ret == 0);
assert(weston_drm_format_array_equal(format_array_A, format_array_B));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
}
TEST(join_arrays_exclusive_content)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
struct weston_drm_format_array *format_array_C;
uint32_t formats_A[] = {1, 2, 3, 4, 5};
uint32_t formats_B[] = {6, 7, 8, 9, 10};
uint32_t formats_C[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
uint64_t modifiers[] = {11, 12, 13, 14, 15};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
format_array_C = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
assert(format_array_C);
/* The joint of DRM-format arrays A and B should be equal to C. */
ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers);
ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers);
ADD_FORMATS_AND_MODS(format_array_C, formats_C, modifiers);
ret = weston_drm_format_array_join(format_array_A, format_array_B);
assert(ret == 0);
assert(weston_drm_format_array_equal(format_array_A, format_array_C));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_C);
}
TEST(join_arrays_modifier_invalid)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
struct weston_drm_format_array *format_array_C;
uint64_t regular_modifiers[] = {1, 2, 3, 4, 5};
uint64_t modifier_invalid[] = {DRM_FORMAT_MOD_INVALID};
uint64_t regular_modifiers_plus_invalid[] = {1, 2, 3, 4, 5, DRM_FORMAT_MOD_INVALID};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
format_array_C = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
assert(format_array_C);
/* DRM-format array A has only one format with MOD_INVALID, and B has
* the same format but with a regular set of formats. The joint should
* contain both MOD_INVALID and the regular modifiers. */
ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifier_invalid);
ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, regular_modifiers);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){1}, regular_modifiers_plus_invalid);
ret = weston_drm_format_array_join(format_array_A, format_array_B);
assert(ret == 0);
assert(weston_drm_format_array_equal(format_array_A, format_array_C));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_C);
}
TEST(intersect_arrays)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
struct weston_drm_format_array *format_array_C, *format_array_result;
uint32_t formats_A[] = {1, 2, 6, 9, 10};
uint32_t formats_B[] = {2, 5, 7, 9, 10};
uint64_t modifiers_A[] = {1, 2, 3, 4, 7};
uint64_t modifiers_B[] = {0, 2, 3, 5, 6};
uint64_t modifiers_intersect[] = {2, 3};
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
format_array_C = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
assert(format_array_C);
ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
format_array_result = weston_drm_format_array_intersect(format_array_A,
format_array_B);
assert(format_array_result);
/* The result of the intersection should have the same content as C. */
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){2}, modifiers_intersect);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){9}, modifiers_intersect);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){10}, modifiers_intersect);
assert(weston_drm_format_array_equal(format_array_result, format_array_C));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_C);
weston_drm_format_array_destroy(format_array_result);
}
TEST(intersect_arrays_same_content)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
struct weston_drm_format_array *format_array_result;
uint32_t formats[] = {1, 2, 3, 4, 5};
uint64_t modifiers[] = {11, 12, 13, 14, 15};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
/* The intersection between two empty arrays must be an
* empty array. */
format_array_result = weston_drm_format_array_intersect(format_array_A,
format_array_B);
assert(format_array_result);
assert(format_array_result->arr.size == 0);
tests: fix leaks in drm-formats-test 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: Leandro Ribeiro <leandro.ribeiro@collabora.com>
4 years ago
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. */
ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
ret = weston_drm_format_array_replace(format_array_B, format_array_A);
assert(ret == 0);
format_array_result = weston_drm_format_array_intersect(format_array_A,
format_array_B);
assert(format_array_result);
assert(weston_drm_format_array_equal(format_array_result,
format_array_A));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_result);
}
TEST(intersect_arrays_exclusive_formats)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
struct weston_drm_format_array *format_array_result;
uint64_t formats_A[] = {1, 2, 3, 4, 5};
uint64_t formats_B[] = {6, 7, 8, 9, 10};
uint64_t modifiers[] = {11, 12, 13, 14, 15};
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
/* DRM-format arrays A and B have formats that are mutually exclusive,
* so the intersection must be empty. */
ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers);
ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers);
format_array_result = weston_drm_format_array_intersect(format_array_A,
format_array_B);
assert(format_array_result);
assert(format_array_result->arr.size == 0);
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_result);
}
TEST(intersect_arrays_exclusive_modifiers)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
struct weston_drm_format_array *format_array_result;
uint64_t modifiers_A[] = {1, 2, 3, 4, 5};
uint64_t modifiers_B[] = {6, 7, 8, 9, 10};
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
/* Both DRM-format arrays A and B have the same format but with modifier
* sets that are mutually exclusive. The intersection between mutually
* exclusive modifier must be empty, and so the format should not be
* added to the array. So the array must also be empty. */
ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, modifiers_B);
format_array_result = weston_drm_format_array_intersect(format_array_A,
format_array_B);
assert(format_array_result);
assert(format_array_result->arr.size == 0);
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_result);
}
TEST(subtract_arrays)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
struct weston_drm_format_array *format_array_C;
uint32_t formats_A[] = {1, 2, 6, 9, 10};
uint32_t formats_B[] = {2, 5, 7, 9, 10};
uint64_t modifiers_A[] = {1, 2, 3, 4, 7};
uint64_t modifiers_B[] = {0, 2, 3, 5, 6};
uint64_t modifiers_subtract[] = {1, 4, 7};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
format_array_C = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
assert(format_array_C);
ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
assert(ret == 0);
/* The result of the subtraction (which is saved in A) should have
* the same content as C. */
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){1}, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){2}, modifiers_subtract);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){6}, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){9}, modifiers_subtract);
ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){10}, modifiers_subtract);
assert(weston_drm_format_array_equal(format_array_A, format_array_C));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_C);
}
TEST(subtract_arrays_same_content)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
uint32_t formats[] = {1, 2, 3, 4, 5};
uint64_t modifiers[] = {11, 12, 13, 14, 15};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
/* Minuend and subtrahend have the same content. The subtraction
* (which is saved in A) should be an empty array. */
ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
ret = weston_drm_format_array_replace(format_array_B, format_array_A);
assert(ret == 0);
ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
assert(ret == 0);
assert(format_array_A->arr.size == 0);
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
}
TEST(subtract_arrays_exclusive_formats)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
struct weston_drm_format_array *format_array_C;
uint32_t formats_A[] = {1, 2, 3, 4, 5};
uint32_t formats_B[] = {6, 7, 8, 9, 10};
uint64_t modifiers[] = {11, 12, 13, 14, 15};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
format_array_C = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
assert(format_array_C);
/* Minuend and subtrahend have mutually exclusive formats. The
* subtraction (which is saved in A) should be equal the minuend. */
ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers);
ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers);
ret = weston_drm_format_array_replace(format_array_C, format_array_A);
assert(ret == 0);
ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
assert(ret == 0);
assert(weston_drm_format_array_equal(format_array_A, format_array_C));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_C);
}
TEST(subtract_arrays_exclusive_modifiers)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
struct weston_drm_format_array *format_array_C;
uint64_t modifiers_A[] = {1, 2, 3, 4, 5};
uint64_t modifiers_B[] = {6, 7, 8, 9, 10};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
format_array_C = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
assert(format_array_C);
/* Minuend and subtrahend have the same format but with modifiers that
* are mutually exclusive. The subtraction (which is saved in A) should
* contain the format and the modifier set of the minuend. */
ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifiers_A);
ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, modifiers_B);
ret = weston_drm_format_array_replace(format_array_C, format_array_A);
assert(ret == 0);
ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
assert(ret == 0);
assert(weston_drm_format_array_equal(format_array_A, format_array_C));
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
weston_drm_format_array_destroy(format_array_C);
}
TEST(subtract_arrays_modifier_invalid)
{
struct weston_drm_format_array *format_array_A, *format_array_B;
uint64_t modifier_invalid[] = {DRM_FORMAT_MOD_INVALID};
uint64_t regular_modifiers_plus_invalid[] = {1, 2, 3, 4, 5, DRM_FORMAT_MOD_INVALID};
int ret;
format_array_A = weston_drm_format_array_create();
format_array_B = weston_drm_format_array_create();
assert(format_array_A);
assert(format_array_B);
/* The minuend has a format with modifier set that contains MOD_INVALID
* and the subtrahend contains the same format but with a regular set of
* modifiers + MOD_INVALID. So the subtraction between the modifiers
* sets results in empty, and so the format should not be included to
* the result. As it is the only format in the minuend, the resulting
* array must be empty. */
ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifier_invalid);
ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, regular_modifiers_plus_invalid);
ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
assert(ret == 0);
assert(format_array_A->arr.size == 0);
weston_drm_format_array_destroy(format_array_A);
weston_drm_format_array_destroy(format_array_B);
}