Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Unified Diff: ui/ozone/platform/drm/gpu/screen_manager.cc

Issue 1338843002: [Ozone-DRM] Use CRTC's mode when configuring it for mirror mode (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fix-scanout3
Patch Set: Removed get_mode() from HDC per dbehr@'s comment Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/ozone/platform/drm/gpu/screen_manager.h ('k') | ui/ozone/platform/drm/gpu/screen_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/ozone/platform/drm/gpu/screen_manager.cc
diff --git a/ui/ozone/platform/drm/gpu/screen_manager.cc b/ui/ozone/platform/drm/gpu/screen_manager.cc
index 72a14a1f17f7a65de3e9fb9a7a7a5bbadcbd7e61..2aba0d96029143a830fdc988c379c8a975f406ff 100644
--- a/ui/ozone/platform/drm/gpu/screen_manager.cc
+++ b/ui/ozone/platform/drm/gpu/screen_manager.cc
@@ -65,6 +65,18 @@ void FillModesetBuffer(const scoped_refptr<DrmDevice>& drm,
modeset_buffer.canvas()->drawImage(image.get(), 0, 0, &paint);
}
+CrtcController* GetCrtcController(HardwareDisplayController* controller,
+ const scoped_refptr<DrmDevice>& drm,
+ uint32_t crtc) {
+ for (CrtcController* crtc_controller : controller->crtc_controllers()) {
+ if (crtc_controller->crtc() == crtc)
+ return crtc_controller;
+ }
+
+ NOTREACHED();
+ return nullptr;
+}
+
} // namespace
ScreenManager::ScreenManager(ScanoutBufferGenerator* buffer_generator)
@@ -133,9 +145,10 @@ bool ScreenManager::ActualConfigureDisplayController(
<< ") doesn't exist.";
HardwareDisplayController* controller = *it;
+ CrtcController* crtc_controller = GetCrtcController(controller, drm, crtc);
// If nothing changed just enable the controller. Note, we perform an exact
// comparison on the mode since the refresh rate may have changed.
- if (SameMode(mode, controller->get_mode()) &&
+ if (SameMode(mode, crtc_controller->mode()) &&
origin == controller->origin()) {
if (controller->IsDisabled()) {
HardwareDisplayControllers::iterator mirror =
@@ -143,12 +156,11 @@ bool ScreenManager::ActualConfigureDisplayController(
// If there is an active controller at the same location then start mirror
// mode.
if (mirror != controllers_.end())
- return HandleMirrorMode(it, mirror, drm, crtc, connector);
+ return HandleMirrorMode(it, mirror, drm, crtc, connector, mode);
}
// Just re-enable the controller to re-use the current state.
- return EnableController(controller, controller->origin(),
- controller->get_mode());
+ return EnableController(controller);
}
// Either the mode or the location of the display changed, so exit mirror
@@ -166,9 +178,9 @@ bool ScreenManager::ActualConfigureDisplayController(
FindActiveDisplayControllerByLocation(modeset_bounds);
// Handle mirror mode.
if (mirror != controllers_.end() && it != mirror)
- return HandleMirrorMode(it, mirror, drm, crtc, connector);
+ return HandleMirrorMode(it, mirror, drm, crtc, connector, mode);
- return EnableController(controller, origin, mode);
+ return ModesetController(controller, origin, mode);
}
bool ScreenManager::DisableDisplayController(
@@ -256,9 +268,20 @@ bool ScreenManager::HandleMirrorMode(
HardwareDisplayControllers::iterator mirror,
const scoped_refptr<DrmDevice>& drm,
uint32_t crtc,
- uint32_t connector) {
- (*mirror)->AddCrtc((*original)->RemoveCrtc(drm, crtc));
- if (EnableController(*mirror, (*mirror)->origin(), (*mirror)->get_mode())) {
+ uint32_t connector,
+ const drmModeModeInfo& mode) {
+ gfx::Point last_origin = (*original)->origin();
+ // There should only be one CRTC in this controller.
+ drmModeModeInfo last_mode = (*original)->crtc_controllers()[0]->mode();
+
+ // Modeset the CRTC with its mode in the original controller so that only this
+ // CRTC is affected by the mode. Otherwise it could apply a mode with the same
+ // resolution and refresh rate but with different timings to the other CRTC.
+ // TODO(dnicoara): This is hacky, instead the DrmDisplay and CrtcController
+ // should be merged and picking the mode should be done properly within
+ // HardwareDisplayController.
+ if (ModesetController(*original, (*mirror)->origin(), mode)) {
+ (*mirror)->AddCrtc((*original)->RemoveCrtc(drm, crtc));
controllers_.erase(original);
return true;
}
@@ -268,8 +291,7 @@ bool ScreenManager::HandleMirrorMode(
// When things go wrong revert back to the previous configuration since
// it is expected that the configuration would not have changed if
// things fail.
- (*original)->AddCrtc((*mirror)->RemoveCrtc(drm, crtc));
- EnableController(*original, (*original)->origin(), (*original)->get_mode());
+ ModesetController(*original, last_origin, last_mode);
return false;
}
@@ -303,42 +325,56 @@ void ScreenManager::UpdateControllerToWindowMapping() {
// If we're moving windows between controllers modeset the controller
// otherwise the controller may be waiting for a page flip while the window
// tries to schedule another buffer.
- if (should_enable)
- EnableController(controller, controller->origin(),
- controller->get_mode());
+ if (should_enable) {
+ EnableController(controller);
+ }
}
}
-bool ScreenManager::EnableController(HardwareDisplayController* controller,
- const gfx::Point& origin,
- const drmModeModeInfo& mode) {
- DCHECK(!controller->crtc_controllers().empty());
- gfx::Rect rect(origin, gfx::Size(mode.hdisplay, mode.vdisplay));
- controller->set_origin(origin);
-
- DrmWindow* window = FindWindowAt(rect);
+OverlayPlane ScreenManager::GetModesetBuffer(
+ HardwareDisplayController* controller,
+ const gfx::Rect& bounds) {
+ DrmWindow* window = FindWindowAt(bounds);
if (window) {
const OverlayPlane* primary = window->GetLastModesetBuffer();
- if (primary) {
- if (!controller->Modeset(*primary, mode)) {
- LOG(ERROR) << "Failed to modeset controller";
- return false;
- }
-
- return true;
- }
+ if (primary && primary->buffer->GetSize() == bounds.size())
+ return *primary;
}
scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice();
scoped_refptr<ScanoutBuffer> buffer =
- buffer_generator_->Create(drm, rect.size());
+ buffer_generator_->Create(drm, bounds.size());
if (!buffer) {
LOG(ERROR) << "Failed to create scanout buffer";
- return false;
+ return OverlayPlane(nullptr, 0, gfx::OVERLAY_TRANSFORM_INVALID, gfx::Rect(),
+ gfx::RectF());
}
FillModesetBuffer(drm, controller, buffer.get());
- if (!controller->Modeset(OverlayPlane(buffer), mode)) {
+ return OverlayPlane(buffer);
+}
+
+bool ScreenManager::EnableController(HardwareDisplayController* controller) {
+ DCHECK(!controller->crtc_controllers().empty());
+ gfx::Rect rect(controller->origin(), controller->GetModeSize());
+ OverlayPlane plane = GetModesetBuffer(controller, rect);
+ if (!plane.buffer || !controller->Enable(plane)) {
+ LOG(ERROR) << "Failed to enable controller";
+ return false;
+ }
+
+ return true;
+}
+
+bool ScreenManager::ModesetController(HardwareDisplayController* controller,
+ const gfx::Point& origin,
+ const drmModeModeInfo& mode) {
+ DCHECK(!controller->crtc_controllers().empty());
+ gfx::Rect rect(origin, gfx::Size(mode.hdisplay, mode.vdisplay));
+ controller->set_origin(origin);
+
+ OverlayPlane plane = GetModesetBuffer(controller, rect);
+ if (!plane.buffer || !controller->Modeset(plane, mode)) {
LOG(ERROR) << "Failed to modeset controller";
return false;
}
« no previous file with comments | « ui/ozone/platform/drm/gpu/screen_manager.h ('k') | ui/ozone/platform/drm/gpu/screen_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698