]> Git Repo - linux.git/blob - drivers/gpu/drm/tests/drm_damage_helper_test.c
net: wan: Add framer framework support
[linux.git] / drivers / gpu / drm / tests / drm_damage_helper_test.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Test case for drm_damage_helper functions
4  *
5  * Copyright (c) 2022 MaĆ­ra Canal <[email protected]>
6  */
7
8 #include <kunit/test.h>
9
10 #include <drm/drm_damage_helper.h>
11 #include <drm/drm_framebuffer.h>
12 #include <drm/drm_plane.h>
13 #include <drm/drm_drv.h>
14
15 struct drm_damage_mock {
16         struct drm_driver driver;
17         struct drm_device device;
18         struct drm_object_properties obj_props;
19         struct drm_plane plane;
20         struct drm_property prop;
21         struct drm_framebuffer fb;
22         struct drm_plane_state state;
23         struct drm_plane_state old_state;
24 };
25
26 static int drm_damage_helper_init(struct kunit *test)
27 {
28         struct drm_damage_mock *mock;
29
30         mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL);
31         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mock);
32
33         mock->fb.width = 2048;
34         mock->fb.height = 2048;
35
36         mock->state.crtc = ZERO_SIZE_PTR;
37         mock->state.fb = &mock->fb;
38         mock->state.visible = true;
39
40         mock->old_state.plane = &mock->plane;
41         mock->state.plane = &mock->plane;
42
43         /* just enough so that drm_plane_enable_fb_damage_clips() works */
44         mock->device.driver = &mock->driver;
45         mock->device.mode_config.prop_fb_damage_clips = &mock->prop;
46         mock->plane.dev = &mock->device;
47         mock->obj_props.count = 0;
48         mock->plane.base.properties = &mock->obj_props;
49         mock->prop.base.id = 1; /* 0 is an invalid id */
50         mock->prop.dev = &mock->device;
51
52         drm_plane_enable_fb_damage_clips(&mock->plane);
53
54         test->priv = mock;
55
56         return 0;
57 }
58
59 static void set_plane_src(struct drm_plane_state *state, int x1, int y1, int x2,
60                           int y2)
61 {
62         state->src_x = x1;
63         state->src_y = y1;
64         state->src_w = x2 - x1;
65         state->src_h = y2 - y1;
66
67         state->src.x1 = x1;
68         state->src.y1 = y1;
69         state->src.x2 = x2;
70         state->src.y2 = y2;
71 }
72
73 static void set_damage_clip(struct drm_mode_rect *r, int x1, int y1, int x2,
74                             int y2)
75 {
76         r->x1 = x1;
77         r->y1 = y1;
78         r->x2 = x2;
79         r->y2 = y2;
80 }
81
82 static void set_damage_blob(struct drm_property_blob *damage_blob,
83                             struct drm_mode_rect *r, u32 size)
84 {
85         damage_blob->length = size;
86         damage_blob->data = r;
87 }
88
89 static void set_plane_damage(struct drm_plane_state *state,
90                              struct drm_property_blob *damage_blob)
91 {
92         state->fb_damage_clips = damage_blob;
93 }
94
95 static void check_damage_clip(struct kunit *test, struct drm_rect *r,
96                               int x1, int y1, int x2, int y2)
97 {
98         struct drm_damage_mock *mock = test->priv;
99         struct drm_plane_state state = mock->state;
100
101         /*
102          * Round down x1/y1 and round up x2/y2. This is because damage is not in
103          * 16.16 fixed point so to catch all pixels.
104          */
105         int src_x1 = state.src.x1 >> 16;
106         int src_y1 = state.src.y1 >> 16;
107         int src_x2 = (state.src.x2 >> 16) + !!(state.src.x2 & 0xFFFF);
108         int src_y2 = (state.src.y2 >> 16) + !!(state.src.y2 & 0xFFFF);
109
110         if (x1 >= x2 || y1 >= y2)
111                 KUNIT_FAIL(test, "Cannot have damage clip with no dimension.");
112         if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2)
113                 KUNIT_FAIL(test, "Damage cannot be outside rounded plane src.");
114         if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2)
115                 KUNIT_FAIL(test, "Damage = %d %d %d %d, want = %d %d %d %d",
116                            r->x1, r->y1, r->x2, r->y2, x1, y1, x2, y2);
117 }
118
119 static void drm_test_damage_iter_no_damage(struct kunit *test)
120 {
121         struct drm_damage_mock *mock = test->priv;
122         struct drm_atomic_helper_damage_iter iter;
123         struct drm_rect clip;
124         u32 num_hits = 0;
125
126         /* Plane src same as fb size. */
127         set_plane_src(&mock->old_state, 0, 0, mock->fb.width << 16, mock->fb.height << 16);
128         set_plane_src(&mock->state, 0, 0, mock->fb.width << 16, mock->fb.height << 16);
129         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
130         drm_atomic_for_each_plane_damage(&iter, &clip)
131                 num_hits++;
132
133         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
134         check_damage_clip(test, &clip, 0, 0, 2048, 2048);
135 }
136
137 static void drm_test_damage_iter_no_damage_fractional_src(struct kunit *test)
138 {
139         struct drm_damage_mock *mock = test->priv;
140         struct drm_atomic_helper_damage_iter iter;
141         struct drm_rect clip;
142         u32 num_hits = 0;
143
144         /* Plane src has fractional part. */
145         set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
146                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
147         set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
148                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
149         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
150         drm_atomic_for_each_plane_damage(&iter, &clip)
151                 num_hits++;
152
153         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
154                             "Should return rounded off plane src as damage.");
155         check_damage_clip(test, &clip, 3, 3, 1028, 772);
156 }
157
158 static void drm_test_damage_iter_no_damage_src_moved(struct kunit *test)
159 {
160         struct drm_damage_mock *mock = test->priv;
161         struct drm_atomic_helper_damage_iter iter;
162         struct drm_rect clip;
163         u32 num_hits = 0;
164
165         /* Plane src moved since old plane state. */
166         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
167         set_plane_src(&mock->state, 10 << 16, 10 << 16,
168                       (10 + 1024) << 16, (10 + 768) << 16);
169         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
170         drm_atomic_for_each_plane_damage(&iter, &clip)
171                 num_hits++;
172
173         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
174         check_damage_clip(test, &clip, 10, 10, 1034, 778);
175 }
176
177 static void drm_test_damage_iter_no_damage_fractional_src_moved(struct kunit *test)
178 {
179         struct drm_damage_mock *mock = test->priv;
180         struct drm_atomic_helper_damage_iter iter;
181         struct drm_rect clip;
182         u32 num_hits = 0;
183
184         /* Plane src has fractional part and it moved since old plane state. */
185         set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
186                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
187         set_plane_src(&mock->state, 0x40002, 0x40002,
188                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
189         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
190         drm_atomic_for_each_plane_damage(&iter, &clip)
191                 num_hits++;
192
193         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
194         check_damage_clip(test, &clip, 4, 4, 1029, 773);
195 }
196
197 static void drm_test_damage_iter_no_damage_not_visible(struct kunit *test)
198 {
199         struct drm_damage_mock *mock = test->priv;
200         struct drm_atomic_helper_damage_iter iter;
201         struct drm_rect clip;
202         u32 num_hits = 0;
203
204         mock->state.visible = false;
205
206         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
207         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
208         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
209         drm_atomic_for_each_plane_damage(&iter, &clip)
210                 num_hits++;
211
212         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
213 }
214
215 static void drm_test_damage_iter_no_damage_no_crtc(struct kunit *test)
216 {
217         struct drm_damage_mock *mock = test->priv;
218         struct drm_atomic_helper_damage_iter iter;
219         struct drm_rect clip;
220         u32 num_hits = 0;
221
222         mock->state.crtc = NULL;
223
224         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
225         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
226         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
227         drm_atomic_for_each_plane_damage(&iter, &clip)
228                 num_hits++;
229
230         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
231 }
232
233 static void drm_test_damage_iter_no_damage_no_fb(struct kunit *test)
234 {
235         struct drm_damage_mock *mock = test->priv;
236         struct drm_atomic_helper_damage_iter iter;
237         struct drm_rect clip;
238         u32 num_hits = 0;
239
240         mock->state.fb = NULL;
241
242         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
243         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
244         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
245         drm_atomic_for_each_plane_damage(&iter, &clip)
246                 num_hits++;
247
248         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
249 }
250
251 static void drm_test_damage_iter_simple_damage(struct kunit *test)
252 {
253         struct drm_damage_mock *mock = test->priv;
254         struct drm_atomic_helper_damage_iter iter;
255         struct drm_property_blob damage_blob;
256         struct drm_mode_rect damage;
257         struct drm_rect clip;
258         u32 num_hits = 0;
259
260         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
261         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
262         /* Damage set to plane src */
263         set_damage_clip(&damage, 0, 0, 1024, 768);
264         set_damage_blob(&damage_blob, &damage, sizeof(damage));
265         set_plane_damage(&mock->state, &damage_blob);
266         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
267         drm_atomic_for_each_plane_damage(&iter, &clip)
268                 num_hits++;
269
270         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
271         check_damage_clip(test, &clip, 0, 0, 1024, 768);
272 }
273
274 static void drm_test_damage_iter_single_damage(struct kunit *test)
275 {
276         struct drm_damage_mock *mock = test->priv;
277         struct drm_atomic_helper_damage_iter iter;
278         struct drm_property_blob damage_blob;
279         struct drm_mode_rect damage;
280         struct drm_rect clip;
281         u32 num_hits = 0;
282
283         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
284         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
285         set_damage_clip(&damage, 256, 192, 768, 576);
286         set_damage_blob(&damage_blob, &damage, sizeof(damage));
287         set_plane_damage(&mock->state, &damage_blob);
288         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
289         drm_atomic_for_each_plane_damage(&iter, &clip)
290                 num_hits++;
291
292         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
293         check_damage_clip(test, &clip, 256, 192, 768, 576);
294 }
295
296 static void drm_test_damage_iter_single_damage_intersect_src(struct kunit *test)
297 {
298         struct drm_damage_mock *mock = test->priv;
299         struct drm_atomic_helper_damage_iter iter;
300         struct drm_property_blob damage_blob;
301         struct drm_mode_rect damage;
302         struct drm_rect clip;
303         u32 num_hits = 0;
304
305         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
306         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
307         /* Damage intersect with plane src. */
308         set_damage_clip(&damage, 256, 192, 1360, 768);
309         set_damage_blob(&damage_blob, &damage, sizeof(damage));
310         set_plane_damage(&mock->state, &damage_blob);
311         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
312         drm_atomic_for_each_plane_damage(&iter, &clip)
313                 num_hits++;
314
315         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage clipped to src.");
316         check_damage_clip(test, &clip, 256, 192, 1024, 768);
317 }
318
319 static void drm_test_damage_iter_single_damage_outside_src(struct kunit *test)
320 {
321         struct drm_damage_mock *mock = test->priv;
322         struct drm_atomic_helper_damage_iter iter;
323         struct drm_property_blob damage_blob;
324         struct drm_mode_rect damage;
325         struct drm_rect clip;
326         u32 num_hits = 0;
327
328         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
329         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
330         /* Damage clip outside plane src */
331         set_damage_clip(&damage, 1360, 1360, 1380, 1380);
332         set_damage_blob(&damage_blob, &damage, sizeof(damage));
333         set_plane_damage(&mock->state, &damage_blob);
334         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
335         drm_atomic_for_each_plane_damage(&iter, &clip)
336                 num_hits++;
337
338         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
339 }
340
341 static void drm_test_damage_iter_single_damage_fractional_src(struct kunit *test)
342 {
343         struct drm_damage_mock *mock = test->priv;
344         struct drm_atomic_helper_damage_iter iter;
345         struct drm_property_blob damage_blob;
346         struct drm_mode_rect damage;
347         struct drm_rect clip;
348         u32 num_hits = 0;
349
350         /* Plane src has fractional part. */
351         set_plane_src(&mock->old_state, 0x40002, 0x40002,
352                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
353         set_plane_src(&mock->state, 0x40002, 0x40002,
354                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
355         set_damage_clip(&damage, 10, 10, 256, 330);
356         set_damage_blob(&damage_blob, &damage, sizeof(damage));
357         set_plane_damage(&mock->state, &damage_blob);
358         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
359         drm_atomic_for_each_plane_damage(&iter, &clip)
360                 num_hits++;
361
362         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
363         check_damage_clip(test, &clip, 10, 10, 256, 330);
364 }
365
366 static void drm_test_damage_iter_single_damage_intersect_fractional_src(struct kunit *test)
367 {
368         struct drm_damage_mock *mock = test->priv;
369         struct drm_atomic_helper_damage_iter iter;
370         struct drm_property_blob damage_blob;
371         struct drm_mode_rect damage;
372         struct drm_rect clip;
373         u32 num_hits = 0;
374
375         /* Plane src has fractional part. */
376         set_plane_src(&mock->old_state, 0x40002, 0x40002,
377                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
378         set_plane_src(&mock->state, 0x40002, 0x40002,
379                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
380         /* Damage intersect with plane src. */
381         set_damage_clip(&damage, 10, 1, 1360, 330);
382         set_damage_blob(&damage_blob, &damage, sizeof(damage));
383         set_plane_damage(&mock->state, &damage_blob);
384         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
385         drm_atomic_for_each_plane_damage(&iter, &clip)
386                 num_hits++;
387
388         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
389                             "Should return damage clipped to rounded off src.");
390         check_damage_clip(test, &clip, 10, 4, 1029, 330);
391 }
392
393 static void drm_test_damage_iter_single_damage_outside_fractional_src(struct kunit *test)
394 {
395         struct drm_damage_mock *mock = test->priv;
396         struct drm_atomic_helper_damage_iter iter;
397         struct drm_property_blob damage_blob;
398         struct drm_mode_rect damage;
399         struct drm_rect clip;
400         u32 num_hits = 0;
401
402         /* Plane src has fractional part. */
403         set_plane_src(&mock->old_state, 0x40002, 0x40002,
404                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
405         set_plane_src(&mock->state, 0x40002, 0x40002,
406                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
407         /* Damage clip outside plane src */
408         set_damage_clip(&damage, 1360, 1360, 1380, 1380);
409         set_damage_blob(&damage_blob, &damage, sizeof(damage));
410         set_plane_damage(&mock->state, &damage_blob);
411         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
412         drm_atomic_for_each_plane_damage(&iter, &clip)
413                 num_hits++;
414
415         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
416 }
417
418 static void drm_test_damage_iter_single_damage_src_moved(struct kunit *test)
419 {
420         struct drm_damage_mock *mock = test->priv;
421         struct drm_atomic_helper_damage_iter iter;
422         struct drm_property_blob damage_blob;
423         struct drm_mode_rect damage;
424         struct drm_rect clip;
425         u32 num_hits = 0;
426
427         /* Plane src moved since old plane state. */
428         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
429         set_plane_src(&mock->state, 10 << 16, 10 << 16,
430                       (10 + 1024) << 16, (10 + 768) << 16);
431         set_damage_clip(&damage, 20, 30, 256, 256);
432         set_damage_blob(&damage_blob, &damage, sizeof(damage));
433         set_plane_damage(&mock->state, &damage_blob);
434         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
435         drm_atomic_for_each_plane_damage(&iter, &clip)
436                 num_hits++;
437
438         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
439                             "Should return plane src as damage.");
440         check_damage_clip(test, &clip, 10, 10, 1034, 778);
441 }
442
443 static void drm_test_damage_iter_single_damage_fractional_src_moved(struct kunit *test)
444 {
445         struct drm_damage_mock *mock = test->priv;
446         struct drm_atomic_helper_damage_iter iter;
447         struct drm_property_blob damage_blob;
448         struct drm_mode_rect damage;
449         struct drm_rect clip;
450         u32 num_hits = 0;
451
452         /* Plane src with fractional part moved since old plane state. */
453         set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
454                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
455         set_plane_src(&mock->state, 0x40002, 0x40002,
456                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
457         /* Damage intersect with plane src. */
458         set_damage_clip(&damage, 20, 30, 1360, 256);
459         set_damage_blob(&damage_blob, &damage, sizeof(damage));
460         set_plane_damage(&mock->state, &damage_blob);
461         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
462         drm_atomic_for_each_plane_damage(&iter, &clip)
463                 num_hits++;
464
465         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
466                             "Should return rounded off plane as damage.");
467         check_damage_clip(test, &clip, 4, 4, 1029, 773);
468 }
469
470 static void drm_test_damage_iter_damage(struct kunit *test)
471 {
472         struct drm_damage_mock *mock = test->priv;
473         struct drm_atomic_helper_damage_iter iter;
474         struct drm_property_blob damage_blob;
475         struct drm_mode_rect damage[2];
476         struct drm_rect clip;
477         u32 num_hits = 0;
478
479         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
480         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
481         /* 2 damage clips. */
482         set_damage_clip(&damage[0], 20, 30, 200, 180);
483         set_damage_clip(&damage[1], 240, 200, 280, 250);
484         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
485         set_plane_damage(&mock->state, &damage_blob);
486         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
487         drm_atomic_for_each_plane_damage(&iter, &clip) {
488                 if (num_hits == 0)
489                         check_damage_clip(test, &clip, 20, 30, 200, 180);
490                 if (num_hits == 1)
491                         check_damage_clip(test, &clip, 240, 200, 280, 250);
492                 num_hits++;
493         }
494
495         KUNIT_EXPECT_EQ_MSG(test, num_hits, 2, "Should return damage when set.");
496 }
497
498 static void drm_test_damage_iter_damage_one_intersect(struct kunit *test)
499 {
500         struct drm_damage_mock *mock = test->priv;
501         struct drm_atomic_helper_damage_iter iter;
502         struct drm_property_blob damage_blob;
503         struct drm_mode_rect damage[2];
504         struct drm_rect clip;
505         u32 num_hits = 0;
506
507         set_plane_src(&mock->old_state, 0x40002, 0x40002,
508                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
509         set_plane_src(&mock->state, 0x40002, 0x40002,
510                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
511         /* 2 damage clips, one intersect plane src. */
512         set_damage_clip(&damage[0], 20, 30, 200, 180);
513         set_damage_clip(&damage[1], 2, 2, 1360, 1360);
514         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
515         set_plane_damage(&mock->state, &damage_blob);
516         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
517         drm_atomic_for_each_plane_damage(&iter, &clip) {
518                 if (num_hits == 0)
519                         check_damage_clip(test, &clip, 20, 30, 200, 180);
520                 if (num_hits == 1)
521                         check_damage_clip(test, &clip, 4, 4, 1029, 773);
522                 num_hits++;
523         }
524
525         KUNIT_EXPECT_EQ_MSG(test, num_hits, 2, "Should return damage when set.");
526 }
527
528 static void drm_test_damage_iter_damage_one_outside(struct kunit *test)
529 {
530         struct drm_damage_mock *mock = test->priv;
531         struct drm_atomic_helper_damage_iter iter;
532         struct drm_property_blob damage_blob;
533         struct drm_mode_rect damage[2];
534         struct drm_rect clip;
535         u32 num_hits = 0;
536
537         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
538         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
539         /* 2 damage clips, one outside plane src. */
540         set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
541         set_damage_clip(&damage[1], 240, 200, 280, 250);
542         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
543         set_plane_damage(&mock->state, &damage_blob);
544         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
545         drm_atomic_for_each_plane_damage(&iter, &clip)
546                 num_hits++;
547
548         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
549         check_damage_clip(test, &clip, 240, 200, 280, 250);
550 }
551
552 static void drm_test_damage_iter_damage_src_moved(struct kunit *test)
553 {
554         struct drm_damage_mock *mock = test->priv;
555         struct drm_atomic_helper_damage_iter iter;
556         struct drm_property_blob damage_blob;
557         struct drm_mode_rect damage[2];
558         struct drm_rect clip;
559         u32 num_hits = 0;
560
561         set_plane_src(&mock->old_state, 0x40002, 0x40002,
562                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
563         set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
564                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
565         /* 2 damage clips, one outside plane src. */
566         set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
567         set_damage_clip(&damage[1], 240, 200, 280, 250);
568         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
569         set_plane_damage(&mock->state, &damage_blob);
570         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
571         drm_atomic_for_each_plane_damage(&iter, &clip)
572                 num_hits++;
573
574         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
575                             "Should return round off plane src as damage.");
576         check_damage_clip(test, &clip, 3, 3, 1028, 772);
577 }
578
579 static void drm_test_damage_iter_damage_not_visible(struct kunit *test)
580 {
581         struct drm_damage_mock *mock = test->priv;
582         struct drm_atomic_helper_damage_iter iter;
583         struct drm_property_blob damage_blob;
584         struct drm_mode_rect damage[2];
585         struct drm_rect clip;
586         u32 num_hits = 0;
587
588         mock->state.visible = false;
589
590         set_plane_src(&mock->old_state, 0x40002, 0x40002,
591                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
592         set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
593                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
594         /* 2 damage clips, one outside plane src. */
595         set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
596         set_damage_clip(&damage[1], 240, 200, 280, 250);
597         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
598         set_plane_damage(&mock->state, &damage_blob);
599         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
600         drm_atomic_for_each_plane_damage(&iter, &clip)
601                 num_hits++;
602
603         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should not return any damage.");
604 }
605
606 static struct kunit_case drm_damage_helper_tests[] = {
607         KUNIT_CASE(drm_test_damage_iter_no_damage),
608         KUNIT_CASE(drm_test_damage_iter_no_damage_fractional_src),
609         KUNIT_CASE(drm_test_damage_iter_no_damage_src_moved),
610         KUNIT_CASE(drm_test_damage_iter_no_damage_fractional_src_moved),
611         KUNIT_CASE(drm_test_damage_iter_no_damage_not_visible),
612         KUNIT_CASE(drm_test_damage_iter_no_damage_no_crtc),
613         KUNIT_CASE(drm_test_damage_iter_no_damage_no_fb),
614         KUNIT_CASE(drm_test_damage_iter_simple_damage),
615         KUNIT_CASE(drm_test_damage_iter_single_damage),
616         KUNIT_CASE(drm_test_damage_iter_single_damage_intersect_src),
617         KUNIT_CASE(drm_test_damage_iter_single_damage_outside_src),
618         KUNIT_CASE(drm_test_damage_iter_single_damage_fractional_src),
619         KUNIT_CASE(drm_test_damage_iter_single_damage_intersect_fractional_src),
620         KUNIT_CASE(drm_test_damage_iter_single_damage_outside_fractional_src),
621         KUNIT_CASE(drm_test_damage_iter_single_damage_src_moved),
622         KUNIT_CASE(drm_test_damage_iter_single_damage_fractional_src_moved),
623         KUNIT_CASE(drm_test_damage_iter_damage),
624         KUNIT_CASE(drm_test_damage_iter_damage_one_intersect),
625         KUNIT_CASE(drm_test_damage_iter_damage_one_outside),
626         KUNIT_CASE(drm_test_damage_iter_damage_src_moved),
627         KUNIT_CASE(drm_test_damage_iter_damage_not_visible),
628         { }
629 };
630
631 static struct kunit_suite drm_damage_helper_test_suite = {
632         .name = "drm_damage_helper",
633         .init = drm_damage_helper_init,
634         .test_cases = drm_damage_helper_tests,
635 };
636
637 kunit_test_suite(drm_damage_helper_test_suite);
638
639 MODULE_LICENSE("GPL");
This page took 0.072243 seconds and 4 git commands to generate.