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