| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Test case for drm_damage_helper functions
- *
- * Copyright (c) 2022 Maíra Canal <mairacanal@riseup.net>
- */
- #include <kunit/test.h>
- #include <drm/drm_damage_helper.h>
- #include <drm/drm_framebuffer.h>
- #include <drm/drm_plane.h>
- #include <drm/drm_drv.h>
- struct drm_damage_mock {
- struct drm_driver driver;
- struct drm_device device;
- struct drm_object_properties obj_props;
- struct drm_plane plane;
- struct drm_property prop;
- struct drm_framebuffer fb;
- struct drm_plane_state state;
- struct drm_plane_state old_state;
- };
- static int drm_damage_helper_init(struct kunit *test)
- {
- struct drm_damage_mock *mock;
- mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mock);
- mock->fb.width = 2048;
- mock->fb.height = 2048;
- mock->state.crtc = ZERO_SIZE_PTR;
- mock->state.fb = &mock->fb;
- mock->state.visible = true;
- mock->old_state.plane = &mock->plane;
- mock->state.plane = &mock->plane;
- /* just enough so that drm_plane_enable_fb_damage_clips() works */
- mock->device.driver = &mock->driver;
- mock->device.mode_config.prop_fb_damage_clips = &mock->prop;
- mock->plane.dev = &mock->device;
- mock->obj_props.count = 0;
- mock->plane.base.properties = &mock->obj_props;
- mock->prop.base.id = 1; /* 0 is an invalid id */
- mock->prop.dev = &mock->device;
- drm_plane_enable_fb_damage_clips(&mock->plane);
- test->priv = mock;
- return 0;
- }
- static void set_plane_src(struct drm_plane_state *state, int x1, int y1, int x2,
- int y2)
- {
- state->src_x = x1;
- state->src_y = y1;
- state->src_w = x2 - x1;
- state->src_h = y2 - y1;
- state->src.x1 = x1;
- state->src.y1 = y1;
- state->src.x2 = x2;
- state->src.y2 = y2;
- }
- static void set_damage_clip(struct drm_mode_rect *r, int x1, int y1, int x2,
- int y2)
- {
- r->x1 = x1;
- r->y1 = y1;
- r->x2 = x2;
- r->y2 = y2;
- }
- static void set_damage_blob(struct drm_property_blob *damage_blob,
- struct drm_mode_rect *r, u32 size)
- {
- damage_blob->length = size;
- damage_blob->data = r;
- }
- static void set_plane_damage(struct drm_plane_state *state,
- struct drm_property_blob *damage_blob)
- {
- state->fb_damage_clips = damage_blob;
- }
- static void check_damage_clip(struct kunit *test, struct drm_rect *r,
- int x1, int y1, int x2, int y2)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_plane_state state = mock->state;
- /*
- * Round down x1/y1 and round up x2/y2. This is because damage is not in
- * 16.16 fixed point so to catch all pixels.
- */
- int src_x1 = state.src.x1 >> 16;
- int src_y1 = state.src.y1 >> 16;
- int src_x2 = (state.src.x2 >> 16) + !!(state.src.x2 & 0xFFFF);
- int src_y2 = (state.src.y2 >> 16) + !!(state.src.y2 & 0xFFFF);
- if (x1 >= x2 || y1 >= y2)
- KUNIT_FAIL(test, "Cannot have damage clip with no dimension.");
- if (x1 < src_x1 || y1 < src_y1 || x2 > src_x2 || y2 > src_y2)
- KUNIT_FAIL(test, "Damage cannot be outside rounded plane src.");
- if (r->x1 != x1 || r->y1 != y1 || r->x2 != x2 || r->y2 != y2)
- KUNIT_FAIL(test, "Damage = %d %d %d %d, want = %d %d %d %d",
- r->x1, r->y1, r->x2, r->y2, x1, y1, x2, y2);
- }
- static void drm_test_damage_iter_no_damage(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_rect clip;
- u32 num_hits = 0;
- /* Plane src same as fb size. */
- set_plane_src(&mock->old_state, 0, 0, mock->fb.width << 16, mock->fb.height << 16);
- set_plane_src(&mock->state, 0, 0, mock->fb.width << 16, mock->fb.height << 16);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
- check_damage_clip(test, &clip, 0, 0, 2048, 2048);
- }
- static void drm_test_damage_iter_no_damage_fractional_src(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_rect clip;
- u32 num_hits = 0;
- /* Plane src has fractional part. */
- set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
- 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
- set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
- 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
- "Should return rounded off plane src as damage.");
- check_damage_clip(test, &clip, 3, 3, 1028, 772);
- }
- static void drm_test_damage_iter_no_damage_src_moved(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_rect clip;
- u32 num_hits = 0;
- /* Plane src moved since old plane state. */
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 10 << 16, 10 << 16,
- (10 + 1024) << 16, (10 + 768) << 16);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
- check_damage_clip(test, &clip, 10, 10, 1034, 778);
- }
- static void drm_test_damage_iter_no_damage_fractional_src_moved(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_rect clip;
- u32 num_hits = 0;
- /* Plane src has fractional part and it moved since old plane state. */
- set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
- 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
- set_plane_src(&mock->state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return plane src as damage.");
- check_damage_clip(test, &clip, 4, 4, 1029, 773);
- }
- static void drm_test_damage_iter_no_damage_not_visible(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_rect clip;
- u32 num_hits = 0;
- mock->state.visible = false;
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
- }
- static void drm_test_damage_iter_no_damage_no_crtc(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_rect clip;
- u32 num_hits = 0;
- mock->state.crtc = NULL;
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
- }
- static void drm_test_damage_iter_no_damage_no_fb(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_rect clip;
- u32 num_hits = 0;
- mock->state.fb = NULL;
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
- }
- static void drm_test_damage_iter_simple_damage(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
- /* Damage set to plane src */
- set_damage_clip(&damage, 0, 0, 1024, 768);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
- check_damage_clip(test, &clip, 0, 0, 1024, 768);
- }
- static void drm_test_damage_iter_single_damage(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
- set_damage_clip(&damage, 256, 192, 768, 576);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
- check_damage_clip(test, &clip, 256, 192, 768, 576);
- }
- static void drm_test_damage_iter_single_damage_intersect_src(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
- /* Damage intersect with plane src. */
- set_damage_clip(&damage, 256, 192, 1360, 768);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage clipped to src.");
- check_damage_clip(test, &clip, 256, 192, 1024, 768);
- }
- static void drm_test_damage_iter_single_damage_outside_src(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
- /* Damage clip outside plane src */
- set_damage_clip(&damage, 1360, 1360, 1380, 1380);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
- }
- static void drm_test_damage_iter_single_damage_fractional_src(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
- /* Plane src has fractional part. */
- set_plane_src(&mock->old_state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- set_plane_src(&mock->state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- set_damage_clip(&damage, 10, 10, 256, 330);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
- check_damage_clip(test, &clip, 10, 10, 256, 330);
- }
- static void drm_test_damage_iter_single_damage_intersect_fractional_src(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
- /* Plane src has fractional part. */
- set_plane_src(&mock->old_state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- set_plane_src(&mock->state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- /* Damage intersect with plane src. */
- set_damage_clip(&damage, 10, 1, 1360, 330);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
- "Should return damage clipped to rounded off src.");
- check_damage_clip(test, &clip, 10, 4, 1029, 330);
- }
- static void drm_test_damage_iter_single_damage_outside_fractional_src(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
- /* Plane src has fractional part. */
- set_plane_src(&mock->old_state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- set_plane_src(&mock->state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- /* Damage clip outside plane src */
- set_damage_clip(&damage, 1360, 1360, 1380, 1380);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should have no damage.");
- }
- static void drm_test_damage_iter_single_damage_src_moved(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
- /* Plane src moved since old plane state. */
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 10 << 16, 10 << 16,
- (10 + 1024) << 16, (10 + 768) << 16);
- set_damage_clip(&damage, 20, 30, 256, 256);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
- "Should return plane src as damage.");
- check_damage_clip(test, &clip, 10, 10, 1034, 778);
- }
- static void drm_test_damage_iter_single_damage_fractional_src_moved(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage;
- struct drm_rect clip;
- u32 num_hits = 0;
- /* Plane src with fractional part moved since old plane state. */
- set_plane_src(&mock->old_state, 0x3fffe, 0x3fffe,
- 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
- set_plane_src(&mock->state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- /* Damage intersect with plane src. */
- set_damage_clip(&damage, 20, 30, 1360, 256);
- set_damage_blob(&damage_blob, &damage, sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
- "Should return rounded off plane as damage.");
- check_damage_clip(test, &clip, 4, 4, 1029, 773);
- }
- static void drm_test_damage_iter_damage(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage[2];
- struct drm_rect clip;
- u32 num_hits = 0;
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
- /* 2 damage clips. */
- set_damage_clip(&damage[0], 20, 30, 200, 180);
- set_damage_clip(&damage[1], 240, 200, 280, 250);
- set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip) {
- if (num_hits == 0)
- check_damage_clip(test, &clip, 20, 30, 200, 180);
- if (num_hits == 1)
- check_damage_clip(test, &clip, 240, 200, 280, 250);
- num_hits++;
- }
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 2, "Should return damage when set.");
- }
- static void drm_test_damage_iter_damage_one_intersect(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage[2];
- struct drm_rect clip;
- u32 num_hits = 0;
- set_plane_src(&mock->old_state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- set_plane_src(&mock->state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- /* 2 damage clips, one intersect plane src. */
- set_damage_clip(&damage[0], 20, 30, 200, 180);
- set_damage_clip(&damage[1], 2, 2, 1360, 1360);
- set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip) {
- if (num_hits == 0)
- check_damage_clip(test, &clip, 20, 30, 200, 180);
- if (num_hits == 1)
- check_damage_clip(test, &clip, 4, 4, 1029, 773);
- num_hits++;
- }
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 2, "Should return damage when set.");
- }
- static void drm_test_damage_iter_damage_one_outside(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage[2];
- struct drm_rect clip;
- u32 num_hits = 0;
- set_plane_src(&mock->old_state, 0, 0, 1024 << 16, 768 << 16);
- set_plane_src(&mock->state, 0, 0, 1024 << 16, 768 << 16);
- /* 2 damage clips, one outside plane src. */
- set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
- set_damage_clip(&damage[1], 240, 200, 280, 250);
- set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1, "Should return damage when set.");
- check_damage_clip(test, &clip, 240, 200, 280, 250);
- }
- static void drm_test_damage_iter_damage_src_moved(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage[2];
- struct drm_rect clip;
- u32 num_hits = 0;
- set_plane_src(&mock->old_state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
- 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
- /* 2 damage clips, one outside plane src. */
- set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
- set_damage_clip(&damage[1], 240, 200, 280, 250);
- set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 1,
- "Should return round off plane src as damage.");
- check_damage_clip(test, &clip, 3, 3, 1028, 772);
- }
- static void drm_test_damage_iter_damage_not_visible(struct kunit *test)
- {
- struct drm_damage_mock *mock = test->priv;
- struct drm_atomic_helper_damage_iter iter;
- struct drm_property_blob damage_blob;
- struct drm_mode_rect damage[2];
- struct drm_rect clip;
- u32 num_hits = 0;
- mock->state.visible = false;
- set_plane_src(&mock->old_state, 0x40002, 0x40002,
- 0x40002 + (1024 << 16), 0x40002 + (768 << 16));
- set_plane_src(&mock->state, 0x3fffe, 0x3fffe,
- 0x3fffe + (1024 << 16), 0x3fffe + (768 << 16));
- /* 2 damage clips, one outside plane src. */
- set_damage_clip(&damage[0], 1360, 1360, 1380, 1380);
- set_damage_clip(&damage[1], 240, 200, 280, 250);
- set_damage_blob(&damage_blob, &damage[0], sizeof(damage));
- set_plane_damage(&mock->state, &damage_blob);
- drm_atomic_helper_damage_iter_init(&iter, &mock->old_state, &mock->state);
- drm_atomic_for_each_plane_damage(&iter, &clip)
- num_hits++;
- KUNIT_EXPECT_EQ_MSG(test, num_hits, 0, "Should not return any damage.");
- }
- static struct kunit_case drm_damage_helper_tests[] = {
- KUNIT_CASE(drm_test_damage_iter_no_damage),
- KUNIT_CASE(drm_test_damage_iter_no_damage_fractional_src),
- KUNIT_CASE(drm_test_damage_iter_no_damage_src_moved),
- KUNIT_CASE(drm_test_damage_iter_no_damage_fractional_src_moved),
- KUNIT_CASE(drm_test_damage_iter_no_damage_not_visible),
- KUNIT_CASE(drm_test_damage_iter_no_damage_no_crtc),
- KUNIT_CASE(drm_test_damage_iter_no_damage_no_fb),
- KUNIT_CASE(drm_test_damage_iter_simple_damage),
- KUNIT_CASE(drm_test_damage_iter_single_damage),
- KUNIT_CASE(drm_test_damage_iter_single_damage_intersect_src),
- KUNIT_CASE(drm_test_damage_iter_single_damage_outside_src),
- KUNIT_CASE(drm_test_damage_iter_single_damage_fractional_src),
- KUNIT_CASE(drm_test_damage_iter_single_damage_intersect_fractional_src),
- KUNIT_CASE(drm_test_damage_iter_single_damage_outside_fractional_src),
- KUNIT_CASE(drm_test_damage_iter_single_damage_src_moved),
- KUNIT_CASE(drm_test_damage_iter_single_damage_fractional_src_moved),
- KUNIT_CASE(drm_test_damage_iter_damage),
- KUNIT_CASE(drm_test_damage_iter_damage_one_intersect),
- KUNIT_CASE(drm_test_damage_iter_damage_one_outside),
- KUNIT_CASE(drm_test_damage_iter_damage_src_moved),
- KUNIT_CASE(drm_test_damage_iter_damage_not_visible),
- { }
- };
- static struct kunit_suite drm_damage_helper_test_suite = {
- .name = "drm_damage_helper",
- .init = drm_damage_helper_init,
- .test_cases = drm_damage_helper_tests,
- };
- kunit_test_suite(drm_damage_helper_test_suite);
- MODULE_DESCRIPTION("Test case for drm_damage_helper functions");
- MODULE_LICENSE("GPL");
|