screen_rotation_animator.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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
  3. // found in the LICENSE file.
  4. #ifndef ASH_ROTATOR_SCREEN_ROTATION_ANIMATOR_H_
  5. #define ASH_ROTATOR_SCREEN_ROTATION_ANIMATOR_H_
  6. #include <stdint.h>
  7. #include <memory>
  8. #include "ash/ash_export.h"
  9. #include "ash/display/display_configuration_controller.h"
  10. #include "base/callback_forward.h"
  11. #include "base/memory/weak_ptr.h"
  12. #include "base/observer_list.h"
  13. #include "third_party/abseil-cpp/absl/types/optional.h"
  14. #include "ui/display/display.h"
  15. namespace aura {
  16. class Window;
  17. } // namespace aura
  18. namespace ui {
  19. class LayerTreeOwner;
  20. class ScopedAnimationDurationScaleMode;
  21. } // namespace ui
  22. namespace viz {
  23. class CopyOutputRequest;
  24. class CopyOutputResult;
  25. } // namespace viz
  26. namespace ash {
  27. class ScreenRotationAnimatorObserver;
  28. // Utility to perform a screen rotation with an animation.
  29. class ASH_EXPORT ScreenRotationAnimator {
  30. public:
  31. static ScreenRotationAnimator* GetForRootWindow(aura::Window* root_window);
  32. explicit ScreenRotationAnimator(aura::Window* root_window);
  33. ScreenRotationAnimator(const ScreenRotationAnimator&) = delete;
  34. ScreenRotationAnimator& operator=(const ScreenRotationAnimator&) = delete;
  35. virtual ~ScreenRotationAnimator();
  36. // Rotates the display::Display specified by |display_id| of the |root_window|
  37. // to the |new_rotation| orientation, for the given |source|. The rotation
  38. // will also become active. |screen_rotation_animator_observer_| will be
  39. // notified when rotation is finished and there is no more pending rotation
  40. // request. Otherwise, any ongoing animation will be stopped and progressed to
  41. // the target position, followed by a new |Rotate()| call with the pending
  42. // rotation request.
  43. void Rotate(display::Display::Rotation new_rotation,
  44. display::Display::RotationSource source,
  45. DisplayConfigurationController::RotationAnimation mode);
  46. void AddObserver(ScreenRotationAnimatorObserver* observer);
  47. void RemoveObserver(ScreenRotationAnimatorObserver* observer);
  48. // When screen rotation animation is ended or aborted, calls |Rotate()| with
  49. // the pending rotation request if the request queue is not empty. Otherwise
  50. // notifies |screen_rotation_animator_observer_|.
  51. void ProcessAnimationQueue();
  52. // True if the screen is in rotating state (not IDLE).
  53. bool IsRotating() const;
  54. // Returns the target (new) rotation. This will return the last requested
  55. // orientation if |IsRotating()| is false.
  56. display::Display::Rotation GetTargetRotation() const;
  57. static void SetScreenRotationAnimatorForTest(
  58. aura::Window* root_window,
  59. std::unique_ptr<ScreenRotationAnimator> animator);
  60. protected:
  61. using CopyCallback =
  62. base::OnceCallback<void(std::unique_ptr<viz::CopyOutputResult> result)>;
  63. struct ScreenRotationRequest {
  64. ScreenRotationRequest(
  65. int64_t id,
  66. int64_t display_id,
  67. display::Display::Rotation to_rotation,
  68. display::Display::RotationSource from_source,
  69. DisplayConfigurationController::RotationAnimation mode)
  70. : id(id),
  71. display_id(display_id),
  72. new_rotation(to_rotation),
  73. source(from_source),
  74. mode(mode) {}
  75. int64_t id;
  76. int64_t display_id;
  77. display::Display::Rotation old_rotation;
  78. display::Display::Rotation new_rotation;
  79. display::Display::RotationSource source;
  80. DisplayConfigurationController::RotationAnimation mode;
  81. };
  82. // This function can be overridden in unit test to test removing external
  83. // display.
  84. virtual CopyCallback CreateAfterCopyCallbackBeforeRotation(
  85. std::unique_ptr<ScreenRotationRequest> rotation_request);
  86. // This function can be overridden in unit test to test removing external
  87. // display.
  88. virtual CopyCallback CreateAfterCopyCallbackAfterRotation(
  89. std::unique_ptr<ScreenRotationRequest> rotation_request);
  90. private:
  91. friend class ScreenRotationAnimatorTestApi;
  92. void StartRotationAnimation(
  93. std::unique_ptr<ScreenRotationRequest> rotation_request);
  94. // The code path to start "slow animation". The difference between the "slow"
  95. // and "smooth" animation, is that "slow animation" will recreate all the
  96. // layers before rotation and use the recreated layers and rotated layers for
  97. // cross-fading animation. This is slow by adding multiple layer animation
  98. // elements. The "smooth animation" copies the layer output before and after
  99. // rotation, and use them for cross-fading animation. The output copy layer
  100. // flatten the layer hierarchy and makes the animation smooth.
  101. void StartSlowAnimation(
  102. std::unique_ptr<ScreenRotationRequest> rotation_request);
  103. // A wrapper to call |display_manager| to set screen rotation and rotate the
  104. // |old_layer_tree| to the |old_rotation|.
  105. void SetRotation(int64_t display_id,
  106. display::Display::Rotation old_rotation,
  107. display::Display::Rotation new_rotation,
  108. display::Display::RotationSource source);
  109. // This is an asynchronous call to request copy output of root layer.
  110. void RequestCopyScreenRotationContainerLayer(
  111. std::unique_ptr<viz::CopyOutputRequest> copy_output_request);
  112. // The callback in |RequestCopyScreenRotationContainerLayer()| before screen
  113. // rotation.
  114. void OnScreenRotationContainerLayerCopiedBeforeRotation(
  115. std::unique_ptr<ScreenRotationRequest> rotation_request,
  116. std::unique_ptr<viz::CopyOutputResult> result);
  117. // The callback in |RequestCopyScreenRotationContainerLayer()| after screen
  118. // rotation.
  119. void OnScreenRotationContainerLayerCopiedAfterRotation(
  120. std::unique_ptr<ScreenRotationRequest> rotation_request,
  121. std::unique_ptr<viz::CopyOutputResult> result);
  122. // Recreates all |root_window| layers and their layer tree owner.
  123. void CreateOldLayerTreeForSlowAnimation();
  124. // Creates a new layer and its layer tree owner from |CopyOutputResult|.
  125. std::unique_ptr<ui::LayerTreeOwner> CopyLayerTree(
  126. std::unique_ptr<viz::CopyOutputResult> result);
  127. // Note: Only call this function when the |old_layer_tree_owner_| is set up
  128. // properly.
  129. // Sets the screen orientation to |new_rotation| and animate the change. The
  130. // animation will rotate the initial orientation's layer towards the new
  131. // orientation through |rotation_degrees| while fading out, and the new
  132. // orientation's layer will be rotated in to the |new_orientation| through
  133. // |rotation_degrees| arc.
  134. void AnimateRotation(std::unique_ptr<ScreenRotationRequest> rotation_request);
  135. void NotifyAnimationFinished(bool canceled);
  136. void set_disable_animation_timers_for_test(bool disable_timers) {
  137. disable_animation_timers_for_test_ = disable_timers;
  138. }
  139. void StopAnimating();
  140. aura::Window* root_window_;
  141. // For current slow rotation animation, there are two states |ROTATING| and
  142. // |IDLE|. For the smooth rotation animation, we need to send copy request
  143. // and get copy result before animating.
  144. enum ScreenRotationState {
  145. COPY_REQUESTED,
  146. ROTATING,
  147. IDLE,
  148. };
  149. ScreenRotationState screen_rotation_state_;
  150. // Rotation request id, used to ignore copy request callback if we decide to
  151. // cancel the previous rotation request.
  152. int64_t rotation_request_id_;
  153. // Only set in unittest to disable animation timers.
  154. bool disable_animation_timers_for_test_;
  155. base::ObserverList<ScreenRotationAnimatorObserver>::Unchecked
  156. screen_rotation_animator_observers_;
  157. std::unique_ptr<ui::LayerTreeOwner> old_layer_tree_owner_;
  158. std::unique_ptr<ui::LayerTreeOwner> new_layer_tree_owner_;
  159. std::unique_ptr<ui::LayerTreeOwner> mask_layer_tree_owner_;
  160. std::unique_ptr<ScreenRotationRequest> last_pending_request_;
  161. absl::optional<ScreenRotationRequest> current_async_rotation_request_;
  162. display::Display::Rotation target_rotation_ = display::Display::ROTATE_0;
  163. std::unique_ptr<ui::ScopedAnimationDurationScaleMode> animation_scale_mode_;
  164. base::WeakPtrFactory<ScreenRotationAnimator> weak_factory_{this};
  165. };
  166. } // namespace ash
  167. #endif // ASH_ROTATOR_SCREEN_ROTATION_ANIMATOR_H_