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

Side by Side Diff: ui/display/chromeos/display_configurator.cc

Issue 226183004: Renamed OutputConfigurator to DisplayConfigurator (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 6 years, 8 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 | Annotate | Revision Log
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/display/chromeos/output_configurator.h" 5 #include "ui/display/chromeos/display_configurator.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/sys_info.h" 12 #include "base/sys_info.h"
13 #include "base/time/time.h" 13 #include "base/time/time.h"
14 #include "ui/display/chromeos/display_mode.h" 14 #include "ui/display/chromeos/display_mode.h"
15 #include "ui/display/chromeos/display_snapshot.h" 15 #include "ui/display/chromeos/display_snapshot.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 case OUTPUT_STATE_DUAL_EXTENDED: 64 case OUTPUT_STATE_DUAL_EXTENDED:
65 return "DUAL_EXTENDED"; 65 return "DUAL_EXTENDED";
66 } 66 }
67 NOTREACHED() << "Unknown state " << state; 67 NOTREACHED() << "Unknown state " << state;
68 return "INVALID"; 68 return "INVALID";
69 } 69 }
70 70
71 // Returns the number of outputs in |outputs| that should be turned on, per 71 // Returns the number of outputs in |outputs| that should be turned on, per
72 // |state|. If |output_power| is non-NULL, it is updated to contain the 72 // |state|. If |output_power| is non-NULL, it is updated to contain the
73 // on/off state of each corresponding entry in |outputs|. 73 // on/off state of each corresponding entry in |outputs|.
74 int GetOutputPower(const std::vector<OutputConfigurator::DisplayState>& outputs, 74 int GetOutputPower(
75 chromeos::DisplayPowerState state, 75 const std::vector<DisplayConfigurator::DisplayState>& outputs,
76 std::vector<bool>* output_power) { 76 chromeos::DisplayPowerState state,
77 std::vector<bool>* output_power) {
77 int num_on_outputs = 0; 78 int num_on_outputs = 0;
78 if (output_power) 79 if (output_power)
79 output_power->resize(outputs.size()); 80 output_power->resize(outputs.size());
80 81
81 for (size_t i = 0; i < outputs.size(); ++i) { 82 for (size_t i = 0; i < outputs.size(); ++i) {
82 bool internal = outputs[i].display->type() == OUTPUT_TYPE_INTERNAL; 83 bool internal = outputs[i].display->type() == OUTPUT_TYPE_INTERNAL;
83 bool on = 84 bool on =
84 state == chromeos::DISPLAY_POWER_ALL_ON || 85 state == chromeos::DISPLAY_POWER_ALL_ON ||
85 (state == chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON && 86 (state == chromeos::DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON &&
86 !internal) || 87 !internal) ||
87 (state == chromeos::DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && internal); 88 (state == chromeos::DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF && internal);
88 if (output_power) 89 if (output_power)
89 (*output_power)[i] = on; 90 (*output_power)[i] = on;
90 if (on) 91 if (on)
91 num_on_outputs++; 92 num_on_outputs++;
92 } 93 }
93 return num_on_outputs; 94 return num_on_outputs;
94 } 95 }
95 96
96 } // namespace 97 } // namespace
97 98
98 OutputConfigurator::CoordinateTransformation::CoordinateTransformation() 99 DisplayConfigurator::CoordinateTransformation::CoordinateTransformation()
99 : x_scale(1.0), 100 : x_scale(1.0),
100 x_offset(0.0), 101 x_offset(0.0),
101 y_scale(1.0), 102 y_scale(1.0),
102 y_offset(0.0) {} 103 y_offset(0.0) {}
103 104
104 OutputConfigurator::DisplayState::DisplayState() 105 DisplayConfigurator::DisplayState::DisplayState()
105 : display(NULL), 106 : display(NULL),
106 touch_device_id(0), 107 touch_device_id(0),
107 selected_mode(NULL), 108 selected_mode(NULL),
108 mirror_mode(NULL) {} 109 mirror_mode(NULL) {}
109 110
110 bool OutputConfigurator::TestApi::TriggerConfigureTimeout() { 111 bool DisplayConfigurator::TestApi::TriggerConfigureTimeout() {
111 if (configurator_->configure_timer_.get() && 112 if (configurator_->configure_timer_.get() &&
112 configurator_->configure_timer_->IsRunning()) { 113 configurator_->configure_timer_->IsRunning()) {
113 configurator_->configure_timer_.reset(); 114 configurator_->configure_timer_.reset();
114 configurator_->ConfigureOutputs(); 115 configurator_->ConfigureOutputs();
115 return true; 116 return true;
116 } else { 117 } else {
117 return false; 118 return false;
118 } 119 }
119 } 120 }
120 121
121 // static 122 // static
122 const DisplayMode* OutputConfigurator::FindDisplayModeMatchingSize( 123 const DisplayMode* DisplayConfigurator::FindDisplayModeMatchingSize(
123 const DisplaySnapshot& output, 124 const DisplaySnapshot& output,
124 const gfx::Size& size) { 125 const gfx::Size& size) {
125 const DisplayMode* best_mode = NULL; 126 const DisplayMode* best_mode = NULL;
126 for (DisplayModeList::const_iterator it = output.modes().begin(); 127 for (DisplayModeList::const_iterator it = output.modes().begin();
127 it != output.modes().end(); 128 it != output.modes().end();
128 ++it) { 129 ++it) {
129 const DisplayMode* mode = *it; 130 const DisplayMode* mode = *it;
130 131
131 if (mode->size() != size) 132 if (mode->size() != size)
132 continue; 133 continue;
(...skipping 16 matching lines...) Expand all
149 } 150 }
150 if (mode->refresh_rate() < best_mode->refresh_rate()) 151 if (mode->refresh_rate() < best_mode->refresh_rate())
151 continue; 152 continue;
152 153
153 best_mode = mode; 154 best_mode = mode;
154 } 155 }
155 156
156 return best_mode; 157 return best_mode;
157 } 158 }
158 159
159 OutputConfigurator::OutputConfigurator() 160 DisplayConfigurator::DisplayConfigurator()
160 : state_controller_(NULL), 161 : state_controller_(NULL),
161 mirroring_controller_(NULL), 162 mirroring_controller_(NULL),
162 is_panel_fitting_enabled_(false), 163 is_panel_fitting_enabled_(false),
163 configure_display_(base::SysInfo::IsRunningOnChromeOS()), 164 configure_display_(base::SysInfo::IsRunningOnChromeOS()),
164 output_state_(OUTPUT_STATE_INVALID), 165 output_state_(OUTPUT_STATE_INVALID),
165 power_state_(chromeos::DISPLAY_POWER_ALL_ON), 166 power_state_(chromeos::DISPLAY_POWER_ALL_ON),
166 next_output_protection_client_id_(1) {} 167 next_output_protection_client_id_(1) {}
167 168
168 OutputConfigurator::~OutputConfigurator() { 169 DisplayConfigurator::~DisplayConfigurator() {
169 if (native_display_delegate_) 170 if (native_display_delegate_)
170 native_display_delegate_->RemoveObserver(this); 171 native_display_delegate_->RemoveObserver(this);
171 } 172 }
172 173
173 void OutputConfigurator::SetNativeDisplayDelegateForTesting( 174 void DisplayConfigurator::SetNativeDisplayDelegateForTesting(
174 scoped_ptr<NativeDisplayDelegate> delegate) { 175 scoped_ptr<NativeDisplayDelegate> delegate) {
175 DCHECK(!native_display_delegate_); 176 DCHECK(!native_display_delegate_);
176 177
177 native_display_delegate_ = delegate.Pass(); 178 native_display_delegate_ = delegate.Pass();
178 native_display_delegate_->AddObserver(this); 179 native_display_delegate_->AddObserver(this);
179 configure_display_ = true; 180 configure_display_ = true;
180 } 181 }
181 182
182 void OutputConfigurator::SetTouchscreenDelegateForTesting( 183 void DisplayConfigurator::SetTouchscreenDelegateForTesting(
183 scoped_ptr<TouchscreenDelegate> delegate) { 184 scoped_ptr<TouchscreenDelegate> delegate) {
184 DCHECK(!touchscreen_delegate_); 185 DCHECK(!touchscreen_delegate_);
185 186
186 touchscreen_delegate_ = delegate.Pass(); 187 touchscreen_delegate_ = delegate.Pass();
187 } 188 }
188 189
189 void OutputConfigurator::SetInitialDisplayPower( 190 void DisplayConfigurator::SetInitialDisplayPower(
190 chromeos::DisplayPowerState power_state) { 191 chromeos::DisplayPowerState power_state) {
191 DCHECK_EQ(output_state_, OUTPUT_STATE_INVALID); 192 DCHECK_EQ(output_state_, OUTPUT_STATE_INVALID);
192 power_state_ = power_state; 193 power_state_ = power_state;
193 } 194 }
194 195
195 void OutputConfigurator::Init(bool is_panel_fitting_enabled) { 196 void DisplayConfigurator::Init(bool is_panel_fitting_enabled) {
196 is_panel_fitting_enabled_ = is_panel_fitting_enabled; 197 is_panel_fitting_enabled_ = is_panel_fitting_enabled;
197 if (!configure_display_) 198 if (!configure_display_)
198 return; 199 return;
199 200
200 if (!native_display_delegate_) { 201 if (!native_display_delegate_) {
201 #if defined(USE_OZONE) 202 #if defined(USE_OZONE)
202 native_display_delegate_.reset(new NativeDisplayDelegateOzone()); 203 native_display_delegate_.reset(new NativeDisplayDelegateOzone());
203 #elif defined(USE_X11) 204 #elif defined(USE_X11)
204 native_display_delegate_.reset(new NativeDisplayDelegateX11()); 205 native_display_delegate_.reset(new NativeDisplayDelegateX11());
205 #else 206 #else
206 NOTREACHED(); 207 NOTREACHED();
207 #endif 208 #endif
208 native_display_delegate_->AddObserver(this); 209 native_display_delegate_->AddObserver(this);
209 } 210 }
210 211
211 if (!touchscreen_delegate_) { 212 if (!touchscreen_delegate_) {
212 #if defined(USE_OZONE) 213 #if defined(USE_OZONE)
213 touchscreen_delegate_.reset(new TouchscreenDelegateOzone()); 214 touchscreen_delegate_.reset(new TouchscreenDelegateOzone());
214 #elif defined(USE_X11) 215 #elif defined(USE_X11)
215 touchscreen_delegate_.reset(new TouchscreenDelegateX11()); 216 touchscreen_delegate_.reset(new TouchscreenDelegateX11());
216 #else 217 #else
217 NOTREACHED(); 218 NOTREACHED();
218 #endif 219 #endif
219 } 220 }
220 } 221 }
221 222
222 void OutputConfigurator::ForceInitialConfigure(uint32_t background_color_argb) { 223 void DisplayConfigurator::ForceInitialConfigure(
224 uint32_t background_color_argb) {
223 if (!configure_display_) 225 if (!configure_display_)
224 return; 226 return;
225 227
226 native_display_delegate_->GrabServer(); 228 native_display_delegate_->GrabServer();
227 native_display_delegate_->Initialize(); 229 native_display_delegate_->Initialize();
228 230
229 UpdateCachedOutputs(); 231 UpdateCachedOutputs();
230 if (cached_outputs_.size() > 1 && background_color_argb) 232 if (cached_outputs_.size() > 1 && background_color_argb)
231 native_display_delegate_->SetBackgroundColor(background_color_argb); 233 native_display_delegate_->SetBackgroundColor(background_color_argb);
232 const OutputState new_state = ChooseOutputState(power_state_); 234 const OutputState new_state = ChooseOutputState(power_state_);
233 const bool success = 235 const bool success =
234 EnterStateOrFallBackToSoftwareMirroring(new_state, power_state_); 236 EnterStateOrFallBackToSoftwareMirroring(new_state, power_state_);
235 237
236 // Force the DPMS on chrome startup as the driver doesn't always detect 238 // Force the DPMS on chrome startup as the driver doesn't always detect
237 // that all displays are on when signing out. 239 // that all displays are on when signing out.
238 native_display_delegate_->ForceDPMSOn(); 240 native_display_delegate_->ForceDPMSOn();
239 native_display_delegate_->UngrabServer(); 241 native_display_delegate_->UngrabServer();
240 NotifyObservers(success, new_state); 242 NotifyObservers(success, new_state);
241 } 243 }
242 244
243 bool OutputConfigurator::ApplyProtections(const DisplayProtections& requests) { 245 bool DisplayConfigurator::ApplyProtections(const DisplayProtections& requests) {
244 for (DisplayStateList::const_iterator it = cached_outputs_.begin(); 246 for (DisplayStateList::const_iterator it = cached_outputs_.begin();
245 it != cached_outputs_.end(); 247 it != cached_outputs_.end();
246 ++it) { 248 ++it) {
247 uint32_t all_desired = 0; 249 uint32_t all_desired = 0;
248 DisplayProtections::const_iterator request_it = 250 DisplayProtections::const_iterator request_it =
249 requests.find(it->display->display_id()); 251 requests.find(it->display->display_id());
250 if (request_it != requests.end()) 252 if (request_it != requests.end())
251 all_desired = request_it->second; 253 all_desired = request_it->second;
252 switch (it->display->type()) { 254 switch (it->display->type()) {
253 case OUTPUT_TYPE_UNKNOWN: 255 case OUTPUT_TYPE_UNKNOWN:
(...skipping 17 matching lines...) Expand all
271 break; 273 break;
272 case OUTPUT_TYPE_NONE: 274 case OUTPUT_TYPE_NONE:
273 NOTREACHED(); 275 NOTREACHED();
274 break; 276 break;
275 } 277 }
276 } 278 }
277 279
278 return true; 280 return true;
279 } 281 }
280 282
281 OutputConfigurator::OutputProtectionClientId 283 DisplayConfigurator::OutputProtectionClientId
282 OutputConfigurator::RegisterOutputProtectionClient() { 284 DisplayConfigurator::RegisterOutputProtectionClient() {
283 if (!configure_display_) 285 if (!configure_display_)
284 return kInvalidClientId; 286 return kInvalidClientId;
285 287
286 return next_output_protection_client_id_++; 288 return next_output_protection_client_id_++;
287 } 289 }
288 290
289 void OutputConfigurator::UnregisterOutputProtectionClient( 291 void DisplayConfigurator::UnregisterOutputProtectionClient(
290 OutputProtectionClientId client_id) { 292 OutputProtectionClientId client_id) {
291 client_protection_requests_.erase(client_id); 293 client_protection_requests_.erase(client_id);
292 294
293 DisplayProtections protections; 295 DisplayProtections protections;
294 for (ProtectionRequests::const_iterator it = 296 for (ProtectionRequests::const_iterator it =
295 client_protection_requests_.begin(); 297 client_protection_requests_.begin();
296 it != client_protection_requests_.end(); 298 it != client_protection_requests_.end();
297 ++it) { 299 ++it) {
298 for (DisplayProtections::const_iterator it2 = it->second.begin(); 300 for (DisplayProtections::const_iterator it2 = it->second.begin();
299 it2 != it->second.end(); 301 it2 != it->second.end();
300 ++it2) { 302 ++it2) {
301 protections[it2->first] |= it2->second; 303 protections[it2->first] |= it2->second;
302 } 304 }
303 } 305 }
304 306
305 ApplyProtections(protections); 307 ApplyProtections(protections);
306 } 308 }
307 309
308 bool OutputConfigurator::QueryOutputProtectionStatus( 310 bool DisplayConfigurator::QueryOutputProtectionStatus(
309 OutputProtectionClientId client_id, 311 OutputProtectionClientId client_id,
310 int64_t display_id, 312 int64_t display_id,
311 uint32_t* link_mask, 313 uint32_t* link_mask,
312 uint32_t* protection_mask) { 314 uint32_t* protection_mask) {
313 if (!configure_display_) 315 if (!configure_display_)
314 return false; 316 return false;
315 317
316 uint32_t enabled = 0; 318 uint32_t enabled = 0;
317 uint32_t unfulfilled = 0; 319 uint32_t unfulfilled = 0;
318 *link_mask = 0; 320 *link_mask = 0;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 uint32_t requested_mask = 0; 357 uint32_t requested_mask = 0;
356 if (it->second.find(display_id) != it->second.end()) 358 if (it->second.find(display_id) != it->second.end())
357 requested_mask = it->second[display_id]; 359 requested_mask = it->second[display_id];
358 *protection_mask = enabled & ~unfulfilled & requested_mask; 360 *protection_mask = enabled & ~unfulfilled & requested_mask;
359 } else { 361 } else {
360 *protection_mask = 0; 362 *protection_mask = 0;
361 } 363 }
362 return true; 364 return true;
363 } 365 }
364 366
365 bool OutputConfigurator::EnableOutputProtection( 367 bool DisplayConfigurator::EnableOutputProtection(
366 OutputProtectionClientId client_id, 368 OutputProtectionClientId client_id,
367 int64_t display_id, 369 int64_t display_id,
368 uint32_t desired_method_mask) { 370 uint32_t desired_method_mask) {
369 if (!configure_display_) 371 if (!configure_display_)
370 return false; 372 return false;
371 373
372 DisplayProtections protections; 374 DisplayProtections protections;
373 for (ProtectionRequests::const_iterator it = 375 for (ProtectionRequests::const_iterator it =
374 client_protection_requests_.begin(); 376 client_protection_requests_.begin();
375 it != client_protection_requests_.end(); 377 it != client_protection_requests_.end();
(...skipping 19 matching lines...) Expand all
395 client_protection_requests_.erase(client_id); 397 client_protection_requests_.erase(client_id);
396 } 398 }
397 } else { 399 } else {
398 client_protection_requests_[client_id][display_id] = desired_method_mask; 400 client_protection_requests_[client_id][display_id] = desired_method_mask;
399 } 401 }
400 402
401 return true; 403 return true;
402 } 404 }
403 405
404 std::vector<ui::ColorCalibrationProfile> 406 std::vector<ui::ColorCalibrationProfile>
405 OutputConfigurator::GetAvailableColorCalibrationProfiles( 407 DisplayConfigurator::GetAvailableColorCalibrationProfiles(int64_t display_id) {
406 int64_t display_id) {
407 if (!base::CommandLine::ForCurrentProcess()->HasSwitch( 408 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
408 switches::kDisableDisplayColorCalibration)) { 409 switches::kDisableDisplayColorCalibration)) {
409 for (size_t i = 0; i < cached_outputs_.size(); ++i) { 410 for (size_t i = 0; i < cached_outputs_.size(); ++i) {
410 if (cached_outputs_[i].display && 411 if (cached_outputs_[i].display &&
411 cached_outputs_[i].display->display_id() == display_id) { 412 cached_outputs_[i].display->display_id() == display_id) {
412 return native_display_delegate_->GetAvailableColorCalibrationProfiles( 413 return native_display_delegate_->GetAvailableColorCalibrationProfiles(
413 *cached_outputs_[i].display); 414 *cached_outputs_[i].display);
414 } 415 }
415 } 416 }
416 } 417 }
417 418
418 return std::vector<ui::ColorCalibrationProfile>(); 419 return std::vector<ui::ColorCalibrationProfile>();
419 } 420 }
420 421
421 bool OutputConfigurator::SetColorCalibrationProfile( 422 bool DisplayConfigurator::SetColorCalibrationProfile(
422 int64_t display_id, 423 int64_t display_id,
423 ui::ColorCalibrationProfile new_profile) { 424 ui::ColorCalibrationProfile new_profile) {
424 for (size_t i = 0; i < cached_outputs_.size(); ++i) { 425 for (size_t i = 0; i < cached_outputs_.size(); ++i) {
425 if (cached_outputs_[i].display && 426 if (cached_outputs_[i].display &&
426 cached_outputs_[i].display->display_id() == display_id) { 427 cached_outputs_[i].display->display_id() == display_id) {
427 return native_display_delegate_->SetColorCalibrationProfile( 428 return native_display_delegate_->SetColorCalibrationProfile(
428 *cached_outputs_[i].display, new_profile); 429 *cached_outputs_[i].display, new_profile);
429 } 430 }
430 } 431 }
431 432
432 return false; 433 return false;
433 } 434 }
434 435
435 void OutputConfigurator::PrepareForExit() { 436 void DisplayConfigurator::PrepareForExit() {
436 configure_display_ = false; 437 configure_display_ = false;
437 } 438 }
438 439
439 bool OutputConfigurator::SetDisplayPower( 440 bool DisplayConfigurator::SetDisplayPower(
440 chromeos::DisplayPowerState power_state, 441 chromeos::DisplayPowerState power_state,
441 int flags) { 442 int flags) {
442 if (!configure_display_) 443 if (!configure_display_)
443 return false; 444 return false;
444 445
445 VLOG(1) << "SetDisplayPower: power_state=" 446 VLOG(1) << "SetDisplayPower: power_state="
446 << DisplayPowerStateToString(power_state) << " flags=" << flags 447 << DisplayPowerStateToString(power_state) << " flags=" << flags
447 << ", configure timer=" 448 << ", configure timer="
448 << ((configure_timer_.get() && configure_timer_->IsRunning()) ? 449 << ((configure_timer_.get() && configure_timer_->IsRunning()) ?
449 "Running" : "Stopped"); 450 "Running" : "Stopped");
(...skipping 21 matching lines...) Expand all
471 if (success && power_state != chromeos::DISPLAY_POWER_ALL_OFF) 472 if (success && power_state != chromeos::DISPLAY_POWER_ALL_OFF)
472 native_display_delegate_->ForceDPMSOn(); 473 native_display_delegate_->ForceDPMSOn();
473 } 474 }
474 475
475 native_display_delegate_->UngrabServer(); 476 native_display_delegate_->UngrabServer();
476 if (attempted_change) 477 if (attempted_change)
477 NotifyObservers(success, new_state); 478 NotifyObservers(success, new_state);
478 return true; 479 return true;
479 } 480 }
480 481
481 bool OutputConfigurator::SetDisplayMode(OutputState new_state) { 482 bool DisplayConfigurator::SetDisplayMode(OutputState new_state) {
482 if (!configure_display_) 483 if (!configure_display_)
483 return false; 484 return false;
484 485
485 VLOG(1) << "SetDisplayMode: state=" << OutputStateToString(new_state); 486 VLOG(1) << "SetDisplayMode: state=" << OutputStateToString(new_state);
486 if (output_state_ == new_state) { 487 if (output_state_ == new_state) {
487 // Cancel software mirroring if the state is moving from 488 // Cancel software mirroring if the state is moving from
488 // OUTPUT_STATE_DUAL_EXTENDED to OUTPUT_STATE_DUAL_EXTENDED. 489 // OUTPUT_STATE_DUAL_EXTENDED to OUTPUT_STATE_DUAL_EXTENDED.
489 if (mirroring_controller_ && new_state == OUTPUT_STATE_DUAL_EXTENDED) 490 if (mirroring_controller_ && new_state == OUTPUT_STATE_DUAL_EXTENDED)
490 mirroring_controller_->SetSoftwareMirroring(false); 491 mirroring_controller_->SetSoftwareMirroring(false);
491 NotifyObservers(true, new_state); 492 NotifyObservers(true, new_state);
492 return true; 493 return true;
493 } 494 }
494 495
495 native_display_delegate_->GrabServer(); 496 native_display_delegate_->GrabServer();
496 UpdateCachedOutputs(); 497 UpdateCachedOutputs();
497 const bool success = 498 const bool success =
498 EnterStateOrFallBackToSoftwareMirroring(new_state, power_state_); 499 EnterStateOrFallBackToSoftwareMirroring(new_state, power_state_);
499 native_display_delegate_->UngrabServer(); 500 native_display_delegate_->UngrabServer();
500 501
501 NotifyObservers(success, new_state); 502 NotifyObservers(success, new_state);
502 return success; 503 return success;
503 } 504 }
504 505
505 void OutputConfigurator::OnConfigurationChanged() { 506 void DisplayConfigurator::OnConfigurationChanged() {
506 // Configure outputs with |kConfigureDelayMs| delay, 507 // Configure outputs with |kConfigureDelayMs| delay,
507 // so that time-consuming ConfigureOutputs() won't be called multiple times. 508 // so that time-consuming ConfigureOutputs() won't be called multiple times.
508 if (configure_timer_.get()) { 509 if (configure_timer_.get()) {
509 configure_timer_->Reset(); 510 configure_timer_->Reset();
510 } else { 511 } else {
511 configure_timer_.reset(new base::OneShotTimer<OutputConfigurator>()); 512 configure_timer_.reset(new base::OneShotTimer<DisplayConfigurator>());
512 configure_timer_->Start( 513 configure_timer_->Start(
513 FROM_HERE, 514 FROM_HERE,
514 base::TimeDelta::FromMilliseconds(kConfigureDelayMs), 515 base::TimeDelta::FromMilliseconds(kConfigureDelayMs),
515 this, 516 this,
516 &OutputConfigurator::ConfigureOutputs); 517 &DisplayConfigurator::ConfigureOutputs);
517 } 518 }
518 } 519 }
519 520
520 void OutputConfigurator::AddObserver(Observer* observer) { 521 void DisplayConfigurator::AddObserver(Observer* observer) {
521 observers_.AddObserver(observer); 522 observers_.AddObserver(observer);
522 } 523 }
523 524
524 void OutputConfigurator::RemoveObserver(Observer* observer) { 525 void DisplayConfigurator::RemoveObserver(Observer* observer) {
525 observers_.RemoveObserver(observer); 526 observers_.RemoveObserver(observer);
526 } 527 }
527 528
528 void OutputConfigurator::SuspendDisplays() { 529 void DisplayConfigurator::SuspendDisplays() {
529 // If the display is off due to user inactivity and there's only a single 530 // If the display is off due to user inactivity and there's only a single
530 // internal display connected, switch to the all-on state before 531 // internal display connected, switch to the all-on state before
531 // suspending. This shouldn't be very noticeable to the user since the 532 // suspending. This shouldn't be very noticeable to the user since the
532 // backlight is off at this point, and doing this lets us resume directly 533 // backlight is off at this point, and doing this lets us resume directly
533 // into the "on" state, which greatly reduces resume times. 534 // into the "on" state, which greatly reduces resume times.
534 if (power_state_ == chromeos::DISPLAY_POWER_ALL_OFF) { 535 if (power_state_ == chromeos::DISPLAY_POWER_ALL_OFF) {
535 SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON, 536 SetDisplayPower(chromeos::DISPLAY_POWER_ALL_ON,
536 kSetDisplayPowerOnlyIfSingleInternalDisplay); 537 kSetDisplayPowerOnlyIfSingleInternalDisplay);
537 538
538 // We need to make sure that the monitor configuration we just did actually 539 // We need to make sure that the monitor configuration we just did actually
539 // completes before we return, because otherwise the X message could be 540 // completes before we return, because otherwise the X message could be
540 // racing with the HandleSuspendReadiness message. 541 // racing with the HandleSuspendReadiness message.
541 native_display_delegate_->SyncWithServer(); 542 native_display_delegate_->SyncWithServer();
542 } 543 }
543 } 544 }
544 545
545 void OutputConfigurator::ResumeDisplays() { 546 void DisplayConfigurator::ResumeDisplays() {
546 // Force probing to ensure that we pick up any changes that were made 547 // Force probing to ensure that we pick up any changes that were made
547 // while the system was suspended. 548 // while the system was suspended.
548 SetDisplayPower(power_state_, kSetDisplayPowerForceProbe); 549 SetDisplayPower(power_state_, kSetDisplayPowerForceProbe);
549 } 550 }
550 551
551 void OutputConfigurator::UpdateCachedOutputs() { 552 void DisplayConfigurator::UpdateCachedOutputs() {
552 std::vector<DisplaySnapshot*> snapshots = 553 std::vector<DisplaySnapshot*> snapshots =
553 native_display_delegate_->GetOutputs(); 554 native_display_delegate_->GetOutputs();
554 555
555 cached_outputs_.clear(); 556 cached_outputs_.clear();
556 for (size_t i = 0; i < snapshots.size(); ++i) { 557 for (size_t i = 0; i < snapshots.size(); ++i) {
557 DisplayState display_state; 558 DisplayState display_state;
558 display_state.display = snapshots[i]; 559 display_state.display = snapshots[i];
559 cached_outputs_.push_back(display_state); 560 cached_outputs_.push_back(display_state);
560 } 561 }
561 562
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 // it will succeed with the other. This way we will have the correct 618 // it will succeed with the other. This way we will have the correct
618 // aspect ratio on at least one of them. 619 // aspect ratio on at least one of them.
619 can_mirror = FindMirrorMode( 620 can_mirror = FindMirrorMode(
620 &cached_outputs_[1], &cached_outputs_[0], false, preserve_aspect); 621 &cached_outputs_[1], &cached_outputs_[0], false, preserve_aspect);
621 } 622 }
622 } 623 }
623 } 624 }
624 } 625 }
625 } 626 }
626 627
627 bool OutputConfigurator::FindMirrorMode(DisplayState* internal_output, 628 bool DisplayConfigurator::FindMirrorMode(DisplayState* internal_output,
628 DisplayState* external_output, 629 DisplayState* external_output,
629 bool try_panel_fitting, 630 bool try_panel_fitting,
630 bool preserve_aspect) { 631 bool preserve_aspect) {
631 const DisplayMode* internal_native_info = 632 const DisplayMode* internal_native_info =
632 internal_output->display->native_mode(); 633 internal_output->display->native_mode();
633 const DisplayMode* external_native_info = 634 const DisplayMode* external_native_info =
634 external_output->display->native_mode(); 635 external_output->display->native_mode();
635 if (!internal_native_info || !external_native_info) 636 if (!internal_native_info || !external_native_info)
636 return false; 637 return false;
637 638
638 // Check if some external output resolution can be mirrored on internal. 639 // Check if some external output resolution can be mirrored on internal.
639 // Prefer the modes in the order that X sorts them, assuming this is the order 640 // Prefer the modes in the order that X sorts them, assuming this is the order
640 // in which they look better on the monitor. 641 // in which they look better on the monitor.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 internal_output->mirror_mode = *external_it; 682 internal_output->mirror_mode = *external_it;
682 external_output->mirror_mode = *external_it; 683 external_output->mirror_mode = *external_it;
683 return true; // Mirror mode created. 684 return true; // Mirror mode created.
684 } 685 }
685 } 686 }
686 } 687 }
687 688
688 return false; 689 return false;
689 } 690 }
690 691
691 void OutputConfigurator::ConfigureOutputs() { 692 void DisplayConfigurator::ConfigureOutputs() {
692 configure_timer_.reset(); 693 configure_timer_.reset();
693 694
694 if (!configure_display_) 695 if (!configure_display_)
695 return; 696 return;
696 697
697 native_display_delegate_->GrabServer(); 698 native_display_delegate_->GrabServer();
698 UpdateCachedOutputs(); 699 UpdateCachedOutputs();
699 const OutputState new_state = ChooseOutputState(power_state_); 700 const OutputState new_state = ChooseOutputState(power_state_);
700 const bool success = 701 const bool success =
701 EnterStateOrFallBackToSoftwareMirroring(new_state, power_state_); 702 EnterStateOrFallBackToSoftwareMirroring(new_state, power_state_);
702 native_display_delegate_->UngrabServer(); 703 native_display_delegate_->UngrabServer();
703 704
704 NotifyObservers(success, new_state); 705 NotifyObservers(success, new_state);
705 } 706 }
706 707
707 void OutputConfigurator::NotifyObservers(bool success, 708 void DisplayConfigurator::NotifyObservers(bool success,
708 OutputState attempted_state) { 709 OutputState attempted_state) {
709 if (success) { 710 if (success) {
710 FOR_EACH_OBSERVER( 711 FOR_EACH_OBSERVER(
711 Observer, observers_, OnDisplayModeChanged(cached_outputs_)); 712 Observer, observers_, OnDisplayModeChanged(cached_outputs_));
712 } else { 713 } else {
713 FOR_EACH_OBSERVER( 714 FOR_EACH_OBSERVER(
714 Observer, observers_, OnDisplayModeChangeFailed(attempted_state)); 715 Observer, observers_, OnDisplayModeChangeFailed(attempted_state));
715 } 716 }
716 } 717 }
717 718
718 bool OutputConfigurator::EnterStateOrFallBackToSoftwareMirroring( 719 bool DisplayConfigurator::EnterStateOrFallBackToSoftwareMirroring(
719 OutputState output_state, 720 OutputState output_state,
720 chromeos::DisplayPowerState power_state) { 721 chromeos::DisplayPowerState power_state) {
721 bool success = EnterState(output_state, power_state); 722 bool success = EnterState(output_state, power_state);
722 if (mirroring_controller_) { 723 if (mirroring_controller_) {
723 bool enable_software_mirroring = false; 724 bool enable_software_mirroring = false;
724 if (!success && output_state == OUTPUT_STATE_DUAL_MIRROR) { 725 if (!success && output_state == OUTPUT_STATE_DUAL_MIRROR) {
725 if (output_state_ != OUTPUT_STATE_DUAL_EXTENDED || 726 if (output_state_ != OUTPUT_STATE_DUAL_EXTENDED ||
726 power_state_ != power_state) 727 power_state_ != power_state)
727 EnterState(OUTPUT_STATE_DUAL_EXTENDED, power_state); 728 EnterState(OUTPUT_STATE_DUAL_EXTENDED, power_state);
728 enable_software_mirroring = success = 729 enable_software_mirroring = success =
729 output_state_ == OUTPUT_STATE_DUAL_EXTENDED; 730 output_state_ == OUTPUT_STATE_DUAL_EXTENDED;
730 } 731 }
731 mirroring_controller_->SetSoftwareMirroring(enable_software_mirroring); 732 mirroring_controller_->SetSoftwareMirroring(enable_software_mirroring);
732 } 733 }
733 return success; 734 return success;
734 } 735 }
735 736
736 bool OutputConfigurator::EnterState(OutputState output_state, 737 bool DisplayConfigurator::EnterState(OutputState output_state,
737 chromeos::DisplayPowerState power_state) { 738 chromeos::DisplayPowerState power_state) {
738 std::vector<bool> output_power; 739 std::vector<bool> output_power;
739 int num_on_outputs = 740 int num_on_outputs =
740 GetOutputPower(cached_outputs_, power_state, &output_power); 741 GetOutputPower(cached_outputs_, power_state, &output_power);
741 VLOG(1) << "EnterState: output=" << OutputStateToString(output_state) 742 VLOG(1) << "EnterState: output=" << OutputStateToString(output_state)
742 << " power=" << DisplayPowerStateToString(power_state); 743 << " power=" << DisplayPowerStateToString(power_state);
743 744
744 // Framebuffer dimensions. 745 // Framebuffer dimensions.
745 gfx::Size size; 746 gfx::Size size;
746 747
747 std::vector<gfx::Point> new_origins(cached_outputs_.size(), gfx::Point()); 748 std::vector<gfx::Point> new_origins(cached_outputs_.size(), gfx::Point());
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 } 917 }
917 } 918 }
918 919
919 if (all_succeeded) { 920 if (all_succeeded) {
920 output_state_ = output_state; 921 output_state_ = output_state;
921 power_state_ = power_state; 922 power_state_ = power_state;
922 } 923 }
923 return all_succeeded; 924 return all_succeeded;
924 } 925 }
925 926
926 OutputState OutputConfigurator::ChooseOutputState( 927 OutputState DisplayConfigurator::ChooseOutputState(
927 chromeos::DisplayPowerState power_state) const { 928 chromeos::DisplayPowerState power_state) const {
928 int num_on_outputs = GetOutputPower(cached_outputs_, power_state, NULL); 929 int num_on_outputs = GetOutputPower(cached_outputs_, power_state, NULL);
929 switch (cached_outputs_.size()) { 930 switch (cached_outputs_.size()) {
930 case 0: 931 case 0:
931 return OUTPUT_STATE_HEADLESS; 932 return OUTPUT_STATE_HEADLESS;
932 case 1: 933 case 1:
933 return OUTPUT_STATE_SINGLE; 934 return OUTPUT_STATE_SINGLE;
934 case 2: { 935 case 2: {
935 if (num_on_outputs == 1) { 936 if (num_on_outputs == 1) {
936 // If only one output is currently turned on, return the "single" 937 // If only one output is currently turned on, return the "single"
(...skipping 13 matching lines...) Expand all
950 } 951 }
951 return state_controller_->GetStateForDisplayIds(display_ids); 952 return state_controller_->GetStateForDisplayIds(display_ids);
952 } 953 }
953 } 954 }
954 default: 955 default:
955 NOTREACHED(); 956 NOTREACHED();
956 } 957 }
957 return OUTPUT_STATE_INVALID; 958 return OUTPUT_STATE_INVALID;
958 } 959 }
959 960
960 OutputConfigurator::CoordinateTransformation 961 DisplayConfigurator::CoordinateTransformation
961 OutputConfigurator::GetMirrorModeCTM(const DisplayState& output) { 962 DisplayConfigurator::GetMirrorModeCTM(const DisplayState& output) {
962 CoordinateTransformation ctm; // Default to identity 963 CoordinateTransformation ctm; // Default to identity
963 const DisplayMode* native_mode_info = output.display->native_mode(); 964 const DisplayMode* native_mode_info = output.display->native_mode();
964 const DisplayMode* mirror_mode_info = output.mirror_mode; 965 const DisplayMode* mirror_mode_info = output.mirror_mode;
965 966
966 if (!native_mode_info || !mirror_mode_info || 967 if (!native_mode_info || !mirror_mode_info ||
967 native_mode_info->size().height() == 0 || 968 native_mode_info->size().height() == 0 ||
968 mirror_mode_info->size().height() == 0 || 969 mirror_mode_info->size().height() == 0 ||
969 native_mode_info->size().width() == 0 || 970 native_mode_info->size().width() == 0 ||
970 mirror_mode_info->size().width() == 0) 971 mirror_mode_info->size().width() == 0)
971 return ctm; 972 return ctm;
(...skipping 14 matching lines...) Expand all
986 ctm.y_scale = 1.0; 987 ctm.y_scale = 1.0;
987 ctm.y_offset = 0.0; 988 ctm.y_offset = 0.0;
988 ctm.x_scale = native_mode_ar / mirror_mode_ar; 989 ctm.x_scale = native_mode_ar / mirror_mode_ar;
989 ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5; 990 ctm.x_offset = (mirror_mode_ar / native_mode_ar - 1.0) * 0.5;
990 return ctm; 991 return ctm;
991 } 992 }
992 993
993 return ctm; // Same aspect ratio - return identity 994 return ctm; // Same aspect ratio - return identity
994 } 995 }
995 996
996 OutputConfigurator::CoordinateTransformation 997 DisplayConfigurator::CoordinateTransformation
997 OutputConfigurator::GetExtendedModeCTM(const DisplayState& output, 998 DisplayConfigurator::GetExtendedModeCTM(const DisplayState& output,
998 const gfx::Point& new_origin, 999 const gfx::Point& new_origin,
999 const gfx::Size& framebuffer_size) { 1000 const gfx::Size& framebuffer_size) {
1000 CoordinateTransformation ctm; // Default to identity 1001 CoordinateTransformation ctm; // Default to identity
1001 const DisplayMode* mode_info = output.selected_mode; 1002 const DisplayMode* mode_info = output.selected_mode;
1002 DCHECK(mode_info); 1003 DCHECK(mode_info);
1003 if (!mode_info) 1004 if (!mode_info)
1004 return ctm; 1005 return ctm;
1005 // An example of how to calculate the CTM. 1006 // An example of how to calculate the CTM.
1006 // Suppose we have 2 monitors, the first one has size 1366 x 768. 1007 // Suppose we have 2 monitors, the first one has size 1366 x 768.
1007 // The second one has size 2560 x 1600 1008 // The second one has size 2560 x 1600
1008 // The total size of framebuffer is 2560 x 2428 1009 // The total size of framebuffer is 2560 x 2428
1009 // where 2428 = 768 + 60 (hidden gap) + 1600 1010 // where 2428 = 768 + 60 (hidden gap) + 1600
1010 // and the sceond monitor is translated to Point (0, 828) in the 1011 // and the sceond monitor is translated to Point (0, 828) in the
1011 // framebuffer. 1012 // framebuffer.
1012 // X will first map input event location to [0, 2560) x [0, 2428), 1013 // X will first map input event location to [0, 2560) x [0, 2428),
1013 // then apply CTM on it. 1014 // then apply CTM on it.
1014 // So to compute CTM, for monitor1, we have 1015 // So to compute CTM, for monitor1, we have
1015 // x_scale = (1366 - 1) / (2560 - 1) 1016 // x_scale = (1366 - 1) / (2560 - 1)
1016 // x_offset = 0 / (2560 - 1) 1017 // x_offset = 0 / (2560 - 1)
1017 // y_scale = (768 - 1) / (2428 - 1) 1018 // y_scale = (768 - 1) / (2428 - 1)
1018 // y_offset = 0 / (2428 -1) 1019 // y_offset = 0 / (2428 -1)
1019 // For Monitor 2, we have 1020 // For Monitor 2, we have
1020 // x_scale = (2560 - 1) / (2560 - 1) 1021 // x_scale = (2560 - 1) / (2560 - 1)
1021 // x_offset = 0 / (2560 - 1) 1022 // x_offset = 0 / (2560 - 1)
1022 // y_scale = (1600 - 1) / (2428 - 1) 1023 // y_scale = (1600 - 1) / (2428 - 1)
1023 // y_offset = 828 / (2428 -1) 1024 // y_offset = 828 / (2428 -1)
1024 // See the unittest OutputConfiguratorTest.CTMForMultiScreens. 1025 // See the unittest DisplayConfiguratorTest.CTMForMultiScreens.
1025 ctm.x_scale = static_cast<float>(mode_info->size().width() - 1) / 1026 ctm.x_scale = static_cast<float>(mode_info->size().width() - 1) /
1026 (framebuffer_size.width() - 1); 1027 (framebuffer_size.width() - 1);
1027 ctm.x_offset = 1028 ctm.x_offset =
1028 static_cast<float>(new_origin.x()) / (framebuffer_size.width() - 1); 1029 static_cast<float>(new_origin.x()) / (framebuffer_size.width() - 1);
1029 ctm.y_scale = static_cast<float>(mode_info->size().height() - 1) / 1030 ctm.y_scale = static_cast<float>(mode_info->size().height() - 1) /
1030 (framebuffer_size.height() - 1); 1031 (framebuffer_size.height() - 1);
1031 ctm.y_offset = 1032 ctm.y_offset =
1032 static_cast<float>(new_origin.y()) / (framebuffer_size.height() - 1); 1033 static_cast<float>(new_origin.y()) / (framebuffer_size.height() - 1);
1033 return ctm; 1034 return ctm;
1034 } 1035 }
1035 1036
1036 float OutputConfigurator::GetMirroredDisplayAreaRatio( 1037 float DisplayConfigurator::GetMirroredDisplayAreaRatio(
1037 const DisplayState& output) { 1038 const DisplayState& output) {
1038 float area_ratio = 1.0f; 1039 float area_ratio = 1.0f;
1039 const DisplayMode* native_mode_info = output.display->native_mode(); 1040 const DisplayMode* native_mode_info = output.display->native_mode();
1040 const DisplayMode* mirror_mode_info = output.mirror_mode; 1041 const DisplayMode* mirror_mode_info = output.mirror_mode;
1041 1042
1042 if (!native_mode_info || !mirror_mode_info || 1043 if (!native_mode_info || !mirror_mode_info ||
1043 native_mode_info->size().height() == 0 || 1044 native_mode_info->size().height() == 0 ||
1044 mirror_mode_info->size().height() == 0 || 1045 mirror_mode_info->size().height() == 0 ||
1045 native_mode_info->size().width() == 0 || 1046 native_mode_info->size().width() == 0 ||
1046 mirror_mode_info->size().width() == 0) 1047 mirror_mode_info->size().width() == 0)
1047 return area_ratio; 1048 return area_ratio;
1048 1049
1049 float width_ratio = static_cast<float>(mirror_mode_info->size().width()) / 1050 float width_ratio = static_cast<float>(mirror_mode_info->size().width()) /
1050 static_cast<float>(native_mode_info->size().width()); 1051 static_cast<float>(native_mode_info->size().width());
1051 float height_ratio = static_cast<float>(mirror_mode_info->size().height()) / 1052 float height_ratio = static_cast<float>(mirror_mode_info->size().height()) /
1052 static_cast<float>(native_mode_info->size().height()); 1053 static_cast<float>(native_mode_info->size().height());
1053 1054
1054 area_ratio = width_ratio * height_ratio; 1055 area_ratio = width_ratio * height_ratio;
1055 return area_ratio; 1056 return area_ratio;
1056 } 1057 }
1057 1058
1058 } // namespace ui 1059 } // namespace ui
OLDNEW
« no previous file with comments | « ui/display/chromeos/display_configurator.h ('k') | ui/display/chromeos/display_configurator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698