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

Side by Side Diff: ash/rotator/screen_rotation_animator.cc

Issue 2848883004: Add screen rotation animator lock. (Closed)
Patch Set: Created 3 years, 7 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
« no previous file with comments | « ash/rotator/screen_rotation_animator.h ('k') | ash/rotator/screen_rotation_animator_lock.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « ash/rotator/screen_rotation_animator.h ('k') | ash/rotator/screen_rotation_animator_lock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698