blob: c7dbf8b1efbb73aa9b2f255ed6943d5da14fe112 [file] [log] [blame]
Leandro Ribeiro859e3f22021-03-15 17:48:45 -03001/*
2 * Copyright © 2021 Collabora, Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26#include "config.h"
27
28#include <assert.h>
29
30#include <libweston/libweston.h>
31#include <libweston-internal.h>
32#include "shared/weston-drm-fourcc.h"
33
34#include "weston-test-client-helper.h"
35#include "weston-test-fixture-compositor.h"
36
37/* Add multiple formats to weston_drm_format_array and add the same set of
38 * modifiers to each format. */
39#define ADD_FORMATS_AND_MODS(dest, formats, mods) \
40do { \
41 unsigned int i; \
42 for (i = 0; i < ARRAY_LENGTH(formats); i++) \
43 format_array_add_format_and_modifiers(dest, (formats)[i], \
44 mods, ARRAY_LENGTH(mods)); \
45} while (0)
46
47/* Same as ADD_FORMATS_AND_MODS, but add the formats in reverse order. */
48#define ADD_FORMATS_AND_MODS_REVERSE(dest, formats, mods) \
49do { \
50 int i; \
51 for (i = ARRAY_LENGTH(formats) - 1; i >= 0; i--) \
52 format_array_add_format_and_modifiers(dest, (formats)[i], \
53 mods, ARRAY_LENGTH(mods)); \
54} while (0)
55
56static void
57format_array_add_format_and_modifiers(struct weston_drm_format_array *formats,
58 uint32_t format, uint64_t *modifiers,
59 unsigned int num_modifiers)
60{
61 struct weston_drm_format *fmt;
62 unsigned int i;
63 int ret;
64
65 fmt = weston_drm_format_array_add_format(formats, format);
66 assert(fmt);
67
68 for (i = 0; i < num_modifiers; i++) {
69 ret = weston_drm_format_add_modifier(fmt, modifiers[i]);
70 assert(ret == 0);
71 }
72}
73
74TEST(basic_operations)
75{
76 struct weston_drm_format_array *format_array;
77 struct weston_drm_format *fmt;
78 uint32_t formats[] = {1, 2, 3, 4, 5};
79 uint64_t modifiers[] = {11, 12, 13, 14, 15};
80 unsigned int i, j;
81
82 format_array = weston_drm_format_array_create();
83 assert(format_array);
84
85 ADD_FORMATS_AND_MODS(format_array, formats, modifiers);
86
87 for (i = 0; i < ARRAY_LENGTH(formats); i++) {
88 fmt = weston_drm_format_array_find_format(format_array, formats[i]);
89 assert(fmt && fmt->format == formats[i]);
90 for (j = 0; j < ARRAY_LENGTH(modifiers); j++)
91 assert(weston_drm_format_has_modifier(fmt, modifiers[j]));
92 }
93
94 weston_drm_format_array_destroy(format_array);
95}
96
97TEST(compare_arrays_same_content)
98{
99 struct weston_drm_format_array *format_array_A, *format_array_B;
100 uint32_t formats[] = {1, 2, 3, 4, 5};
101 uint64_t modifiers[] = {11, 12, 13, 14, 15};
102
103 format_array_A = weston_drm_format_array_create();
104 format_array_B = weston_drm_format_array_create();
105 assert(format_array_A);
106 assert(format_array_B);
107
108 /* Both are empty arrays, so they have the same content. */
109 assert(weston_drm_format_array_equal(format_array_A, format_array_B));
110
111 /* Test non-empty arrays with same content. */
112 ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
113 ADD_FORMATS_AND_MODS(format_array_B, formats, modifiers);
114 assert(weston_drm_format_array_equal(format_array_A, format_array_B));
115
116 /* Test non-empty arrays with same content, but add elements to B in
117 * reverse order. This is important as in the future we may keep
118 * DRM-format arrays ordered to improve performance. */
119 weston_drm_format_array_fini(format_array_B);
120 weston_drm_format_array_init(format_array_B);
121 ADD_FORMATS_AND_MODS_REVERSE(format_array_B, formats, modifiers);
122 assert(weston_drm_format_array_equal(format_array_A, format_array_B));
123
124 weston_drm_format_array_destroy(format_array_A);
125 weston_drm_format_array_destroy(format_array_B);
126}
127
128TEST(compare_arrays_exclusive_content)
129{
130 struct weston_drm_format_array *format_array_A, *format_array_B;
131 uint32_t formats_A[] = {1, 2, 3, 4, 5};
132 uint32_t formats_B[] = {6, 7, 8, 9, 10};
133 uint64_t modifiers_A[] = {11, 12, 13, 14, 15};
134 uint64_t modifiers_B[] = {16, 17, 18, 19, 20};
135
136 format_array_A = weston_drm_format_array_create();
137 format_array_B = weston_drm_format_array_create();
138 assert(format_array_A);
139 assert(format_array_B);
140
141 /* Arrays with formats that are mutually exclusive. */
142 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
143 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
144 assert(!weston_drm_format_array_equal(format_array_A, format_array_B));
145
146 weston_drm_format_array_destroy(format_array_A);
147 weston_drm_format_array_destroy(format_array_B);
148}
149
150TEST(replace_array)
151{
152 struct weston_drm_format_array *format_array_A, *format_array_B;
153 uint32_t formats[] = {1, 2, 3, 4, 5};
154 uint64_t modifiers[] = {11, 12, 13, 14, 15};
155 int ret;
156
157 format_array_A = weston_drm_format_array_create();
158 format_array_B = weston_drm_format_array_create();
159 assert(format_array_A);
160 assert(format_array_B);
161
162 /* Replace content of B with the content of A, so they should
163 * have the same content. */
164 ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
165 ret = weston_drm_format_array_replace(format_array_B, format_array_A);
166 assert(ret == 0);
167 assert(weston_drm_format_array_equal(format_array_A, format_array_B));
168
169 weston_drm_format_array_destroy(format_array_A);
170 weston_drm_format_array_destroy(format_array_B);
171}
172
173TEST(remove_from_array)
174{
175 struct weston_drm_format_array *format_array_A, *format_array_B, *format_array_C;
176 uint32_t formats_A[] = {1, 2, 3, 4, 5};
177 uint32_t formats_B[] = {1, 2, 3, 4};
178 uint32_t formats_C[] = {1, 2, 3, 4, 6};
179 uint64_t modifiers[] = {11, 12, 13, 14, 15};
180
181 format_array_A = weston_drm_format_array_create();
182 format_array_B = weston_drm_format_array_create();
183 format_array_C = weston_drm_format_array_create();
184 assert(format_array_A);
185 assert(format_array_B);
186 assert(format_array_C);
187
188 /* After removing latest added format from array A, it should
189 * be equal to B. */
190 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers);
191 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers);
192 weston_drm_format_array_remove_latest_format(format_array_A);
193 assert(weston_drm_format_array_equal(format_array_A, format_array_B));
194
195 /* Add 6 to the format array A, so it should be equal to C. */
196 ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){6}, modifiers);
197 ADD_FORMATS_AND_MODS(format_array_C, formats_C, modifiers);
198 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
199
200 weston_drm_format_array_destroy(format_array_A);
201 weston_drm_format_array_destroy(format_array_B);
202 weston_drm_format_array_destroy(format_array_C);
203}
204
205TEST(join_arrays)
206{
207 struct weston_drm_format_array *format_array_A, *format_array_B;
208 struct weston_drm_format_array *format_array_C;
209 uint32_t formats_A[] = {1, 2, 6, 9, 10};
210 uint32_t formats_B[] = {2, 5, 7, 9, 10};
211 uint64_t modifiers_A[] = {1, 2, 3, 4, 7};
212 uint64_t modifiers_B[] = {0, 2, 3, 5, 6};
213 uint64_t modifiers_join[] = {0, 1, 2, 3, 4, 5, 6, 7};
214 int ret;
215
216 format_array_A = weston_drm_format_array_create();
217 format_array_B = weston_drm_format_array_create();
218 format_array_C = weston_drm_format_array_create();
219 assert(format_array_A);
220 assert(format_array_B);
221 assert(format_array_C);
222
223 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
224 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
225 ret = weston_drm_format_array_join(format_array_A, format_array_B);
226 assert(ret == 0);
227
228 /* The result of the joint (which is saved in A) should have
229 * the same content as C. */
230 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){1}, modifiers_A);
231 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){2}, modifiers_join);
232 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){5}, modifiers_B);
233 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){6}, modifiers_A);
234 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){7}, modifiers_B);
235 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){9}, modifiers_join);
236 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){10}, modifiers_join);
237 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
238
239 weston_drm_format_array_destroy(format_array_A);
240 weston_drm_format_array_destroy(format_array_B);
241 weston_drm_format_array_destroy(format_array_C);
242}
243
244TEST(join_arrays_same_content)
245{
246 struct weston_drm_format_array *format_array_A, *format_array_B;
247 uint32_t formats[] = {1, 2, 3, 4, 5};
248 uint64_t modifiers[] = {11, 12, 13, 14, 15};
249 int ret;
250
251 format_array_A = weston_drm_format_array_create();
252 format_array_B = weston_drm_format_array_create();
253 assert(format_array_A);
254 assert(format_array_B);
255
256 /* Joint of empty arrays must be empty. */
257 ret = weston_drm_format_array_join(format_array_A, format_array_B);
258 assert(ret == 0);
259 assert(format_array_A->arr.size == 0);
260
261 /* Join B, which is empty, with A, which is non-empty. The joint (which
262 * is saved in B) should have the same content as A. */
263 ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
264 ret = weston_drm_format_array_join(format_array_B, format_array_A);
265 assert(ret == 0);
266 assert(weston_drm_format_array_equal(format_array_A, format_array_B));
267
268 /* Now A and B are non-empty and have the same content. The joint (which
269 * is saved in A) should not change its content. */
270 ret = weston_drm_format_array_join(format_array_A, format_array_B);
271 assert(ret == 0);
272 assert(weston_drm_format_array_equal(format_array_A, format_array_B));
273
274 weston_drm_format_array_destroy(format_array_A);
275 weston_drm_format_array_destroy(format_array_B);
276}
277
278TEST(join_arrays_exclusive_content)
279{
280 struct weston_drm_format_array *format_array_A, *format_array_B;
281 struct weston_drm_format_array *format_array_C;
282 uint32_t formats_A[] = {1, 2, 3, 4, 5};
283 uint32_t formats_B[] = {6, 7, 8, 9, 10};
284 uint32_t formats_C[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
285 uint64_t modifiers[] = {11, 12, 13, 14, 15};
286 int ret;
287
288 format_array_A = weston_drm_format_array_create();
289 format_array_B = weston_drm_format_array_create();
290 format_array_C = weston_drm_format_array_create();
291 assert(format_array_A);
292 assert(format_array_B);
293 assert(format_array_C);
294
295 /* The joint of DRM-format arrays A and B should be equal to C. */
296 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers);
297 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers);
298 ADD_FORMATS_AND_MODS(format_array_C, formats_C, modifiers);
299 ret = weston_drm_format_array_join(format_array_A, format_array_B);
300 assert(ret == 0);
301 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
302
303 weston_drm_format_array_destroy(format_array_A);
304 weston_drm_format_array_destroy(format_array_B);
305 weston_drm_format_array_destroy(format_array_C);
306}
307
308TEST(join_arrays_modifier_invalid)
309{
310 struct weston_drm_format_array *format_array_A, *format_array_B;
311 struct weston_drm_format_array *format_array_C;
312 uint64_t regular_modifiers[] = {1, 2, 3, 4, 5};
313 uint64_t modifier_invalid[] = {DRM_FORMAT_MOD_INVALID};
314 uint64_t regular_modifiers_plus_invalid[] = {1, 2, 3, 4, 5, DRM_FORMAT_MOD_INVALID};
315 int ret;
316
317 format_array_A = weston_drm_format_array_create();
318 format_array_B = weston_drm_format_array_create();
319 format_array_C = weston_drm_format_array_create();
320 assert(format_array_A);
321 assert(format_array_B);
322 assert(format_array_C);
323
324 /* DRM-format array A has only one format with MOD_INVALID, and B has
325 * the same format but with a regular set of formats. The joint should
326 * contain both MOD_INVALID and the regular modifiers. */
327 ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifier_invalid);
328 ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, regular_modifiers);
329 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){1}, regular_modifiers_plus_invalid);
330 ret = weston_drm_format_array_join(format_array_A, format_array_B);
331 assert(ret == 0);
332 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
333
334 weston_drm_format_array_destroy(format_array_A);
335 weston_drm_format_array_destroy(format_array_B);
336 weston_drm_format_array_destroy(format_array_C);
337}
338
339TEST(intersect_arrays)
340{
341 struct weston_drm_format_array *format_array_A, *format_array_B;
342 struct weston_drm_format_array *format_array_C, *format_array_result;
343 uint32_t formats_A[] = {1, 2, 6, 9, 10};
344 uint32_t formats_B[] = {2, 5, 7, 9, 10};
345 uint64_t modifiers_A[] = {1, 2, 3, 4, 7};
346 uint64_t modifiers_B[] = {0, 2, 3, 5, 6};
347 uint64_t modifiers_intersect[] = {2, 3};
348
349 format_array_A = weston_drm_format_array_create();
350 format_array_B = weston_drm_format_array_create();
351 format_array_C = weston_drm_format_array_create();
352 format_array_result = weston_drm_format_array_create();
353 assert(format_array_A);
354 assert(format_array_B);
355 assert(format_array_C);
356 assert(format_array_result);
357
358 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
359 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
360 format_array_result = weston_drm_format_array_intersect(format_array_A,
361 format_array_B);
362 assert(format_array_result);
363
364 /* The result of the intersection should have the same content as C. */
365 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){2}, modifiers_intersect);
366 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){9}, modifiers_intersect);
367 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){10}, modifiers_intersect);
368 assert(weston_drm_format_array_equal(format_array_result, format_array_C));
369
370 weston_drm_format_array_destroy(format_array_A);
371 weston_drm_format_array_destroy(format_array_B);
372 weston_drm_format_array_destroy(format_array_C);
373 weston_drm_format_array_destroy(format_array_result);
374}
375
376TEST(intersect_arrays_same_content)
377{
378 struct weston_drm_format_array *format_array_A, *format_array_B;
379 struct weston_drm_format_array *format_array_result;
380 uint32_t formats[] = {1, 2, 3, 4, 5};
381 uint64_t modifiers[] = {11, 12, 13, 14, 15};
382 int ret;
383
384 format_array_A = weston_drm_format_array_create();
385 format_array_B = weston_drm_format_array_create();
386 assert(format_array_A);
387 assert(format_array_B);
388
389 /* The intersection between two empty arrays must be an
390 * empty array. */
391 format_array_result = weston_drm_format_array_intersect(format_array_A,
392 format_array_B);
393 assert(format_array_result);
394 assert(format_array_result->arr.size == 0);
395
396 weston_drm_format_array_fini(format_array_result);
397
398 /* DRM-format arrays A and B have the same content, so the intersection
399 * should be equal to them. */
400 ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
401 ret = weston_drm_format_array_replace(format_array_B, format_array_A);
402 assert(ret == 0);
403 format_array_result = weston_drm_format_array_intersect(format_array_A,
404 format_array_B);
405 assert(format_array_result);
406 assert(weston_drm_format_array_equal(format_array_result,
407 format_array_A));
408
409 weston_drm_format_array_destroy(format_array_A);
410 weston_drm_format_array_destroy(format_array_B);
411 weston_drm_format_array_destroy(format_array_result);
412}
413
414TEST(intersect_arrays_exclusive_formats)
415{
416 struct weston_drm_format_array *format_array_A, *format_array_B;
417 struct weston_drm_format_array *format_array_result;
418 uint64_t formats_A[] = {1, 2, 3, 4, 5};
419 uint64_t formats_B[] = {6, 7, 8, 9, 10};
420 uint64_t modifiers[] = {11, 12, 13, 14, 15};
421
422 format_array_A = weston_drm_format_array_create();
423 format_array_B = weston_drm_format_array_create();
424 assert(format_array_A);
425 assert(format_array_B);
426
427 /* DRM-format arrays A and B have formats that are mutually exclusive,
428 * so the intersection must be empty. */
429 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers);
430 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers);
431 format_array_result = weston_drm_format_array_intersect(format_array_A,
432 format_array_B);
433 assert(format_array_result);
434 assert(format_array_result->arr.size == 0);
435
436 weston_drm_format_array_destroy(format_array_A);
437 weston_drm_format_array_destroy(format_array_B);
438 weston_drm_format_array_destroy(format_array_result);
439}
440
441TEST(intersect_arrays_exclusive_modifiers)
442{
443 struct weston_drm_format_array *format_array_A, *format_array_B;
444 struct weston_drm_format_array *format_array_result;
445 uint64_t modifiers_A[] = {1, 2, 3, 4, 5};
446 uint64_t modifiers_B[] = {6, 7, 8, 9, 10};
447
448 format_array_A = weston_drm_format_array_create();
449 format_array_B = weston_drm_format_array_create();
450 assert(format_array_A);
451 assert(format_array_B);
452
453 /* Both DRM-format arrays A and B have the same format but with modifier
454 * sets that are mutually exclusive. The intersection between mutually
455 * exclusive modifier must be empty, and so the format should not be
456 * added to the array. So the array must also be empty. */
457 ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifiers_A);
458 ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, modifiers_B);
459 format_array_result = weston_drm_format_array_intersect(format_array_A,
460 format_array_B);
461 assert(format_array_result);
462 assert(format_array_result->arr.size == 0);
463
464 weston_drm_format_array_destroy(format_array_A);
465 weston_drm_format_array_destroy(format_array_B);
466 weston_drm_format_array_destroy(format_array_result);
467}
468
469TEST(subtract_arrays)
470{
471 struct weston_drm_format_array *format_array_A, *format_array_B;
472 struct weston_drm_format_array *format_array_C;
473 uint32_t formats_A[] = {1, 2, 6, 9, 10};
474 uint32_t formats_B[] = {2, 5, 7, 9, 10};
475 uint64_t modifiers_A[] = {1, 2, 3, 4, 7};
476 uint64_t modifiers_B[] = {0, 2, 3, 5, 6};
477 uint64_t modifiers_subtract[] = {1, 4, 7};
478 int ret;
479
480 format_array_A = weston_drm_format_array_create();
481 format_array_B = weston_drm_format_array_create();
482 format_array_C = weston_drm_format_array_create();
483 assert(format_array_A);
484 assert(format_array_B);
485 assert(format_array_C);
486
487 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
488 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
489 ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
490 assert(ret == 0);
491
492 /* The result of the subtraction (which is saved in A) should have
493 * the same content as C. */
494 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){1}, modifiers_A);
495 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){2}, modifiers_subtract);
496 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){6}, modifiers_A);
497 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){9}, modifiers_subtract);
498 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){10}, modifiers_subtract);
499 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
500
501 weston_drm_format_array_destroy(format_array_A);
502 weston_drm_format_array_destroy(format_array_B);
503 weston_drm_format_array_destroy(format_array_C);
504}
505
506TEST(subtract_arrays_same_content)
507{
508 struct weston_drm_format_array *format_array_A, *format_array_B;
509 uint32_t formats[] = {1, 2, 3, 4, 5};
510 uint64_t modifiers[] = {11, 12, 13, 14, 15};
511 int ret;
512
513 format_array_A = weston_drm_format_array_create();
514 format_array_B = weston_drm_format_array_create();
515 assert(format_array_A);
516 assert(format_array_B);
517
518 /* Minuend and subtrahend have the same content. The subtraction
519 * (which is saved in A) should be an empty array. */
520 ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
521 ret = weston_drm_format_array_replace(format_array_B, format_array_A);
522 assert(ret == 0);
523 ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
524 assert(ret == 0);
525 assert(format_array_A->arr.size == 0);
526
527 weston_drm_format_array_destroy(format_array_A);
528 weston_drm_format_array_destroy(format_array_B);
529}
530
531TEST(subtract_arrays_exclusive_formats)
532{
533 struct weston_drm_format_array *format_array_A, *format_array_B;
534 struct weston_drm_format_array *format_array_C;
535 uint32_t formats_A[] = {1, 2, 3, 4, 5};
536 uint32_t formats_B[] = {6, 7, 8, 9, 10};
537 uint64_t modifiers[] = {11, 12, 13, 14, 15};
538 int ret;
539
540 format_array_A = weston_drm_format_array_create();
541 format_array_B = weston_drm_format_array_create();
542 format_array_C = weston_drm_format_array_create();
543 assert(format_array_A);
544 assert(format_array_B);
545 assert(format_array_C);
546
547 /* Minuend and subtrahend have mutually exclusive formats. The
548 * subtraction (which is saved in A) should be equal the minuend. */
549 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers);
550 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers);
551 ret = weston_drm_format_array_replace(format_array_C, format_array_A);
552 assert(ret == 0);
553
554 ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
555 assert(ret == 0);
556 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
557
558 weston_drm_format_array_destroy(format_array_A);
559 weston_drm_format_array_destroy(format_array_B);
560 weston_drm_format_array_destroy(format_array_C);
561}
562
563TEST(subtract_arrays_exclusive_modifiers)
564{
565 struct weston_drm_format_array *format_array_A, *format_array_B;
566 struct weston_drm_format_array *format_array_C;
567 uint64_t modifiers_A[] = {1, 2, 3, 4, 5};
568 uint64_t modifiers_B[] = {6, 7, 8, 9, 10};
569 int ret;
570
571 format_array_A = weston_drm_format_array_create();
572 format_array_B = weston_drm_format_array_create();
573 format_array_C = weston_drm_format_array_create();
574 assert(format_array_A);
575 assert(format_array_B);
576 assert(format_array_C);
577
578 /* Minuend and subtrahend have the same format but with modifiers that
579 * are mutually exclusive. The subtraction (which is saved in A) should
580 * contain the format and the modifier set of the minuend. */
581 ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifiers_A);
582 ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, modifiers_B);
583 ret = weston_drm_format_array_replace(format_array_C, format_array_A);
584 assert(ret == 0);
585
586 ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
587 assert(ret == 0);
588 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
589
590 weston_drm_format_array_destroy(format_array_A);
591 weston_drm_format_array_destroy(format_array_B);
592 weston_drm_format_array_destroy(format_array_C);
593}
594
595TEST(subtract_arrays_modifier_invalid)
596{
597 struct weston_drm_format_array *format_array_A, *format_array_B;
598 uint64_t modifier_invalid[] = {DRM_FORMAT_MOD_INVALID};
599 uint64_t regular_modifiers_plus_invalid[] = {1, 2, 3, 4, 5, DRM_FORMAT_MOD_INVALID};
600 int ret;
601
602 format_array_A = weston_drm_format_array_create();
603 format_array_B = weston_drm_format_array_create();
604 assert(format_array_A);
605 assert(format_array_B);
606
607 /* The minuend has a format with modifier set that contains MOD_INVALID
608 * and the subtrahend contains the same format but with a regular set of
609 * modifiers + MOD_INVALID. So the subtraction between the modifiers
610 * sets results in empty, and so the format should not be included to
611 * the result. As it is the only format in the minuend, the resulting
612 * array must be empty. */
613 ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifier_invalid);
614 ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, regular_modifiers_plus_invalid);
615 ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
616 assert(ret == 0);
617 assert(format_array_A->arr.size == 0);
618
619 weston_drm_format_array_destroy(format_array_A);
620 weston_drm_format_array_destroy(format_array_B);
621}