summaryrefslogtreecommitdiffstats
path: root/ui/ozone/platform/drm/gpu/screen_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/ozone/platform/drm/gpu/screen_manager.cc')
-rw-r--r--ui/ozone/platform/drm/gpu/screen_manager.cc36
1 files changed, 29 insertions, 7 deletions
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)