summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/ozone/platform/drm/gbm_surface_factory.cc11
-rw-r--r--ui/ozone/platform/drm/gpu/drm_surface.cc11
-rw-r--r--ui/ozone/platform/drm/gpu/drm_window.cc28
-rw-r--r--ui/ozone/platform/drm/gpu/drm_window.h17
-rw-r--r--ui/ozone/platform/drm/gpu/gbm_surface.cc3
-rw-r--r--ui/ozone/platform/drm/gpu/gbm_surfaceless.cc16
-rw-r--r--ui/ozone/platform/drm/gpu/hardware_display_controller.cc31
-rw-r--r--ui/ozone/platform/drm/gpu/hardware_display_controller.h9
-rw-r--r--ui/ozone/platform/drm/gpu/hardware_display_controller_unittest.cc81
-rw-r--r--ui/ozone/platform/drm/gpu/screen_manager.cc29
-rw-r--r--ui/ozone/platform/drm/gpu/screen_manager.h6
-rw-r--r--ui/ozone/platform/drm/gpu/screen_manager_unittest.cc8
12 files changed, 149 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..22a70f0 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,31 @@ 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;
+}
+
+bool DrmWindow::PrepareController(HardwareDisplayController* controller) {
+ const OverlayPlane* primary =
+ OverlayPlane::GetPrimaryPlane(last_submitted_planes_);
+
+ return controller->Modeset(*primary, controller->get_mode());
+}
+
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..00f2cc0 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);
+
+ // About to enable hardware display controller, aquire pending frames.
+ bool PrepareController(HardwareDisplayController* controller);
+
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..19b6025 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,17 @@ 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);
+ }
+
+ return window->PrepareController(controller);
+}
+
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..444117b 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) {