| 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/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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |