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 12 static void drm_test_rect_clip_scaled_div_by_zero(struct kunit *test) 13 { 14 struct drm_rect src, dst, clip; 15 bool visible; 16 17 /* 18 * Make sure we don't divide by zero when dst 19 * width/height is zero and dst and clip do not intersect. 20 */ 21 drm_rect_init(&src, 0, 0, 0, 0); 22 drm_rect_init(&dst, 0, 0, 0, 0); 23 drm_rect_init(&clip, 1, 1, 1, 1); 24 visible = drm_rect_clip_scaled(&src, &dst, &clip); 25 26 KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination not be visible\n"); 27 KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n"); 28 29 drm_rect_init(&src, 0, 0, 0, 0); 30 drm_rect_init(&dst, 3, 3, 0, 0); 31 drm_rect_init(&clip, 1, 1, 1, 1); 32 visible = drm_rect_clip_scaled(&src, &dst, &clip); 33 34 KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination not be visible\n"); 35 KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n"); 36 } 37 38 static void drm_test_rect_clip_scaled_not_clipped(struct kunit *test) 39 { 40 struct drm_rect src, dst, clip; 41 bool visible; 42 43 /* 1:1 scaling */ 44 drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16); 45 drm_rect_init(&dst, 0, 0, 1, 1); 46 drm_rect_init(&clip, 0, 0, 1, 1); 47 48 visible = drm_rect_clip_scaled(&src, &dst, &clip); 49 50 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || 51 src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); 52 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || 53 dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n"); 54 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 55 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 56 57 /* 2:1 scaling */ 58 drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 59 drm_rect_init(&dst, 0, 0, 1, 1); 60 drm_rect_init(&clip, 0, 0, 1, 1); 61 62 visible = drm_rect_clip_scaled(&src, &dst, &clip); 63 64 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 2 << 16 || 65 src.y1 != 0 || src.y2 != 2 << 16, "Source badly clipped\n"); 66 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || 67 dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n"); 68 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 69 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 70 71 /* 1:2 scaling */ 72 drm_rect_init(&src, 0, 0, 1 << 16, 1 << 16); 73 drm_rect_init(&dst, 0, 0, 2, 2); 74 drm_rect_init(&clip, 0, 0, 2, 2); 75 76 visible = drm_rect_clip_scaled(&src, &dst, &clip); 77 78 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || 79 src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); 80 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 2 || 81 dst.y1 != 0 || dst.y2 != 2, "Destination badly clipped\n"); 82 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 83 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 84 } 85 86 static void drm_test_rect_clip_scaled_clipped(struct kunit *test) 87 { 88 struct drm_rect src, dst, clip; 89 bool visible; 90 91 /* 1:1 scaling top/left clip */ 92 drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 93 drm_rect_init(&dst, 0, 0, 2, 2); 94 drm_rect_init(&clip, 0, 0, 1, 1); 95 96 visible = drm_rect_clip_scaled(&src, &dst, &clip); 97 98 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || 99 src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); 100 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || 101 dst.y1 != 0 || dst.y2 != 1, "Destination badly clipped\n"); 102 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 103 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 104 105 /* 1:1 scaling bottom/right clip */ 106 drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 107 drm_rect_init(&dst, 0, 0, 2, 2); 108 drm_rect_init(&clip, 1, 1, 1, 1); 109 110 visible = drm_rect_clip_scaled(&src, &dst, &clip); 111 112 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 1 << 16 || src.x2 != 2 << 16 || 113 src.y1 != 1 << 16 || src.y2 != 2 << 16, "Source badly clipped\n"); 114 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 1 || dst.x2 != 2 || dst.y1 != 1 || 115 dst.y2 != 2, "Destination badly clipped\n"); 116 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 117 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 118 119 /* 2:1 scaling top/left clip */ 120 drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16); 121 drm_rect_init(&dst, 0, 0, 2, 2); 122 drm_rect_init(&clip, 0, 0, 1, 1); 123 124 visible = drm_rect_clip_scaled(&src, &dst, &clip); 125 126 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 2 << 16 || 127 src.y1 != 0 || src.y2 != 2 << 16, "Source badly clipped\n"); 128 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 1 || dst.y1 != 0 || 129 dst.y2 != 1, "Destination badly clipped\n"); 130 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 131 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 132 133 /* 2:1 scaling bottom/right clip */ 134 drm_rect_init(&src, 0, 0, 4 << 16, 4 << 16); 135 drm_rect_init(&dst, 0, 0, 2, 2); 136 drm_rect_init(&clip, 1, 1, 1, 1); 137 138 visible = drm_rect_clip_scaled(&src, &dst, &clip); 139 140 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 2 << 16 || src.x2 != 4 << 16 || 141 src.y1 != 2 << 16 || src.y2 != 4 << 16, "Source badly clipped\n"); 142 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 1 || dst.x2 != 2 || dst.y1 != 1 || 143 dst.y2 != 2, "Destination badly clipped\n"); 144 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 145 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 146 147 /* 1:2 scaling top/left clip */ 148 drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 149 drm_rect_init(&dst, 0, 0, 4, 4); 150 drm_rect_init(&clip, 0, 0, 2, 2); 151 152 visible = drm_rect_clip_scaled(&src, &dst, &clip); 153 154 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 0 || src.x2 != 1 << 16 || 155 src.y1 != 0 || src.y2 != 1 << 16, "Source badly clipped\n"); 156 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 0 || dst.x2 != 2 || dst.y1 != 0 || 157 dst.y2 != 2, "Destination badly clipped\n"); 158 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 159 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 160 161 /* 1:2 scaling bottom/right clip */ 162 drm_rect_init(&src, 0, 0, 2 << 16, 2 << 16); 163 drm_rect_init(&dst, 0, 0, 4, 4); 164 drm_rect_init(&clip, 2, 2, 2, 2); 165 166 visible = drm_rect_clip_scaled(&src, &dst, &clip); 167 168 KUNIT_EXPECT_FALSE_MSG(test, src.x1 != 1 << 16 || src.x2 != 2 << 16 || 169 src.y1 != 1 << 16 || src.y2 != 2 << 16, "Source badly clipped\n"); 170 KUNIT_EXPECT_FALSE_MSG(test, dst.x1 != 2 || dst.x2 != 4 || dst.y1 != 2 || 171 dst.y2 != 4, "Destination badly clipped\n"); 172 KUNIT_EXPECT_TRUE_MSG(test, visible, "Destination should be visible\n"); 173 KUNIT_EXPECT_TRUE_MSG(test, drm_rect_visible(&src), "Source should be visible\n"); 174 } 175 176 static void drm_test_rect_clip_scaled_signed_vs_unsigned(struct kunit *test) 177 { 178 struct drm_rect src, dst, clip; 179 bool visible; 180 181 /* 182 * 'clip.x2 - dst.x1 >= dst width' could result a negative 183 * src rectangle width which is no longer expected by the 184 * code as it's using unsigned types. This could lead to 185 * the clipped source rectangle appering visible when it 186 * should have been fully clipped. Make sure both rectangles 187 * end up invisible. 188 */ 189 drm_rect_init(&src, 0, 0, INT_MAX, INT_MAX); 190 drm_rect_init(&dst, 0, 0, 2, 2); 191 drm_rect_init(&clip, 3, 3, 1, 1); 192 193 visible = drm_rect_clip_scaled(&src, &dst, &clip); 194 195 KUNIT_EXPECT_FALSE_MSG(test, visible, "Destination should not be visible\n"); 196 KUNIT_EXPECT_FALSE_MSG(test, drm_rect_visible(&src), "Source should not be visible\n"); 197 } 198 199 static struct kunit_case drm_rect_tests[] = { 200 KUNIT_CASE(drm_test_rect_clip_scaled_div_by_zero), 201 KUNIT_CASE(drm_test_rect_clip_scaled_not_clipped), 202 KUNIT_CASE(drm_test_rect_clip_scaled_clipped), 203 KUNIT_CASE(drm_test_rect_clip_scaled_signed_vs_unsigned), 204 { } 205 }; 206 207 static struct kunit_suite drm_rect_test_suite = { 208 .name = "drm_rect", 209 .test_cases = drm_rect_tests, 210 }; 211 212 kunit_test_suite(drm_rect_test_suite); 213 214 MODULE_LICENSE("GPL"); 215