Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Test case for drm_damage_helper functions
0004  */
0005 
0006 #define pr_fmt(fmt) "drm_damage_helper: " fmt
0007 
0008 #include <drm/drm_damage_helper.h>
0009 #include <drm/drm_framebuffer.h>
0010 #include <drm/drm_plane.h>
0011 #include <drm/drm_drv.h>
0012 
0013 #include "test-drm_modeset_common.h"
0014 
0015 struct drm_driver mock_driver;
0016 static struct drm_device mock_device;
0017 static struct drm_object_properties mock_obj_props;
0018 static struct drm_plane mock_plane;
0019 static struct drm_property mock_prop;
0020 
0021 static void mock_setup(struct drm_plane_state *state)
0022 {
0023     static bool setup_done = false;
0024 
0025     state->plane = &mock_plane;
0026 
0027     if (setup_done)
0028         return;
0029 
0030     /* just enough so that drm_plane_enable_fb_damage_clips() works */
0031     mock_device.driver = &mock_driver;
0032     mock_device.mode_config.prop_fb_damage_clips = &mock_prop;
0033     mock_plane.dev = &mock_device;
0034     mock_obj_props.count = 0;
0035     mock_plane.base.properties = &mock_obj_props;
0036     mock_prop.base.id = 1; /* 0 is an invalid id */
0037     mock_prop.dev = &mock_device;
0038 
0039     drm_plane_enable_fb_damage_clips(&mock_plane);
0040 }
0041 
0042 static void set_plane_src(struct drm_plane_state *state, int x1, int y1, int x2,
0043               int y2)
0044 {
0045     state->src.x1 = x1;
0046     state->src.y1 = y1;
0047     state->src.x2 = x2;
0048     state->src.y2 = y2;
0049 }
0050 
0051 static void set_damage_clip(struct drm_mode_rect *r, int x1, int y1, int x2,
0052                 int y2)
0053 {
0054     r->x1 = x1;
0055     r->y1 = y1;
0056     r->x2 = x2;
0057     r->y2 = y2;
0058 }
0059 
0060 static void set_damage_blob(struct drm_property_blob *damage_blob,
0061                 struct drm_mode_rect *r, uint32_t size)
0062 {
0063     damage_blob->length = size;
0064     damage_blob->data = r;
0065 }
0066 
0067 static void set_plane_damage(struct drm_plane_state *state,
0068                  struct drm_property_blob *damage_blob)
0069 {
0070     state->fb_damage_clips = damage_blob;
0071 }
0072 
0073 static bool check_damage_clip(struct drm_plane_state *state, struct drm_rect *r,
0074                   int x1, int y1, int x2, int y2)
0075 {
0076     /*
0077      * Round down x1/y1 and round up x2/y2. This is because damage is not in
0078      * 16.16 fixed point so to catch all pixels.
0079      */
0080     int src_x1 = state->src.x1 >> 16;
0081     int src_y1 = state->src.y1 >> 16;
0082     int src_x2 = (state->src.x2 >> 16) + !!(state->src.x2 & 0xFFFF);
0083     int src_y2 = (state->src.y2 >> 16) + !!(state->src.y2 & 0xFFFF);
0084 
0085     if (x1 >= x2 || y1 >= y2) {
0086         pr_err("Cannot have damage clip with no dimension.\n");
0087         return false;
0088     }
0089 
0090     if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2) {
0091         pr_err("Damage cannot be outside rounded plane src.\n");
0092         return false;
0093     }
0094 
0095     if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2) {
0096         pr_err("Damage = %d %d %d %d\n", r->x1, r->y1, r->x2, r->y2);
0097         return false;
0098     }
0099 
0100     return true;
0101 }
0102 
0103 const struct drm_framebuffer fb = {
0104     .width = 2048,
0105     .height = 2048
0106 };
0107 
0108 /* common mocked structs many tests need */
0109 #define MOCK_VARIABLES() \
0110     struct drm_plane_state old_state; \
0111     struct drm_plane_state state = { \
0112         .crtc = ZERO_SIZE_PTR, \
0113         .fb = (struct drm_framebuffer *) &fb, \
0114         .visible = true, \
0115     }; \
0116     mock_setup(&old_state); \
0117     mock_setup(&state);
0118 
0119 int igt_damage_iter_no_damage(void *ignored)
0120 {
0121     struct drm_atomic_helper_damage_iter iter;
0122     struct drm_rect clip;
0123     uint32_t num_hits = 0;
0124 
0125     MOCK_VARIABLES();
0126 
0127     /* Plane src same as fb size. */
0128     set_plane_src(&old_state, 0, 0, fb.width << 16, fb.height << 16);
0129     set_plane_src(&state, 0, 0, fb.width << 16, fb.height << 16);
0130     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0131     drm_atomic_for_each_plane_damage(&iter, &clip)
0132         num_hits++;
0133 
0134     FAIL(num_hits != 1, "Should return plane src as damage.");
0135     FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 2048, 2048));
0136 
0137     return 0;
0138 }
0139 
0140 int igt_damage_iter_no_damage_fractional_src(void *ignored)
0141 {
0142     struct drm_atomic_helper_damage_iter iter;
0143     struct drm_rect clip;
0144     uint32_t num_hits = 0;
0145 
0146     MOCK_VARIABLES();
0147 
0148     /* Plane src has fractional part. */
0149     set_plane_src(&old_state, 0x3fffe, 0x3fffe,
0150               0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
0151     set_plane_src(&state, 0x3fffe, 0x3fffe,
0152               0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
0153     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0154     drm_atomic_for_each_plane_damage(&iter, &clip)
0155         num_hits++;
0156 
0157     FAIL(num_hits != 1, "Should return rounded off plane src as damage.");
0158     FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772));
0159 
0160     return 0;
0161 }
0162 
0163 int igt_damage_iter_no_damage_src_moved(void *ignored)
0164 {
0165     struct drm_atomic_helper_damage_iter iter;
0166     struct drm_rect clip;
0167     uint32_t num_hits = 0;
0168 
0169     MOCK_VARIABLES();
0170 
0171     /* Plane src moved since old plane state. */
0172     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0173     set_plane_src(&state, 10 << 16, 10 << 16,
0174               (10 + 1024) << 16, (10 + 768) << 16);
0175     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0176     drm_atomic_for_each_plane_damage(&iter, &clip)
0177         num_hits++;
0178 
0179     FAIL(num_hits != 1, "Should return plane src as damage.");
0180     FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778));
0181 
0182     return 0;
0183 }
0184 
0185 int igt_damage_iter_no_damage_fractional_src_moved(void *ignored)
0186 {
0187     struct drm_atomic_helper_damage_iter iter;
0188     struct drm_rect clip;
0189     uint32_t num_hits = 0;
0190 
0191     MOCK_VARIABLES();
0192 
0193     /* Plane src has fractional part and it moved since old plane state. */
0194     set_plane_src(&old_state, 0x3fffe, 0x3fffe,
0195               0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
0196     set_plane_src(&state, 0x40002, 0x40002,
0197               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0198     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0199     drm_atomic_for_each_plane_damage(&iter, &clip)
0200         num_hits++;
0201 
0202     FAIL(num_hits != 1, "Should return plane src as damage.");
0203     FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773));
0204 
0205     return 0;
0206 }
0207 
0208 int igt_damage_iter_no_damage_not_visible(void *ignored)
0209 {
0210     struct drm_atomic_helper_damage_iter iter;
0211     struct drm_rect clip;
0212     uint32_t num_hits = 0;
0213 
0214     MOCK_VARIABLES();
0215 
0216     state.visible = false;
0217 
0218     mock_setup(&old_state);
0219 
0220     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0221     set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
0222     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0223     drm_atomic_for_each_plane_damage(&iter, &clip)
0224         num_hits++;
0225 
0226     FAIL(num_hits != 0, "Should have no damage.");
0227 
0228     return 0;
0229 }
0230 
0231 int igt_damage_iter_no_damage_no_crtc(void *ignored)
0232 {
0233     struct drm_atomic_helper_damage_iter iter;
0234     struct drm_rect clip;
0235     uint32_t num_hits = 0;
0236 
0237     MOCK_VARIABLES();
0238 
0239     state.crtc = NULL;
0240 
0241     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0242     set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
0243     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0244     drm_atomic_for_each_plane_damage(&iter, &clip)
0245         num_hits++;
0246 
0247     FAIL(num_hits != 0, "Should have no damage.");
0248 
0249     return 0;
0250 }
0251 
0252 int igt_damage_iter_no_damage_no_fb(void *ignored)
0253 {
0254     struct drm_atomic_helper_damage_iter iter;
0255     struct drm_plane_state old_state;
0256     struct drm_rect clip;
0257     uint32_t num_hits = 0;
0258 
0259     struct drm_plane_state state = {
0260         .crtc = ZERO_SIZE_PTR,
0261         .fb = 0,
0262     };
0263 
0264     mock_setup(&old_state);
0265 
0266     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0267     set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
0268     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0269     drm_atomic_for_each_plane_damage(&iter, &clip)
0270         num_hits++;
0271 
0272     FAIL(num_hits != 0, "Should have no damage.");
0273 
0274     return 0;
0275 }
0276 
0277 int igt_damage_iter_simple_damage(void *ignored)
0278 {
0279     struct drm_atomic_helper_damage_iter iter;
0280     struct drm_property_blob damage_blob;
0281     struct drm_mode_rect damage;
0282     struct drm_rect clip;
0283     uint32_t num_hits = 0;
0284 
0285     MOCK_VARIABLES();
0286 
0287     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0288     set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
0289     /* Damage set to plane src */
0290     set_damage_clip(&damage, 0, 0, 1024, 768);
0291     set_damage_blob(&damage_blob, &damage, sizeof(damage));
0292     set_plane_damage(&state, &damage_blob);
0293     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0294     drm_atomic_for_each_plane_damage(&iter, &clip)
0295         num_hits++;
0296 
0297     FAIL(num_hits != 1, "Should return damage when set.");
0298     FAIL_ON(!check_damage_clip(&state, &clip, 0, 0, 1024, 768));
0299 
0300     return 0;
0301 }
0302 
0303 int igt_damage_iter_single_damage(void *ignored)
0304 {
0305     struct drm_atomic_helper_damage_iter iter;
0306     struct drm_property_blob damage_blob;
0307     struct drm_mode_rect damage;
0308     struct drm_rect clip;
0309     uint32_t num_hits = 0;
0310 
0311     MOCK_VARIABLES();
0312 
0313     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0314     set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
0315     set_damage_clip(&damage, 256, 192, 768, 576);
0316     set_damage_blob(&damage_blob, &damage, sizeof(damage));
0317     set_plane_damage(&state, &damage_blob);
0318     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0319     drm_atomic_for_each_plane_damage(&iter, &clip)
0320         num_hits++;
0321 
0322     FAIL(num_hits != 1, "Should return damage when set.");
0323     FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 768, 576));
0324 
0325     return 0;
0326 }
0327 
0328 int igt_damage_iter_single_damage_intersect_src(void *ignored)
0329 {
0330     struct drm_atomic_helper_damage_iter iter;
0331     struct drm_property_blob damage_blob;
0332     struct drm_mode_rect damage;
0333     struct drm_rect clip;
0334     uint32_t num_hits = 0;
0335 
0336     MOCK_VARIABLES();
0337 
0338     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0339     set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
0340     /* Damage intersect with plane src. */
0341     set_damage_clip(&damage, 256, 192, 1360, 768);
0342     set_damage_blob(&damage_blob, &damage, sizeof(damage));
0343     set_plane_damage(&state, &damage_blob);
0344     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0345     drm_atomic_for_each_plane_damage(&iter, &clip)
0346         num_hits++;
0347 
0348     FAIL(num_hits != 1, "Should return damage clipped to src.");
0349     FAIL_ON(!check_damage_clip(&state, &clip, 256, 192, 1024, 768));
0350 
0351     return 0;
0352 }
0353 
0354 int igt_damage_iter_single_damage_outside_src(void *ignored)
0355 {
0356     struct drm_atomic_helper_damage_iter iter;
0357     struct drm_property_blob damage_blob;
0358     struct drm_mode_rect damage;
0359     struct drm_rect clip;
0360     uint32_t num_hits = 0;
0361 
0362     MOCK_VARIABLES();
0363 
0364     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0365     set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
0366     /* Damage clip outside plane src */
0367     set_damage_clip(&damage, 1360, 1360, 1380, 1380);
0368     set_damage_blob(&damage_blob, &damage, sizeof(damage));
0369     set_plane_damage(&state, &damage_blob);
0370     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0371     drm_atomic_for_each_plane_damage(&iter, &clip)
0372         num_hits++;
0373 
0374     FAIL(num_hits != 0, "Should have no damage.");
0375 
0376     return 0;
0377 }
0378 
0379 int igt_damage_iter_single_damage_fractional_src(void *ignored)
0380 {
0381     struct drm_atomic_helper_damage_iter iter;
0382     struct drm_property_blob damage_blob;
0383     struct drm_mode_rect damage;
0384     struct drm_rect clip;
0385     uint32_t num_hits = 0;
0386 
0387     MOCK_VARIABLES();
0388 
0389     /* Plane src has fractional part. */
0390     set_plane_src(&old_state, 0x40002, 0x40002,
0391               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0392     set_plane_src(&state, 0x40002, 0x40002,
0393               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0394     set_damage_clip(&damage, 10, 10, 256, 330);
0395     set_damage_blob(&damage_blob, &damage, sizeof(damage));
0396     set_plane_damage(&state, &damage_blob);
0397     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0398     drm_atomic_for_each_plane_damage(&iter, &clip)
0399         num_hits++;
0400 
0401     FAIL(num_hits != 1, "Should return damage when set.");
0402     FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 256, 330));
0403 
0404     return 0;
0405 }
0406 
0407 int igt_damage_iter_single_damage_intersect_fractional_src(void *ignored)
0408 {
0409     struct drm_atomic_helper_damage_iter iter;
0410     struct drm_property_blob damage_blob;
0411     struct drm_mode_rect damage;
0412     struct drm_rect clip;
0413     uint32_t num_hits = 0;
0414 
0415     MOCK_VARIABLES();
0416 
0417     /* Plane src has fractional part. */
0418     set_plane_src(&old_state, 0x40002, 0x40002,
0419               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0420     set_plane_src(&state, 0x40002, 0x40002,
0421               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0422     /* Damage intersect with plane src. */
0423     set_damage_clip(&damage, 10, 1, 1360, 330);
0424     set_damage_blob(&damage_blob, &damage, sizeof(damage));
0425     set_plane_damage(&state, &damage_blob);
0426     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0427     drm_atomic_for_each_plane_damage(&iter, &clip)
0428         num_hits++;
0429 
0430     FAIL(num_hits != 1, "Should return damage clipped to rounded off src.");
0431     FAIL_ON(!check_damage_clip(&state, &clip, 10, 4, 1029, 330));
0432 
0433     return 0;
0434 }
0435 
0436 int igt_damage_iter_single_damage_outside_fractional_src(void *ignored)
0437 {
0438     struct drm_atomic_helper_damage_iter iter;
0439     struct drm_property_blob damage_blob;
0440     struct drm_mode_rect damage;
0441     struct drm_rect clip;
0442     uint32_t num_hits = 0;
0443 
0444     MOCK_VARIABLES();
0445 
0446     /* Plane src has fractional part. */
0447     set_plane_src(&old_state, 0x40002, 0x40002,
0448               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0449     set_plane_src(&state, 0x40002, 0x40002,
0450               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0451     /* Damage clip outside plane src */
0452     set_damage_clip(&damage, 1360, 1360, 1380, 1380);
0453     set_damage_blob(&damage_blob, &damage, sizeof(damage));
0454     set_plane_damage(&state, &damage_blob);
0455     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0456     drm_atomic_for_each_plane_damage(&iter, &clip)
0457         num_hits++;
0458 
0459     FAIL(num_hits != 0, "Should have no damage.");
0460 
0461     return 0;
0462 }
0463 
0464 int igt_damage_iter_single_damage_src_moved(void *ignored)
0465 {
0466     struct drm_atomic_helper_damage_iter iter;
0467     struct drm_property_blob damage_blob;
0468     struct drm_mode_rect damage;
0469     struct drm_rect clip;
0470     uint32_t num_hits = 0;
0471 
0472     MOCK_VARIABLES();
0473 
0474     /* Plane src moved since old plane state. */
0475     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0476     set_plane_src(&state, 10 << 16, 10 << 16,
0477               (10 + 1024) << 16, (10 + 768) << 16);
0478     set_damage_clip(&damage, 20, 30, 256, 256);
0479     set_damage_blob(&damage_blob, &damage, sizeof(damage));
0480     set_plane_damage(&state, &damage_blob);
0481     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0482     drm_atomic_for_each_plane_damage(&iter, &clip)
0483         num_hits++;
0484 
0485     FAIL(num_hits != 1, "Should return plane src as damage.");
0486     FAIL_ON(!check_damage_clip(&state, &clip, 10, 10, 1034, 778));
0487 
0488     return 0;
0489 }
0490 
0491 int igt_damage_iter_single_damage_fractional_src_moved(void *ignored)
0492 {
0493     struct drm_atomic_helper_damage_iter iter;
0494     struct drm_property_blob damage_blob;
0495     struct drm_mode_rect damage;
0496     struct drm_rect clip;
0497     uint32_t num_hits = 0;
0498 
0499     MOCK_VARIABLES();
0500 
0501     /* Plane src with fractional part moved since old plane state. */
0502     set_plane_src(&old_state, 0x3fffe, 0x3fffe,
0503               0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
0504     set_plane_src(&state, 0x40002, 0x40002,
0505               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0506     /* Damage intersect with plane src. */
0507     set_damage_clip(&damage, 20, 30, 1360, 256);
0508     set_damage_blob(&damage_blob, &damage, sizeof(damage));
0509     set_plane_damage(&state, &damage_blob);
0510     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0511     drm_atomic_for_each_plane_damage(&iter, &clip)
0512         num_hits++;
0513 
0514     FAIL(num_hits != 1, "Should return rounded off plane src as damage.");
0515     FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773));
0516 
0517     return 0;
0518 }
0519 
0520 int igt_damage_iter_damage(void *ignored)
0521 {
0522     struct drm_atomic_helper_damage_iter iter;
0523     struct drm_property_blob damage_blob;
0524     struct drm_mode_rect damage[2];
0525     struct drm_rect clip;
0526     uint32_t num_hits = 0;
0527 
0528     MOCK_VARIABLES();
0529 
0530     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0531     set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
0532     /* 2 damage clips. */
0533     set_damage_clip(&damage[0], 20, 30, 200, 180);
0534     set_damage_clip(&damage[1], 240, 200, 280, 250);
0535     set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
0536     set_plane_damage(&state, &damage_blob);
0537     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0538     drm_atomic_for_each_plane_damage(&iter, &clip) {
0539         if (num_hits == 0)
0540             FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, 200, 180));
0541         if (num_hits == 1)
0542             FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250));
0543         num_hits++;
0544     }
0545 
0546     FAIL(num_hits != 2, "Should return damage when set.");
0547 
0548     return 0;
0549 }
0550 
0551 int igt_damage_iter_damage_one_intersect(void *ignored)
0552 {
0553     struct drm_atomic_helper_damage_iter iter;
0554     struct drm_property_blob damage_blob;
0555     struct drm_mode_rect damage[2];
0556     struct drm_rect clip;
0557     uint32_t num_hits = 0;
0558 
0559     MOCK_VARIABLES();
0560 
0561     set_plane_src(&old_state, 0x40002, 0x40002,
0562               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0563     set_plane_src(&state, 0x40002, 0x40002,
0564               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0565     /* 2 damage clips, one intersect plane src. */
0566     set_damage_clip(&damage[0], 20, 30, 200, 180);
0567     set_damage_clip(&damage[1], 2, 2, 1360, 1360);
0568     set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
0569     set_plane_damage(&state, &damage_blob);
0570     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0571     drm_atomic_for_each_plane_damage(&iter, &clip) {
0572         if (num_hits == 0)
0573             FAIL_ON(!check_damage_clip(&state, &clip, 20, 30, 200, 180));
0574         if (num_hits == 1)
0575             FAIL_ON(!check_damage_clip(&state, &clip, 4, 4, 1029, 773));
0576         num_hits++;
0577     }
0578 
0579     FAIL(num_hits != 2, "Should return damage when set.");
0580 
0581     return 0;
0582 }
0583 
0584 int igt_damage_iter_damage_one_outside(void *ignored)
0585 {
0586     struct drm_atomic_helper_damage_iter iter;
0587     struct drm_property_blob damage_blob;
0588     struct drm_mode_rect damage[2];
0589     struct drm_rect clip;
0590     uint32_t num_hits = 0;
0591 
0592     MOCK_VARIABLES();
0593 
0594     set_plane_src(&old_state, 0, 0, 1024 << 16, 768 << 16);
0595     set_plane_src(&state, 0, 0, 1024 << 16, 768 << 16);
0596     /* 2 damage clips, one outside plane src. */
0597     set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
0598     set_damage_clip(&damage[1], 240, 200, 280, 250);
0599     set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
0600     set_plane_damage(&state, &damage_blob);
0601     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0602     drm_atomic_for_each_plane_damage(&iter, &clip)
0603         num_hits++;
0604 
0605     FAIL(num_hits != 1, "Should return damage when set.");
0606     FAIL_ON(!check_damage_clip(&state, &clip, 240, 200, 280, 250));
0607 
0608     return 0;
0609 }
0610 
0611 int igt_damage_iter_damage_src_moved(void *ignored)
0612 {
0613     struct drm_atomic_helper_damage_iter iter;
0614     struct drm_property_blob damage_blob;
0615     struct drm_mode_rect damage[2];
0616     struct drm_rect clip;
0617     uint32_t num_hits = 0;
0618 
0619     MOCK_VARIABLES();
0620 
0621     set_plane_src(&old_state, 0x40002, 0x40002,
0622               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0623     set_plane_src(&state, 0x3fffe, 0x3fffe,
0624               0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
0625     /* 2 damage clips, one outside plane src. */
0626     set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
0627     set_damage_clip(&damage[1], 240, 200, 280, 250);
0628     set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
0629     set_plane_damage(&state, &damage_blob);
0630     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0631     drm_atomic_for_each_plane_damage(&iter, &clip)
0632         num_hits++;
0633 
0634     FAIL(num_hits != 1, "Should return round off plane src as damage.");
0635     FAIL_ON(!check_damage_clip(&state, &clip, 3, 3, 1028, 772));
0636 
0637     return 0;
0638 }
0639 
0640 int igt_damage_iter_damage_not_visible(void *ignored)
0641 {
0642     struct drm_atomic_helper_damage_iter iter;
0643     struct drm_property_blob damage_blob;
0644     struct drm_mode_rect damage[2];
0645     struct drm_rect clip;
0646     uint32_t num_hits = 0;
0647 
0648     MOCK_VARIABLES();
0649 
0650     state.visible = false;
0651 
0652     set_plane_src(&old_state, 0x40002, 0x40002,
0653               0x40002 + (1024 << 16), 0x40002 + (768 << 16));
0654     set_plane_src(&state, 0x3fffe, 0x3fffe,
0655               0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
0656     /* 2 damage clips, one outside plane src. */
0657     set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
0658     set_damage_clip(&damage[1], 240, 200, 280, 250);
0659     set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
0660     set_plane_damage(&state, &damage_blob);
0661     drm_atomic_helper_damage_iter_init(&iter, &old_state, &state);
0662     drm_atomic_for_each_plane_damage(&iter, &clip)
0663         num_hits++;
0664 
0665     FAIL(num_hits != 0, "Should not return any damage.");
0666 
0667     return 0;
0668 }