diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/ozone/platform/drm/gbm_surface_factory.cc | 11 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/drm_surface.cc | 11 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/drm_window.cc | 25 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/drm_window.h | 17 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/gbm_surface.cc | 3 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/gbm_surfaceless.cc | 16 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/hardware_display_controller.cc | 31 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/hardware_display_controller.h | 9 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc | 81 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/screen_manager.cc | 36 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/screen_manager.h | 6 | ||||
-rw-r--r-- | ui/ozone/platform/drm/gpu/screen_manager_unittest.cc | 38 |
12 files changed, 183 insertions, 101 deletions
diff --git a/ui/ozone/platform/drm/gbm_surface_factory.cc b/ui/ozone/platform/drm/gbm_surface_factory.cc index 4c836ee..8ecf724 100644 --- a/ui/ozone/platform/drm/gbm_surface_factory.cc +++ b/ui/ozone/platform/drm/gbm_surface_factory.cc @@ -191,14 +191,9 @@ bool GbmSurfaceFactory::ScheduleOverlayPlane( LOG(ERROR) << "ScheduleOverlayPlane passed NULL buffer."; return false; } - HardwareDisplayController* hdc = - screen_manager_->GetWindow(widget)->GetController(); - if (!hdc) - return true; - - hdc->QueueOverlayPlane(OverlayPlane(pixmap->buffer(), plane_z_order, - plane_transform, display_bounds, - crop_rect)); + screen_manager_->GetWindow(widget)->QueueOverlayPlane( + OverlayPlane(pixmap->buffer(), plane_z_order, plane_transform, + display_bounds, crop_rect)); return true; } diff --git a/ui/ozone/platform/drm/gpu/drm_surface.cc b/ui/ozone/platform/drm/gpu/drm_surface.cc index 466441e..0964c9e 100644 --- a/ui/ozone/platform/drm/gpu/drm_surface.cc +++ b/ui/ozone/platform/drm/gpu/drm_surface.cc @@ -65,16 +65,13 @@ void DrmSurface::ResizeCanvas(const gfx::Size& viewport_size) { void DrmSurface::PresentCanvas(const gfx::Rect& damage) { DCHECK(base::MessageLoopForUI::IsCurrent()); - HardwareDisplayController* controller = window_delegate_->GetController(); - if (!controller) - return; - DCHECK(buffers_[front_buffer_ ^ 1].get()); - controller->QueueOverlayPlane(OverlayPlane(buffers_[front_buffer_ ^ 1])); + window_delegate_->QueueOverlayPlane( + OverlayPlane(buffers_[front_buffer_ ^ 1])); UpdateNativeSurface(damage); - controller->SchedulePageFlip(false /* is_sync */, - base::Bind(&base::DoNothing)); + window_delegate_->SchedulePageFlip(false /* is_sync */, + base::Bind(&base::DoNothing)); // Update our front buffer pointer. front_buffer_ ^= 1; diff --git a/ui/ozone/platform/drm/gpu/drm_window.cc b/ui/ozone/platform/drm/gpu/drm_window.cc index 7517f09..ec6a0ea 100644 --- a/ui/ozone/platform/drm/gpu/drm_window.cc +++ b/ui/ozone/platform/drm/gpu/drm_window.cc @@ -51,7 +51,8 @@ DrmWindow::DrmWindow(gfx::AcceleratedWidget widget, controller_(NULL), cursor_frontbuffer_(0), cursor_frame_(0), - cursor_frame_delay_ms_(0) { + cursor_frame_delay_ms_(0), + last_swap_sync_(false) { } DrmWindow::~DrmWindow() { @@ -116,6 +117,28 @@ void DrmWindow::MoveCursor(const gfx::Point& location) { controller_->MoveCursor(location); } +void DrmWindow::QueueOverlayPlane(const OverlayPlane& plane) { + pending_planes_.push_back(plane); +} + +bool DrmWindow::SchedulePageFlip(bool is_sync, const base::Closure& callback) { + last_submitted_planes_.clear(); + last_submitted_planes_.swap(pending_planes_); + last_swap_sync_ = is_sync; + + if (controller_) { + return controller_->SchedulePageFlip(last_submitted_planes_, is_sync, + callback); + } + + callback.Run(); + return true; +} + +const OverlayPlane* DrmWindow::GetLastModesetBuffer() { + return OverlayPlane::GetPrimaryPlane(last_submitted_planes_); +} + void DrmWindow::ResetCursor(bool bitmap_only) { if (!controller_) return; diff --git a/ui/ozone/platform/drm/gpu/drm_window.h b/ui/ozone/platform/drm/gpu/drm_window.h index f655bbb..74e1e53 100644 --- a/ui/ozone/platform/drm/gpu/drm_window.h +++ b/ui/ozone/platform/drm/gpu/drm_window.h @@ -12,6 +12,7 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/ozone_export.h" +#include "ui/ozone/platform/drm/gpu/overlay_plane.h" class SkBitmap; @@ -73,6 +74,16 @@ class OZONE_EXPORT DrmWindow { // Move the HW cursor to the specified location. void MoveCursor(const gfx::Point& location); + // Queue overlay planes and page flips. + // If hardware display controller is available, forward the information + // immediately, otherwise queue up on the window and forward when the hardware + // is once again ready. + void QueueOverlayPlane(const OverlayPlane& plane); + bool SchedulePageFlip(bool is_sync, const base::Closure& callback); + + // Returns the last buffer associated with this window. + const OverlayPlane* GetLastModesetBuffer(); + private: // Draw the last set cursor & update the cursor plane. void ResetCursor(bool bitmap_only); @@ -106,6 +117,12 @@ class OZONE_EXPORT DrmWindow { int cursor_frame_; int cursor_frame_delay_ms_; + // Planes and flips currently being queued in the absence of hardware display + // controller. + OverlayPlaneList pending_planes_; + OverlayPlaneList last_submitted_planes_; + bool last_swap_sync_; + DISALLOW_COPY_AND_ASSIGN(DrmWindow); }; diff --git a/ui/ozone/platform/drm/gpu/gbm_surface.cc b/ui/ozone/platform/drm/gpu/gbm_surface.cc index 80c84f9..8b5b167 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surface.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surface.cc @@ -150,8 +150,7 @@ bool GbmSurface::OnSwapBuffersAsync(const SwapCompletionCallback& callback) { } // The primary buffer is a special case. - if (window_delegate_->GetController()) - window_delegate_->GetController()->QueueOverlayPlane(OverlayPlane(primary)); + window_delegate_->QueueOverlayPlane(OverlayPlane(primary)); if (!GbmSurfaceless::OnSwapBuffersAsync( base::Bind(&GbmSurface::OnSwapBuffersCallback, diff --git a/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc b/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc index 138d207..c906cfd 100644 --- a/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc +++ b/ui/ozone/platform/drm/gpu/gbm_surfaceless.cc @@ -34,23 +34,13 @@ bool GbmSurfaceless::ResizeNativeWindow(const gfx::Size& viewport_size) { } bool GbmSurfaceless::OnSwapBuffers() { - HardwareDisplayController* controller = window_delegate_->GetController(); - if (!controller) - return true; - - return controller->SchedulePageFlip(true /* is_sync */, - base::Bind(&base::DoNothing)); + return window_delegate_->SchedulePageFlip(true /* is_sync */, + base::Bind(&base::DoNothing)); } bool GbmSurfaceless::OnSwapBuffersAsync( const SwapCompletionCallback& callback) { - HardwareDisplayController* controller = window_delegate_->GetController(); - if (!controller) { - callback.Run(); - return true; - } - - return controller->SchedulePageFlip(false /* is_sync */, callback); + return window_delegate_->SchedulePageFlip(false /* is_sync */, callback); } scoped_ptr<gfx::VSyncProvider> GbmSurfaceless::CreateVSyncProvider() { diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller.cc index f9f08ea..278dc15 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_controller.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_controller.cc @@ -67,45 +67,34 @@ bool HardwareDisplayController::Modeset(const OverlayPlane& primary, return status; } -bool HardwareDisplayController::Enable() { - TRACE_EVENT0("drm", "HDC::Enable"); - DCHECK(!current_planes_.empty()); - - const OverlayPlane* primary = nullptr; - // Use the last scheduled buffer to modeset to preserve request order. - if (!requests_.empty()) - primary = OverlayPlane::GetPrimaryPlane(requests_.back().planes); - else - primary = OverlayPlane::GetPrimaryPlane(current_planes_); - - return Modeset(*primary, mode_); -} - void HardwareDisplayController::Disable() { TRACE_EVENT0("drm", "HDC::Disable"); for (size_t i = 0; i < crtc_controllers_.size(); ++i) crtc_controllers_[i]->Disable(); - is_disabled_ = true; -} + // Don't hold onto any requests because we don't track fron buffer while + // disabled. + while (requests_.size()) + ProcessPageFlipRequest(); -void HardwareDisplayController::QueueOverlayPlane(const OverlayPlane& plane) { - pending_planes_.push_back(plane); + current_planes_.clear(); + + is_disabled_ = true; } bool HardwareDisplayController::SchedulePageFlip( + const OverlayPlaneList& plane_list, bool is_sync, const base::Closure& callback) { TRACE_EVENT0("drm", "HDC::SchedulePageFlip"); // Ignore requests with no planes to schedule. - if (pending_planes_.empty()) { + if (plane_list.empty()) { callback.Run(); return true; } - requests_.push_back(PageFlipRequest(pending_planes_, is_sync, callback)); - pending_planes_.clear(); + requests_.push_back(PageFlipRequest(plane_list, is_sync, callback)); // A request is being serviced right now. if (HasPendingPageFlips()) diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller.h b/ui/ozone/platform/drm/gpu/hardware_display_controller.h index 52095d5..196b2dd 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_controller.h +++ b/ui/ozone/platform/drm/gpu/hardware_display_controller.h @@ -98,14 +98,9 @@ class OZONE_EXPORT HardwareDisplayController // framebuffer for |primary| with |mode|. bool Modeset(const OverlayPlane& primary, drmModeModeInfo mode); - // Reconfigures the CRTC with the current surface and mode. - bool Enable(); - // Disables the CRTC. void Disable(); - void QueueOverlayPlane(const OverlayPlane& plane); - // Schedules the |overlays|' framebuffers to be displayed on the next vsync // event. The event will be posted on the graphics card file descriptor |fd_| // and it can be read and processed by |drmHandleEvent|. That function can @@ -122,7 +117,9 @@ class OZONE_EXPORT HardwareDisplayController // called again before the page flip occurrs. // // Returns true if the page flip was successfully registered, false otherwise. - bool SchedulePageFlip(bool is_sync, const base::Closure& callback); + bool SchedulePageFlip(const OverlayPlaneList& plane_list, + bool is_sync, + const base::Closure& callback); // Set the hardware cursor to show the contents of |surface|. bool SetCursor(const scoped_refptr<ScanoutBuffer>& buffer); diff --git a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc index fb03519..c325f8b 100644 --- a/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc +++ b/ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc @@ -101,10 +101,12 @@ TEST_F(HardwareDisplayControllerTest, CheckStateAfterPageFlip) { ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( new MockScanoutBuffer(kDefaultModeSize))); - controller_->QueueOverlayPlane(plane2); + std::vector<ui::OverlayPlane> planes = + std::vector<ui::OverlayPlane>(1, plane2); EXPECT_TRUE(controller_->SchedulePageFlip( - false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, - base::Unretained(this)))); + planes, false, + base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this)))); drm_->RunCallbacks(); EXPECT_TRUE(plane1.buffer->HasOneRef()); EXPECT_FALSE(plane2.buffer->HasOneRef()); @@ -132,11 +134,14 @@ TEST_F(HardwareDisplayControllerTest, CheckStateIfPageFlipFails) { ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( new MockScanoutBuffer(kDefaultModeSize))); - controller_->QueueOverlayPlane(plane2); + std::vector<ui::OverlayPlane> planes = + std::vector<ui::OverlayPlane>(1, plane2); EXPECT_FALSE(controller_->SchedulePageFlip( - false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, - base::Unretained(this)))); + planes, false, + base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this)))); drm_->RunCallbacks(); + planes.clear(); EXPECT_FALSE(plane1.buffer->HasOneRef()); EXPECT_TRUE(plane2.buffer->HasOneRef()); @@ -150,18 +155,20 @@ TEST_F(HardwareDisplayControllerTest, VerifyNoDRMCallsWhenDisabled) { controller_->Disable(); ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( new MockScanoutBuffer(kDefaultModeSize))); - controller_->QueueOverlayPlane(plane2); + std::vector<ui::OverlayPlane> planes = + std::vector<ui::OverlayPlane>(1, plane2); EXPECT_TRUE(controller_->SchedulePageFlip( - false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, - base::Unretained(this)))); + planes, false, + base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this)))); drm_->RunCallbacks(); EXPECT_EQ(0, drm_->get_page_flip_call_count()); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); - controller_->QueueOverlayPlane(plane2); EXPECT_TRUE(controller_->SchedulePageFlip( - false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, - base::Unretained(this)))); + planes, false, + base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this)))); drm_->RunCallbacks(); EXPECT_EQ(1, drm_->get_page_flip_call_count()); } @@ -176,12 +183,14 @@ TEST_F(HardwareDisplayControllerTest, CheckOverlayPresent) { EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); - controller_->QueueOverlayPlane(plane1); - controller_->QueueOverlayPlane(plane2); + std::vector<ui::OverlayPlane> planes; + planes.push_back(plane1); + planes.push_back(plane2); EXPECT_TRUE(controller_->SchedulePageFlip( - false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, - base::Unretained(this)))); + planes, false, + base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this)))); drm_->RunCallbacks(); EXPECT_EQ(1, drm_->get_page_flip_call_count()); EXPECT_EQ(1, drm_->get_overlay_flip_call_count()); @@ -198,10 +207,12 @@ TEST_F(HardwareDisplayControllerTest, PageflipMirroredControllers) { ui::OverlayPlane plane2(scoped_refptr<ui::ScanoutBuffer>( new MockScanoutBuffer(kDefaultModeSize))); - controller_->QueueOverlayPlane(plane2); + std::vector<ui::OverlayPlane> planes = + std::vector<ui::OverlayPlane>(1, plane2); EXPECT_TRUE(controller_->SchedulePageFlip( - false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, - base::Unretained(this)))); + planes, false, + base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this)))); drm_->RunCallbacks(); EXPECT_EQ(2, drm_->get_page_flip_call_count()); EXPECT_EQ(1, page_flips_); @@ -211,10 +222,12 @@ TEST_F(HardwareDisplayControllerTest, PlaneStateAfterRemoveCrtc) { ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( new MockScanoutBuffer(kDefaultModeSize))); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); - controller_->QueueOverlayPlane(plane1); + std::vector<ui::OverlayPlane> planes = + std::vector<ui::OverlayPlane>(1, plane1); EXPECT_TRUE(controller_->SchedulePageFlip( - false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, - base::Unretained(this)))); + planes, false, + base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this)))); drm_->RunCallbacks(); const ui::HardwareDisplayPlane* owned_plane = nullptr; @@ -233,10 +246,12 @@ TEST_F(HardwareDisplayControllerTest, ModesetWhilePageFlipping) { ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( new MockScanoutBuffer(kDefaultModeSize))); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); - controller_->QueueOverlayPlane(plane1); + std::vector<ui::OverlayPlane> planes = + std::vector<ui::OverlayPlane>(1, plane1); EXPECT_TRUE(controller_->SchedulePageFlip( - false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, - base::Unretained(this)))); + planes, false, + base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this)))); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); drm_->RunCallbacks(); @@ -247,10 +262,12 @@ TEST_F(HardwareDisplayControllerTest, AddCrtcMidPageFlip) { ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( new MockScanoutBuffer(kDefaultModeSize))); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); - controller_->QueueOverlayPlane(plane1); + std::vector<ui::OverlayPlane> planes = + std::vector<ui::OverlayPlane>(1, plane1); EXPECT_TRUE(controller_->SchedulePageFlip( - false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, - base::Unretained(this)))); + planes, false, + base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this)))); controller_->AddCrtc(scoped_ptr<ui::CrtcController>( new ui::CrtcController(drm_.get(), kSecondaryCrtc, kSecondaryConnector))); @@ -263,10 +280,12 @@ TEST_F(HardwareDisplayControllerTest, RemoveCrtcMidPageFlip) { ui::OverlayPlane plane1(scoped_refptr<ui::ScanoutBuffer>( new MockScanoutBuffer(kDefaultModeSize))); EXPECT_TRUE(controller_->Modeset(plane1, kDefaultMode)); - controller_->QueueOverlayPlane(plane1); + std::vector<ui::OverlayPlane> planes = + std::vector<ui::OverlayPlane>(1, plane1); EXPECT_TRUE(controller_->SchedulePageFlip( - false, base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, - base::Unretained(this)))); + planes, false, + base::Bind(&HardwareDisplayControllerTest::PageFlipCallback, + base::Unretained(this)))); controller_->RemoveCrtc(drm_, kPrimaryCrtc); diff --git a/ui/ozone/platform/drm/gpu/screen_manager.cc b/ui/ozone/platform/drm/gpu/screen_manager.cc index 5793572..532b8c9 100644 --- a/ui/ozone/platform/drm/gpu/screen_manager.cc +++ b/ui/ozone/platform/drm/gpu/screen_manager.cc @@ -146,8 +146,7 @@ bool ScreenManager::ActualConfigureDisplayController( } // Just re-enable the controller to re-use the current state. - bool enabled = controller->Enable(); - return enabled; + return EnableController(controller); } // Either the mode or the location of the display changed, so exit mirror @@ -167,7 +166,7 @@ bool ScreenManager::ActualConfigureDisplayController( if (mirror != controllers_.end() && it != mirror) return HandleMirrorMode(it, mirror, drm, crtc, connector); - return ModesetDisplayController(controller, origin, mode); + return ModesetDisplayController(controller, origin, mode, true); } bool ScreenManager::DisableDisplayController( @@ -181,6 +180,9 @@ bool ScreenManager::DisableDisplayController( controllers_.push_back(controller); } + // Workaround for driver bug that does not release the buffer on null + // modeset. + ModesetDisplayController((*it), (*it)->origin(), (*it)->get_mode(), false); (*it)->Disable(); UpdateControllerToWindowMapping(); return true; @@ -252,7 +254,8 @@ ScreenManager::FindActiveDisplayControllerByLocation(const gfx::Rect& bounds) { bool ScreenManager::ModesetDisplayController( HardwareDisplayController* controller, const gfx::Point& origin, - const drmModeModeInfo& mode) { + const drmModeModeInfo& mode, + bool fill_modeset_buffer) { DCHECK(!controller->crtc_controllers().empty()); scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice(); controller->set_origin(origin); @@ -266,7 +269,8 @@ bool ScreenManager::ModesetDisplayController( return false; } - FillModesetBuffer(drm, controller, buffer.get()); + if (fill_modeset_buffer) + FillModesetBuffer(drm, controller, buffer.get()); if (!controller->Modeset(OverlayPlane(buffer), mode)) { LOG(ERROR) << "Failed to modeset controller"; @@ -283,7 +287,7 @@ bool ScreenManager::HandleMirrorMode( uint32_t crtc, uint32_t connector) { (*mirror)->AddCrtc((*original)->RemoveCrtc(drm, crtc)); - if ((*mirror)->Enable()) { + if (EnableController(*mirror)) { controllers_.erase(original); return true; } @@ -294,7 +298,7 @@ bool ScreenManager::HandleMirrorMode( // it is expected that the configuration would not have changed if // things fail. (*original)->AddCrtc((*mirror)->RemoveCrtc(drm, crtc)); - (*original)->Enable(); + EnableController(*original); return false; } @@ -324,6 +328,24 @@ void ScreenManager::UpdateControllerToWindowMapping() { } } +bool ScreenManager::EnableController(HardwareDisplayController* controller) { + DrmWindow* window = + FindWindowAt(gfx::Rect(controller->origin(), controller->GetModeSize())); + if (!window) { + return ModesetDisplayController(controller, controller->origin(), + controller->get_mode(), false); + } + + const OverlayPlane* primary = window->GetLastModesetBuffer(); + if (primary) + return controller->Modeset(*primary, controller->get_mode()); + + // No window, but we were previously modeset, reuse stored buffer's contents + // to avoid black flickers. + return ModesetDisplayController(controller, controller->origin(), + controller->get_mode(), true); +} + DrmWindow* ScreenManager::FindWindowAt(const gfx::Rect& bounds) const { for (auto pair : window_map_) { if (pair.second->bounds() == bounds) diff --git a/ui/ozone/platform/drm/gpu/screen_manager.h b/ui/ozone/platform/drm/gpu/screen_manager.h index 2732769..4e8123d 100644 --- a/ui/ozone/platform/drm/gpu/screen_manager.h +++ b/ui/ozone/platform/drm/gpu/screen_manager.h @@ -104,7 +104,8 @@ class OZONE_EXPORT ScreenManager { // Perform modesetting in |controller| using |origin| and |mode|. bool ModesetDisplayController(HardwareDisplayController* controller, const gfx::Point& origin, - const drmModeModeInfo& mode); + const drmModeModeInfo& mode, + bool fill_mode_set_buffer); // Tries to set the controller identified by (|crtc|, |connector|) to mirror // those in |mirror|. |original| is an iterator to the HDC where the @@ -115,6 +116,9 @@ class OZONE_EXPORT ScreenManager { uint32_t crtc, uint32_t connector); + // Aquire pending frames from the time the controller was disabled. + bool EnableController(HardwareDisplayController* controller); + DrmWindow* FindWindowAt(const gfx::Rect& bounds) const; ScanoutBufferGenerator* buffer_generator_; // Not owned. diff --git a/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc b/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc index bf0d211..7ed4266 100644 --- a/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc +++ b/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc @@ -121,8 +121,8 @@ TEST_F(ScreenManagerTest, CheckDuplicateConfiguration) { drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); - // Should reuse existing framebuffer. - EXPECT_EQ(framebuffer, drm_->current_framebuffer()); + // Should not hold onto buffers. + EXPECT_NE(framebuffer, drm_->current_framebuffer()); EXPECT_TRUE(screen_manager_->GetDisplayController(GetPrimaryBounds())); EXPECT_FALSE(screen_manager_->GetDisplayController(GetSecondaryBounds())); @@ -254,8 +254,8 @@ TEST_F(ScreenManagerTest, ReuseFramebufferIfDisabledThenReEnabled) { drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), kDefaultMode); - // Should reuse existing framebuffer. - EXPECT_EQ(framebuffer, drm_->current_framebuffer()); + // Buffers are released when disabled. + EXPECT_NE(framebuffer, drm_->current_framebuffer()); } TEST_F(ScreenManagerTest, CheckMirrorModeAfterBeginReEnabled) { @@ -398,3 +398,33 @@ TEST_F(ScreenManagerTest, ShouldDissociateWindowOnControllerRemoval) { window = screen_manager_->RemoveWindow(1); window->Shutdown(); } + +TEST_F(ScreenManagerTest, EnableControllerWhenWindowHasNoBuffer) { + ui::DrmDeviceManager device_manager(drm_); + scoped_ptr<ui::DrmWindow> window( + new ui::DrmWindow(1, &device_manager, screen_manager_.get())); + window->Initialize(); + window->OnBoundsChanged(GetPrimaryBounds()); + screen_manager_->AddWindow(1, window.Pass()); + + screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector); + screen_manager_->ConfigureDisplayController( + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); + + EXPECT_TRUE(screen_manager_->GetWindow(1)->GetController()); + // There is a buffer after initial config. + uint32_t framebuffer = drm_->current_framebuffer(); + EXPECT_NE(0U, framebuffer); + + screen_manager_->ConfigureDisplayController( + drm_, kPrimaryCrtc, kPrimaryConnector, GetPrimaryBounds().origin(), + kDefaultMode); + + // There is a new buffer after we configured with the same mode but no + // pending frames on the window. + EXPECT_NE(framebuffer, drm_->current_framebuffer()); + + window = screen_manager_->RemoveWindow(1); + window->Shutdown(); +} |