| OLD | NEW |
| 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/dri/screen_manager.h" | 5 #include "ui/ozone/platform/dri/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" |
| 11 #include "ui/gfx/geometry/rect.h" | 11 #include "ui/gfx/geometry/rect.h" |
| 12 #include "ui/gfx/geometry/size.h" | 12 #include "ui/gfx/geometry/size.h" |
| 13 #include "ui/ozone/platform/dri/crtc_controller.h" | 13 #include "ui/ozone/platform/dri/crtc_controller.h" |
| 14 #include "ui/ozone/platform/dri/dri_console_buffer.h" | 14 #include "ui/ozone/platform/dri/dri_console_buffer.h" |
| 15 #include "ui/ozone/platform/dri/dri_util.h" | 15 #include "ui/ozone/platform/dri/dri_util.h" |
| 16 #include "ui/ozone/platform/dri/dri_wrapper.h" | 16 #include "ui/ozone/platform/dri/drm_device.h" |
| 17 #include "ui/ozone/platform/dri/hardware_display_controller.h" | 17 #include "ui/ozone/platform/dri/hardware_display_controller.h" |
| 18 #include "ui/ozone/platform/dri/scanout_buffer.h" | 18 #include "ui/ozone/platform/dri/scanout_buffer.h" |
| 19 | 19 |
| 20 namespace ui { | 20 namespace ui { |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 // Copies the contents of the saved framebuffer from the CRTCs in |controller| | 24 // Copies the contents of the saved framebuffer from the CRTCs in |controller| |
| 25 // to the new modeset buffer |buffer|. | 25 // to the new modeset buffer |buffer|. |
| 26 void FillModesetBuffer(const scoped_refptr<DriWrapper>& dri, | 26 void FillModesetBuffer(const scoped_refptr<DrmDevice>& drm, |
| 27 HardwareDisplayController* controller, | 27 HardwareDisplayController* controller, |
| 28 ScanoutBuffer* buffer) { | 28 ScanoutBuffer* buffer) { |
| 29 DriConsoleBuffer modeset_buffer(dri, buffer->GetFramebufferId()); | 29 DriConsoleBuffer modeset_buffer(drm, buffer->GetFramebufferId()); |
| 30 if (!modeset_buffer.Initialize()) { | 30 if (!modeset_buffer.Initialize()) { |
| 31 LOG(ERROR) << "Failed to grab framebuffer " << buffer->GetFramebufferId(); | 31 LOG(ERROR) << "Failed to grab framebuffer " << buffer->GetFramebufferId(); |
| 32 return; | 32 return; |
| 33 } | 33 } |
| 34 | 34 |
| 35 auto crtcs = controller->crtc_controllers(); | 35 auto crtcs = controller->crtc_controllers(); |
| 36 DCHECK(!crtcs.empty()); | 36 DCHECK(!crtcs.empty()); |
| 37 | 37 |
| 38 if (!crtcs[0]->saved_crtc() || !crtcs[0]->saved_crtc()->buffer_id) | 38 if (!crtcs[0]->saved_crtc() || !crtcs[0]->saved_crtc()->buffer_id) |
| 39 return; | 39 return; |
| 40 | 40 |
| 41 // If the display controller is in mirror mode, the CRTCs should be sharing | 41 // If the display controller is in mirror mode, the CRTCs should be sharing |
| 42 // the same framebuffer. | 42 // the same framebuffer. |
| 43 DriConsoleBuffer saved_buffer(dri, crtcs[0]->saved_crtc()->buffer_id); | 43 DriConsoleBuffer saved_buffer(drm, crtcs[0]->saved_crtc()->buffer_id); |
| 44 if (!saved_buffer.Initialize()) { | 44 if (!saved_buffer.Initialize()) { |
| 45 LOG(ERROR) << "Failed to grab saved framebuffer " | 45 LOG(ERROR) << "Failed to grab saved framebuffer " |
| 46 << crtcs[0]->saved_crtc()->buffer_id; | 46 << crtcs[0]->saved_crtc()->buffer_id; |
| 47 return; | 47 return; |
| 48 } | 48 } |
| 49 | 49 |
| 50 // Don't copy anything if the sizes mismatch. This can happen when the user | 50 // Don't copy anything if the sizes mismatch. This can happen when the user |
| 51 // changes modes. | 51 // changes modes. |
| 52 if (saved_buffer.canvas()->getBaseLayerSize() != | 52 if (saved_buffer.canvas()->getBaseLayerSize() != |
| 53 modeset_buffer.canvas()->getBaseLayerSize()) | 53 modeset_buffer.canvas()->getBaseLayerSize()) |
| 54 return; | 54 return; |
| 55 | 55 |
| 56 skia::RefPtr<SkImage> image = saved_buffer.image(); | 56 skia::RefPtr<SkImage> image = saved_buffer.image(); |
| 57 SkPaint paint; | 57 SkPaint paint; |
| 58 // Copy the source buffer. Do not perform any blending. | 58 // Copy the source buffer. Do not perform any blending. |
| 59 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 59 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
| 60 modeset_buffer.canvas()->drawImage(image.get(), 0, 0, &paint); | 60 modeset_buffer.canvas()->drawImage(image.get(), 0, 0, &paint); |
| 61 } | 61 } |
| 62 | 62 |
| 63 } // namespace | 63 } // namespace |
| 64 | 64 |
| 65 ScreenManager::ScreenManager(ScanoutBufferGenerator* buffer_generator) | 65 ScreenManager::ScreenManager(ScanoutBufferGenerator* buffer_generator) |
| 66 : buffer_generator_(buffer_generator) { | 66 : buffer_generator_(buffer_generator) { |
| 67 } | 67 } |
| 68 | 68 |
| 69 ScreenManager::~ScreenManager() { | 69 ScreenManager::~ScreenManager() { |
| 70 } | 70 } |
| 71 | 71 |
| 72 void ScreenManager::AddDisplayController(const scoped_refptr<DriWrapper>& dri, | 72 void ScreenManager::AddDisplayController(const scoped_refptr<DrmDevice>& drm, |
| 73 uint32_t crtc, | 73 uint32_t crtc, |
| 74 uint32_t connector) { | 74 uint32_t connector) { |
| 75 HardwareDisplayControllers::iterator it = FindDisplayController(dri, crtc); | 75 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); |
| 76 // TODO(dnicoara): Turn this into a DCHECK when async display configuration is | 76 // TODO(dnicoara): Turn this into a DCHECK when async display configuration is |
| 77 // properly supported. (When there can't be a race between forcing initial | 77 // properly supported. (When there can't be a race between forcing initial |
| 78 // display configuration in ScreenManager and NativeDisplayDelegate creating | 78 // display configuration in ScreenManager and NativeDisplayDelegate creating |
| 79 // the display controllers.) | 79 // the display controllers.) |
| 80 if (it != controllers_.end()) { | 80 if (it != controllers_.end()) { |
| 81 LOG(WARNING) << "Display controller (crtc=" << crtc << ") already present."; | 81 LOG(WARNING) << "Display controller (crtc=" << crtc << ") already present."; |
| 82 return; | 82 return; |
| 83 } | 83 } |
| 84 | 84 |
| 85 controllers_.push_back(new HardwareDisplayController( | 85 controllers_.push_back(new HardwareDisplayController( |
| 86 scoped_ptr<CrtcController>(new CrtcController(dri, crtc, connector)))); | 86 scoped_ptr<CrtcController>(new CrtcController(drm, crtc, connector)))); |
| 87 } | 87 } |
| 88 | 88 |
| 89 void ScreenManager::RemoveDisplayController( | 89 void ScreenManager::RemoveDisplayController(const scoped_refptr<DrmDevice>& drm, |
| 90 const scoped_refptr<DriWrapper>& drm, | 90 uint32_t crtc) { |
| 91 uint32_t crtc) { | |
| 92 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); | 91 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); |
| 93 if (it != controllers_.end()) { | 92 if (it != controllers_.end()) { |
| 94 bool is_mirrored = (*it)->IsMirrored(); | 93 bool is_mirrored = (*it)->IsMirrored(); |
| 95 (*it)->RemoveCrtc(drm, crtc); | 94 (*it)->RemoveCrtc(drm, crtc); |
| 96 if (!is_mirrored) { | 95 if (!is_mirrored) { |
| 97 FOR_EACH_OBSERVER(DisplayChangeObserver, observers_, | 96 FOR_EACH_OBSERVER(DisplayChangeObserver, observers_, |
| 98 OnDisplayRemoved(*it)); | 97 OnDisplayRemoved(*it)); |
| 99 controllers_.erase(it); | 98 controllers_.erase(it); |
| 100 } | 99 } |
| 101 } | 100 } |
| 102 } | 101 } |
| 103 | 102 |
| 104 bool ScreenManager::ConfigureDisplayController( | 103 bool ScreenManager::ConfigureDisplayController( |
| 105 const scoped_refptr<DriWrapper>& drm, | 104 const scoped_refptr<DrmDevice>& drm, |
| 106 uint32_t crtc, | 105 uint32_t crtc, |
| 107 uint32_t connector, | 106 uint32_t connector, |
| 108 const gfx::Point& origin, | 107 const gfx::Point& origin, |
| 109 const drmModeModeInfo& mode) { | 108 const drmModeModeInfo& mode) { |
| 110 gfx::Rect modeset_bounds(origin.x(), origin.y(), mode.hdisplay, | 109 gfx::Rect modeset_bounds(origin.x(), origin.y(), mode.hdisplay, |
| 111 mode.vdisplay); | 110 mode.vdisplay); |
| 112 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); | 111 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); |
| 113 DCHECK(controllers_.end() != it) << "Display controller (crtc=" << crtc | 112 DCHECK(controllers_.end() != it) << "Display controller (crtc=" << crtc |
| 114 << ") doesn't exist."; | 113 << ") doesn't exist."; |
| 115 | 114 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 HardwareDisplayControllers::iterator mirror = | 148 HardwareDisplayControllers::iterator mirror = |
| 150 FindActiveDisplayControllerByLocation(modeset_bounds); | 149 FindActiveDisplayControllerByLocation(modeset_bounds); |
| 151 // Handle mirror mode. | 150 // Handle mirror mode. |
| 152 if (mirror != controllers_.end() && it != mirror) | 151 if (mirror != controllers_.end() && it != mirror) |
| 153 return HandleMirrorMode(it, mirror, drm, crtc, connector); | 152 return HandleMirrorMode(it, mirror, drm, crtc, connector); |
| 154 | 153 |
| 155 return ModesetDisplayController(controller, origin, mode); | 154 return ModesetDisplayController(controller, origin, mode); |
| 156 } | 155 } |
| 157 | 156 |
| 158 bool ScreenManager::DisableDisplayController( | 157 bool ScreenManager::DisableDisplayController( |
| 159 const scoped_refptr<DriWrapper>& drm, | 158 const scoped_refptr<DrmDevice>& drm, |
| 160 uint32_t crtc) { | 159 uint32_t crtc) { |
| 161 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); | 160 HardwareDisplayControllers::iterator it = FindDisplayController(drm, crtc); |
| 162 if (it != controllers_.end()) { | 161 if (it != controllers_.end()) { |
| 163 if ((*it)->IsMirrored()) { | 162 if ((*it)->IsMirrored()) { |
| 164 HardwareDisplayController* controller = | 163 HardwareDisplayController* controller = |
| 165 new HardwareDisplayController((*it)->RemoveCrtc(drm, crtc)); | 164 new HardwareDisplayController((*it)->RemoveCrtc(drm, crtc)); |
| 166 controllers_.push_back(controller); | 165 controllers_.push_back(controller); |
| 167 } | 166 } |
| 168 | 167 |
| 169 (*it)->Disable(); | 168 (*it)->Disable(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 186 | 185 |
| 187 void ScreenManager::AddObserver(DisplayChangeObserver* observer) { | 186 void ScreenManager::AddObserver(DisplayChangeObserver* observer) { |
| 188 observers_.AddObserver(observer); | 187 observers_.AddObserver(observer); |
| 189 } | 188 } |
| 190 | 189 |
| 191 void ScreenManager::RemoveObserver(DisplayChangeObserver* observer) { | 190 void ScreenManager::RemoveObserver(DisplayChangeObserver* observer) { |
| 192 observers_.RemoveObserver(observer); | 191 observers_.RemoveObserver(observer); |
| 193 } | 192 } |
| 194 | 193 |
| 195 ScreenManager::HardwareDisplayControllers::iterator | 194 ScreenManager::HardwareDisplayControllers::iterator |
| 196 ScreenManager::FindDisplayController(const scoped_refptr<DriWrapper>& drm, | 195 ScreenManager::FindDisplayController(const scoped_refptr<DrmDevice>& drm, |
| 197 uint32_t crtc) { | 196 uint32_t crtc) { |
| 198 for (HardwareDisplayControllers::iterator it = controllers_.begin(); | 197 for (HardwareDisplayControllers::iterator it = controllers_.begin(); |
| 199 it != controllers_.end(); | 198 it != controllers_.end(); |
| 200 ++it) { | 199 ++it) { |
| 201 if ((*it)->HasCrtc(drm, crtc)) | 200 if ((*it)->HasCrtc(drm, crtc)) |
| 202 return it; | 201 return it; |
| 203 } | 202 } |
| 204 | 203 |
| 205 return controllers_.end(); | 204 return controllers_.end(); |
| 206 } | 205 } |
| 207 | 206 |
| 208 ScreenManager::HardwareDisplayControllers::iterator | 207 ScreenManager::HardwareDisplayControllers::iterator |
| 209 ScreenManager::FindActiveDisplayControllerByLocation(const gfx::Rect& bounds) { | 208 ScreenManager::FindActiveDisplayControllerByLocation(const gfx::Rect& bounds) { |
| 210 for (HardwareDisplayControllers::iterator it = controllers_.begin(); | 209 for (HardwareDisplayControllers::iterator it = controllers_.begin(); |
| 211 it != controllers_.end(); | 210 it != controllers_.end(); |
| 212 ++it) { | 211 ++it) { |
| 213 gfx::Rect controller_bounds((*it)->origin(), (*it)->GetModeSize()); | 212 gfx::Rect controller_bounds((*it)->origin(), (*it)->GetModeSize()); |
| 214 if (controller_bounds == bounds && !(*it)->IsDisabled()) | 213 if (controller_bounds == bounds && !(*it)->IsDisabled()) |
| 215 return it; | 214 return it; |
| 216 } | 215 } |
| 217 | 216 |
| 218 return controllers_.end(); | 217 return controllers_.end(); |
| 219 } | 218 } |
| 220 | 219 |
| 221 bool ScreenManager::ModesetDisplayController( | 220 bool ScreenManager::ModesetDisplayController( |
| 222 HardwareDisplayController* controller, | 221 HardwareDisplayController* controller, |
| 223 const gfx::Point& origin, | 222 const gfx::Point& origin, |
| 224 const drmModeModeInfo& mode) { | 223 const drmModeModeInfo& mode) { |
| 225 DCHECK(!controller->crtc_controllers().empty()); | 224 DCHECK(!controller->crtc_controllers().empty()); |
| 226 scoped_refptr<DriWrapper> drm = controller->GetAllocationDriWrapper(); | 225 scoped_refptr<DrmDevice> drm = controller->GetAllocationDrmDevice(); |
| 227 controller->set_origin(origin); | 226 controller->set_origin(origin); |
| 228 | 227 |
| 229 // Create a surface suitable for the current controller. | 228 // Create a surface suitable for the current controller. |
| 230 scoped_refptr<ScanoutBuffer> buffer = | 229 scoped_refptr<ScanoutBuffer> buffer = |
| 231 buffer_generator_->Create(drm, gfx::Size(mode.hdisplay, mode.vdisplay)); | 230 buffer_generator_->Create(drm, gfx::Size(mode.hdisplay, mode.vdisplay)); |
| 232 | 231 |
| 233 if (!buffer.get()) { | 232 if (!buffer.get()) { |
| 234 LOG(ERROR) << "Failed to create scanout buffer"; | 233 LOG(ERROR) << "Failed to create scanout buffer"; |
| 235 return false; | 234 return false; |
| 236 } | 235 } |
| 237 | 236 |
| 238 FillModesetBuffer(drm, controller, buffer.get()); | 237 FillModesetBuffer(drm, controller, buffer.get()); |
| 239 | 238 |
| 240 if (!controller->Modeset(OverlayPlane(buffer), mode)) { | 239 if (!controller->Modeset(OverlayPlane(buffer), mode)) { |
| 241 LOG(ERROR) << "Failed to modeset controller"; | 240 LOG(ERROR) << "Failed to modeset controller"; |
| 242 return false; | 241 return false; |
| 243 } | 242 } |
| 244 | 243 |
| 245 FOR_EACH_OBSERVER(DisplayChangeObserver, observers_, | 244 FOR_EACH_OBSERVER(DisplayChangeObserver, observers_, |
| 246 OnDisplayChanged(controller)); | 245 OnDisplayChanged(controller)); |
| 247 return true; | 246 return true; |
| 248 } | 247 } |
| 249 | 248 |
| 250 bool ScreenManager::HandleMirrorMode( | 249 bool ScreenManager::HandleMirrorMode( |
| 251 HardwareDisplayControllers::iterator original, | 250 HardwareDisplayControllers::iterator original, |
| 252 HardwareDisplayControllers::iterator mirror, | 251 HardwareDisplayControllers::iterator mirror, |
| 253 const scoped_refptr<DriWrapper>& drm, | 252 const scoped_refptr<DrmDevice>& drm, |
| 254 uint32_t crtc, | 253 uint32_t crtc, |
| 255 uint32_t connector) { | 254 uint32_t connector) { |
| 256 (*mirror)->AddCrtc((*original)->RemoveCrtc(drm, crtc)); | 255 (*mirror)->AddCrtc((*original)->RemoveCrtc(drm, crtc)); |
| 257 if ((*mirror)->Enable()) { | 256 if ((*mirror)->Enable()) { |
| 258 FOR_EACH_OBSERVER(DisplayChangeObserver, observers_, | 257 FOR_EACH_OBSERVER(DisplayChangeObserver, observers_, |
| 259 OnDisplayRemoved(*original)); | 258 OnDisplayRemoved(*original)); |
| 260 FOR_EACH_OBSERVER(DisplayChangeObserver, observers_, | 259 FOR_EACH_OBSERVER(DisplayChangeObserver, observers_, |
| 261 OnDisplayChanged(*mirror)); | 260 OnDisplayChanged(*mirror)); |
| 262 controllers_.erase(original); | 261 controllers_.erase(original); |
| 263 return true; | 262 return true; |
| 264 } | 263 } |
| 265 | 264 |
| 266 LOG(ERROR) << "Failed to switch to mirror mode"; | 265 LOG(ERROR) << "Failed to switch to mirror mode"; |
| 267 | 266 |
| 268 // When things go wrong revert back to the previous configuration since | 267 // When things go wrong revert back to the previous configuration since |
| 269 // it is expected that the configuration would not have changed if | 268 // it is expected that the configuration would not have changed if |
| 270 // things fail. | 269 // things fail. |
| 271 (*original)->AddCrtc((*mirror)->RemoveCrtc(drm, crtc)); | 270 (*original)->AddCrtc((*mirror)->RemoveCrtc(drm, crtc)); |
| 272 (*original)->Enable(); | 271 (*original)->Enable(); |
| 273 return false; | 272 return false; |
| 274 } | 273 } |
| 275 | 274 |
| 276 } // namespace ui | 275 } // namespace ui |
| OLD | NEW |