OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/bind.h" |
| 6 #include "testing/gtest/include/gtest/gtest.h" |
| 7 #include "third_party/skia/include/core/SkCanvas.h" |
| 8 #include "ui/ozone/platform/drm/gpu/crtc_controller.h" |
| 9 #include "ui/ozone/platform/drm/gpu/drm_buffer.h" |
| 10 #include "ui/ozone/platform/drm/gpu/drm_device.h" |
| 11 #include "ui/ozone/platform/drm/gpu/hardware_display_controller.h" |
| 12 #include "ui/ozone/platform/drm/test/mock_drm_device.h" |
| 13 #include "ui/ozone/public/native_pixmap.h" |
| 14 |
| 15 namespace { |
| 16 |
| 17 // Create a basic mode for a 6x4 screen. |
| 18 const drmModeModeInfo kDefaultMode = |
| 19 {0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}}; |
| 20 |
| 21 const uint32_t kPrimaryCrtc = 1; |
| 22 const uint32_t kPrimaryConnector = 2; |
| 23 const uint32_t kSecondaryCrtc = 3; |
| 24 const uint32_t kSecondaryConnector = 4; |
| 25 const size_t kPlanesPerCrtc = 2; |
| 26 |
| 27 const gfx::Size kDefaultModeSize(kDefaultMode.hdisplay, kDefaultMode.vdisplay); |
| 28 const gfx::SizeF kDefaultModeSizeF(1.0, 1.0); |
| 29 |
| 30 class MockScanoutBuffer : public ui::ScanoutBuffer { |
| 31 public: |
| 32 MockScanoutBuffer(const gfx::Size& size) : size_(size) {} |
| 33 |
| 34 // ScanoutBuffer: |
| 35 uint32_t GetFramebufferId() const override { return 0; } |
| 36 uint32_t GetHandle() const override { return 0; } |
| 37 gfx::Size GetSize() const override { return size_; } |
| 38 |
| 39 private: |
| 40 ~MockScanoutBuffer() override {} |
| 41 |
| 42 gfx::Size size_; |
| 43 |
| 44 DISALLOW_COPY_AND_ASSIGN(MockScanoutBuffer); |
| 45 }; |
| 46 |
| 47 } // namespace |
| 48 |
| 49 class HardwareDisplayControllerTest : public testing::Test { |
| 50 public: |
| 51 HardwareDisplayControllerTest() : page_flips_(0) {} |
| 52 ~HardwareDisplayControllerTest() override {} |
| 53 |
| 54 void SetUp() override; |
| 55 void TearDown() override; |
| 56 |
| 57 void PageFlipCallback(gfx::SwapResult); |
| 58 |
| 59 protected: |
| 60 scoped_ptr<ui::HardwareDisplayController> controller_; |
| 61 scoped_refptr<ui::MockDrmDevice> drm_; |
| 62 |
| 63 int page_flips_; |
| 64 |
| 65 private: |
| 66 DISALLOW_COPY_AND_ASSIGN(HardwareDisplayControllerTest); |
| 67 }; |
| 68 |
| 69 void HardwareDisplayControllerTest::SetUp() { |
| 70 std::vector<uint32_t> crtcs; |
| 71 crtcs.push_back(kPrimaryCrtc); |
| 72 crtcs.push_back(kSecondaryCrtc); |
| 73 drm_ = new ui::MockDrmDevice(false, crtcs, kPlanesPerCrtc); |
| 74 controller_.reset(new ui::HardwareDisplayController( |
| 75 scoped_ptr<ui::CrtcController>( |
| 76 new ui::CrtcController(drm_.get(), kPrimaryCrtc, kPrimaryConnector)), |
| 77 gfx::Point())); |
| 78 } |
| 79 |
| 80 void HardwareDisplayControllerTest::TearDown() { |
| 81 controller_.reset(); |
| 82 drm_ = nullptr; |
| 83 } |
| 84 |
| 85 void HardwareDisplayControllerTest::PageFlipCallback(gfx::SwapResult) { |
| 86 page_flips_++; |
| 87 } |
| 88 |
| 89 TEST_F(HardwareDisplayControllerTest, CheckModesettingResult) { |
| 90 ui::OverlayPlane plane(scoped_refptr<ui::ScanoutBuffer>( |
| 91 new MockScanoutBuffer(kDefaultModeSize))); |
| 92 |
| 93 EXPECT_TRUE(controller_->Modeset(plane, kDefaultMode)); |
| 94 EXPECT_FALSE(plane.buffer->HasOneRef()); |
| 95 } |
| 96 |
| 97 TEST_F(HardwareDisplayControllerTest, CheckStateAfterPageFlip) { |
| 98 ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( |
| 99 new MockScanoutBuffer(kDefaultModeSize))); |
| 100 |
| 101 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 102 |
| 103 ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( |
| 104 new MockScanoutBuffer(kDefaultModeSize))); |
| 105 std::vector<ui::OverlayPlane> planes = |
| 106 std::vector<ui::OverlayPlane>(1, plane2); |
| 107 EXPECT_TRUE(controller_->SchedulePageFlip( |
| 108 planes, false, false, |
| 109 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 110 base::Unretained(this)))); |
| 111 drm_->RunCallbacks(); |
| 112 EXPECT_TRUE(plane1.buffer->HasOneRef()); |
| 113 EXPECT_FALSE(plane2.buffer->HasOneRef()); |
| 114 |
| 115 EXPECT_EQ(1, drm_->get_page_flip_call_count()); |
| 116 EXPECT_EQ(0, drm_->get_overlay_flip_call_count()); |
| 117 } |
| 118 |
| 119 TEST_F(HardwareDisplayControllerTest, CheckStateIfModesetFails) { |
| 120 drm_->set_set_crtc_expectation(false); |
| 121 |
| 122 ui::OverlayPlane plane(scoped_refptr<ui::ScanoutBuffer>( |
| 123 new MockScanoutBuffer(kDefaultModeSize))); |
| 124 |
| 125 EXPECT_FALSE(controller_->Modeset(plane, kDefaultMode)); |
| 126 } |
| 127 |
| 128 TEST_F(HardwareDisplayControllerTest, CheckStateIfPageFlipFails) { |
| 129 drm_->set_page_flip_expectation(false); |
| 130 |
| 131 ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( |
| 132 new MockScanoutBuffer(kDefaultModeSize))); |
| 133 |
| 134 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 135 |
| 136 ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( |
| 137 new MockScanoutBuffer(kDefaultModeSize))); |
| 138 std::vector<ui::OverlayPlane> planes = |
| 139 std::vector<ui::OverlayPlane>(1, plane2); |
| 140 EXPECT_FALSE(controller_->SchedulePageFlip( |
| 141 planes, false, false, |
| 142 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 143 base::Unretained(this)))); |
| 144 drm_->RunCallbacks(); |
| 145 planes.clear(); |
| 146 |
| 147 EXPECT_FALSE(plane1.buffer->HasOneRef()); |
| 148 EXPECT_TRUE(plane2.buffer->HasOneRef()); |
| 149 } |
| 150 |
| 151 TEST_F(HardwareDisplayControllerTest, CheckOverlayPresent) { |
| 152 ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( |
| 153 new MockScanoutBuffer(kDefaultModeSize))); |
| 154 ui::OverlayPlane plane2( |
| 155 scoped_refptr<ui::ScanoutBuffer>(new MockScanoutBuffer(kDefaultModeSize)), |
| 156 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(kDefaultModeSize), |
| 157 gfx::RectF(kDefaultModeSizeF)); |
| 158 |
| 159 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 160 |
| 161 std::vector<ui::OverlayPlane> planes; |
| 162 planes.push_back(plane1); |
| 163 planes.push_back(plane2); |
| 164 |
| 165 EXPECT_TRUE(controller_->SchedulePageFlip( |
| 166 planes, false, false, |
| 167 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 168 base::Unretained(this)))); |
| 169 drm_->RunCallbacks(); |
| 170 EXPECT_EQ(1, drm_->get_page_flip_call_count()); |
| 171 EXPECT_EQ(1, drm_->get_overlay_flip_call_count()); |
| 172 } |
| 173 |
| 174 TEST_F(HardwareDisplayControllerTest, CheckOverlayTestMode) { |
| 175 ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( |
| 176 new MockScanoutBuffer(kDefaultModeSize))); |
| 177 ui::OverlayPlane plane2( |
| 178 scoped_refptr<ui::ScanoutBuffer>(new MockScanoutBuffer(kDefaultModeSize)), |
| 179 1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(kDefaultModeSize), |
| 180 gfx::RectF(kDefaultModeSizeF)); |
| 181 |
| 182 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 183 |
| 184 std::vector<ui::OverlayPlane> planes; |
| 185 planes.push_back(plane1); |
| 186 planes.push_back(plane2); |
| 187 |
| 188 EXPECT_TRUE(controller_->SchedulePageFlip( |
| 189 planes, false, false, |
| 190 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 191 base::Unretained(this)))); |
| 192 drm_->RunCallbacks(); |
| 193 EXPECT_EQ(1, drm_->get_page_flip_call_count()); |
| 194 EXPECT_EQ(1, drm_->get_overlay_flip_call_count()); |
| 195 |
| 196 // A test call shouldn't cause new flips, but should succeed. |
| 197 EXPECT_TRUE(controller_->SchedulePageFlip( |
| 198 planes, false, true, |
| 199 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 200 base::Unretained(this)))); |
| 201 drm_->RunCallbacks(); |
| 202 EXPECT_EQ(1, drm_->get_page_flip_call_count()); |
| 203 EXPECT_EQ(1, drm_->get_overlay_flip_call_count()); |
| 204 |
| 205 // Regular flips should continue on normally. |
| 206 EXPECT_TRUE(controller_->SchedulePageFlip( |
| 207 planes, false, false, |
| 208 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 209 base::Unretained(this)))); |
| 210 drm_->RunCallbacks(); |
| 211 EXPECT_EQ(2, drm_->get_page_flip_call_count()); |
| 212 EXPECT_EQ(2, drm_->get_overlay_flip_call_count()); |
| 213 } |
| 214 |
| 215 TEST_F(HardwareDisplayControllerTest, RejectUnderlays) { |
| 216 ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( |
| 217 new MockScanoutBuffer(kDefaultModeSize))); |
| 218 ui::OverlayPlane plane2( |
| 219 scoped_refptr<ui::ScanoutBuffer>(new MockScanoutBuffer(kDefaultModeSize)), |
| 220 -1, gfx::OVERLAY_TRANSFORM_NONE, gfx::Rect(kDefaultModeSize), |
| 221 gfx::RectF(kDefaultModeSizeF)); |
| 222 |
| 223 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 224 |
| 225 std::vector<ui::OverlayPlane> planes; |
| 226 planes.push_back(plane1); |
| 227 planes.push_back(plane2); |
| 228 |
| 229 EXPECT_FALSE(controller_->SchedulePageFlip( |
| 230 planes, false, false, |
| 231 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 232 base::Unretained(this)))); |
| 233 } |
| 234 |
| 235 TEST_F(HardwareDisplayControllerTest, PageflipMirroredControllers) { |
| 236 controller_->AddCrtc(scoped_ptr<ui::CrtcController>( |
| 237 new ui::CrtcController(drm_.get(), kSecondaryCrtc, kSecondaryConnector))); |
| 238 |
| 239 ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( |
| 240 new MockScanoutBuffer(kDefaultModeSize))); |
| 241 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 242 EXPECT_EQ(2, drm_->get_set_crtc_call_count()); |
| 243 |
| 244 ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( |
| 245 new MockScanoutBuffer(kDefaultModeSize))); |
| 246 std::vector<ui::OverlayPlane> planes = |
| 247 std::vector<ui::OverlayPlane>(1, plane2); |
| 248 EXPECT_TRUE(controller_->SchedulePageFlip( |
| 249 planes, false, false, |
| 250 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 251 base::Unretained(this)))); |
| 252 drm_->RunCallbacks(); |
| 253 EXPECT_EQ(2, drm_->get_page_flip_call_count()); |
| 254 EXPECT_EQ(1, page_flips_); |
| 255 } |
| 256 |
| 257 TEST_F(HardwareDisplayControllerTest, PlaneStateAfterRemoveCrtc) { |
| 258 ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( |
| 259 new MockScanoutBuffer(kDefaultModeSize))); |
| 260 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 261 std::vector<ui::OverlayPlane> planes = |
| 262 std::vector<ui::OverlayPlane>(1, plane1); |
| 263 EXPECT_TRUE(controller_->SchedulePageFlip( |
| 264 planes, false, false, |
| 265 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 266 base::Unretained(this)))); |
| 267 drm_->RunCallbacks(); |
| 268 |
| 269 const ui::HardwareDisplayPlane* owned_plane = nullptr; |
| 270 for (const auto& plane : drm_->plane_manager()->planes()) |
| 271 if (plane->in_use()) |
| 272 owned_plane = plane; |
| 273 ASSERT_TRUE(owned_plane != nullptr); |
| 274 EXPECT_EQ(kPrimaryCrtc, owned_plane->owning_crtc()); |
| 275 // Removing the crtc should free the plane. |
| 276 scoped_ptr<ui::CrtcController> crtc = |
| 277 controller_->RemoveCrtc(drm_, kPrimaryCrtc); |
| 278 EXPECT_FALSE(owned_plane->in_use()); |
| 279 } |
| 280 |
| 281 TEST_F(HardwareDisplayControllerTest, ModesetWhilePageFlipping) { |
| 282 ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( |
| 283 new MockScanoutBuffer(kDefaultModeSize))); |
| 284 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 285 std::vector<ui::OverlayPlane> planes = |
| 286 std::vector<ui::OverlayPlane>(1, plane1); |
| 287 EXPECT_TRUE(controller_->SchedulePageFlip( |
| 288 planes, false, false, |
| 289 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 290 base::Unretained(this)))); |
| 291 |
| 292 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 293 drm_->RunCallbacks(); |
| 294 EXPECT_EQ(1, page_flips_); |
| 295 } |
| 296 |
| 297 TEST_F(HardwareDisplayControllerTest, AddCrtcMidPageFlip) { |
| 298 ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( |
| 299 new MockScanoutBuffer(kDefaultModeSize))); |
| 300 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 301 std::vector<ui::OverlayPlane> planes = |
| 302 std::vector<ui::OverlayPlane>(1, plane1); |
| 303 EXPECT_TRUE(controller_->SchedulePageFlip( |
| 304 planes, false, false, |
| 305 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 306 base::Unretained(this)))); |
| 307 |
| 308 controller_->AddCrtc(scoped_ptr<ui::CrtcController>( |
| 309 new ui::CrtcController(drm_.get(), kSecondaryCrtc, kSecondaryConnector))); |
| 310 |
| 311 drm_->RunCallbacks(); |
| 312 EXPECT_EQ(1, page_flips_); |
| 313 } |
| 314 |
| 315 TEST_F(HardwareDisplayControllerTest, RemoveCrtcMidPageFlip) { |
| 316 ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( |
| 317 new MockScanoutBuffer(kDefaultModeSize))); |
| 318 EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); |
| 319 std::vector<ui::OverlayPlane> planes = |
| 320 std::vector<ui::OverlayPlane>(1, plane1); |
| 321 EXPECT_TRUE(controller_->SchedulePageFlip( |
| 322 planes, false, false, |
| 323 base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, |
| 324 base::Unretained(this)))); |
| 325 |
| 326 controller_->RemoveCrtc(drm_, kPrimaryCrtc); |
| 327 |
| 328 EXPECT_EQ(1, page_flips_); |
| 329 drm_->RunCallbacks(); |
| 330 EXPECT_EQ(1, page_flips_); |
| 331 } |
OLD | NEW |