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. |
sabercrombie
2013/02/16 00:01:08
This comment doesn't look accurate any more.
oshima
2013/02/16 01:32:52
Done.
| |
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); |
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", |
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 |