LCOV - code coverage report
Current view: top level - drivers/gpu/drm/tests - drm_damage_helper_test.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 322 331 97.3 %
Date: 2023-03-27 20:00:47 Functions: 23 23 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Test case for drm_damage_helper functions
       4             :  *
       5             :  * Copyright (c) 2022 MaĆ­ra Canal <mairacanal@riseup.net>
       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          21 : static int drm_damage_helper_init(struct kunit *test)
      27             : {
      28             :         struct drm_damage_mock *mock;
      29             : 
      30          21 :         mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL);
      31          42 :         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mock);
      32             : 
      33          21 :         mock->fb.width = 2048;
      34          21 :         mock->fb.height = 2048;
      35             : 
      36          21 :         mock->state.crtc = ZERO_SIZE_PTR;
      37          21 :         mock->state.fb = &mock->fb;
      38          21 :         mock->state.visible = true;
      39             : 
      40          21 :         mock->old_state.plane = &mock->plane;
      41          21 :         mock->state.plane = &mock->plane;
      42             : 
      43             :         /* just enough so that drm_plane_enable_fb_damage_clips() works */
      44          21 :         mock->device.driver = &mock->driver;
      45          21 :         mock->device.mode_config.prop_fb_damage_clips = &mock->prop;
      46          21 :         mock->plane.dev = &mock->device;
      47          21 :         mock->obj_props.count = 0;
      48          21 :         mock->plane.base.properties = &mock->obj_props;
      49          21 :         mock->prop.base.id = 1; /* 0 is an invalid id */
      50          21 :         mock->prop.dev = &mock->device;
      51             : 
      52          21 :         drm_plane_enable_fb_damage_clips(&mock->plane);
      53             : 
      54          21 :         test->priv = mock;
      55             : 
      56          21 :         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          42 :         state->src_x = x1;
      63          42 :         state->src_y = y1;
      64          42 :         state->src_w = x2 - x1;
      65          42 :         state->src_h = y2 - y1;
      66             : 
      67          42 :         state->src.x1 = x1;
      68          42 :         state->src.y1 = y1;
      69          42 :         state->src.x2 = x2;
      70          42 :         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          19 :         r->x1 = x1;
      77          19 :         r->y1 = y1;
      78          19 :         r->x2 = x2;
      79          19 :         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          14 :         damage_blob->length = size;
      86          14 :         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          14 :         state->fb_damage_clips = damage_blob;
      93             : }
      94             : 
      95          17 : static void check_damage_clip(struct kunit *test, struct drm_rect *r,
      96             :                               int x1, int y1, int x2, int y2)
      97             : {
      98          17 :         struct drm_damage_mock *mock = test->priv;
      99          17 :         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          17 :         int src_x1 = state.src.x1 >> 16;
     106          17 :         int src_y1 = state.src.y1 >> 16;
     107          17 :         int src_x2 = (state.src.x2 >> 16) + !!(state.src.x2 & 0xFFFF);
     108          17 :         int src_y2 = (state.src.y2 >> 16) + !!(state.src.y2 & 0xFFFF);
     109             : 
     110          17 :         if (x1 >= x2 || y1 >= y2)
     111           0 :                 KUNIT_FAIL(test, "Cannot have damage clip with no dimension.");
     112          17 :         if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2)
     113           0 :                 KUNIT_FAIL(test, "Damage cannot be outside rounded plane src.");
     114          17 :         if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2)
     115           0 :                 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          17 : }
     118             : 
     119           1 : static void drm_test_damage_iter_no_damage(struct kunit *test)
     120             : {
     121           1 :         struct drm_damage_mock *mock = test->priv;
     122             :         struct drm_atomic_helper_damage_iter iter;
     123             :         struct drm_rect clip;
     124           1 :         u32 num_hits = 0;
     125             : 
     126             :         /* Plane src same as fb size. */
     127           2 :         set_plane_src(&mock->old_state, 0, 0, mock->fb.width << 16, mock->fb.height << 16);
     128           2 :         set_plane_src(&mock->state, 0, 0, mock->fb.width << 16, mock->fb.height << 16);
     129           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     130           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     131           1 :                 num_hits++;
     132             : 
     133           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
     134           1 :         check_damage_clip(test, &clip, 0, 0, 2048, 2048);
     135           1 : }
     136             : 
     137           1 : static void drm_test_damage_iter_no_damage_fractional_src(struct kunit *test)
     138             : {
     139           1 :         struct drm_damage_mock *mock = test->priv;
     140             :         struct drm_atomic_helper_damage_iter iter;
     141             :         struct drm_rect clip;
     142           1 :         u32 num_hits = 0;
     143             : 
     144             :         /* Plane src has fractional part. */
     145           2 :         set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
     146             :                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
     147           2 :         set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
     148             :                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
     149           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     150           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     151           1 :                 num_hits++;
     152             : 
     153           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
     154             :                             "Should return rounded off plane src as damage.");
     155           1 :         check_damage_clip(test, &clip, 3, 3, 1028, 772);
     156           1 : }
     157             : 
     158           1 : static void drm_test_damage_iter_no_damage_src_moved(struct kunit *test)
     159             : {
     160           1 :         struct drm_damage_mock *mock = test->priv;
     161             :         struct drm_atomic_helper_damage_iter iter;
     162             :         struct drm_rect clip;
     163           1 :         u32 num_hits = 0;
     164             : 
     165             :         /* Plane src moved since old plane state. */
     166           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     167           2 :         set_plane_src(&mock->state, 10 << 16, 10 << 16,
     168             :                       (10 + 1024) << 16, (10 + 768) << 16);
     169           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     170           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     171           1 :                 num_hits++;
     172             : 
     173           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
     174           1 :         check_damage_clip(test, &clip, 10, 10, 1034, 778);
     175           1 : }
     176             : 
     177           1 : static void drm_test_damage_iter_no_damage_fractional_src_moved(struct kunit *test)
     178             : {
     179           1 :         struct drm_damage_mock *mock = test->priv;
     180             :         struct drm_atomic_helper_damage_iter iter;
     181             :         struct drm_rect clip;
     182           1 :         u32 num_hits = 0;
     183             : 
     184             :         /* Plane src has fractional part and it moved since old plane state. */
     185           2 :         set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
     186             :                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
     187           2 :         set_plane_src(&mock->state, 0x40002, 0x40002,
     188             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     189           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     190           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     191           1 :                 num_hits++;
     192             : 
     193           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
     194           1 :         check_damage_clip(test, &clip, 4, 4, 1029, 773);
     195           1 : }
     196             : 
     197           1 : static void drm_test_damage_iter_no_damage_not_visible(struct kunit *test)
     198             : {
     199           1 :         struct drm_damage_mock *mock = test->priv;
     200             :         struct drm_atomic_helper_damage_iter iter;
     201             :         struct drm_rect clip;
     202           1 :         u32 num_hits = 0;
     203             : 
     204           1 :         mock->state.visible = false;
     205             : 
     206           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     207           2 :         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
     208           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     209           2 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     210           0 :                 num_hits++;
     211             : 
     212           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
     213           1 : }
     214             : 
     215           1 : static void drm_test_damage_iter_no_damage_no_crtc(struct kunit *test)
     216             : {
     217           1 :         struct drm_damage_mock *mock = test->priv;
     218             :         struct drm_atomic_helper_damage_iter iter;
     219             :         struct drm_rect clip;
     220           1 :         u32 num_hits = 0;
     221             : 
     222           1 :         mock->state.crtc = NULL;
     223             : 
     224           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     225           2 :         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
     226           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     227           2 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     228           0 :                 num_hits++;
     229             : 
     230           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
     231           1 : }
     232             : 
     233           1 : static void drm_test_damage_iter_no_damage_no_fb(struct kunit *test)
     234             : {
     235           1 :         struct drm_damage_mock *mock = test->priv;
     236             :         struct drm_atomic_helper_damage_iter iter;
     237             :         struct drm_rect clip;
     238           1 :         u32 num_hits = 0;
     239             : 
     240           1 :         mock->state.fb = NULL;
     241             : 
     242           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     243           2 :         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
     244           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     245           2 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     246           0 :                 num_hits++;
     247             : 
     248           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
     249           1 : }
     250             : 
     251           1 : static void drm_test_damage_iter_simple_damage(struct kunit *test)
     252             : {
     253           1 :         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           1 :         u32 num_hits = 0;
     259             : 
     260           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     261           2 :         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
     262             :         /* Damage set to plane src */
     263           1 :         set_damage_clip(&damage, 0, 0, 1024, 768);
     264           2 :         set_damage_blob(&damage_blob, &damage, sizeof(damage));
     265           2 :         set_plane_damage(&mock->state, &damage_blob);
     266           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     267           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     268           1 :                 num_hits++;
     269             : 
     270           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
     271           1 :         check_damage_clip(test, &clip, 0, 0, 1024, 768);
     272           1 : }
     273             : 
     274           1 : static void drm_test_damage_iter_single_damage(struct kunit *test)
     275             : {
     276           1 :         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           1 :         u32 num_hits = 0;
     282             : 
     283           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     284           2 :         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
     285           1 :         set_damage_clip(&damage, 256, 192, 768, 576);
     286           2 :         set_damage_blob(&damage_blob, &damage, sizeof(damage));
     287           2 :         set_plane_damage(&mock->state, &damage_blob);
     288           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     289           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     290           1 :                 num_hits++;
     291             : 
     292           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
     293           1 :         check_damage_clip(test, &clip, 256, 192, 768, 576);
     294           1 : }
     295             : 
     296           1 : static void drm_test_damage_iter_single_damage_intersect_src(struct kunit *test)
     297             : {
     298           1 :         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           1 :         u32 num_hits = 0;
     304             : 
     305           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     306           2 :         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
     307             :         /* Damage intersect with plane src. */
     308           1 :         set_damage_clip(&damage, 256, 192, 1360, 768);
     309           2 :         set_damage_blob(&damage_blob, &damage, sizeof(damage));
     310           2 :         set_plane_damage(&mock->state, &damage_blob);
     311           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     312           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     313           1 :                 num_hits++;
     314             : 
     315           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage clipped to src.");
     316           1 :         check_damage_clip(test, &clip, 256, 192, 1024, 768);
     317           1 : }
     318             : 
     319           1 : static void drm_test_damage_iter_single_damage_outside_src(struct kunit *test)
     320             : {
     321           1 :         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           1 :         u32 num_hits = 0;
     327             : 
     328           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     329           2 :         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
     330             :         /* Damage clip outside plane src */
     331           1 :         set_damage_clip(&damage, 1360, 1360, 1380, 1380);
     332           2 :         set_damage_blob(&damage_blob, &damage, sizeof(damage));
     333           2 :         set_plane_damage(&mock->state, &damage_blob);
     334           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     335           2 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     336           0 :                 num_hits++;
     337             : 
     338           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
     339           1 : }
     340             : 
     341           1 : static void drm_test_damage_iter_single_damage_fractional_src(struct kunit *test)
     342             : {
     343           1 :         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           1 :         u32 num_hits = 0;
     349             : 
     350             :         /* Plane src has fractional part. */
     351           2 :         set_plane_src(&mock->old_state, 0x40002, 0x40002,
     352             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     353           2 :         set_plane_src(&mock->state, 0x40002, 0x40002,
     354             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     355           1 :         set_damage_clip(&damage, 10, 10, 256, 330);
     356           2 :         set_damage_blob(&damage_blob, &damage, sizeof(damage));
     357           2 :         set_plane_damage(&mock->state, &damage_blob);
     358           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     359           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     360           1 :                 num_hits++;
     361             : 
     362           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
     363           1 :         check_damage_clip(test, &clip, 10, 10, 256, 330);
     364           1 : }
     365             : 
     366           1 : static void drm_test_damage_iter_single_damage_intersect_fractional_src(struct kunit *test)
     367             : {
     368           1 :         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           1 :         u32 num_hits = 0;
     374             : 
     375             :         /* Plane src has fractional part. */
     376           2 :         set_plane_src(&mock->old_state, 0x40002, 0x40002,
     377             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     378           2 :         set_plane_src(&mock->state, 0x40002, 0x40002,
     379             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     380             :         /* Damage intersect with plane src. */
     381           1 :         set_damage_clip(&damage, 10, 1, 1360, 330);
     382           2 :         set_damage_blob(&damage_blob, &damage, sizeof(damage));
     383           2 :         set_plane_damage(&mock->state, &damage_blob);
     384           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     385           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     386           1 :                 num_hits++;
     387             : 
     388           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
     389             :                             "Should return damage clipped to rounded off src.");
     390           1 :         check_damage_clip(test, &clip, 10, 4, 1029, 330);
     391           1 : }
     392             : 
     393           1 : static void drm_test_damage_iter_single_damage_outside_fractional_src(struct kunit *test)
     394             : {
     395           1 :         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           1 :         u32 num_hits = 0;
     401             : 
     402             :         /* Plane src has fractional part. */
     403           2 :         set_plane_src(&mock->old_state, 0x40002, 0x40002,
     404             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     405           2 :         set_plane_src(&mock->state, 0x40002, 0x40002,
     406             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     407             :         /* Damage clip outside plane src */
     408           1 :         set_damage_clip(&damage, 1360, 1360, 1380, 1380);
     409           2 :         set_damage_blob(&damage_blob, &damage, sizeof(damage));
     410           2 :         set_plane_damage(&mock->state, &damage_blob);
     411           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     412           2 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     413           0 :                 num_hits++;
     414             : 
     415           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
     416           1 : }
     417             : 
     418           1 : static void drm_test_damage_iter_single_damage_src_moved(struct kunit *test)
     419             : {
     420           1 :         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           1 :         u32 num_hits = 0;
     426             : 
     427             :         /* Plane src moved since old plane state. */
     428           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     429           2 :         set_plane_src(&mock->state, 10 << 16, 10 << 16,
     430             :                       (10 + 1024) << 16, (10 + 768) << 16);
     431           1 :         set_damage_clip(&damage, 20, 30, 256, 256);
     432           2 :         set_damage_blob(&damage_blob, &damage, sizeof(damage));
     433           2 :         set_plane_damage(&mock->state, &damage_blob);
     434           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     435           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     436           1 :                 num_hits++;
     437             : 
     438           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
     439             :                             "Should return plane src as damage.");
     440           1 :         check_damage_clip(test, &clip, 10, 10, 1034, 778);
     441           1 : }
     442             : 
     443           1 : static void drm_test_damage_iter_single_damage_fractional_src_moved(struct kunit *test)
     444             : {
     445           1 :         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           1 :         u32 num_hits = 0;
     451             : 
     452             :         /* Plane src with fractional part moved since old plane state. */
     453           2 :         set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
     454             :                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
     455           2 :         set_plane_src(&mock->state, 0x40002, 0x40002,
     456             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     457             :         /* Damage intersect with plane src. */
     458           1 :         set_damage_clip(&damage, 20, 30, 1360, 256);
     459           2 :         set_damage_blob(&damage_blob, &damage, sizeof(damage));
     460           2 :         set_plane_damage(&mock->state, &damage_blob);
     461           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     462           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     463           1 :                 num_hits++;
     464             : 
     465           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
     466             :                             "Should return rounded off plane as damage.");
     467           1 :         check_damage_clip(test, &clip, 4, 4, 1029, 773);
     468           1 : }
     469             : 
     470           1 : static void drm_test_damage_iter_damage(struct kunit *test)
     471             : {
     472           1 :         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           1 :         u32 num_hits = 0;
     478             : 
     479           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     480           2 :         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
     481             :         /* 2 damage clips. */
     482           1 :         set_damage_clip(&damage[0], 20, 30, 200, 180);
     483           1 :         set_damage_clip(&damage[1], 240, 200, 280, 250);
     484           2 :         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
     485           2 :         set_plane_damage(&mock->state, &damage_blob);
     486           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     487           4 :         drm_atomic_for_each_plane_damage(&iter, &clip) {
     488           2 :                 if (num_hits == 0)
     489           1 :                         check_damage_clip(test, &clip, 20, 30, 200, 180);
     490           2 :                 if (num_hits == 1)
     491           1 :                         check_damage_clip(test, &clip, 240, 200, 280, 250);
     492           2 :                 num_hits++;
     493             :         }
     494             : 
     495           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 2, "Should return damage when set.");
     496           1 : }
     497             : 
     498           1 : static void drm_test_damage_iter_damage_one_intersect(struct kunit *test)
     499             : {
     500           1 :         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           1 :         u32 num_hits = 0;
     506             : 
     507           2 :         set_plane_src(&mock->old_state, 0x40002, 0x40002,
     508             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     509           2 :         set_plane_src(&mock->state, 0x40002, 0x40002,
     510             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     511             :         /* 2 damage clips, one intersect plane src. */
     512           1 :         set_damage_clip(&damage[0], 20, 30, 200, 180);
     513           1 :         set_damage_clip(&damage[1], 2, 2, 1360, 1360);
     514           2 :         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
     515           2 :         set_plane_damage(&mock->state, &damage_blob);
     516           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     517           4 :         drm_atomic_for_each_plane_damage(&iter, &clip) {
     518           2 :                 if (num_hits == 0)
     519           1 :                         check_damage_clip(test, &clip, 20, 30, 200, 180);
     520           2 :                 if (num_hits == 1)
     521           1 :                         check_damage_clip(test, &clip, 4, 4, 1029, 773);
     522           2 :                 num_hits++;
     523             :         }
     524             : 
     525           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 2, "Should return damage when set.");
     526           1 : }
     527             : 
     528           1 : static void drm_test_damage_iter_damage_one_outside(struct kunit *test)
     529             : {
     530           1 :         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           1 :         u32 num_hits = 0;
     536             : 
     537           2 :         set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
     538           2 :         set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
     539             :         /* 2 damage clips, one outside plane src. */
     540           1 :         set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
     541           1 :         set_damage_clip(&damage[1], 240, 200, 280, 250);
     542           2 :         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
     543           2 :         set_plane_damage(&mock->state, &damage_blob);
     544           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     545           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     546           1 :                 num_hits++;
     547             : 
     548           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
     549           1 :         check_damage_clip(test, &clip, 240, 200, 280, 250);
     550           1 : }
     551             : 
     552           1 : static void drm_test_damage_iter_damage_src_moved(struct kunit *test)
     553             : {
     554           1 :         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           1 :         u32 num_hits = 0;
     560             : 
     561           2 :         set_plane_src(&mock->old_state, 0x40002, 0x40002,
     562             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     563           2 :         set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
     564             :                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
     565             :         /* 2 damage clips, one outside plane src. */
     566           1 :         set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
     567           1 :         set_damage_clip(&damage[1], 240, 200, 280, 250);
     568           2 :         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
     569           2 :         set_plane_damage(&mock->state, &damage_blob);
     570           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     571           3 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     572           1 :                 num_hits++;
     573             : 
     574           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
     575             :                             "Should return round off plane src as damage.");
     576           1 :         check_damage_clip(test, &clip, 3, 3, 1028, 772);
     577           1 : }
     578             : 
     579           1 : static void drm_test_damage_iter_damage_not_visible(struct kunit *test)
     580             : {
     581           1 :         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           1 :         u32 num_hits = 0;
     587             : 
     588           1 :         mock->state.visible = false;
     589             : 
     590           2 :         set_plane_src(&mock->old_state, 0x40002, 0x40002,
     591             :                       0x40002 + (1024 << 16), 0x40002 + (768 << 16));
     592           2 :         set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
     593             :                       0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
     594             :         /* 2 damage clips, one outside plane src. */
     595           1 :         set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
     596           1 :         set_damage_clip(&damage[1], 240, 200, 280, 250);
     597           2 :         set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
     598           2 :         set_plane_damage(&mock->state, &damage_blob);
     599           1 :         drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
     600           2 :         drm_atomic_for_each_plane_damage(&iter, &clip)
     601           0 :                 num_hits++;
     602             : 
     603           1 :         KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should not return any damage.");
     604           1 : }
     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");

Generated by: LCOV version 1.14