Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chromeos/display/output_configurator.h" | 5 #include "chromeos/display/output_configurator.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
| 10 #include <X11/Xlib.h> | 10 #include <X11/Xlib.h> |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 // such that one is primary and another is correctly positioned as | 365 // such that one is primary and another is correctly positioned as |
| 366 // secondary. If any of these assumptions are false, this is an unknown | 366 // secondary. If any of these assumptions are false, this is an unknown |
| 367 // configuration. | 367 // configuration. |
| 368 bool primary_native = (primary_mode == outputs[0].native_mode) || | 368 bool primary_native = (primary_mode == outputs[0].native_mode) || |
| 369 (primary_mode == None); | 369 (primary_mode == None); |
| 370 bool secondary_native = (secondary_mode == outputs[1].native_mode) || | 370 bool secondary_native = (secondary_mode == outputs[1].native_mode) || |
| 371 (secondary_mode == None); | 371 (secondary_mode == None); |
| 372 if (primary_native && secondary_native) { | 372 if (primary_native && secondary_native) { |
| 373 // Just check the relative locations. | 373 // Just check the relative locations. |
| 374 int secondary_offset = outputs[0].height + kVerticalGap; | 374 int secondary_offset = outputs[0].height + kVerticalGap; |
| 375 int primary_offset = outputs[1].height + kVerticalGap; | |
| 376 if ((outputs[0].y == 0) && (outputs[1].y == secondary_offset)) { | 375 if ((outputs[0].y == 0) && (outputs[1].y == secondary_offset)) { |
| 377 state = STATE_DUAL_PRIMARY_ONLY; | 376 state = STATE_DUAL_EXTENDED; |
| 378 } else if ((outputs[1].y == 0) && (outputs[0].y == primary_offset)) { | |
| 379 state = STATE_DUAL_SECONDARY_ONLY; | |
| 380 } else { | 377 } else { |
| 381 // Unexpected locations. | 378 // Unexpected locations. |
| 382 state = STATE_DUAL_UNKNOWN; | 379 state = STATE_DUAL_UNKNOWN; |
| 383 } | 380 } |
| 384 } else { | 381 } else { |
| 385 // Mode assumptions don't hold. | 382 // Mode assumptions don't hold. |
| 386 state = STATE_DUAL_UNKNOWN; | 383 state = STATE_DUAL_UNKNOWN; |
| 387 } | 384 } |
| 388 } | 385 } |
| 389 break; | 386 break; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 405 case 0: | 402 case 0: |
| 406 state = STATE_HEADLESS; | 403 state = STATE_HEADLESS; |
| 407 break; | 404 break; |
| 408 case 1: | 405 case 1: |
| 409 state = STATE_SINGLE; | 406 state = STATE_SINGLE; |
| 410 break; | 407 break; |
| 411 case 2: { | 408 case 2: { |
| 412 bool mirror_supported = (0 != outputs[0].mirror_mode) && | 409 bool mirror_supported = (0 != outputs[0].mirror_mode) && |
| 413 (0 != outputs[1].mirror_mode); | 410 (0 != outputs[1].mirror_mode); |
| 414 switch (current_state) { | 411 switch (current_state) { |
| 415 case STATE_DUAL_PRIMARY_ONLY: | 412 case STATE_DUAL_EXTENDED: |
| 416 state = | 413 state = |
| 417 mirror_supported ? STATE_DUAL_MIRROR : STATE_DUAL_PRIMARY_ONLY; | 414 mirror_supported ? STATE_DUAL_MIRROR : STATE_DUAL_EXTENDED; |
| 418 break; | 415 break; |
| 419 case STATE_DUAL_MIRROR: | 416 case STATE_DUAL_MIRROR: |
| 420 state = STATE_DUAL_PRIMARY_ONLY; | 417 state = STATE_DUAL_EXTENDED; |
| 421 break; | 418 break; |
| 422 default: | 419 default: |
| 423 // Default to primary only. | 420 // Default to primary only. |
| 424 state = STATE_DUAL_PRIMARY_ONLY; | 421 state = STATE_DUAL_EXTENDED; |
| 425 } | 422 } |
| 426 break; | 423 break; |
| 427 } | 424 } |
| 428 default: | 425 default: |
| 429 CHECK(false); | 426 CHECK(false); |
| 430 } | 427 } |
| 431 return state; | 428 return state; |
| 432 } | 429 } |
| 433 | 430 |
| 434 RRCrtc GetNextCrtcAfter(Display* display, | 431 RRCrtc GetNextCrtcAfter(Display* display, |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 801 | 798 |
| 802 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); | 799 Display* display = base::MessagePumpAuraX11::GetDefaultXDisplay(); |
| 803 CHECK(display != NULL); | 800 CHECK(display != NULL); |
| 804 XGrabServer(display); | 801 XGrabServer(display); |
| 805 Window window = DefaultRootWindow(display); | 802 Window window = DefaultRootWindow(display); |
| 806 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window); | 803 XRRScreenResources* screen = GetScreenResourcesAndRecordUMA(display, window); |
| 807 CHECK(screen != NULL); | 804 CHECK(screen != NULL); |
| 808 | 805 |
| 809 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen); | 806 std::vector<OutputSnapshot> outputs = GetDualOutputs(display, screen); |
| 810 int new_output_count = outputs.size(); | 807 int new_output_count = outputs.size(); |
| 811 bool changed = false; | 808 // Don't skip even if the output counts didn't change because |
| 812 if (new_output_count != connected_output_count_) { | 809 // a display might have been swapped during the suspend. |
| 813 connected_output_count_ = new_output_count; | 810 connected_output_count_ = new_output_count; |
| 814 OutputState new_state = | 811 OutputState new_state = |
| 815 GetNextState(display, screen, STATE_INVALID, outputs); | 812 GetNextState(display, screen, STATE_INVALID, outputs); |
| 816 changed = EnterState(display, screen, window, new_state, outputs); | 813 // When a display was swapped, the state moves from |
| 817 if (changed) | 814 // STATE_DUAL_EXTENDED to STATE_DUAL_EXTENDED, so don't rely on |
| 818 output_state_ = new_state; | 815 // the state chagne to tell if it was successful. |
| 819 } | 816 bool success = EnterState(display, screen, window, new_state, outputs); |
|
Jun Mukai
2013/02/14 22:13:03
Does this mean that the output configuration happe
oshima
2013/02/14 22:33:12
Hmm, this wasn't the issue as there used to be no
oshima
2013/02/15 23:14:10
Looks like this was temporary regression on TOT an
| |
| 820 bool is_projecting = IsProjecting(outputs); | 817 bool is_projecting = IsProjecting(outputs); |
| 821 XRRFreeScreenResources(screen); | 818 XRRFreeScreenResources(screen); |
| 822 XUngrabServer(display); | 819 XUngrabServer(display); |
| 823 | 820 |
| 824 if (changed) | 821 if (success) { |
| 822 output_state_ = new_state; | |
| 825 NotifyOnDisplayChanged(); | 823 NotifyOnDisplayChanged(); |
| 824 } | |
| 826 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> | 825 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> |
| 827 SetIsProjecting(is_projecting); | 826 SetIsProjecting(is_projecting); |
| 828 } | 827 } |
| 829 | 828 |
| 830 void OutputConfigurator::AddObserver(Observer* observer) { | 829 void OutputConfigurator::AddObserver(Observer* observer) { |
| 831 observers_.AddObserver(observer); | 830 observers_.AddObserver(observer); |
| 832 } | 831 } |
| 833 | 832 |
| 834 void OutputConfigurator::RemoveObserver(Observer* observer) { | 833 void OutputConfigurator::RemoveObserver(Observer* observer) { |
| 835 observers_.RemoveObserver(observer); | 834 observers_.RemoveObserver(observer); |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1249 return false; | 1248 return false; |
| 1250 } | 1249 } |
| 1251 | 1250 |
| 1252 int primary_height = primary_mode_info->height; | 1251 int primary_height = primary_mode_info->height; |
| 1253 int secondary_height = secondary_mode_info->height; | 1252 int secondary_height = secondary_mode_info->height; |
| 1254 CrtcConfig config1(primary_crtc, 0, 0, outputs[0].native_mode, | 1253 CrtcConfig config1(primary_crtc, 0, 0, outputs[0].native_mode, |
| 1255 outputs[0].output); | 1254 outputs[0].output); |
| 1256 CrtcConfig config2(secondary_crtc, 0, 0, outputs[1].native_mode, | 1255 CrtcConfig config2(secondary_crtc, 0, 0, outputs[1].native_mode, |
| 1257 outputs[1].output); | 1256 outputs[1].output); |
| 1258 | 1257 |
| 1259 if (new_state == STATE_DUAL_PRIMARY_ONLY) | 1258 if (new_state == STATE_DUAL_EXTENDED) |
| 1260 config2.y = primary_height + kVerticalGap; | 1259 config2.y = primary_height + kVerticalGap; |
| 1261 else | 1260 else |
| 1262 config1.y = secondary_height + kVerticalGap; | 1261 config1.y = secondary_height + kVerticalGap; |
| 1263 | 1262 |
| 1264 | 1263 |
| 1265 int width = | 1264 int width = |
| 1266 std::max<int>(primary_mode_info->width, secondary_mode_info->width); | 1265 std::max<int>(primary_mode_info->width, secondary_mode_info->width); |
| 1267 int height = primary_height + secondary_height + kVerticalGap; | 1266 int height = primary_height + secondary_height + kVerticalGap; |
| 1268 | 1267 |
| 1269 CreateFrameBuffer(display, screen, window, width, height, &config1, | 1268 CreateFrameBuffer(display, screen, window, width, height, &config1, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1311 UMA_HISTOGRAM_LONG_TIMES("Display.EnterState.single_duration", duration); | 1310 UMA_HISTOGRAM_LONG_TIMES("Display.EnterState.single_duration", duration); |
| 1312 break; | 1311 break; |
| 1313 case STATE_DUAL_MIRROR: | 1312 case STATE_DUAL_MIRROR: |
| 1314 if (mirror_mode_preserved_aspect_) | 1313 if (mirror_mode_preserved_aspect_) |
| 1315 UMA_HISTOGRAM_LONG_TIMES("Display.EnterState.mirror_aspect_duration", | 1314 UMA_HISTOGRAM_LONG_TIMES("Display.EnterState.mirror_aspect_duration", |
| 1316 duration); | 1315 duration); |
| 1317 else | 1316 else |
| 1318 UMA_HISTOGRAM_LONG_TIMES("Display.EnterState.mirror_fallback_duration", | 1317 UMA_HISTOGRAM_LONG_TIMES("Display.EnterState.mirror_fallback_duration", |
| 1319 duration); | 1318 duration); |
| 1320 break; | 1319 break; |
| 1321 case STATE_DUAL_PRIMARY_ONLY: | 1320 case STATE_DUAL_EXTENDED: |
| 1322 UMA_HISTOGRAM_LONG_TIMES("Display.EnterState.dual_primary_duration", | 1321 UMA_HISTOGRAM_LONG_TIMES("Display.EnterState.dual_primary_duration", |
|
Jun Mukai
2013/02/14 22:13:03
change it to "Display.EnterState.extended" or some
oshima
2013/02/14 22:33:12
I won't touch UMA name as we have historical data.
| |
| 1323 duration); | 1322 duration); |
| 1324 break; | 1323 break; |
| 1325 case STATE_DUAL_SECONDARY_ONLY: | |
| 1326 UMA_HISTOGRAM_LONG_TIMES("Display.EnterState.dual_secondary_duration", | |
| 1327 duration); | |
| 1328 default: | 1324 default: |
| 1329 break; | 1325 break; |
| 1330 } | 1326 } |
| 1331 | 1327 |
| 1332 mirror_mode_preserved_aspect_ = mirror_mode_will_preserve_aspect_; | 1328 mirror_mode_preserved_aspect_ = mirror_mode_will_preserve_aspect_; |
| 1333 last_enter_state_time_ = base::TimeTicks::Now(); | 1329 last_enter_state_time_ = base::TimeTicks::Now(); |
| 1334 } | 1330 } |
| 1335 | 1331 |
| 1336 // static | 1332 // static |
| 1337 bool OutputConfigurator::IsInternalOutput(const XRROutputInfo* output_info) { | 1333 bool OutputConfigurator::IsInternalOutput(const XRROutputInfo* output_info) { |
| 1338 return IsInternalOutputName(std::string(output_info->name)); | 1334 return IsInternalOutputName(std::string(output_info->name)); |
| 1339 } | 1335 } |
| 1340 | 1336 |
| 1341 // static | 1337 // static |
| 1342 RRMode OutputConfigurator::GetOutputNativeMode( | 1338 RRMode OutputConfigurator::GetOutputNativeMode( |
| 1343 const XRROutputInfo* output_info) { | 1339 const XRROutputInfo* output_info) { |
| 1344 if (output_info->nmode <= 0) | 1340 if (output_info->nmode <= 0) |
| 1345 return None; | 1341 return None; |
| 1346 | 1342 |
| 1347 return output_info->modes[0]; | 1343 return output_info->modes[0]; |
| 1348 } | 1344 } |
| 1349 | 1345 |
| 1350 } // namespace chromeos | 1346 } // namespace chromeos |
| OLD | NEW |