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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/ozone/platform/drm/gpu/screen_manager.h" 5 #include "ui/ozone/platform/drm/gpu/screen_manager.h"
6 6
7 #include <xf86drmMode.h> 7 #include <xf86drmMode.h>
8 8
9 #include "third_party/skia/include/core/SkCanvas.h" 9 #include "third_party/skia/include/core/SkCanvas.h"
10 #include "ui/gfx/geometry/point.h" 10 #include "ui/gfx/geometry/point.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 return; 58 return;
59 } 59 }
60 60
61 skia::RefPtr<SkImage> image = saved_buffer.image(); 61 skia::RefPtr<SkImage> image = saved_buffer.image();
62 SkPaint paint; 62 SkPaint paint;
63 // Copy the source buffer. Do not perform any blending. 63 // Copy the source buffer. Do not perform any blending.
64 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 64 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
65 modeset_buffer.canvas()->drawImage(image.get(), 0, 0, &paint); 65 modeset_buffer.canvas()->drawImage(image.get(), 0, 0, &paint);
66 } 66 }
67 67
68 CrtcController* GetCrtcController(HardwareDisplayController* controller,
69 const scoped_refptr<DrmDevice>& drm,
70 uint32_t crtc) {
71 for (CrtcController* crtc_controller : controller->crtc_controllers()) {
72 if (crtc_controller->crtc() == crtc)
73 return crtc_controller;
74 }
75
76 NOTREACHED();
77 return nullptr;
78 }
79
68 } // namespace 80 } // namespace
69 81
70 ScreenManager::ScreenManager(ScanoutBufferGenerator* buffer_generator) 82 ScreenManager::ScreenManager(ScanoutBufferGenerator* buffer_generator)
71 : buffer_generator_(buffer_generator) { 83 : buffer_generator_(buffer_generator) {
72 } 84 }
73 85
74 ScreenManager::~ScreenManager() { 86 ScreenManager::~ScreenManager() {
75 DCHECK(window_map_.empty()); 87 DCHECK(window_map_.empty());
76 } 88 }
77 89
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 uint32_t connector, 138 uint32_t connector,
127 const gfx::Point& origin, 139 const gfx::Point& origin,
128 const drmModeModeInfo& mode) { 140 const drmModeModeInfo& mode) {
129 gfx::Rect modeset_bounds(origin.x(), origin.y(), mode.hdisplay, 141 gfx::Rect modeset_bounds(origin.x(), origin.y(), mode.hdisplay,
130 mode.vdisplay); 142 mode.vdisplay);
131 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); 143 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc);
132 DCHECK(controllers_.end() != it) << "Display controller (crtc=" << crtc 144 DCHECK(controllers_.end() != it) << "Display controller (crtc=" << crtc
133 << ") doesn't exist."; 145 << ") doesn't exist.";
134 146
135 HardwareDisplayController* controller = *it; 147 HardwareDisplayController* controller = *it;
148 CrtcController* crtc_controller = GetCrtcController(controller, drm, crtc);
136 // If nothing changed just enable the controller. Note, we perform an exact 149 // If nothing changed just enable the controller. Note, we perform an exact
137 // comparison on the mode since the refresh rate may have changed. 150 // comparison on the mode since the refresh rate may have changed.
138 if (SameMode(mode, controller->get_mode()) && 151 if (SameMode(mode, crtc_controller->mode()) &&
139 origin == controller->origin()) { 152 origin == controller->origin()) {
140 if (controller->IsDisabled()) { 153 if (controller->IsDisabled()) {
141 HardwareDisplayControllers::iterator mirror = 154 HardwareDisplayControllers::iterator mirror =
142 FindActiveDisplayControllerByLocation(modeset_bounds); 155 FindActiveDisplayControllerByLocation(modeset_bounds);
143 // If there is an active controller at the same location then start mirror 156 // If there is an active controller at the same location then start mirror
144 // mode. 157 // mode.
145 if (mirror != controllers_.end()) 158 if (mirror != controllers_.end())
146 return HandleMirrorMode(it, mirror, drm, crtc, connector); 159 return HandleMirrorMode(it, mirror, drm, crtc, connector, mode);
147 } 160 }
148 161
149 // Just re-enable the controller to re-use the current state. 162 // Just re-enable the controller to re-use the current state.
150 return EnableController(controller, controller->origin(), 163 return EnableController(controller);
151 controller->get_mode());
152 } 164 }
153 165
154 // Either the mode or the location of the display changed, so exit mirror 166 // Either the mode or the location of the display changed, so exit mirror
155 // mode and configure the display independently. If the caller still wants 167 // mode and configure the display independently. If the caller still wants
156 // mirror mode, subsequent calls configuring the other controllers will 168 // mirror mode, subsequent calls configuring the other controllers will
157 // restore mirror mode. 169 // restore mirror mode.
158 if (controller->IsMirrored()) { 170 if (controller->IsMirrored()) {
159 controller = new HardwareDisplayController( 171 controller = new HardwareDisplayController(
160 controller->RemoveCrtc(drm, crtc), controller->origin()); 172 controller->RemoveCrtc(drm, crtc), controller->origin());
161 controllers_.push_back(controller); 173 controllers_.push_back(controller);
162 it = controllers_.end() - 1; 174 it = controllers_.end() - 1;
163 } 175 }
164 176
165 HardwareDisplayControllers::iterator mirror = 177 HardwareDisplayControllers::iterator mirror =
166 FindActiveDisplayControllerByLocation(modeset_bounds); 178 FindActiveDisplayControllerByLocation(modeset_bounds);
167 // Handle mirror mode. 179 // Handle mirror mode.
168 if (mirror != controllers_.end() && it != mirror) 180 if (mirror != controllers_.end() && it != mirror)
169 return HandleMirrorMode(it, mirror, drm, crtc, connector); 181 return HandleMirrorMode(it, mirror, drm, crtc, connector, mode);
170 182
171 return EnableController(controller, origin, mode); 183 return ModesetController(controller, origin, mode);
172 } 184 }
173 185
174 bool ScreenManager::DisableDisplayController( 186 bool ScreenManager::DisableDisplayController(
175 const scoped_refptr<DrmDevice>& drm, 187 const scoped_refptr<DrmDevice>& drm,
176 uint32_t crtc) { 188 uint32_t crtc) {
177 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); 189 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc);
178 if (it != controllers_.end()) { 190 if (it != controllers_.end()) {
179 HardwareDisplayController* controller = *it; 191 HardwareDisplayController* controller = *it;
180 if (controller->IsMirrored()) { 192 if (controller->IsMirrored()) {
181 controller = new HardwareDisplayController( 193 controller = new HardwareDisplayController(
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 } 261 }
250 262
251 return controllers_.end(); 263 return controllers_.end();
252 } 264 }
253 265
254 bool ScreenManager::HandleMirrorMode( 266 bool ScreenManager::HandleMirrorMode(
255 HardwareDisplayControllers::iterator original, 267 HardwareDisplayControllers::iterator original,
256 HardwareDisplayControllers::iterator mirror, 268 HardwareDisplayControllers::iterator mirror,
257 const scoped_refptr<DrmDevice>& drm, 269 const scoped_refptr<DrmDevice>& drm,
258 uint32_t crtc, 270 uint32_t crtc,
259 uint32_t connector) { 271 uint32_t connector,
260 (*mirror)->AddCrtc((*original)->RemoveCrtc(drm, crtc)); 272 const drmModeModeInfo& mode) {
261 if (EnableController(*mirror, (*mirror)->origin(), (*mirror)->get_mode())) { 273 gfx::Point last_origin = (*original)->origin();
274 // There should only be one CRTC in this controller.
275 drmModeModeInfo last_mode = (*original)->crtc_controllers()[0]->mode();
276
277 // Modeset the CRTC with its mode in the original controller so that only this
278 // CRTC is affected by the mode. Otherwise it could apply a mode with the same
279 // resolution and refresh rate but with different timings to the other CRTC.
280 // TODO(dnicoara): This is hacky, instead the DrmDisplay and CrtcController
281 // should be merged and picking the mode should be done properly within
282 // HardwareDisplayController.
283 if (ModesetController(*original, (*mirror)->origin(), mode)) {
284 (*mirror)->AddCrtc((*original)->RemoveCrtc(drm, crtc));
262 controllers_.erase(original); 285 controllers_.erase(original);
263 return true; 286 return true;
264 } 287 }
265 288
266 LOG(ERROR) << "Failed to switch to mirror mode"; 289 LOG(ERROR) << "Failed to switch to mirror mode";
267 290
268 // When things go wrong revert back to the previous configuration since 291 // When things go wrong revert back to the previous configuration since
269 // it is expected that the configuration would not have changed if 292 // it is expected that the configuration would not have changed if
270 // things fail. 293 // things fail.
271 (*original)->AddCrtc((*mirror)->RemoveCrtc(drm, crtc)); 294 ModesetController(*original, last_origin, last_mode);
272 EnableController(*original, (*original)->origin(), (*original)->get_mode());
273 return false; 295 return false;
274 } 296 }
275 297
276 void ScreenManager::UpdateControllerToWindowMapping() { 298 void ScreenManager::UpdateControllerToWindowMapping() {
277 std::map<DrmWindow*, HardwareDisplayController*> window_to_controller_map; 299 std::map<DrmWindow*, HardwareDisplayController*> window_to_controller_map;
278 // First create a unique mapping between a window and a controller. Note, a 300 // First create a unique mapping between a window and a controller. Note, a
279 // controller may be associated with at most 1 window. 301 // controller may be associated with at most 1 window.
280 for (HardwareDisplayController* controller : controllers_) { 302 for (HardwareDisplayController* controller : controllers_) {
281 if (controller->IsDisabled()) 303 if (controller->IsDisabled())
282 continue; 304 continue;
(...skipping 13 matching lines...) Expand all
296 if (it != window_to_controller_map.end()) 318 if (it != window_to_controller_map.end())
297 controller = it->second; 319 controller = it->second;
298 320
299 bool should_enable = 321 bool should_enable =
300 controller && pair.second->GetController() != controller; 322 controller && pair.second->GetController() != controller;
301 pair.second->SetController(controller); 323 pair.second->SetController(controller);
302 324
303 // If we're moving windows between controllers modeset the controller 325 // If we're moving windows between controllers modeset the controller
304 // otherwise the controller may be waiting for a page flip while the window 326 // otherwise the controller may be waiting for a page flip while the window
305 // tries to schedule another buffer. 327 // tries to schedule another buffer.
306 if (should_enable) 328 if (should_enable) {
307 EnableController(controller, controller->origin(), 329 EnableController(controller);
308 controller->get_mode()); 330 }
309 } 331 }
310 } 332 }
311 333
312 bool ScreenManager::EnableController(HardwareDisplayController* controller, 334 OverlayPlane ScreenManager::GetModesetBuffer(
313 const gfx::Point& origin, 335 HardwareDisplayController* controller,
314 const drmModeModeInfo& mode) { 336 const gfx::Rect& bounds) {
337 DrmWindow* window = FindWindowAt(bounds);
338 if (window) {
339 const OverlayPlane* primary = window->GetLastModesetBuffer();
340 if (primary && primary->buffer->GetSize() == bounds.size())
341 return *primary;
342 }
343
344 scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice();
345 scoped_refptr<ScanoutBuffer> buffer =
346 buffer_generator_->Create(drm, bounds.size());
347 if (!buffer) {
348 LOG(ERROR) << "Failed to create scanout buffer";
349 return OverlayPlane(nullptr, 0, gfx::OVERLAY_TRANSFORM_INVALID, gfx::Rect(),
350 gfx::RectF());
351 }
352
353 FillModesetBuffer(drm, controller, buffer.get());
354 return OverlayPlane(buffer);
355 }
356
357 bool ScreenManager::EnableController(HardwareDisplayController* controller) {
358 DCHECK(!controller->crtc_controllers().empty());
359 gfx::Rect rect(controller->origin(), controller->GetModeSize());
360 OverlayPlane plane = GetModesetBuffer(controller, rect);
361 if (!plane.buffer || !controller->Enable(plane)) {
362 LOG(ERROR) << "Failed to enable controller";
363 return false;
364 }
365
366 return true;
367 }
368
369 bool ScreenManager::ModesetController(HardwareDisplayController* controller,
370 const gfx::Point& origin,
371 const drmModeModeInfo& mode) {
315 DCHECK(!controller->crtc_controllers().empty()); 372 DCHECK(!controller->crtc_controllers().empty());
316 gfx::Rect rect(origin, gfx::Size(mode.hdisplay, mode.vdisplay)); 373 gfx::Rect rect(origin, gfx::Size(mode.hdisplay, mode.vdisplay));
317 controller->set_origin(origin); 374 controller->set_origin(origin);
318 375
319 DrmWindow* window = FindWindowAt(rect); 376 OverlayPlane plane = GetModesetBuffer(controller, rect);
320 if (window) { 377 if (!plane.buffer || !controller->Modeset(plane, mode)) {
321 const OverlayPlane* primary = window->GetLastModesetBuffer();
322 if (primary) {
323 if (!controller->Modeset(*primary, mode)) {
324 LOG(ERROR) << "Failed to modeset controller";
325 return false;
326 }
327
328 return true;
329 }
330 }
331
332 scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice();
333 scoped_refptr<ScanoutBuffer> buffer =
334 buffer_generator_->Create(drm, rect.size());
335 if (!buffer) {
336 LOG(ERROR) << "Failed to create scanout buffer";
337 return false;
338 }
339
340 FillModesetBuffer(drm, controller, buffer.get());
341 if (!controller->Modeset(OverlayPlane(buffer), mode)) {
342 LOG(ERROR) << "Failed to modeset controller"; 378 LOG(ERROR) << "Failed to modeset controller";
343 return false; 379 return false;
344 } 380 }
345 381
346 return true; 382 return true;
347 } 383 }
348 384
349 DrmWindow* ScreenManager::FindWindowAt(const gfx::Rect& bounds) const { 385 DrmWindow* ScreenManager::FindWindowAt(const gfx::Rect& bounds) const {
350 for (auto pair : window_map_) { 386 for (auto pair : window_map_) {
351 if (pair.second->bounds() == bounds) 387 if (pair.second->bounds() == bounds)
352 return pair.second; 388 return pair.second;
353 } 389 }
354 390
355 return nullptr; 391 return nullptr;
356 } 392 }
357 393
358 } // namespace ui 394 } // namespace ui
OLDNEW
« 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