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 |