LCOV - code coverage report
Current view: top level - drivers/gpu/drm/tests - drm_rect_test.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 145 145 100.0 %
Date: 2023-04-06 08:38:28 Functions: 17 17 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Test cases for the drm_rect functions
       4             :  *
       5             :  * Copyright (c) 2022 MaĆ­ra Canal <mairacanal@riseup.net>
       6             :  */
       7             : 
       8             : #include <kunit/test.h>
       9             : 
      10             : #include <drm/drm_rect.h>
      11             : #include <drm/drm_mode.h>
      12             : 
      13             : #include <linux/string_helpers.h>
      14             : #include <linux/errno.h>
      15             : 
      16          27 : static void drm_rect_compare(struct kunit *test, const struct drm_rect *r,
      17             :                              const struct drm_rect *expected)
      18             : {
      19          27 :         KUNIT_EXPECT_EQ(test, r->x1, expected->x1);
      20          27 :         KUNIT_EXPECT_EQ(test, r->y1, expected->y1);
      21          81 :         KUNIT_EXPECT_EQ(test, drm_rect_width(r), drm_rect_width(expected));
      22          81 :         KUNIT_EXPECT_EQ(test, drm_rect_height(r), drm_rect_height(expected));
      23          27 : }
      24             : 
      25           1 : static void drm_test_rect_clip_scaled_div_by_zero(struct kunit *test)
      26             : {
      27             :         struct drm_rect src, dst, clip;
      28             :         bool visible;
      29             : 
      30             :         /*
      31             :          * Make sure we don't divide by zero when dst
      32             :          * width/height is zero and dst and clip do not intersect.
      33             :          */
      34           1 :         drm_rect_init(&src, 0, 0, 0, 0);
      35           1 :         drm_rect_init(&dst, 0, 0, 0, 0);
      36           1 :         drm_rect_init(&clip, 1, 1, 1, 1);
      37           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
      38             : 
      39           1 :         KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination not be visible\n");
      40           1 :         KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n");
      41             : 
      42           1 :         drm_rect_init(&src, 0, 0, 0, 0);
      43           1 :         drm_rect_init(&dst, 3, 3, 0, 0);
      44           1 :         drm_rect_init(&clip, 1, 1, 1, 1);
      45           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
      46             : 
      47           1 :         KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination not be visible\n");
      48           1 :         KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n");
      49           1 : }
      50             : 
      51           1 : static void drm_test_rect_clip_scaled_not_clipped(struct kunit *test)
      52             : {
      53             :         struct drm_rect src, dst, clip;
      54             :         bool visible;
      55             : 
      56             :         /* 1:1 scaling */
      57           1 :         drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16);
      58           1 :         drm_rect_init(&dst, 0, 0, 1, 1);
      59           1 :         drm_rect_init(&clip, 0, 0, 1, 1);
      60             : 
      61           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
      62             : 
      63           1 :         KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 ||
      64             :                                src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n");
      65           1 :         KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 ||
      66             :                                dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n");
      67           1 :         KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n");
      68           1 :         KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
      69             : 
      70             :         /* 2:1 scaling */
      71           1 :         drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16);
      72           1 :         drm_rect_init(&dst, 0, 0, 1, 1);
      73           1 :         drm_rect_init(&clip, 0, 0, 1, 1);
      74             : 
      75           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
      76             : 
      77           1 :         KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 2 << 16 ||
      78             :                                src.y1 != 0 || src.y2 != 2 << 16, "Source badly clipped\n");
      79           1 :         KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 ||
      80             :                                dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n");
      81           1 :         KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n");
      82           1 :         KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
      83             : 
      84             :         /* 1:2 scaling */
      85           1 :         drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16);
      86           1 :         drm_rect_init(&dst, 0, 0, 2, 2);
      87           1 :         drm_rect_init(&clip, 0, 0, 2, 2);
      88             : 
      89           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
      90             : 
      91           1 :         KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 ||
      92             :                                src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n");
      93           1 :         KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 2 ||
      94             :                                dst.y1 != 0 || dst.y2 != 2, "Destination badly clipped\n");
      95           1 :         KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n");
      96           1 :         KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
      97           1 : }
      98             : 
      99           1 : static void drm_test_rect_clip_scaled_clipped(struct kunit *test)
     100             : {
     101             :         struct drm_rect src, dst, clip;
     102             :         bool visible;
     103             : 
     104             :         /* 1:1 scaling top/left clip */
     105           1 :         drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16);
     106           1 :         drm_rect_init(&dst, 0, 0, 2, 2);
     107             :         drm_rect_init(&clip, 0, 0, 1, 1);
     108             : 
     109           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
     110             : 
     111           1 :         KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 ||
     112             :                                src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n");
     113           1 :         KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 ||
     114             :                                dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n");
     115           1 :         KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n");
     116           1 :         KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
     117             : 
     118             :         /* 1:1 scaling bottom/right clip */
     119           1 :         drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16);
     120           1 :         drm_rect_init(&dst, 0, 0, 2, 2);
     121           1 :         drm_rect_init(&clip, 1, 1, 1, 1);
     122             : 
     123           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
     124             : 
     125           1 :         KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 1 << 16 || src.x2 != 2 << 16 ||
     126             :                                src.y1 != 1 << 16 || src.y2 != 2 << 16, "Source badly clipped\n");
     127           1 :         KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 1 || dst.x2 != 2 || dst.y1 != 1 ||
     128             :                                dst.y2 != 2, "Destination badly clipped\n");
     129           1 :         KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n");
     130           1 :         KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
     131             : 
     132             :         /* 2:1 scaling top/left clip */
     133           1 :         drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16);
     134           1 :         drm_rect_init(&dst, 0, 0, 2, 2);
     135           1 :         drm_rect_init(&clip, 0, 0, 1, 1);
     136             : 
     137           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
     138             : 
     139           1 :         KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 2 << 16 ||
     140             :                                src.y1 != 0 || src.y2 != 2 << 16, "Source badly clipped\n");
     141           1 :         KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || dst.y1 != 0 ||
     142             :                                dst.y2 != 1, "Destination badly clipped\n");
     143           1 :         KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n");
     144           1 :         KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
     145             : 
     146             :         /* 2:1 scaling bottom/right clip */
     147           1 :         drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16);
     148           1 :         drm_rect_init(&dst, 0, 0, 2, 2);
     149           1 :         drm_rect_init(&clip, 1, 1, 1, 1);
     150             : 
     151           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
     152             : 
     153           1 :         KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 2 << 16 || src.x2 != 4 << 16 ||
     154             :                                src.y1 != 2 << 16 || src.y2 != 4 << 16, "Source badly clipped\n");
     155           1 :         KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 1 || dst.x2 != 2 || dst.y1 != 1 ||
     156             :                                dst.y2 != 2, "Destination badly clipped\n");
     157           1 :         KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n");
     158           1 :         KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
     159             : 
     160             :         /* 1:2 scaling top/left clip */
     161           1 :         drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16);
     162           1 :         drm_rect_init(&dst, 0, 0, 4, 4);
     163           1 :         drm_rect_init(&clip, 0, 0, 2, 2);
     164             : 
     165           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
     166             : 
     167           1 :         KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 ||
     168             :                                src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n");
     169           1 :         KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 2 || dst.y1 != 0 ||
     170             :                                dst.y2 != 2, "Destination badly clipped\n");
     171           1 :         KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n");
     172           1 :         KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
     173             : 
     174             :         /* 1:2 scaling bottom/right clip */
     175           1 :         drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16);
     176           1 :         drm_rect_init(&dst, 0, 0, 4, 4);
     177           1 :         drm_rect_init(&clip, 2, 2, 2, 2);
     178             : 
     179           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
     180             : 
     181           1 :         KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 1 << 16 || src.x2 != 2 << 16 ||
     182             :                                src.y1 != 1 << 16 || src.y2 != 2 << 16, "Source badly clipped\n");
     183           1 :         KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 2 || dst.x2 != 4 || dst.y1 != 2 ||
     184             :                                dst.y2 != 4, "Destination badly clipped\n");
     185           1 :         KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n");
     186           1 :         KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n");
     187           1 : }
     188             : 
     189           1 : static void drm_test_rect_clip_scaled_signed_vs_unsigned(struct kunit *test)
     190             : {
     191             :         struct drm_rect src, dst, clip;
     192             :         bool visible;
     193             : 
     194             :         /*
     195             :          * 'clip.x2 - dst.x1 >= dst width' could result a negative
     196             :          * src rectangle width which is no longer expected by the
     197             :          * code as it's using unsigned types. This could lead to
     198             :          * the clipped source rectangle appering visible when it
     199             :          * should have been fully clipped. Make sure both rectangles
     200             :          * end up invisible.
     201             :          */
     202           1 :         drm_rect_init(&src, 0, 0, INT_MAX, INT_MAX);
     203           1 :         drm_rect_init(&dst, 0, 0, 2, 2);
     204           1 :         drm_rect_init(&clip, 3, 3, 1, 1);
     205             : 
     206           1 :         visible = drm_rect_clip_scaled(&src, &dst, &clip);
     207             : 
     208           1 :         KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination should not be visible\n");
     209           1 :         KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n");
     210           1 : }
     211             : 
     212             : struct drm_rect_intersect_case {
     213             :         const char *description;
     214             :         struct drm_rect r1, r2;
     215             :         bool should_be_visible;
     216             :         struct drm_rect expected_intersection;
     217             : };
     218             : 
     219             : static const struct drm_rect_intersect_case drm_rect_intersect_cases[] = {
     220             :         {
     221             :                 .description = "top-left x bottom-right",
     222             :                 .r1 = DRM_RECT_INIT(1, 1, 2, 2),
     223             :                 .r2 = DRM_RECT_INIT(0, 0, 2, 2),
     224             :                 .should_be_visible = true,
     225             :                 .expected_intersection = DRM_RECT_INIT(1, 1, 1, 1),
     226             :         },
     227             :         {
     228             :                 .description = "top-right x bottom-left",
     229             :                 .r1 = DRM_RECT_INIT(0, 0, 2, 2),
     230             :                 .r2 = DRM_RECT_INIT(1, -1, 2, 2),
     231             :                 .should_be_visible = true,
     232             :                 .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1),
     233             :         },
     234             :         {
     235             :                 .description = "bottom-left x top-right",
     236             :                 .r1 = DRM_RECT_INIT(1, -1, 2, 2),
     237             :                 .r2 = DRM_RECT_INIT(0, 0, 2, 2),
     238             :                 .should_be_visible = true,
     239             :                 .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1),
     240             :         },
     241             :         {
     242             :                 .description = "bottom-right x top-left",
     243             :                 .r1 = DRM_RECT_INIT(0, 0, 2, 2),
     244             :                 .r2 = DRM_RECT_INIT(1, 1, 2, 2),
     245             :                 .should_be_visible = true,
     246             :                 .expected_intersection = DRM_RECT_INIT(1, 1, 1, 1),
     247             :         },
     248             :         {
     249             :                 .description = "right x left",
     250             :                 .r1 = DRM_RECT_INIT(0, 0, 2, 1),
     251             :                 .r2 = DRM_RECT_INIT(1, 0, 3, 1),
     252             :                 .should_be_visible = true,
     253             :                 .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1),
     254             :         },
     255             :         {
     256             :                 .description = "left x right",
     257             :                 .r1 = DRM_RECT_INIT(1, 0, 3, 1),
     258             :                 .r2 = DRM_RECT_INIT(0, 0, 2, 1),
     259             :                 .should_be_visible = true,
     260             :                 .expected_intersection = DRM_RECT_INIT(1, 0, 1, 1),
     261             :         },
     262             :         {
     263             :                 .description = "up x bottom",
     264             :                 .r1 = DRM_RECT_INIT(0, 0, 1, 2),
     265             :                 .r2 = DRM_RECT_INIT(0, -1, 1, 3),
     266             :                 .should_be_visible = true,
     267             :                 .expected_intersection = DRM_RECT_INIT(0, 0, 1, 2),
     268             :         },
     269             :         {
     270             :                 .description = "bottom x up",
     271             :                 .r1 = DRM_RECT_INIT(0, -1, 1, 3),
     272             :                 .r2 = DRM_RECT_INIT(0, 0, 1, 2),
     273             :                 .should_be_visible = true,
     274             :                 .expected_intersection = DRM_RECT_INIT(0, 0, 1, 2),
     275             :         },
     276             :         {
     277             :                 .description = "touching corner",
     278             :                 .r1 = DRM_RECT_INIT(0, 0, 1, 1),
     279             :                 .r2 = DRM_RECT_INIT(1, 1, 2, 2),
     280             :                 .should_be_visible = false,
     281             :                 .expected_intersection = DRM_RECT_INIT(1, 1, 0, 0),
     282             :         },
     283             :         {
     284             :                 .description = "touching side",
     285             :                 .r1 = DRM_RECT_INIT(0, 0, 1, 1),
     286             :                 .r2 = DRM_RECT_INIT(1, 0, 1, 1),
     287             :                 .should_be_visible = false,
     288             :                 .expected_intersection = DRM_RECT_INIT(1, 0, 0, 1),
     289             :         },
     290             :         {
     291             :                 .description = "equal rects",
     292             :                 .r1 = DRM_RECT_INIT(0, 0, 2, 2),
     293             :                 .r2 = DRM_RECT_INIT(0, 0, 2, 2),
     294             :                 .should_be_visible = true,
     295             :                 .expected_intersection = DRM_RECT_INIT(0, 0, 2, 2),
     296             :         },
     297             :         {
     298             :                 .description = "inside another",
     299             :                 .r1 = DRM_RECT_INIT(0, 0, 2, 2),
     300             :                 .r2 = DRM_RECT_INIT(1, 1, 1, 1),
     301             :                 .should_be_visible = true,
     302             :                 .expected_intersection = DRM_RECT_INIT(1, 1, 1, 1),
     303             :         },
     304             :         {
     305             :                 .description = "far away",
     306             :                 .r1 = DRM_RECT_INIT(0, 0, 1, 1),
     307             :                 .r2 = DRM_RECT_INIT(3, 6, 1, 1),
     308             :                 .should_be_visible = false,
     309             :                 .expected_intersection = DRM_RECT_INIT(3, 6, -2, -5),
     310             :         },
     311             :         {
     312             :                 .description = "points intersecting",
     313             :                 .r1 = DRM_RECT_INIT(5, 10, 0, 0),
     314             :                 .r2 = DRM_RECT_INIT(5, 10, 0, 0),
     315             :                 .should_be_visible = false,
     316             :                 .expected_intersection = DRM_RECT_INIT(5, 10, 0, 0),
     317             :         },
     318             :         {
     319             :                 .description = "points not intersecting",
     320             :                 .r1 = DRM_RECT_INIT(0, 0, 0, 0),
     321             :                 .r2 = DRM_RECT_INIT(5, 10, 0, 0),
     322             :                 .should_be_visible = false,
     323             :                 .expected_intersection = DRM_RECT_INIT(5, 10, -5, -10),
     324             :         },
     325             : };
     326             : 
     327          15 : static void drm_rect_intersect_case_desc(const struct drm_rect_intersect_case *t, char *desc)
     328             : {
     329          75 :         snprintf(desc, KUNIT_PARAM_DESC_SIZE,
     330             :                  "%s: " DRM_RECT_FMT " x " DRM_RECT_FMT,
     331             :                  t->description, DRM_RECT_ARG(&t->r1), DRM_RECT_ARG(&t->r2));
     332          15 : }
     333             : 
     334          16 : KUNIT_ARRAY_PARAM(drm_rect_intersect, drm_rect_intersect_cases, drm_rect_intersect_case_desc);
     335             : 
     336          15 : static void drm_test_rect_intersect(struct kunit *test)
     337             : {
     338          15 :         const struct drm_rect_intersect_case *params = test->param_value;
     339          15 :         struct drm_rect r1_aux = params->r1;
     340             :         bool visible;
     341             : 
     342          15 :         visible = drm_rect_intersect(&r1_aux, &params->r2);
     343             : 
     344          15 :         KUNIT_EXPECT_EQ(test, visible, params->should_be_visible);
     345          15 :         drm_rect_compare(test, &r1_aux, &params->expected_intersection);
     346          15 : }
     347             : 
     348             : struct drm_rect_scale_case {
     349             :         const char *name;
     350             :         struct drm_rect src, dst;
     351             :         int min_range, max_range;
     352             :         int expected_scaling_factor;
     353             : };
     354             : 
     355             : static const struct drm_rect_scale_case drm_rect_hscale_cases[] = {
     356             :         {
     357             :                 .name = "normal use",
     358             :                 .src = DRM_RECT_INIT(0, 0, 2 << 16, 0),
     359             :                 .dst = DRM_RECT_INIT(0, 0, 1 << 16, 0),
     360             :                 .min_range = 0, .max_range = INT_MAX,
     361             :                 .expected_scaling_factor = 2,
     362             :         },
     363             :         {
     364             :                 .name = "out of max range",
     365             :                 .src = DRM_RECT_INIT(0, 0, 10 << 16, 0),
     366             :                 .dst = DRM_RECT_INIT(0, 0, 1 << 16, 0),
     367             :                 .min_range = 3, .max_range = 5,
     368             :                 .expected_scaling_factor = -ERANGE,
     369             :         },
     370             :         {
     371             :                 .name = "out of min range",
     372             :                 .src = DRM_RECT_INIT(0, 0, 2 << 16, 0),
     373             :                 .dst = DRM_RECT_INIT(0, 0, 1 << 16, 0),
     374             :                 .min_range = 3, .max_range = 5,
     375             :                 .expected_scaling_factor = -ERANGE,
     376             :         },
     377             :         {
     378             :                 .name = "zero dst width",
     379             :                 .src = DRM_RECT_INIT(0, 0, 2 << 16, 0),
     380             :                 .dst = DRM_RECT_INIT(0, 0, 0 << 16, 0),
     381             :                 .min_range = 0, .max_range = INT_MAX,
     382             :                 .expected_scaling_factor = 0,
     383             :         },
     384             :         {
     385             :                 .name = "negative src width",
     386             :                 .src = DRM_RECT_INIT(0, 0, -(1 << 16), 0),
     387             :                 .dst = DRM_RECT_INIT(0, 0, 1 << 16, 0),
     388             :                 .min_range = 0, .max_range = INT_MAX,
     389             :                 .expected_scaling_factor = -EINVAL,
     390             :         },
     391             :         {
     392             :                 .name = "negative dst width",
     393             :                 .src = DRM_RECT_INIT(0, 0, 1 << 16, 0),
     394             :                 .dst = DRM_RECT_INIT(0, 0, -(1 << 16), 0),
     395             :                 .min_range = 0, .max_range = INT_MAX,
     396             :                 .expected_scaling_factor = -EINVAL,
     397             :         },
     398             : };
     399             : 
     400          12 : static void drm_rect_scale_case_desc(const struct drm_rect_scale_case *t, char *desc)
     401             : {
     402          12 :         strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
     403          12 : }
     404             : 
     405           7 : KUNIT_ARRAY_PARAM(drm_rect_hscale, drm_rect_hscale_cases, drm_rect_scale_case_desc);
     406             : 
     407           6 : static void drm_test_rect_calc_hscale(struct kunit *test)
     408             : {
     409           6 :         const struct drm_rect_scale_case *params = test->param_value;
     410             :         int scaling_factor;
     411             : 
     412           6 :         scaling_factor = drm_rect_calc_hscale(&params->src, &params->dst,
     413             :                                               params->min_range, params->max_range);
     414             : 
     415           6 :         KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor);
     416           6 : }
     417             : 
     418             : static const struct drm_rect_scale_case drm_rect_vscale_cases[] = {
     419             :         {
     420             :                 .name = "normal use",
     421             :                 .src = DRM_RECT_INIT(0, 0, 0, 2 << 16),
     422             :                 .dst = DRM_RECT_INIT(0, 0, 0, 1 << 16),
     423             :                 .min_range = 0, .max_range = INT_MAX,
     424             :                 .expected_scaling_factor = 2,
     425             :         },
     426             :         {
     427             :                 .name = "out of max range",
     428             :                 .src = DRM_RECT_INIT(0, 0, 0, 10 << 16),
     429             :                 .dst = DRM_RECT_INIT(0, 0, 0, 1 << 16),
     430             :                 .min_range = 3, .max_range = 5,
     431             :                 .expected_scaling_factor = -ERANGE,
     432             :         },
     433             :         {
     434             :                 .name = "out of min range",
     435             :                 .src = DRM_RECT_INIT(0, 0, 0, 2 << 16),
     436             :                 .dst = DRM_RECT_INIT(0, 0, 0, 1 << 16),
     437             :                 .min_range = 3, .max_range = 5,
     438             :                 .expected_scaling_factor = -ERANGE,
     439             :         },
     440             :         {
     441             :                 .name = "zero dst height",
     442             :                 .src = DRM_RECT_INIT(0, 0, 0, 2 << 16),
     443             :                 .dst = DRM_RECT_INIT(0, 0, 0, 0 << 16),
     444             :                 .min_range = 0, .max_range = INT_MAX,
     445             :                 .expected_scaling_factor = 0,
     446             :         },
     447             :         {
     448             :                 .name = "negative src height",
     449             :                 .src = DRM_RECT_INIT(0, 0, 0, -(1 << 16)),
     450             :                 .dst = DRM_RECT_INIT(0, 0, 0, 1 << 16),
     451             :                 .min_range = 0, .max_range = INT_MAX,
     452             :                 .expected_scaling_factor = -EINVAL,
     453             :         },
     454             :         {
     455             :                 .name = "negative dst height",
     456             :                 .src = DRM_RECT_INIT(0, 0, 0, 1 << 16),
     457             :                 .dst = DRM_RECT_INIT(0, 0, 0, -(1 << 16)),
     458             :                 .min_range = 0, .max_range = INT_MAX,
     459             :                 .expected_scaling_factor = -EINVAL,
     460             :         },
     461             : };
     462             : 
     463           7 : KUNIT_ARRAY_PARAM(drm_rect_vscale, drm_rect_vscale_cases, drm_rect_scale_case_desc);
     464             : 
     465           6 : static void drm_test_rect_calc_vscale(struct kunit *test)
     466             : {
     467           6 :         const struct drm_rect_scale_case *params = test->param_value;
     468             :         int scaling_factor;
     469             : 
     470           6 :         scaling_factor = drm_rect_calc_vscale(&params->src, &params->dst,
     471             :                                               params->min_range, params->max_range);
     472             : 
     473           6 :         KUNIT_EXPECT_EQ(test, scaling_factor, params->expected_scaling_factor);
     474           6 : }
     475             : 
     476             : struct drm_rect_rotate_case {
     477             :         const char *name;
     478             :         unsigned int rotation;
     479             :         struct drm_rect rect;
     480             :         int width, height;
     481             :         struct drm_rect expected;
     482             : };
     483             : 
     484             : static const struct drm_rect_rotate_case drm_rect_rotate_cases[] = {
     485             :         {
     486             :                 .name = "reflect-x",
     487             :                 .rotation = DRM_MODE_REFLECT_X,
     488             :                 .rect = DRM_RECT_INIT(0, 0, 5, 5),
     489             :                 .width = 5, .height = 10,
     490             :                 .expected = DRM_RECT_INIT(0, 0, 5, 5),
     491             :         },
     492             :         {
     493             :                 .name = "reflect-y",
     494             :                 .rotation = DRM_MODE_REFLECT_Y,
     495             :                 .rect = DRM_RECT_INIT(0, 0, 5, 5),
     496             :                 .width = 5, .height = 10,
     497             :                 .expected = DRM_RECT_INIT(0, 5, 5, 5),
     498             :         },
     499             :         {
     500             :                 .name = "rotate-0",
     501             :                 .rotation = DRM_MODE_ROTATE_0,
     502             :                 .rect = DRM_RECT_INIT(0, 0, 5, 5),
     503             :                 .width = 5, .height = 10,
     504             :                 .expected = DRM_RECT_INIT(0, 0, 5, 5),
     505             :         },
     506             :         {
     507             :                 .name = "rotate-90",
     508             :                 .rotation = DRM_MODE_ROTATE_90,
     509             :                 .rect = DRM_RECT_INIT(0, 0, 5, 10),
     510             :                 .width = 5, .height = 10,
     511             :                 .expected = DRM_RECT_INIT(0, 0, 10, 5),
     512             :         },
     513             :         {
     514             :                 .name = "rotate-180",
     515             :                 .rotation = DRM_MODE_ROTATE_180,
     516             :                 .rect = DRM_RECT_INIT(0, 0, 5, 10),
     517             :                 .width = 5, .height = 10,
     518             :                 .expected = DRM_RECT_INIT(0, 0, 5, 10),
     519             :         },
     520             :         {
     521             :                 .name = "rotate-270",
     522             :                 .rotation = DRM_MODE_ROTATE_270,
     523             :                 .rect = DRM_RECT_INIT(0, 0, 5, 10),
     524             :                 .width = 5, .height = 10,
     525             :                 .expected = DRM_RECT_INIT(0, 0, 10, 5),
     526             :         },
     527             : };
     528             : 
     529          12 : static void drm_rect_rotate_case_desc(const struct drm_rect_rotate_case *t, char *desc)
     530             : {
     531          12 :         strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
     532          12 : }
     533             : 
     534          14 : KUNIT_ARRAY_PARAM(drm_rect_rotate, drm_rect_rotate_cases, drm_rect_rotate_case_desc);
     535             : 
     536           6 : static void drm_test_rect_rotate(struct kunit *test)
     537             : {
     538           6 :         const struct drm_rect_rotate_case *params = test->param_value;
     539           6 :         struct drm_rect r = params->rect;
     540             : 
     541           6 :         drm_rect_rotate(&r, params->width, params->height, params->rotation);
     542             : 
     543           6 :         drm_rect_compare(test, &r, &params->expected);
     544           6 : }
     545             : 
     546           6 : static void drm_test_rect_rotate_inv(struct kunit *test)
     547             : {
     548           6 :         const struct drm_rect_rotate_case *params = test->param_value;
     549           6 :         struct drm_rect r = params->expected;
     550             : 
     551           6 :         drm_rect_rotate_inv(&r, params->width, params->height, params->rotation);
     552             : 
     553           6 :         drm_rect_compare(test, &r, &params->rect);
     554           6 : }
     555             : 
     556             : static struct kunit_case drm_rect_tests[] = {
     557             :         KUNIT_CASE(drm_test_rect_clip_scaled_div_by_zero),
     558             :         KUNIT_CASE(drm_test_rect_clip_scaled_not_clipped),
     559             :         KUNIT_CASE(drm_test_rect_clip_scaled_clipped),
     560             :         KUNIT_CASE(drm_test_rect_clip_scaled_signed_vs_unsigned),
     561             :         KUNIT_CASE_PARAM(drm_test_rect_intersect, drm_rect_intersect_gen_params),
     562             :         KUNIT_CASE_PARAM(drm_test_rect_calc_hscale, drm_rect_hscale_gen_params),
     563             :         KUNIT_CASE_PARAM(drm_test_rect_calc_vscale, drm_rect_vscale_gen_params),
     564             :         KUNIT_CASE_PARAM(drm_test_rect_rotate, drm_rect_rotate_gen_params),
     565             :         KUNIT_CASE_PARAM(drm_test_rect_rotate_inv, drm_rect_rotate_gen_params),
     566             :         { }
     567             : };
     568             : 
     569             : static struct kunit_suite drm_rect_test_suite = {
     570             :         .name = "drm_rect",
     571             :         .test_cases = drm_rect_tests,
     572             : };
     573             : 
     574             : kunit_test_suite(drm_rect_test_suite);
     575             : 
     576             : MODULE_LICENSE("GPL");

Generated by: LCOV version 1.14