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

Side by Side Diff: ui/ozone/platform/dri/screen_manager.cc

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/ozone/platform/dri/screen_manager.h"
6
7 #include <xf86drmMode.h>
8
9 #include "ui/gfx/geometry/point.h"
10 #include "ui/gfx/geometry/rect.h"
11 #include "ui/gfx/geometry/size.h"
12 #include "ui/ozone/platform/dri/crtc_controller.h"
13 #include "ui/ozone/platform/dri/dri_util.h"
14 #include "ui/ozone/platform/dri/dri_wrapper.h"
15 #include "ui/ozone/platform/dri/hardware_display_controller.h"
16 #include "ui/ozone/platform/dri/scanout_buffer.h"
17
18 namespace ui {
19
20 ScreenManager::ScreenManager(DriWrapper* dri,
21 ScanoutBufferGenerator* buffer_generator)
22 : dri_(dri), buffer_generator_(buffer_generator) {
23 }
24
25 ScreenManager::~ScreenManager() {
26 }
27
28 void ScreenManager::AddDisplayController(DriWrapper* dri,
29 uint32_t crtc,
30 uint32_t connector) {
31 HardwareDisplayControllers::iterator it = FindDisplayController(crtc);
32 // TODO(dnicoara): Turn this into a DCHECK when async display configuration is
33 // properly supported. (When there can't be a race between forcing initial
34 // display configuration in ScreenManager and NativeDisplayDelegate creating
35 // the display controllers.)
36 if (it != controllers_.end()) {
37 LOG(WARNING) << "Display controller (crtc=" << crtc << ") already present.";
38 return;
39 }
40
41 controllers_.push_back(new HardwareDisplayController(
42 scoped_ptr<CrtcController>(new CrtcController(dri, crtc, connector))));
43 }
44
45 void ScreenManager::RemoveDisplayController(uint32_t crtc) {
46 HardwareDisplayControllers::iterator it = FindDisplayController(crtc);
47 if (it != controllers_.end()) {
48 bool is_mirrored = (*it)->IsMirrored();
49 (*it)->RemoveCrtc(crtc);
50 if (!is_mirrored)
51 controllers_.erase(it);
52 }
53 }
54
55 bool ScreenManager::ConfigureDisplayController(uint32_t crtc,
56 uint32_t connector,
57 const gfx::Point& origin,
58 const drmModeModeInfo& mode) {
59 gfx::Rect modeset_bounds(
60 origin.x(), origin.y(), mode.hdisplay, mode.vdisplay);
61 HardwareDisplayControllers::iterator it = FindDisplayController(crtc);
62 DCHECK(controllers_.end() != it) << "Display controller (crtc=" << crtc
63 << ") doesn't exist.";
64
65 HardwareDisplayController* controller = *it;
66 controller = *it;
67 // If nothing changed just enable the controller. Note, we perform an exact
68 // comparison on the mode since the refresh rate may have changed.
69 if (SameMode(mode, controller->get_mode()) &&
70 origin == controller->origin() && !controller->IsDisabled())
71 return controller->Enable();
72
73 // Either the mode or the location of the display changed, so exit mirror
74 // mode and configure the display independently. If the caller still wants
75 // mirror mode, subsequent calls configuring the other controllers will
76 // restore mirror mode.
77 if (controller->IsMirrored()) {
78 controller = new HardwareDisplayController(controller->RemoveCrtc(crtc));
79 controllers_.push_back(controller);
80 it = controllers_.end() - 1;
81 }
82
83 HardwareDisplayControllers::iterator mirror =
84 FindActiveDisplayControllerByLocation(modeset_bounds);
85 // Handle mirror mode.
86 if (mirror != controllers_.end() && it != mirror)
87 return HandleMirrorMode(it, mirror, crtc, connector);
88
89 return ModesetDisplayController(controller, origin, mode);
90 }
91
92 bool ScreenManager::DisableDisplayController(uint32_t crtc) {
93 HardwareDisplayControllers::iterator it = FindDisplayController(crtc);
94 if (it != controllers_.end()) {
95 if ((*it)->IsMirrored()) {
96 HardwareDisplayController* controller =
97 new HardwareDisplayController((*it)->RemoveCrtc(crtc));
98 controllers_.push_back(controller);
99 }
100
101 (*it)->Disable();
102 return true;
103 }
104
105 LOG(ERROR) << "Failed to find display controller crtc=" << crtc;
106 return false;
107 }
108
109 base::WeakPtr<HardwareDisplayController> ScreenManager::GetDisplayController(
110 const gfx::Rect& bounds) {
111 // TODO(dnicoara): Remove hack once TestScreen uses a simple Ozone display
112 // configuration reader and ScreenManager is called from there to create the
113 // one display needed by the content_shell target.
114 if (controllers_.empty())
115 ForceInitializationOfPrimaryDisplay();
116
117 HardwareDisplayControllers::iterator it =
118 FindActiveDisplayControllerByLocation(bounds);
119 if (it != controllers_.end())
120 return (*it)->AsWeakPtr();
121
122 return base::WeakPtr<HardwareDisplayController>();
123 }
124
125 ScreenManager::HardwareDisplayControllers::iterator
126 ScreenManager::FindDisplayController(uint32_t crtc) {
127 for (HardwareDisplayControllers::iterator it = controllers_.begin();
128 it != controllers_.end();
129 ++it) {
130 if ((*it)->HasCrtc(crtc))
131 return it;
132 }
133
134 return controllers_.end();
135 }
136
137 ScreenManager::HardwareDisplayControllers::iterator
138 ScreenManager::FindActiveDisplayControllerByLocation(const gfx::Rect& bounds) {
139 for (HardwareDisplayControllers::iterator it = controllers_.begin();
140 it != controllers_.end();
141 ++it) {
142 gfx::Rect controller_bounds((*it)->origin(), (*it)->GetModeSize());
143 // We don't perform a strict check since content_shell will have windows
144 // smaller than the display size.
145 if (controller_bounds.Contains(bounds) && !(*it)->IsDisabled())
146 return it;
147 }
148
149 return controllers_.end();
150 }
151
152 void ScreenManager::ForceInitializationOfPrimaryDisplay() {
153 LOG(WARNING) << "Forcing initialization of primary display.";
154 ScopedVector<HardwareDisplayControllerInfo> displays =
155 GetAvailableDisplayControllerInfos(dri_->get_fd());
156
157 DCHECK_NE(0u, displays.size());
158
159 ScopedDrmPropertyPtr dpms(
160 dri_->GetProperty(displays[0]->connector(), "DPMS"));
161 if (dpms)
162 dri_->SetProperty(displays[0]->connector()->connector_id,
163 dpms->prop_id,
164 DRM_MODE_DPMS_ON);
165
166 AddDisplayController(dri_,
167 displays[0]->crtc()->crtc_id,
168 displays[0]->connector()->connector_id);
169 ConfigureDisplayController(displays[0]->crtc()->crtc_id,
170 displays[0]->connector()->connector_id,
171 gfx::Point(),
172 displays[0]->connector()->modes[0]);
173 }
174
175 bool ScreenManager::ModesetDisplayController(
176 HardwareDisplayController* controller,
177 const gfx::Point& origin,
178 const drmModeModeInfo& mode) {
179 controller->set_origin(origin);
180 // Create a surface suitable for the current controller.
181 scoped_refptr<ScanoutBuffer> buffer =
182 buffer_generator_->Create(gfx::Size(mode.hdisplay, mode.vdisplay));
183
184 if (!buffer.get()) {
185 LOG(ERROR) << "Failed to create scanout buffer";
186 return false;
187 }
188
189 if (!controller->Modeset(OverlayPlane(buffer), mode)) {
190 LOG(ERROR) << "Failed to modeset controller";
191 return false;
192 }
193
194 return true;
195 }
196
197 bool ScreenManager::HandleMirrorMode(
198 HardwareDisplayControllers::iterator original,
199 HardwareDisplayControllers::iterator mirror,
200 uint32_t crtc,
201 uint32_t connector) {
202 (*mirror)->AddCrtc((*original)->RemoveCrtc(crtc));
203 if ((*mirror)->Enable()) {
204 controllers_.erase(original);
205 return true;
206 }
207
208 LOG(ERROR) << "Failed to switch to mirror mode";
209
210 // When things go wrong revert back to the previous configuration since
211 // it is expected that the configuration would not have changed if
212 // things fail.
213 (*original)->AddCrtc((*mirror)->RemoveCrtc(crtc));
214 (*original)->Enable();
215 return false;
216 }
217
218 } // namespace ui
OLDNEW
« no previous file with comments | « ui/ozone/platform/dri/screen_manager.h ('k') | ui/ozone/platform/dri/screen_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698