Index: ash/rotator/screen_rotation_animator.cc |
diff --git a/ash/rotator/screen_rotation_animator.cc b/ash/rotator/screen_rotation_animator.cc |
index f1c51a4c70edb8a1783d996859033570c3e60f9e..9c6bf5f6a265e267233df974a15b4f00b9571f2f 100644 |
--- a/ash/rotator/screen_rotation_animator.cc |
+++ b/ash/rotator/screen_rotation_animator.cc |
@@ -4,16 +4,13 @@ |
#include "ash/rotator/screen_rotation_animator.h" |
-#include <string> |
-#include <utility> |
-#include <vector> |
- |
#include "ash/ash_switches.h" |
#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_observer.h" |
#include "ash/shell.h" |
+#include "ash/utility/transformer_util.h" |
#include "base/command_line.h" |
#include "base/memory/ptr_util.h" |
#include "base/metrics/histogram_macros.h" |
@@ -21,9 +18,9 @@ |
#include "cc/output/copy_output_request.h" |
#include "cc/output/copy_output_result.h" |
#include "ui/aura/window.h" |
+#include "ui/compositor/callback_layer_animation_observer.h" |
#include "ui/compositor/layer.h" |
#include "ui/compositor/layer_animation_element.h" |
-#include "ui/compositor/layer_animation_observer.h" |
#include "ui/compositor/layer_animation_sequence.h" |
#include "ui/compositor/layer_animator.h" |
#include "ui/compositor/layer_owner.h" |
@@ -77,6 +74,10 @@ aura::Window* GetRootWindow(int64_t display_id) { |
display_id); |
} |
+aura::Window* GetScreenRotationContainer(aura::Window* root_window) { |
+ return root_window->GetChildById(kShellWindowId_ScreenRotationContainer); |
+} |
+ |
// Returns true if the rotation between |initial_rotation| and |new_rotation| is |
// 180 degrees. |
bool Is180DegreeFlip(display::Display::Rotation initial_rotation, |
@@ -90,78 +91,70 @@ int GetInitialDegrees(display::Display::Rotation initial_rotation, |
return (Is180DegreeFlip(initial_rotation, new_rotation) ? 180 : 90); |
} |
-// A LayerAnimationObserver that will destroy the contained LayerTreeOwner |
-// when notified that a layer animation has ended or was aborted. |
-class LayerCleanupObserver : public ui::LayerAnimationObserver { |
- public: |
- // Takes WeakPtr of ScreenRotationAnimator. |this| may outlive the |animator_| |
- // instance and the |animator_| isn't detaching itself as an observer when |
- // being destroyed. However, ideally, when |animator_| is destroying, |
- // deleting |old_layer_tree_owner_| will trigger OnLayerAnimationAborted and |
- // delete |this| before |animator_| deleted. |
- explicit LayerCleanupObserver(base::WeakPtr<ScreenRotationAnimator> animator); |
- ~LayerCleanupObserver() override; |
- |
- // ui::LayerAnimationObserver: |
- void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override; |
- void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override; |
- void OnLayerAnimationScheduled( |
- ui::LayerAnimationSequence* sequence) override {} |
- |
- protected: |
- // ui::LayerAnimationObserver: |
- bool RequiresNotificationWhenAnimatorDestroyed() const override { |
- return true; |
- } |
- void OnAttachedToSequence(ui::LayerAnimationSequence* sequence) override; |
- void OnDetachedFromSequence(ui::LayerAnimationSequence* sequence) override; |
- |
- private: |
- base::WeakPtr<ScreenRotationAnimator> animator_; |
- |
- // The LayerAnimationSequence that |this| has been attached to. Defaults to |
- // nullptr. |
- ui::LayerAnimationSequence* sequence_; |
- |
- DISALLOW_COPY_AND_ASSIGN(LayerCleanupObserver); |
-}; |
- |
-LayerCleanupObserver::LayerCleanupObserver( |
- base::WeakPtr<ScreenRotationAnimator> animator) |
- : animator_(animator), sequence_(nullptr) {} |
- |
-LayerCleanupObserver::~LayerCleanupObserver() { |
- // We must eplicitly detach from |sequence_| because we return true from |
- // RequiresNotificationWhenAnimatorDestroyed. |
- if (sequence_) |
- sequence_->RemoveObserver(this); |
+void AddLayerAtTopOfWindowLayers(aura::Window* root_window, ui::Layer* layer) { |
+ // Add the cloned/copied layer tree into the root, so it will be rendered. |
+ root_window->layer()->Add(layer); |
+ root_window->layer()->StackAtTop(layer); |
} |
-void LayerCleanupObserver::OnLayerAnimationEnded( |
- ui::LayerAnimationSequence* sequence) { |
- if (animator_) |
- animator_->ProcessAnimationQueue(); |
+void AddLayerBelowWindowLayer(aura::Window* root_window, |
+ ui::Layer* top_layer, |
+ ui::Layer* layer) { |
+ // Add the cloned/copied layer tree into the root, so it will be rendered. |
+ root_window->layer()->Add(layer); |
+ root_window->layer()->StackBelow(layer, top_layer); |
+} |
- delete this; |
+// The Callback will be invoked when all animation sequences have |
+// finished. |observer| will be destroyed after invoking the Callback if it |
+// returns true. |
+bool AnimationEndedCallback( |
+ base::WeakPtr<ScreenRotationAnimator> animator, |
+ const ui::CallbackLayerAnimationObserver& observer) { |
+ if (animator) |
+ animator->ProcessAnimationQueue(); |
+ return true; |
} |
-void LayerCleanupObserver::OnLayerAnimationAborted( |
- ui::LayerAnimationSequence* sequence) { |
- if (animator_) |
- animator_->ProcessAnimationQueue(); |
+// Creates a Transform for the old layer in screen rotation animation. |
+gfx::Transform CreateScreenRotationOldLayerTransformForDisplay( |
+ display::Display::Rotation old_rotation, |
+ display::Display::Rotation new_rotation, |
+ const display::Display& display) { |
+ gfx::Transform inverse; |
+ CHECK(CreateRotationTransform(old_rotation, new_rotation, display) |
+ .GetInverse(&inverse)); |
+ return inverse; |
+} |
- delete this; |
+// The |request_id| changed since last copy request, which means a |
+// new rotation stated, we need to ignore this copy result. |
+bool IgnoreCopyResult(int64_t request_id, int64_t current_request_id) { |
+ DCHECK(request_id <= current_request_id); |
+ return request_id < current_request_id; |
} |
-void LayerCleanupObserver::OnAttachedToSequence( |
- ui::LayerAnimationSequence* sequence) { |
- sequence_ = sequence; |
+// In the following cases, abort rotation: |
+// 1) if the display was removed, |
+// 2) the copy request has been canceled or failed. It would fail if, |
+// for examples: a) The layer is removed from the compositor and destroye |
+// before committing the request to the compositor. b) The compositor is |
+// shutdown. |
+bool AbortRotation(int64_t display_id, cc::CopyOutputResult* result) { |
+ return !IsDisplayIdValid(display_id) || result->IsEmpty(); |
} |
-void LayerCleanupObserver::OnDetachedFromSequence( |
- ui::LayerAnimationSequence* sequence) { |
- DCHECK_EQ(sequence, sequence_); |
- sequence_ = nullptr; |
+// Creates a black mask layer and returns the |layer_owner|. |
+std::unique_ptr<ui::LayerOwner> CreateBlackMaskLayerOwner( |
+ const gfx::Rect& rect) { |
+ std::unique_ptr<ui::Layer> black_mask_layer = |
+ base::MakeUnique<ui::Layer>(ui::LAYER_SOLID_COLOR); |
+ black_mask_layer->SetBounds(rect); |
+ black_mask_layer->SetColor(SK_ColorBLACK); |
+ std::unique_ptr<ui::LayerOwner> black_mask_layer_owner = |
+ base::MakeUnique<ui::LayerOwner>(); |
+ black_mask_layer_owner->SetLayer(std::move(black_mask_layer)); |
+ return black_mask_layer_owner; |
} |
class ScreenRotationAnimationMetricsReporter |
@@ -187,11 +180,17 @@ ScreenRotationAnimator::ScreenRotationAnimator(int64_t display_id) |
metrics_reporter_( |
base::MakeUnique<ScreenRotationAnimationMetricsReporter>()), |
disable_animation_timers_for_test_(false), |
+ has_switch_ash_enable_smooth_screen_rotation_( |
+ base::CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kAshEnableSmoothScreenRotation)), |
+ root_window_(GetRootWindow(display_id_)), |
+ screen_rotation_container_layer_( |
+ GetScreenRotationContainer(root_window_)->layer()), |
weak_factory_(this) {} |
ScreenRotationAnimator::~ScreenRotationAnimator() { |
- // To prevent a call to |LayerCleanupObserver::OnLayerAnimationAborted()| from |
- // calling a method on the |animator_|. |
+ // To prevent a call to |AnimationEndedCallback()| from calling a method on |
+ // the |animator_|. |
weak_factory_.InvalidateWeakPtrs(); |
// Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in |
@@ -203,133 +202,175 @@ ScreenRotationAnimator::~ScreenRotationAnimator() { |
void ScreenRotationAnimator::StartRotationAnimation( |
std::unique_ptr<ScreenRotationRequest> rotation_request) { |
- if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
- switches::kAshEnableSmoothScreenRotation)) { |
- RequestCopyRootLayerAndAnimateRotation(std::move(rotation_request)); |
+ const display::Display::Rotation current_rotation = |
+ GetCurrentScreenRotation(display_id_); |
+ if (current_rotation == rotation_request->new_rotation) { |
+ // We need to call |ProcessAnimationQueue()| to prepare for next rotation |
+ // request. |
+ ProcessAnimationQueue(); |
+ return; |
+ } |
+ |
+ rotation_request->old_rotation = current_rotation; |
+ if (has_switch_ash_enable_smooth_screen_rotation_) { |
+ std::unique_ptr<cc::CopyOutputRequest> copy_output_request = |
+ cc::CopyOutputRequest::CreateRequest( |
+ CreateAfterCopyCallbackBeforeRotation(std::move(rotation_request))); |
+ RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); |
+ screen_rotation_state_ = COPY_REQUESTED; |
} else { |
- CreateOldLayerTree(); |
- AnimateRotation(std::move(rotation_request)); |
+ StartSlowAnimation(std::move(rotation_request)); |
} |
} |
-void ScreenRotationAnimator::RequestCopyRootLayerAndAnimateRotation( |
+void ScreenRotationAnimator::StartSlowAnimation( |
std::unique_ptr<ScreenRotationRequest> rotation_request) { |
- std::unique_ptr<cc::CopyOutputRequest> copy_output_request = |
- cc::CopyOutputRequest::CreateRequest( |
- CreateAfterCopyCallback(std::move(rotation_request))); |
- ui::Layer* layer = GetRootWindow(display_id_)->layer(); |
- copy_output_request->set_area(gfx::Rect(layer->size())); |
- layer->RequestCopyOfOutput(std::move(copy_output_request)); |
+ CreateOldLayerTreeForSlowAnimation(); |
+ SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, |
+ rotation_request->source); |
+ AnimateRotation(std::move(rotation_request)); |
+} |
+ |
+void ScreenRotationAnimator::SetRotation( |
+ display::Display::Rotation old_rotation, |
+ display::Display::Rotation new_rotation, |
+ display::Display::RotationSource source) { |
+ Shell::Get()->display_manager()->SetDisplayRotation(display_id_, new_rotation, |
+ source); |
+ const display::Display display = |
+ Shell::Get()->display_manager()->GetDisplayForId(display_id_); |
+ old_layer_tree_owner_->root()->SetTransform( |
+ CreateScreenRotationOldLayerTransformForDisplay(old_rotation, |
+ new_rotation, display)); |
+} |
+ |
+void ScreenRotationAnimator::RequestCopyScreenRotationContainerLayer( |
+ std::unique_ptr<cc::CopyOutputRequest> copy_output_request) { |
+ copy_output_request->set_area( |
+ gfx::Rect(screen_rotation_container_layer_->size())); |
+ screen_rotation_container_layer_->RequestCopyOfOutput( |
+ std::move(copy_output_request)); |
+} |
- screen_rotation_state_ = COPY_REQUESTED; |
+ScreenRotationAnimator::CopyCallback |
+ScreenRotationAnimator::CreateAfterCopyCallbackBeforeRotation( |
+ std::unique_ptr<ScreenRotationRequest> rotation_request) { |
+ return base::Bind(&ScreenRotationAnimator:: |
+ OnScreenRotationContainerLayerCopiedBeforeRotation, |
+ weak_factory_.GetWeakPtr(), |
+ base::Passed(&rotation_request)); |
} |
ScreenRotationAnimator::CopyCallback |
-ScreenRotationAnimator::CreateAfterCopyCallback( |
+ScreenRotationAnimator::CreateAfterCopyCallbackAfterRotation( |
std::unique_ptr<ScreenRotationRequest> rotation_request) { |
- return base::Bind(&ScreenRotationAnimator::OnRootLayerCopiedBeforeRotation, |
+ return base::Bind(&ScreenRotationAnimator:: |
+ OnScreenRotationContainerLayerCopiedAfterRotation, |
weak_factory_.GetWeakPtr(), |
base::Passed(&rotation_request)); |
} |
-void ScreenRotationAnimator::OnRootLayerCopiedBeforeRotation( |
+void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedBeforeRotation( |
std::unique_ptr<ScreenRotationRequest> rotation_request, |
std::unique_ptr<cc::CopyOutputResult> result) { |
- DCHECK(rotation_request->id <= rotation_request_id_); |
- // The |rotation_request_id_| changed since last copy request, which means a |
- // new rotation stated, we need to ignore this copy result. |
- if (rotation_request->id < rotation_request_id_) |
+ if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) |
+ return; |
+ if (AbortRotation(display_id_, result.get())) { |
+ ProcessAnimationQueue(); |
return; |
+ } |
- // In the following cases, abort rotation: |
- // 1) if the display was removed, |
- // 2) the copy request has been canceled or failed. It would fail if, |
- // for examples: a) The layer is removed from the compositor and destroye |
- // before committing the request to the compositor. b) The compositor is |
- // shutdown. |
- if (!IsDisplayIdValid(display_id_) || result->IsEmpty()) { |
+ old_layer_tree_owner_ = CopyLayerTree(std::move(result)); |
+ 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)); |
+} |
+ |
+void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedAfterRotation( |
+ std::unique_ptr<ScreenRotationRequest> rotation_request, |
+ std::unique_ptr<cc::CopyOutputResult> result) { |
+ if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) |
+ return; |
+ if (AbortRotation(display_id_, result.get())) { |
ProcessAnimationQueue(); |
return; |
} |
- CopyOldLayerTree(std::move(result)); |
+ new_layer_tree_owner_ = CopyLayerTree(std::move(result)); |
+ AddLayerBelowWindowLayer(root_window_, old_layer_tree_owner_->root(), |
+ new_layer_tree_owner_->root()); |
AnimateRotation(std::move(rotation_request)); |
} |
-void ScreenRotationAnimator::CreateOldLayerTree() { |
- old_layer_tree_owner_ = ::wm::RecreateLayers(GetRootWindow(display_id_)); |
+void ScreenRotationAnimator::CreateOldLayerTreeForSlowAnimation() { |
+ old_layer_tree_owner_ = ::wm::RecreateLayers(root_window_); |
+ // |screen_rotation_container_layer_| needs update after |RecreateLayers()|. |
+ screen_rotation_container_layer_ = |
+ GetScreenRotationContainer(root_window_)->layer(); |
+ AddLayerAtTopOfWindowLayers(root_window_, old_layer_tree_owner_->root()); |
} |
-void ScreenRotationAnimator::CopyOldLayerTree( |
+std::unique_ptr<ui::LayerTreeOwner> ScreenRotationAnimator::CopyLayerTree( |
std::unique_ptr<cc::CopyOutputResult> result) { |
cc::TextureMailbox texture_mailbox; |
std::unique_ptr<cc::SingleReleaseCallback> release_callback; |
result->TakeTexture(&texture_mailbox, &release_callback); |
DCHECK(texture_mailbox.IsTexture()); |
- aura::Window* root_window = GetRootWindow(display_id_); |
- gfx::Rect rect(root_window->layer()->size()); |
+ const gfx::Rect rect(screen_rotation_container_layer_->size()); |
std::unique_ptr<ui::Layer> copy_layer = base::MakeUnique<ui::Layer>(); |
copy_layer->SetBounds(rect); |
copy_layer->SetTextureMailbox(texture_mailbox, std::move(release_callback), |
rect.size()); |
- old_layer_tree_owner_ = |
- base::MakeUnique<ui::LayerTreeOwner>(std::move(copy_layer)); |
+ return base::MakeUnique<ui::LayerTreeOwner>(std::move(copy_layer)); |
} |
void ScreenRotationAnimator::AnimateRotation( |
std::unique_ptr<ScreenRotationRequest> rotation_request) { |
screen_rotation_state_ = ROTATING; |
- |
- aura::Window* root_window = GetRootWindow(display_id_); |
- std::unique_ptr<LayerCleanupObserver> old_layer_cleanup_observer( |
- new LayerCleanupObserver(weak_factory_.GetWeakPtr())); |
- ui::Layer* old_root_layer = old_layer_tree_owner_->root(); |
- old_root_layer->set_name("ScreenRotationAnimator:old_layer_tree"); |
- // Add the cloned layer tree in to the root, so it will be rendered. |
- root_window->layer()->Add(old_root_layer); |
- root_window->layer()->StackAtTop(old_root_layer); |
- |
- const gfx::Rect original_screen_bounds = root_window->GetTargetBounds(); |
- |
- const int rotation_factor = GetRotationFactor( |
- GetCurrentScreenRotation(display_id_), rotation_request->new_rotation); |
- |
+ const int rotation_factor = GetRotationFactor(rotation_request->old_rotation, |
+ rotation_request->new_rotation); |
const int old_layer_initial_rotation_degrees = GetInitialDegrees( |
- GetCurrentScreenRotation(display_id_), rotation_request->new_rotation); |
- |
+ rotation_request->old_rotation, rotation_request->new_rotation); |
const base::TimeDelta duration = |
base::TimeDelta::FromMilliseconds(kRotationDurationInMs); |
- |
const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN; |
- |
- Shell::Get()->display_manager()->SetDisplayRotation( |
- display_id_, rotation_request->new_rotation, rotation_request->source); |
- |
- const gfx::Rect rotated_screen_bounds = root_window->GetTargetBounds(); |
+ const gfx::Rect rotated_screen_bounds = root_window_->GetTargetBounds(); |
const gfx::Point pivot = gfx::Point(rotated_screen_bounds.width() / 2, |
rotated_screen_bounds.height() / 2); |
- ui::Layer* screen_rotation_container_layer = |
- root_window->GetChildById(kShellWindowId_ScreenRotationContainer) |
- ->layer(); |
- std::unique_ptr<ScreenRotationAnimation> current_layer_screen_rotation = |
+ ui::Layer* new_root_layer; |
+ if (new_layer_tree_owner_ && has_switch_ash_enable_smooth_screen_rotation_) { |
+ new_root_layer = new_layer_tree_owner_->root(); |
+ // Add a black mask layer on top of |screen_rotation_container_layer_|. |
+ black_mask_layer_owner_ = CreateBlackMaskLayerOwner( |
+ gfx::Rect(screen_rotation_container_layer_->size())); |
+ AddLayerBelowWindowLayer(root_window_, new_root_layer, |
+ black_mask_layer_owner_->layer()); |
+ } else { |
+ new_root_layer = screen_rotation_container_layer_; |
+ } |
+ |
+ std::unique_ptr<ScreenRotationAnimation> new_layer_screen_rotation = |
base::MakeUnique<ScreenRotationAnimation>( |
- screen_rotation_container_layer, kRotationDegrees * rotation_factor, |
- 0 /* end_degrees */, screen_rotation_container_layer->opacity(), |
- screen_rotation_container_layer->opacity() /* target_opacity */, |
- pivot, duration, tween_type); |
- |
- ui::LayerAnimator* current_layer_animator = |
- screen_rotation_container_layer->GetAnimator(); |
- current_layer_animator->set_preemption_strategy( |
+ new_root_layer, kRotationDegrees * rotation_factor, |
+ 0 /* end_degrees */, new_root_layer->opacity(), |
+ new_root_layer->opacity() /* target_opacity */, pivot, duration, |
+ tween_type); |
+ |
+ ui::LayerAnimator* new_layer_animator = new_root_layer->GetAnimator(); |
+ new_layer_animator->set_preemption_strategy( |
ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS); |
- std::unique_ptr<ui::LayerAnimationSequence> current_layer_animation_sequence = |
+ std::unique_ptr<ui::LayerAnimationSequence> new_layer_animation_sequence = |
base::MakeUnique<ui::LayerAnimationSequence>( |
- std::move(current_layer_screen_rotation)); |
- current_layer_animator->StartAnimation( |
- current_layer_animation_sequence.release()); |
+ std::move(new_layer_screen_rotation)); |
+ ui::Layer* old_root_layer = old_layer_tree_owner_->root(); |
+ const gfx::Rect original_screen_bounds = old_root_layer->GetTargetBounds(); |
// The old layer will also be transformed into the new orientation. We will |
// translate it so that the old layer's center point aligns with the new |
// orientation's center point and use that center point as the pivot for the |
@@ -354,31 +395,41 @@ void ScreenRotationAnimator::AnimateRotation( |
std::unique_ptr<ui::LayerAnimationSequence> old_layer_animation_sequence = |
base::MakeUnique<ui::LayerAnimationSequence>( |
std::move(old_layer_screen_rotation)); |
- // Add an observer so that the cloned layers can be cleaned up with the |
- // animation completes/aborts. |
- old_layer_animation_sequence->AddObserver( |
- old_layer_cleanup_observer.release()); |
+ |
// In unit test, we can use ash::test::ScreenRotationAnimatorTestApi to |
// control the animation. |
- if (disable_animation_timers_for_test_) |
+ if (disable_animation_timers_for_test_) { |
+ if (new_layer_tree_owner_) |
+ new_layer_animator->set_disable_timer_for_test(true); |
old_layer_animator->set_disable_timer_for_test(true); |
+ } |
old_layer_animation_sequence->SetAnimationMetricsReporter( |
metrics_reporter_.get()); |
- old_layer_animator->StartAnimation(old_layer_animation_sequence.release()); |
- rotation_request.reset(); |
+ // Add an observer so that the cloned/copied layers can be cleaned up with the |
+ // animation completes/aborts. |
+ ui::CallbackLayerAnimationObserver* observer = |
+ new ui::CallbackLayerAnimationObserver( |
+ base::Bind(&AnimationEndedCallback, weak_factory_.GetWeakPtr())); |
+ if (new_layer_tree_owner_) |
+ new_layer_animator->AddObserver(observer); |
+ new_layer_animator->StartAnimation(new_layer_animation_sequence.release()); |
+ old_layer_animator->AddObserver(observer); |
+ old_layer_animator->StartAnimation(old_layer_animation_sequence.release()); |
+ observer->SetActive(); |
} |
void ScreenRotationAnimator::Rotate(display::Display::Rotation new_rotation, |
display::Display::RotationSource source) { |
- if (GetCurrentScreenRotation(display_id_) == new_rotation) |
- return; |
- |
+ // |rotation_request_id_| is used to skip stale requests. Before the layer |
+ // CopyOutputResult callback called, there could have new rotation request. |
+ // Increases |rotation_request_id_| for each new request and in the callback, |
+ // we compare the |rotation_request.id| and |rotation_request_id_| to |
+ // determine the stale status. |
rotation_request_id_++; |
std::unique_ptr<ScreenRotationRequest> rotation_request = |
base::MakeUnique<ScreenRotationRequest>(rotation_request_id_, |
new_rotation, source); |
- |
switch (screen_rotation_state_) { |
case IDLE: |
case COPY_REQUESTED: |
@@ -387,8 +438,7 @@ void ScreenRotationAnimator::Rotate(display::Display::Rotation new_rotation, |
case ROTATING: |
last_pending_request_ = std::move(rotation_request); |
// The pending request will be processed when the |
- // OnLayerAnimation(Ended|Aborted) methods should be called after |
- // |StopAnimating()|. |
+ // |AnimationEndedCallback()| should be called after |StopAnimating()|. |
StopAnimating(); |
break; |
} |
@@ -406,33 +456,30 @@ void ScreenRotationAnimator::RemoveScreenRotationAnimatorObserver( |
void ScreenRotationAnimator::ProcessAnimationQueue() { |
screen_rotation_state_ = IDLE; |
+ if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) |
+ root_window_->layer()->Remove(black_mask_layer_owner_->layer()); |
old_layer_tree_owner_.reset(); |
+ new_layer_tree_owner_.reset(); |
+ black_mask_layer_owner_.reset(); |
if (last_pending_request_ && IsDisplayIdValid(display_id_)) { |
- display::Display::Rotation new_rotation = |
- last_pending_request_->new_rotation; |
- display::Display::RotationSource source = last_pending_request_->source; |
- last_pending_request_.reset(); |
- Rotate(new_rotation, source); |
+ StartRotationAnimation(std::move(last_pending_request_)); |
return; |
} |
+ // This is only used in test to notify animator observer. |
for (auto& observer : screen_rotation_animator_observers_) |
observer.OnScreenRotationAnimationFinished(this); |
} |
-void ScreenRotationAnimator::set_disable_animation_timers_for_test( |
- bool disable_timers) { |
- disable_animation_timers_for_test_ = disable_timers; |
-} |
- |
void ScreenRotationAnimator::StopAnimating() { |
- GetRootWindow(display_id_) |
- ->GetChildById(kShellWindowId_ScreenRotationContainer) |
- ->layer() |
- ->GetAnimator() |
- ->StopAnimating(); |
+ // |old_layer_tree_owner_| new_layer_tree_owner_| could be nullptr if another |
+ // the rotation request comes before the copy request finished. |
if (old_layer_tree_owner_) |
old_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); |
+ if (new_layer_tree_owner_) |
+ new_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); |
+ if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) |
+ root_window_->layer()->Remove(black_mask_layer_owner_->layer()); |
} |
} // namespace ash |