| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "ash/rotator/screen_rotation_animator.h" | 5 #include "ash/rotator/screen_rotation_animator.h" |
| 6 | 6 |
| 7 #include "ash/ash_switches.h" | 7 #include "ash/ash_switches.h" |
| 8 #include "ash/display/window_tree_host_manager.h" | 8 #include "ash/display/window_tree_host_manager.h" |
| 9 #include "ash/public/cpp/shell_window_ids.h" | 9 #include "ash/public/cpp/shell_window_ids.h" |
| 10 #include "ash/rotator/screen_rotation_animation.h" | 10 #include "ash/rotator/screen_rotation_animation.h" |
| 11 #include "ash/rotator/screen_rotation_animator_lock.h" |
| 11 #include "ash/rotator/screen_rotation_animator_observer.h" | 12 #include "ash/rotator/screen_rotation_animator_observer.h" |
| 12 #include "ash/shell.h" | 13 #include "ash/shell.h" |
| 13 #include "ash/utility/transformer_util.h" | 14 #include "ash/utility/transformer_util.h" |
| 15 #include "ash/wallpaper/wallpaper_controller.h" |
| 14 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 15 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" |
| 16 #include "base/metrics/histogram_macros.h" | 18 #include "base/metrics/histogram_macros.h" |
| 19 #include "base/threading/thread_task_runner_handle.h" |
| 17 #include "base/time/time.h" | 20 #include "base/time/time.h" |
| 18 #include "cc/output/copy_output_request.h" | 21 #include "cc/output/copy_output_request.h" |
| 19 #include "cc/output/copy_output_result.h" | 22 #include "cc/output/copy_output_result.h" |
| 20 #include "ui/aura/window.h" | 23 #include "ui/aura/window.h" |
| 21 #include "ui/compositor/callback_layer_animation_observer.h" | 24 #include "ui/compositor/callback_layer_animation_observer.h" |
| 22 #include "ui/compositor/layer.h" | 25 #include "ui/compositor/layer.h" |
| 23 #include "ui/compositor/layer_animation_element.h" | 26 #include "ui/compositor/layer_animation_element.h" |
| 24 #include "ui/compositor/layer_animation_sequence.h" | 27 #include "ui/compositor/layer_animation_sequence.h" |
| 25 #include "ui/compositor/layer_animator.h" | 28 #include "ui/compositor/layer_animator.h" |
| 26 #include "ui/compositor/layer_owner.h" | 29 #include "ui/compositor/layer_owner.h" |
| 27 #include "ui/compositor/layer_tree_owner.h" | 30 #include "ui/compositor/layer_tree_owner.h" |
| 28 #include "ui/display/display.h" | 31 #include "ui/display/display.h" |
| 29 #include "ui/display/manager/display_manager.h" | 32 #include "ui/display/manager/display_manager.h" |
| 30 #include "ui/display/manager/managed_display_info.h" | 33 #include "ui/display/manager/managed_display_info.h" |
| 31 #include "ui/gfx/animation/tween.h" | 34 #include "ui/gfx/animation/tween.h" |
| 32 #include "ui/gfx/geometry/point.h" | 35 #include "ui/gfx/geometry/point.h" |
| 33 #include "ui/gfx/geometry/rect.h" | 36 #include "ui/gfx/geometry/rect.h" |
| 34 #include "ui/gfx/geometry/rect_f.h" | 37 #include "ui/gfx/geometry/rect_f.h" |
| 35 #include "ui/gfx/transform.h" | 38 #include "ui/gfx/transform.h" |
| 36 #include "ui/gfx/transform_util.h" | 39 #include "ui/gfx/transform_util.h" |
| 37 #include "ui/wm/core/window_util.h" | 40 #include "ui/wm/core/window_util.h" |
| 38 | 41 |
| 39 namespace ash { | 42 namespace ash { |
| 40 | 43 |
| 41 namespace { | 44 namespace { |
| 42 | 45 |
| 43 // The number of degrees that the rotation animations animate through. | 46 // The number of degrees that the rotation animations animate through. |
| 44 const int kRotationDegrees = 20; | 47 constexpr int kRotationDegrees = 20; |
| 45 | 48 |
| 46 // The time it takes for the rotation animations to run. | 49 // The time it takes for the rotation animations to run. |
| 47 const int kRotationDurationInMs = 250; | 50 constexpr int kRotationDurationInMs = 250; |
| 51 |
| 52 // The timeout for waiting |ScreenRotationAnimatorLock|. |
| 53 constexpr int kAnimatorLockTimeoutMs = 500; |
| 48 | 54 |
| 49 // The rotation factors. | 55 // The rotation factors. |
| 50 const int kCounterClockWiseRotationFactor = 1; | 56 constexpr int kCounterClockWiseRotationFactor = 1; |
| 51 const int kClockWiseRotationFactor = -1; | 57 constexpr int kClockWiseRotationFactor = -1; |
| 52 | 58 |
| 53 display::Display::Rotation GetCurrentScreenRotation(int64_t display_id) { | 59 display::Display::Rotation GetCurrentScreenRotation(int64_t display_id) { |
| 54 return Shell::Get() | 60 return Shell::Get() |
| 55 ->display_manager() | 61 ->display_manager() |
| 56 ->GetDisplayInfo(display_id) | 62 ->GetDisplayInfo(display_id) |
| 57 .GetActiveRotation(); | 63 .GetActiveRotation(); |
| 58 } | 64 } |
| 59 | 65 |
| 60 bool IsDisplayIdValid(int64_t display_id) { | 66 bool IsDisplayIdValid(int64_t display_id) { |
| 61 return Shell::Get()->display_manager()->IsDisplayIdValid(display_id); | 67 return Shell::Get()->display_manager()->IsDisplayIdValid(display_id); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 rotation_request_id_(0), | 175 rotation_request_id_(0), |
| 170 metrics_reporter_( | 176 metrics_reporter_( |
| 171 base::MakeUnique<ScreenRotationAnimationMetricsReporter>()), | 177 base::MakeUnique<ScreenRotationAnimationMetricsReporter>()), |
| 172 disable_animation_timers_for_test_(false), | 178 disable_animation_timers_for_test_(false), |
| 173 has_switch_ash_disable_smooth_screen_rotation_( | 179 has_switch_ash_disable_smooth_screen_rotation_( |
| 174 base::CommandLine::ForCurrentProcess()->HasSwitch( | 180 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 175 switches::kAshDisableSmoothScreenRotation)), | 181 switches::kAshDisableSmoothScreenRotation)), |
| 176 root_window_(GetRootWindow(display_id_)), | 182 root_window_(GetRootWindow(display_id_)), |
| 177 screen_rotation_container_layer_( | 183 screen_rotation_container_layer_( |
| 178 GetScreenRotationContainer(root_window_)->layer()), | 184 GetScreenRotationContainer(root_window_)->layer()), |
| 179 weak_factory_(this) {} | 185 weak_factory_(this), |
| 186 lock_weak_ptr_factory_(this) {} |
| 180 | 187 |
| 181 ScreenRotationAnimator::~ScreenRotationAnimator() { | 188 ScreenRotationAnimator::~ScreenRotationAnimator() { |
| 189 lock_weak_ptr_factory_.InvalidateWeakPtrs(); |
| 182 // To prevent a call to |AnimationEndedCallback()| from calling a method on | 190 // To prevent a call to |AnimationEndedCallback()| from calling a method on |
| 183 // the |animator_|. | 191 // the |animator_|. |
| 184 weak_factory_.InvalidateWeakPtrs(); | 192 weak_factory_.InvalidateWeakPtrs(); |
| 185 | 193 |
| 186 // Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in | 194 // Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in |
| 187 // order to make sure |metrics_reporter_| outlives the attached animation | 195 // order to make sure |metrics_reporter_| outlives the attached animation |
| 188 // sequence. | 196 // sequence. |
| 189 old_layer_tree_owner_.reset(); | 197 old_layer_tree_owner_.reset(); |
| 190 metrics_reporter_.reset(); | 198 metrics_reporter_.reset(); |
| 191 } | 199 } |
| 192 | 200 |
| 193 void ScreenRotationAnimator::StartRotationAnimation( | 201 void ScreenRotationAnimator::StartRotationAnimation( |
| 194 std::unique_ptr<ScreenRotationRequest> rotation_request) { | 202 std::unique_ptr<ScreenRotationRequest> rotation_request) { |
| 195 const display::Display::Rotation current_rotation = | 203 const display::Display::Rotation current_rotation = |
| 196 GetCurrentScreenRotation(display_id_); | 204 GetCurrentScreenRotation(display_id_); |
| 197 if (current_rotation == rotation_request->new_rotation) { | 205 if (current_rotation == rotation_request->new_rotation) { |
| 198 // We need to call |ProcessAnimationQueue()| to prepare for next rotation | 206 // We need to call |ProcessAnimationQueue()| to prepare for next rotation |
| 199 // request. | 207 // request. |
| 200 ProcessAnimationQueue(); | 208 ProcessAnimationQueue(); |
| 201 return; | 209 return; |
| 202 } | 210 } |
| 203 | 211 |
| 212 // The |ScreenRotationAnimatorLock| will be reset in |ProcessAnimationQueue| |
| 213 // when animation is finished. |
| 214 // |ScreenRotationAnimatorLock| will only work in the smooth animation. But |
| 215 // for simplicity, set/reset the lock for both slow/smooth animation. |
| 216 // If we need to wait for multiple event, e.g. ARC app resize, we can add more |
| 217 // locks here. |
| 218 Shell::Get()->wallpaper_controller()->SetScreenRotationAnimatorLock( |
| 219 CreateAnimatorLock()); |
| 204 rotation_request->old_rotation = current_rotation; | 220 rotation_request->old_rotation = current_rotation; |
| 205 if (has_switch_ash_disable_smooth_screen_rotation_) { | 221 if (has_switch_ash_disable_smooth_screen_rotation_) { |
| 206 StartSlowAnimation(std::move(rotation_request)); | 222 StartSlowAnimation(std::move(rotation_request)); |
| 207 } else { | 223 } else { |
| 208 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = | 224 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = |
| 209 cc::CopyOutputRequest::CreateRequest( | 225 cc::CopyOutputRequest::CreateRequest( |
| 210 CreateAfterCopyCallbackBeforeRotation(std::move(rotation_request))); | 226 CreateAfterCopyCallbackBeforeRotation(std::move(rotation_request))); |
| 211 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); | 227 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); |
| 212 screen_rotation_state_ = COPY_REQUESTED; | 228 screen_rotation_state_ = COPY_REQUESTED; |
| 213 } | 229 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 Shell::Get()->display_manager()->SetDisplayRotation( | 294 Shell::Get()->display_manager()->SetDisplayRotation( |
| 279 display_id_, rotation_request->new_rotation, rotation_request->source); | 295 display_id_, rotation_request->new_rotation, rotation_request->source); |
| 280 ProcessAnimationQueue(); | 296 ProcessAnimationQueue(); |
| 281 return; | 297 return; |
| 282 } | 298 } |
| 283 | 299 |
| 284 old_layer_tree_owner_ = CopyLayerTree(std::move(result)); | 300 old_layer_tree_owner_ = CopyLayerTree(std::move(result)); |
| 285 AddLayerAtTopOfWindowLayers(root_window_, old_layer_tree_owner_->root()); | 301 AddLayerAtTopOfWindowLayers(root_window_, old_layer_tree_owner_->root()); |
| 286 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, | 302 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, |
| 287 rotation_request->source); | 303 rotation_request->source); |
| 288 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = | 304 |
| 289 cc::CopyOutputRequest::CreateRequest( | 305 // If the rotation angle is 180 degree, there is no resize. |
| 290 CreateAfterCopyCallbackAfterRotation(std::move(rotation_request))); | 306 if (Is180DegreeFlip(rotation_request->old_rotation, |
| 291 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); | 307 rotation_request->new_rotation)) { |
| 308 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = |
| 309 cc::CopyOutputRequest::CreateRequest( |
| 310 CreateAfterCopyCallbackAfterRotation(std::move(rotation_request))); |
| 311 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); |
| 312 } else { |
| 313 rotation_request_after_unlock_ = std::move(rotation_request); |
| 314 } |
| 292 } | 315 } |
| 293 | 316 |
| 294 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedAfterRotation( | 317 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedAfterRotation( |
| 295 std::unique_ptr<ScreenRotationRequest> rotation_request, | 318 std::unique_ptr<ScreenRotationRequest> rotation_request, |
| 296 std::unique_ptr<cc::CopyOutputResult> result) { | 319 std::unique_ptr<cc::CopyOutputResult> result) { |
| 297 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) | 320 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) |
| 298 return; | 321 return; |
| 299 // In the following cases, abort animation: | 322 // In the following cases, abort animation: |
| 300 // 1) if the display was removed, | 323 // 1) if the display was removed, |
| 301 // 2) the copy request has been canceled or failed. It would fail if, | 324 // 2) the copy request has been canceled or failed. It would fail if, |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 screen_rotation_animator_observers_.RemoveObserver(observer); | 485 screen_rotation_animator_observers_.RemoveObserver(observer); |
| 463 } | 486 } |
| 464 | 487 |
| 465 void ScreenRotationAnimator::ProcessAnimationQueue() { | 488 void ScreenRotationAnimator::ProcessAnimationQueue() { |
| 466 screen_rotation_state_ = IDLE; | 489 screen_rotation_state_ = IDLE; |
| 467 if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) | 490 if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) |
| 468 root_window_->layer()->Remove(black_mask_layer_owner_->layer()); | 491 root_window_->layer()->Remove(black_mask_layer_owner_->layer()); |
| 469 old_layer_tree_owner_.reset(); | 492 old_layer_tree_owner_.reset(); |
| 470 new_layer_tree_owner_.reset(); | 493 new_layer_tree_owner_.reset(); |
| 471 black_mask_layer_owner_.reset(); | 494 black_mask_layer_owner_.reset(); |
| 495 ResetCreatedAnimatorLocks(); |
| 472 if (last_pending_request_ && IsDisplayIdValid(display_id_)) { | 496 if (last_pending_request_ && IsDisplayIdValid(display_id_)) { |
| 473 StartRotationAnimation(std::move(last_pending_request_)); | 497 StartRotationAnimation(std::move(last_pending_request_)); |
| 474 return; | 498 return; |
| 475 } | 499 } |
| 476 | 500 |
| 477 // This is only used in test to notify animator observer. | 501 // This is only used in test to notify animator observer. |
| 478 for (auto& observer : screen_rotation_animator_observers_) | 502 for (auto& observer : screen_rotation_animator_observers_) |
| 479 observer.OnScreenRotationAnimationFinished(this); | 503 observer.OnScreenRotationAnimationFinished(this); |
| 480 } | 504 } |
| 481 | 505 |
| 482 void ScreenRotationAnimator::StopAnimating() { | 506 void ScreenRotationAnimator::StopAnimating() { |
| 483 // |old_layer_tree_owner_| new_layer_tree_owner_| could be nullptr if another | 507 // |old_layer_tree_owner_| new_layer_tree_owner_| could be nullptr if another |
| 484 // the rotation request comes before the copy request finished. | 508 // the rotation request comes before the copy request finished. |
| 485 if (old_layer_tree_owner_) | 509 if (old_layer_tree_owner_) |
| 486 old_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); | 510 old_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); |
| 487 if (new_layer_tree_owner_) | 511 if (new_layer_tree_owner_) |
| 488 new_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); | 512 new_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); |
| 489 if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) | 513 if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) |
| 490 root_window_->layer()->Remove(black_mask_layer_owner_->layer()); | 514 root_window_->layer()->Remove(black_mask_layer_owner_->layer()); |
| 491 } | 515 } |
| 492 | 516 |
| 517 ScreenRotationAnimatorLock* ScreenRotationAnimator::CreateAnimatorLock() { |
| 518 auto lock_unique_ptr = base::MakeUnique<ScreenRotationAnimatorLock>( |
| 519 lock_weak_ptr_factory_.GetWeakPtr()); |
| 520 auto* lock = lock_unique_ptr.get(); |
| 521 created_locks_.push_back(std::move(lock_unique_ptr)); |
| 522 return lock; |
| 523 } |
| 524 |
| 525 void ScreenRotationAnimator::AddAnimatorLock(ScreenRotationAnimatorLock* lock) { |
| 526 bool was_empty = active_locks_.empty(); |
| 527 active_locks_.push_back(lock); |
| 528 if (was_empty) { |
| 529 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 530 FROM_HERE, |
| 531 base::Bind(&ScreenRotationAnimator::TimeoutAnimatorLocks, |
| 532 lock_weak_ptr_factory_.GetWeakPtr()), |
| 533 base::TimeDelta::FromMilliseconds(kAnimatorLockTimeoutMs)); |
| 534 } |
| 535 } |
| 536 |
| 537 void ScreenRotationAnimator::RemoveAnimatorLock( |
| 538 ScreenRotationAnimatorLock* lock) { |
| 539 base::Erase(active_locks_, lock); |
| 540 if (active_locks_.empty()) { |
| 541 lock_weak_ptr_factory_.InvalidateWeakPtrs(); |
| 542 // If we are waiting for the lock, we should send the second copy request |
| 543 // after screen rotation. |
| 544 if (rotation_request_after_unlock_) { |
| 545 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = |
| 546 cc::CopyOutputRequest::CreateRequest( |
| 547 CreateAfterCopyCallbackAfterRotation( |
| 548 std::move(rotation_request_after_unlock_))); |
| 549 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); |
| 550 } |
| 551 } |
| 552 } |
| 553 |
| 554 void ScreenRotationAnimator::TimeoutAnimatorLocks() { |
| 555 // Make a copy, we're going to cause |active_locks_| to become |
| 556 // empty |
| 557 std::vector<ScreenRotationAnimatorLock*> locks = active_locks_; |
| 558 for (auto* lock : locks) |
| 559 lock->TimeoutLock(); |
| 560 DCHECK(active_locks_.empty()); |
| 561 } |
| 562 |
| 563 void ScreenRotationAnimator::ResetCreatedAnimatorLocks() { |
| 564 created_locks_.clear(); |
| 565 active_locks_.clear(); |
| 566 } |
| 567 |
| 493 } // namespace ash | 568 } // namespace ash |
| OLD | NEW |