blob: e0ab378da0643c3288b388b64515b2cbb52c123b [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;
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300342 struct weston_drm_format_array *format_array_C;
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300343 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};
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300348 int ret;
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300349
350 format_array_A = weston_drm_format_array_create();
351 format_array_B = weston_drm_format_array_create();
352 format_array_C = weston_drm_format_array_create();
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300353 assert(format_array_A);
354 assert(format_array_B);
355 assert(format_array_C);
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300356
357 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
358 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300359 ret = weston_drm_format_array_intersect(format_array_A, format_array_B);
360 assert(ret == 0);
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300361
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300362 /* The result of the intersection (stored in A) should have the same
363 * content as C. */
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300364 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){2}, modifiers_intersect);
365 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){9}, modifiers_intersect);
366 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){10}, modifiers_intersect);
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300367 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300368
369 weston_drm_format_array_destroy(format_array_A);
370 weston_drm_format_array_destroy(format_array_B);
371 weston_drm_format_array_destroy(format_array_C);
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300372}
373
374TEST(intersect_arrays_same_content)
375{
376 struct weston_drm_format_array *format_array_A, *format_array_B;
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300377 uint32_t formats[] = {1, 2, 3, 4, 5};
378 uint64_t modifiers[] = {11, 12, 13, 14, 15};
379 int ret;
380
381 format_array_A = weston_drm_format_array_create();
382 format_array_B = weston_drm_format_array_create();
383 assert(format_array_A);
384 assert(format_array_B);
385
386 /* The intersection between two empty arrays must be an
387 * empty array. */
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300388 ret = weston_drm_format_array_intersect(format_array_A, format_array_B);
389 assert(ret == 0);
390 assert(format_array_A->arr.size == 0);
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300391
392 /* DRM-format arrays A and B have the same content, so the intersection
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300393 * should be equal to them. A keeps the result of the intersection, and B
394 * does not change. So we compare them. */
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300395 ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
396 ret = weston_drm_format_array_replace(format_array_B, format_array_A);
397 assert(ret == 0);
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300398 ret = weston_drm_format_array_intersect(format_array_A, format_array_B);
399 assert(ret == 0);
400 assert(weston_drm_format_array_equal(format_array_A, format_array_B));
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300401
402 weston_drm_format_array_destroy(format_array_A);
403 weston_drm_format_array_destroy(format_array_B);
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300404}
405
406TEST(intersect_arrays_exclusive_formats)
407{
408 struct weston_drm_format_array *format_array_A, *format_array_B;
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300409 uint64_t formats_A[] = {1, 2, 3, 4, 5};
410 uint64_t formats_B[] = {6, 7, 8, 9, 10};
411 uint64_t modifiers[] = {11, 12, 13, 14, 15};
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300412 int ret;
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300413
414 format_array_A = weston_drm_format_array_create();
415 format_array_B = weston_drm_format_array_create();
416 assert(format_array_A);
417 assert(format_array_B);
418
419 /* DRM-format arrays A and B have formats that are mutually exclusive,
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300420 * so the intersection (which is stored in A) must be empty. */
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300421 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers);
422 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers);
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300423 ret = weston_drm_format_array_intersect(format_array_A, format_array_B);
424 assert(ret == 0);
425 assert(format_array_A->arr.size == 0);
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300426
427 weston_drm_format_array_destroy(format_array_A);
428 weston_drm_format_array_destroy(format_array_B);
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300429}
430
431TEST(intersect_arrays_exclusive_modifiers)
432{
433 struct weston_drm_format_array *format_array_A, *format_array_B;
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300434 uint64_t modifiers_A[] = {1, 2, 3, 4, 5};
435 uint64_t modifiers_B[] = {6, 7, 8, 9, 10};
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300436 int ret;
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300437
438 format_array_A = weston_drm_format_array_create();
439 format_array_B = weston_drm_format_array_create();
440 assert(format_array_A);
441 assert(format_array_B);
442
443 /* Both DRM-format arrays A and B have the same format but with modifier
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300444 * sets that are mutually exclusive. The intersection (which is stored
445 * in A) between mutually exclusive modifier must be empty, and so the
446 * format should not be added to the array. So the array must also be
447 * empty. */
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300448 ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifiers_A);
449 ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, modifiers_B);
Leandro Ribeiroc51d4ad2021-08-30 12:52:26 -0300450 ret = weston_drm_format_array_intersect(format_array_A, format_array_B);
451 assert(ret == 0);
452 assert(format_array_A->arr.size == 0);
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300453
454 weston_drm_format_array_destroy(format_array_A);
455 weston_drm_format_array_destroy(format_array_B);
Leandro Ribeiro859e3f22021-03-15 17:48:45 -0300456}
457
458TEST(subtract_arrays)
459{
460 struct weston_drm_format_array *format_array_A, *format_array_B;
461 struct weston_drm_format_array *format_array_C;
462 uint32_t formats_A[] = {1, 2, 6, 9, 10};
463 uint32_t formats_B[] = {2, 5, 7, 9, 10};
464 uint64_t modifiers_A[] = {1, 2, 3, 4, 7};
465 uint64_t modifiers_B[] = {0, 2, 3, 5, 6};
466 uint64_t modifiers_subtract[] = {1, 4, 7};
467 int ret;
468
469 format_array_A = weston_drm_format_array_create();
470 format_array_B = weston_drm_format_array_create();
471 format_array_C = weston_drm_format_array_create();
472 assert(format_array_A);
473 assert(format_array_B);
474 assert(format_array_C);
475
476 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers_A);
477 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers_B);
478 ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
479 assert(ret == 0);
480
481 /* The result of the subtraction (which is saved in A) should have
482 * the same content as C. */
483 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){1}, modifiers_A);
484 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){2}, modifiers_subtract);
485 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){6}, modifiers_A);
486 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){9}, modifiers_subtract);
487 ADD_FORMATS_AND_MODS(format_array_C, (uint32_t[]){10}, modifiers_subtract);
488 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
489
490 weston_drm_format_array_destroy(format_array_A);
491 weston_drm_format_array_destroy(format_array_B);
492 weston_drm_format_array_destroy(format_array_C);
493}
494
495TEST(subtract_arrays_same_content)
496{
497 struct weston_drm_format_array *format_array_A, *format_array_B;
498 uint32_t formats[] = {1, 2, 3, 4, 5};
499 uint64_t modifiers[] = {11, 12, 13, 14, 15};
500 int ret;
501
502 format_array_A = weston_drm_format_array_create();
503 format_array_B = weston_drm_format_array_create();
504 assert(format_array_A);
505 assert(format_array_B);
506
507 /* Minuend and subtrahend have the same content. The subtraction
508 * (which is saved in A) should be an empty array. */
509 ADD_FORMATS_AND_MODS(format_array_A, formats, modifiers);
510 ret = weston_drm_format_array_replace(format_array_B, format_array_A);
511 assert(ret == 0);
512 ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
513 assert(ret == 0);
514 assert(format_array_A->arr.size == 0);
515
516 weston_drm_format_array_destroy(format_array_A);
517 weston_drm_format_array_destroy(format_array_B);
518}
519
520TEST(subtract_arrays_exclusive_formats)
521{
522 struct weston_drm_format_array *format_array_A, *format_array_B;
523 struct weston_drm_format_array *format_array_C;
524 uint32_t formats_A[] = {1, 2, 3, 4, 5};
525 uint32_t formats_B[] = {6, 7, 8, 9, 10};
526 uint64_t modifiers[] = {11, 12, 13, 14, 15};
527 int ret;
528
529 format_array_A = weston_drm_format_array_create();
530 format_array_B = weston_drm_format_array_create();
531 format_array_C = weston_drm_format_array_create();
532 assert(format_array_A);
533 assert(format_array_B);
534 assert(format_array_C);
535
536 /* Minuend and subtrahend have mutually exclusive formats. The
537 * subtraction (which is saved in A) should be equal the minuend. */
538 ADD_FORMATS_AND_MODS(format_array_A, formats_A, modifiers);
539 ADD_FORMATS_AND_MODS(format_array_B, formats_B, modifiers);
540 ret = weston_drm_format_array_replace(format_array_C, format_array_A);
541 assert(ret == 0);
542
543 ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
544 assert(ret == 0);
545 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
546
547 weston_drm_format_array_destroy(format_array_A);
548 weston_drm_format_array_destroy(format_array_B);
549 weston_drm_format_array_destroy(format_array_C);
550}
551
552TEST(subtract_arrays_exclusive_modifiers)
553{
554 struct weston_drm_format_array *format_array_A, *format_array_B;
555 struct weston_drm_format_array *format_array_C;
556 uint64_t modifiers_A[] = {1, 2, 3, 4, 5};
557 uint64_t modifiers_B[] = {6, 7, 8, 9, 10};
558 int ret;
559
560 format_array_A = weston_drm_format_array_create();
561 format_array_B = weston_drm_format_array_create();
562 format_array_C = weston_drm_format_array_create();
563 assert(format_array_A);
564 assert(format_array_B);
565 assert(format_array_C);
566
567 /* Minuend and subtrahend have the same format but with modifiers that
568 * are mutually exclusive. The subtraction (which is saved in A) should
569 * contain the format and the modifier set of the minuend. */
570 ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifiers_A);
571 ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, modifiers_B);
572 ret = weston_drm_format_array_replace(format_array_C, format_array_A);
573 assert(ret == 0);
574
575 ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
576 assert(ret == 0);
577 assert(weston_drm_format_array_equal(format_array_A, format_array_C));
578
579 weston_drm_format_array_destroy(format_array_A);
580 weston_drm_format_array_destroy(format_array_B);
581 weston_drm_format_array_destroy(format_array_C);
582}
583
584TEST(subtract_arrays_modifier_invalid)
585{
586 struct weston_drm_format_array *format_array_A, *format_array_B;
587 uint64_t modifier_invalid[] = {DRM_FORMAT_MOD_INVALID};
588 uint64_t regular_modifiers_plus_invalid[] = {1, 2, 3, 4, 5, DRM_FORMAT_MOD_INVALID};
589 int ret;
590
591 format_array_A = weston_drm_format_array_create();
592 format_array_B = weston_drm_format_array_create();
593 assert(format_array_A);
594 assert(format_array_B);
595
596 /* The minuend has a format with modifier set that contains MOD_INVALID
597 * and the subtrahend contains the same format but with a regular set of
598 * modifiers + MOD_INVALID. So the subtraction between the modifiers
599 * sets results in empty, and so the format should not be included to
600 * the result. As it is the only format in the minuend, the resulting
601 * array must be empty. */
602 ADD_FORMATS_AND_MODS(format_array_A, (uint32_t[]){1}, modifier_invalid);
603 ADD_FORMATS_AND_MODS(format_array_B, (uint32_t[]){1}, regular_modifiers_plus_invalid);
604 ret = weston_drm_format_array_subtract(format_array_A, format_array_B);
605 assert(ret == 0);
606 assert(format_array_A->arr.size == 0);
607
608 weston_drm_format_array_destroy(format_array_A);
609 weston_drm_format_array_destroy(format_array_B);
610}