| Index: ash/rotator/screen_rotation_animator.cc
|
| diff --git a/ash/rotator/screen_rotation_animator.cc b/ash/rotator/screen_rotation_animator.cc
|
| index b78ccd15e0c9cb8350679dcc7232cd7b2485da64..5128813eb8861d5b4cbb6b9e43a8dcdc0aa5bebe 100644
|
| --- a/ash/rotator/screen_rotation_animator.cc
|
| +++ b/ash/rotator/screen_rotation_animator.cc
|
| @@ -8,6 +8,7 @@
|
| #include <utility>
|
| #include <vector>
|
|
|
| +#include "ash/common/ash_switches.h"
|
| #include "ash/display/window_tree_host_manager.h"
|
| #include "ash/rotator/screen_rotation_animation.h"
|
| #include "ash/rotator/screen_rotation_animator_observer.h"
|
| @@ -16,6 +17,8 @@
|
| #include "base/memory/ptr_util.h"
|
| #include "base/metrics/histogram_macros.h"
|
| #include "base/time/time.h"
|
| +#include "cc/output/copy_output_request.h"
|
| +#include "cc/output/copy_output_result.h"
|
| #include "ui/aura/window.h"
|
| #include "ui/compositor/layer.h"
|
| #include "ui/compositor/layer_animation_element.h"
|
| @@ -184,14 +187,6 @@ class ScreenRotationAnimationMetricsReporter
|
|
|
| } // namespace
|
|
|
| -struct ScreenRotationAnimator::ScreenRotationRequest {
|
| - ScreenRotationRequest(display::Display::Rotation to_rotation,
|
| - display::Display::RotationSource from_source)
|
| - : new_rotation(to_rotation), source(from_source) {}
|
| - display::Display::Rotation new_rotation;
|
| - display::Display::RotationSource source;
|
| -};
|
| -
|
| ScreenRotationAnimator::ScreenRotationAnimator(int64_t display_id)
|
| : display_id_(display_id),
|
| is_rotating_(false),
|
| @@ -212,9 +207,86 @@ ScreenRotationAnimator::~ScreenRotationAnimator() {
|
| metrics_reporter_.reset();
|
| }
|
|
|
| +void ScreenRotationAnimator::StartRotationAnimation(
|
| + std::unique_ptr<ScreenRotationRequest> rotation_request) {
|
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kAshEnableSmoothScreenRotation)) {
|
| + RequestCopyRootLayerAndAnimateRotation(std::move(rotation_request));
|
| + } else {
|
| + CreateOldLayerTree();
|
| + AnimateRotation(std::move(rotation_request));
|
| + }
|
| +}
|
| +
|
| +void ScreenRotationAnimator::RequestCopyRootLayerAndAnimateRotation(
|
| + 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));
|
| +}
|
| +
|
| +ScreenRotationAnimator::CopyCallback
|
| +ScreenRotationAnimator::CreateAfterCopyCallback(
|
| + std::unique_ptr<ScreenRotationRequest> rotation_request) {
|
| + return base::Bind(&ScreenRotationAnimator::OnRootLayerCopiedBeforeRotation,
|
| + weak_factory_.GetWeakPtr(),
|
| + base::Passed(&rotation_request));
|
| +}
|
| +
|
| +void ScreenRotationAnimator::OnRootLayerCopiedBeforeRotation(
|
| + std::unique_ptr<ScreenRotationRequest> rotation_request,
|
| + std::unique_ptr<cc::CopyOutputResult> result) {
|
| + // If display was removed, should abort rotation.
|
| + if (!IsDisplayIdValid(display_id_)) {
|
| + ProcessAnimationQueue();
|
| + return;
|
| + }
|
| +
|
| + // Fall back to recreate layers solution when the copy request has been
|
| + // canceled or failed. It would fail if, for examples: a) The layer is removed
|
| + // from the compositor and destroyed before committing the request to the
|
| + // compositor. b) The compositor is shutdown.
|
| + if (result->IsEmpty())
|
| + CreateOldLayerTree();
|
| + else
|
| + CopyOldLayerTree(std::move(result));
|
| + AnimateRotation(std::move(rotation_request));
|
| +}
|
| +
|
| +void ScreenRotationAnimator::CreateOldLayerTree() {
|
| + old_layer_tree_owner_ = ::wm::RecreateLayers(GetRootWindow(display_id_));
|
| +}
|
| +
|
| +void ScreenRotationAnimator::CopyOldLayerTree(
|
| + 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());
|
| + 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));
|
| +}
|
| +
|
| void ScreenRotationAnimator::AnimateRotation(
|
| std::unique_ptr<ScreenRotationRequest> rotation_request) {
|
| 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();
|
|
|
| @@ -229,18 +301,6 @@ void ScreenRotationAnimator::AnimateRotation(
|
|
|
| const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN;
|
|
|
| - std::unique_ptr<ui::LayerTreeOwner> old_layer_tree =
|
| - ::wm::RecreateLayers(root_window);
|
| - old_layer_tree->root()->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_layer_tree->root());
|
| - root_window->layer()->StackAtTop(old_layer_tree->root());
|
| -
|
| - old_layer_tree_owner_ = std::move(old_layer_tree);
|
| - std::unique_ptr<LayerCleanupObserver> old_layer_cleanup_observer(
|
| - new LayerCleanupObserver(weak_factory_.GetWeakPtr()));
|
| -
|
| Shell::Get()->display_manager()->SetDisplayRotation(
|
| display_id_, rotation_request->new_rotation, rotation_request->source);
|
|
|
| @@ -248,7 +308,6 @@ void ScreenRotationAnimator::AnimateRotation(
|
| const gfx::Point pivot = gfx::Point(rotated_screen_bounds.width() / 2,
|
| rotated_screen_bounds.height() / 2);
|
|
|
| - ui::Layer* old_root_layer = old_layer_tree_owner_->root();
|
| // We must animate each non-cloned child layer individually because the cloned
|
| // layer was added as a child to |root_window|'s layer so that it will be
|
| // rendered.
|
| @@ -327,7 +386,7 @@ void ScreenRotationAnimator::Rotate(display::Display::Rotation new_rotation,
|
| StopAnimating();
|
| } else {
|
| is_rotating_ = true;
|
| - AnimateRotation(std::move(rotation_request));
|
| + StartRotationAnimation(std::move(rotation_request));
|
| }
|
| }
|
|
|
|
|