61
62
RealKMSOutputTest()
62
: invalid_id{0}, crtc_ids{10, 11},
63
: drm_fd{open(drm_device, 0, 0)},
64
invalid_id{0}, crtc_ids{10, 11},
63
65
encoder_ids{20, 21}, connector_ids{30, 21},
64
66
possible_encoder_ids1{encoder_ids[0]},
65
67
possible_encoder_ids2{encoder_ids[0], encoder_ids[1]}
67
69
ON_CALL(mock_page_flipper, wait_for_flip(_))
68
70
.WillByDefault(Return(mg::Frame{}));
72
ON_CALL(mock_gbm, gbm_bo_get_handle(_))
73
.WillByDefault(Return(gbm_bo_handle{0}));
71
76
void setup_outputs_connected_crtc()
73
mtd::FakeDRMResources& resources(mock_drm.fake_drm);
74
78
uint32_t const possible_crtcs_mask{0x1};
78
resources.add_crtc(crtc_ids[0], drmModeModeInfo());
79
resources.add_encoder(encoder_ids[0], crtc_ids[0], possible_crtcs_mask);
80
resources.add_connector(connector_ids[0], DRM_MODE_CONNECTOR_VGA,
81
DRM_MODE_CONNECTED, encoder_ids[0],
82
modes_empty, possible_encoder_ids1, geom::Size());
80
mock_drm.reset(drm_device);
91
mock_drm.add_connector(
94
DRM_MODE_CONNECTOR_VGA,
98
possible_encoder_ids1,
101
mock_drm.prepare(drm_device);
87
104
void setup_outputs_no_connected_crtc()
89
mtd::FakeDRMResources& resources(mock_drm.fake_drm);
90
106
uint32_t const possible_crtcs_mask1{0x1};
91
107
uint32_t const possible_crtcs_mask_all{0x3};
95
resources.add_crtc(crtc_ids[0], drmModeModeInfo());
96
resources.add_crtc(crtc_ids[1], drmModeModeInfo());
97
resources.add_encoder(encoder_ids[0], crtc_ids[0], possible_crtcs_mask1);
98
resources.add_encoder(encoder_ids[1], invalid_id, possible_crtcs_mask_all);
99
resources.add_connector(connector_ids[0], DRM_MODE_CONNECTOR_Composite,
100
DRM_MODE_CONNECTED, invalid_id,
101
modes_empty, possible_encoder_ids2, geom::Size());
102
resources.add_connector(connector_ids[1], DRM_MODE_CONNECTOR_DVIA,
103
DRM_MODE_CONNECTED, encoder_ids[0],
104
modes_empty, possible_encoder_ids2, geom::Size());
109
mock_drm.reset(drm_device);
119
mock_drm.add_encoder(
123
possible_crtcs_mask1);
124
mock_drm.add_encoder(
128
possible_crtcs_mask_all);
129
mock_drm.add_connector(
132
DRM_MODE_CONNECTOR_Composite,
136
possible_encoder_ids2,
138
mock_drm.add_connector(
141
DRM_MODE_CONNECTOR_DVIA,
145
possible_encoder_ids2,
148
mock_drm.prepare(drm_device);
151
void append_fb_id(uint32_t fb_id)
153
EXPECT_CALL(mock_drm, drmModeAddFB2(_,_,_,_,_,_,_,_,_))
156
SetArgPointee<7>(fb_id),
109
160
testing::NiceMock<mtd::MockDRM> mock_drm;
110
161
testing::NiceMock<mtd::MockGBM> mock_gbm;
111
162
MockPageFlipper mock_page_flipper;
112
163
NullPageFlipper null_page_flipper;
114
164
std::vector<drmModeModeInfo> modes_empty;
166
char const* const drm_device = "/dev/dri/card0";
169
gbm_bo* const fake_bo{reinterpret_cast<gbm_bo*>(0x123ba)};
115
170
uint32_t const invalid_id;
116
171
std::vector<uint32_t> const crtc_ids;
117
172
std::vector<uint32_t> const encoder_ids;
125
TEST_F(RealKMSOutputTest, construction_queries_connector)
127
using namespace testing;
129
setup_outputs_connected_crtc();
131
EXPECT_CALL(mock_drm, drmModeGetConnector(_,connector_ids[0]))
134
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
135
mt::fake_shared(null_page_flipper)};
138
180
TEST_F(RealKMSOutputTest, operations_use_existing_crtc)
140
182
using namespace testing;
142
uint32_t const fb_id{67};
144
184
setup_outputs_connected_crtc();
186
uint32_t const fb_id{42};
166
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
167
mt::fake_shared(mock_page_flipper)};
169
EXPECT_TRUE(output.set_crtc(fb_id));
170
EXPECT_TRUE(output.schedule_page_flip(fb_id));
209
mgm::RealKMSOutput output{
211
mg::kms::get_connector(drm_fd, connector_ids[0]),
212
mt::fake_shared(mock_page_flipper)};
214
auto fb = output.fb_for(fake_bo);
216
EXPECT_TRUE(output.set_crtc(*fb));
217
EXPECT_TRUE(output.schedule_page_flip(*fb));
171
218
output.wait_for_page_flip();
202
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
203
mt::fake_shared(mock_page_flipper)};
205
EXPECT_TRUE(output.set_crtc(fb_id));
206
EXPECT_TRUE(output.schedule_page_flip(fb_id));
251
mgm::RealKMSOutput output{
253
mg::kms::get_connector(drm_fd, connector_ids[0]),
254
mt::fake_shared(mock_page_flipper)};
256
auto fb = output.fb_for(fake_bo);
258
EXPECT_TRUE(output.set_crtc(*fb));
259
EXPECT_TRUE(output.schedule_page_flip(*fb));
207
260
output.wait_for_page_flip();
236
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
237
mt::fake_shared(mock_page_flipper)};
239
EXPECT_FALSE(output.set_crtc(fb_id));
291
mgm::RealKMSOutput output{
293
mg::kms::get_connector(drm_fd, connector_ids[0]),
294
mt::fake_shared(mock_page_flipper)};
296
auto fb = output.fb_for(fake_bo);
298
EXPECT_FALSE(output.set_crtc(*fb));
240
300
EXPECT_NO_THROW({
241
EXPECT_FALSE(output.schedule_page_flip(fb_id));
301
EXPECT_FALSE(output.schedule_page_flip(*fb));
243
303
EXPECT_THROW({ // schedule failed. It's programmer error if you then wait.
244
304
output.wait_for_page_flip();
252
312
setup_outputs_connected_crtc();
254
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
255
mt::fake_shared(mock_page_flipper)};
314
mgm::RealKMSOutput output{
316
mg::kms::get_connector(drm_fd, connector_ids[0]),
317
mt::fake_shared(mock_page_flipper)};
257
319
EXPECT_CALL(mock_drm, drmModeSetCrtc(_, crtc_ids[0], 0, 0, 0, nullptr, 0, nullptr))
266
328
using namespace testing;
268
mtd::FakeDRMResources& resources(mock_drm.fake_drm);
269
330
uint32_t const possible_crtcs_mask_empty{0x0};
273
resources.add_encoder(encoder_ids[0], invalid_id, possible_crtcs_mask_empty);
274
resources.add_connector(connector_ids[0], DRM_MODE_CONNECTOR_VGA,
275
DRM_MODE_CONNECTED, encoder_ids[0],
276
modes_empty, possible_encoder_ids1, geom::Size());
280
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
281
mt::fake_shared(mock_page_flipper)};
332
mock_drm.reset(drm_device);
334
mock_drm.add_encoder(
338
possible_crtcs_mask_empty);
339
mock_drm.add_connector(
342
DRM_MODE_CONNECTOR_VGA,
346
possible_encoder_ids1,
349
mock_drm.prepare(drm_device);
351
mgm::RealKMSOutput output{
353
mg::kms::get_connector(drm_fd, connector_ids[0]),
354
mt::fake_shared(mock_page_flipper)};
283
356
EXPECT_CALL(mock_drm, drmModeSetCrtc(_, _, 0, 0, 0, nullptr, 0, nullptr))
297
370
setup_outputs_connected_crtc();
299
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
300
mt::fake_shared(mock_page_flipper)};
302
EXPECT_TRUE(output.set_crtc(987));
372
mgm::RealKMSOutput output{
374
mg::kms::get_connector(drm_fd, connector_ids[0]),
375
mt::fake_shared(mock_page_flipper)};
377
auto fb = output.fb_for(fake_bo);
379
EXPECT_TRUE(output.set_crtc(*fb));
303
380
EXPECT_NO_THROW({
304
381
output.move_cursor({123, 456});
321
398
setup_outputs_connected_crtc();
323
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
324
mt::fake_shared(mock_page_flipper)};
326
EXPECT_TRUE(output.set_crtc(987));
400
mgm::RealKMSOutput output{
402
mg::kms::get_connector(drm_fd, connector_ids[0]),
403
mt::fake_shared(mock_page_flipper)};
405
auto fb = output.fb_for(fake_bo);
407
EXPECT_TRUE(output.set_crtc(*fb));
327
408
struct gbm_bo *dummy = reinterpret_cast<struct gbm_bo*>(0x1234567);
328
409
EXPECT_NO_THROW({
329
410
output.set_cursor(dummy);
346
427
setup_outputs_connected_crtc();
348
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
349
mt::fake_shared(mock_page_flipper)};
351
EXPECT_TRUE(output.set_crtc(987));
429
mgm::RealKMSOutput output{
431
mg::kms::get_connector(drm_fd, connector_ids[0]),
432
mt::fake_shared(mock_page_flipper)};
434
auto fb = output.fb_for(fake_bo);
436
EXPECT_TRUE(output.set_crtc(*fb));
352
437
struct gbm_bo *dummy = reinterpret_cast<struct gbm_bo*>(0x1234567);
353
438
output.set_cursor(dummy);
354
439
EXPECT_FALSE(output.has_cursor());
363
448
setup_outputs_connected_crtc();
365
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
366
mt::fake_shared(mock_page_flipper)};
450
mgm::RealKMSOutput output{
452
mg::kms::get_connector(drm_fd, connector_ids[0]),
453
mt::fake_shared(mock_page_flipper)};
368
455
EXPECT_CALL(mock_drm, drmModeSetCrtc(_, crtc_ids[0], 0, 0, 0, nullptr, 0, nullptr))
383
470
setup_outputs_connected_crtc();
385
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
386
mt::fake_shared(mock_page_flipper)};
472
mgm::RealKMSOutput output{
474
mg::kms::get_connector(drm_fd, connector_ids[0]),
475
mt::fake_shared(mock_page_flipper)};
388
477
mg::GammaCurves gamma{{1}, {2}, {3}};
390
EXPECT_CALL(mock_drm, drmModeCrtcSetGamma(mock_drm.fake_drm.fd(), crtc_ids[0],
479
EXPECT_CALL(mock_drm, drmModeCrtcSetGamma(drm_fd, crtc_ids[0],
391
480
gamma.red.size(),
392
481
const_cast<uint16_t*>(gamma.red.data()),
393
482
const_cast<uint16_t*>(gamma.green.data()),
394
483
const_cast<uint16_t*>(gamma.blue.data())))
397
EXPECT_TRUE(output.set_crtc(fb_id));
488
auto fb = output.fb_for(fake_bo);
490
EXPECT_TRUE(output.set_crtc(*fb));
398
492
output.set_gamma(gamma);
407
501
setup_outputs_connected_crtc();
409
mgm::RealKMSOutput output{mock_drm.fake_drm.fd(), connector_ids[0],
410
mt::fake_shared(mock_page_flipper)};
503
mgm::RealKMSOutput output{
505
mg::kms::get_connector(drm_fd, connector_ids[0]),
506
mt::fake_shared(mock_page_flipper)};
412
508
mg::GammaCurves gamma{{1}, {2}, {3}};
414
EXPECT_CALL(mock_drm, drmModeCrtcSetGamma(mock_drm.fake_drm.fd(), crtc_ids[0],
510
EXPECT_CALL(mock_drm, drmModeCrtcSetGamma(drm_fd, crtc_ids[0],
415
511
gamma.red.size(),
416
512
const_cast<uint16_t*>(gamma.red.data()),
417
513
const_cast<uint16_t*>(gamma.green.data()),
418
514
const_cast<uint16_t*>(gamma.blue.data())))
419
515
.WillOnce(Return(-ENOSYS));
421
EXPECT_TRUE(output.set_crtc(fb_id));
519
auto fb = output.fb_for(fake_bo);
521
EXPECT_TRUE(output.set_crtc(*fb));
423
523
EXPECT_NO_THROW(output.set_gamma(gamma););