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

Unified Diff: ash/rotator/screen_rotation_animator.cc

Issue 2848883004: Add screen rotation animator lock. (Closed)
Patch Set: Created 3 years, 8 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ash/rotator/screen_rotation_animator.cc
diff --git a/ash/rotator/screen_rotation_animator.cc b/ash/rotator/screen_rotation_animator.cc
index 31a54537dd859ca1f3d8535baabb1442e81af0d6..f52bdb723306525b2ebae1c88afc5025a93e4783 100644
--- a/ash/rotator/screen_rotation_animator.cc
+++ b/ash/rotator/screen_rotation_animator.cc
@@ -8,12 +8,15 @@
#include "ash/display/window_tree_host_manager.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/rotator/screen_rotation_animation.h"
+#include "ash/rotator/screen_rotation_animator_lock.h"
#include "ash/rotator/screen_rotation_animator_observer.h"
#include "ash/shell.h"
#include "ash/utility/transformer_util.h"
+#include "ash/wallpaper/wallpaper_controller.h"
#include "base/command_line.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
+#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
@@ -41,14 +44,17 @@ namespace ash {
namespace {
// The number of degrees that the rotation animations animate through.
-const int kRotationDegrees = 20;
+constexpr int kRotationDegrees = 20;
// The time it takes for the rotation animations to run.
-const int kRotationDurationInMs = 250;
+constexpr int kRotationDurationInMs = 250;
+
+// The timeout for waiting |ScreenRotationAnimatorLock|.
+constexpr int kAnimatorLockTimeoutMs = 500;
// The rotation factors.
-const int kCounterClockWiseRotationFactor = 1;
-const int kClockWiseRotationFactor = -1;
+constexpr int kCounterClockWiseRotationFactor = 1;
+constexpr int kClockWiseRotationFactor = -1;
display::Display::Rotation GetCurrentScreenRotation(int64_t display_id) {
return Shell::Get()
@@ -176,9 +182,11 @@ ScreenRotationAnimator::ScreenRotationAnimator(int64_t display_id)
root_window_(GetRootWindow(display_id_)),
screen_rotation_container_layer_(
GetScreenRotationContainer(root_window_)->layer()),
- weak_factory_(this) {}
+ weak_factory_(this),
+ lock_weak_ptr_factory_(this) {}
ScreenRotationAnimator::~ScreenRotationAnimator() {
+ lock_weak_ptr_factory_.InvalidateWeakPtrs();
// To prevent a call to |AnimationEndedCallback()| from calling a method on
// the |animator_|.
weak_factory_.InvalidateWeakPtrs();
@@ -201,6 +209,14 @@ void ScreenRotationAnimator::StartRotationAnimation(
return;
}
+ // The |ScreenRotationAnimatorLock| will be reset in |ProcessAnimationQueue|
+ // when animation is finished.
+ // |ScreenRotationAnimatorLock| will only work in the smooth animation. But
+ // for simplicity, set/reset the lock for both slow/smooth animation.
+ // If we need to wait for multiple event, e.g. ARC app resize, we can add more
+ // locks here.
+ Shell::Get()->wallpaper_controller()->SetScreenRotationAnimatorLock(
+ CreateAnimatorLock());
rotation_request->old_rotation = current_rotation;
if (has_switch_ash_disable_smooth_screen_rotation_) {
StartSlowAnimation(std::move(rotation_request));
@@ -285,10 +301,17 @@ void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedBeforeRotation(
AddLayerAtTopOfWindowLayers(root_window_, old_layer_tree_owner_->root());
SetRotation(rotation_request->old_rotation, rotation_request->new_rotation,
rotation_request->source);
- std::unique_ptr<cc::CopyOutputRequest> copy_output_request =
- cc::CopyOutputRequest::CreateRequest(
- CreateAfterCopyCallbackAfterRotation(std::move(rotation_request)));
- RequestCopyScreenRotationContainerLayer(std::move(copy_output_request));
+
+ // If the rotation angle is 180 degree, there is no resize.
+ if (Is180DegreeFlip(rotation_request->old_rotation,
+ rotation_request->new_rotation)) {
+ std::unique_ptr<cc::CopyOutputRequest> copy_output_request =
+ cc::CopyOutputRequest::CreateRequest(
+ CreateAfterCopyCallbackAfterRotation(std::move(rotation_request)));
+ RequestCopyScreenRotationContainerLayer(std::move(copy_output_request));
+ } else {
+ rotation_request_after_unlock_ = std::move(rotation_request);
+ }
}
void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedAfterRotation(
@@ -469,6 +492,7 @@ void ScreenRotationAnimator::ProcessAnimationQueue() {
old_layer_tree_owner_.reset();
new_layer_tree_owner_.reset();
black_mask_layer_owner_.reset();
+ ResetCreatedAnimatorLocks();
if (last_pending_request_ && IsDisplayIdValid(display_id_)) {
StartRotationAnimation(std::move(last_pending_request_));
return;
@@ -490,4 +514,55 @@ void ScreenRotationAnimator::StopAnimating() {
root_window_->layer()->Remove(black_mask_layer_owner_->layer());
}
+ScreenRotationAnimatorLock* ScreenRotationAnimator::CreateAnimatorLock() {
+ auto lock_unique_ptr = base::MakeUnique<ScreenRotationAnimatorLock>(
+ lock_weak_ptr_factory_.GetWeakPtr());
+ auto* lock = lock_unique_ptr.get();
+ created_locks_.push_back(std::move(lock_unique_ptr));
+ return lock;
+}
+
+void ScreenRotationAnimator::AddAnimatorLock(ScreenRotationAnimatorLock* lock) {
+ bool was_empty = active_locks_.empty();
+ active_locks_.push_back(lock);
+ if (was_empty) {
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&ScreenRotationAnimator::TimeoutAnimatorLocks,
+ lock_weak_ptr_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kAnimatorLockTimeoutMs));
+ }
+}
+
+void ScreenRotationAnimator::RemoveAnimatorLock(
+ ScreenRotationAnimatorLock* lock) {
+ base::Erase(active_locks_, lock);
+ if (active_locks_.empty()) {
+ lock_weak_ptr_factory_.InvalidateWeakPtrs();
+ // If we are waiting for the lock, we should send the second copy request
+ // after screen rotation.
+ if (rotation_request_after_unlock_) {
+ std::unique_ptr<cc::CopyOutputRequest> copy_output_request =
+ cc::CopyOutputRequest::CreateRequest(
+ CreateAfterCopyCallbackAfterRotation(
+ std::move(rotation_request_after_unlock_)));
+ RequestCopyScreenRotationContainerLayer(std::move(copy_output_request));
+ }
+ }
+}
+
+void ScreenRotationAnimator::TimeoutAnimatorLocks() {
+ // Make a copy, we're going to cause |active_locks_| to become
+ // empty
+ std::vector<ScreenRotationAnimatorLock*> locks = active_locks_;
+ for (auto* lock : locks)
+ lock->TimeoutLock();
+ DCHECK(active_locks_.empty());
+}
+
+void ScreenRotationAnimator::ResetCreatedAnimatorLocks() {
+ created_locks_.clear();
+ active_locks_.clear();
+}
+
} // namespace ash
« 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