| OLD | NEW |
| 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" |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 return inverse; | 127 return inverse; |
| 128 } | 128 } |
| 129 | 129 |
| 130 // The |request_id| changed since last copy request, which means a | 130 // The |request_id| changed since last copy request, which means a |
| 131 // new rotation stated, we need to ignore this copy result. | 131 // new rotation stated, we need to ignore this copy result. |
| 132 bool IgnoreCopyResult(int64_t request_id, int64_t current_request_id) { | 132 bool IgnoreCopyResult(int64_t request_id, int64_t current_request_id) { |
| 133 DCHECK(request_id <= current_request_id); | 133 DCHECK(request_id <= current_request_id); |
| 134 return request_id < current_request_id; | 134 return request_id < current_request_id; |
| 135 } | 135 } |
| 136 | 136 |
| 137 // In the following cases, abort rotation: | |
| 138 // 1) if the display was removed, | |
| 139 // 2) the copy request has been canceled or failed. It would fail if, | |
| 140 // for examples: a) The layer is removed from the compositor and destroye | |
| 141 // before committing the request to the compositor. b) The compositor is | |
| 142 // shutdown. | |
| 143 bool AbortRotation(int64_t display_id, cc::CopyOutputResult* result) { | |
| 144 return !IsDisplayIdValid(display_id) || result->IsEmpty(); | |
| 145 } | |
| 146 | |
| 147 // Creates a black mask layer and returns the |layer_owner|. | 137 // Creates a black mask layer and returns the |layer_owner|. |
| 148 std::unique_ptr<ui::LayerOwner> CreateBlackMaskLayerOwner( | 138 std::unique_ptr<ui::LayerOwner> CreateBlackMaskLayerOwner( |
| 149 const gfx::Rect& rect) { | 139 const gfx::Rect& rect) { |
| 150 std::unique_ptr<ui::Layer> black_mask_layer = | 140 std::unique_ptr<ui::Layer> black_mask_layer = |
| 151 base::MakeUnique<ui::Layer>(ui::LAYER_SOLID_COLOR); | 141 base::MakeUnique<ui::Layer>(ui::LAYER_SOLID_COLOR); |
| 152 black_mask_layer->SetBounds(rect); | 142 black_mask_layer->SetBounds(rect); |
| 153 black_mask_layer->SetColor(SK_ColorBLACK); | 143 black_mask_layer->SetColor(SK_ColorBLACK); |
| 154 std::unique_ptr<ui::LayerOwner> black_mask_layer_owner = | 144 std::unique_ptr<ui::LayerOwner> black_mask_layer_owner = |
| 155 base::MakeUnique<ui::LayerOwner>(); | 145 base::MakeUnique<ui::LayerOwner>(); |
| 156 black_mask_layer_owner->SetLayer(std::move(black_mask_layer)); | 146 black_mask_layer_owner->SetLayer(std::move(black_mask_layer)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 173 | 163 |
| 174 } // namespace | 164 } // namespace |
| 175 | 165 |
| 176 ScreenRotationAnimator::ScreenRotationAnimator(int64_t display_id) | 166 ScreenRotationAnimator::ScreenRotationAnimator(int64_t display_id) |
| 177 : display_id_(display_id), | 167 : display_id_(display_id), |
| 178 screen_rotation_state_(IDLE), | 168 screen_rotation_state_(IDLE), |
| 179 rotation_request_id_(0), | 169 rotation_request_id_(0), |
| 180 metrics_reporter_( | 170 metrics_reporter_( |
| 181 base::MakeUnique<ScreenRotationAnimationMetricsReporter>()), | 171 base::MakeUnique<ScreenRotationAnimationMetricsReporter>()), |
| 182 disable_animation_timers_for_test_(false), | 172 disable_animation_timers_for_test_(false), |
| 183 has_switch_ash_enable_smooth_screen_rotation_( | 173 has_switch_ash_disable_smooth_screen_rotation_( |
| 184 base::CommandLine::ForCurrentProcess()->HasSwitch( | 174 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 185 switches::kAshEnableSmoothScreenRotation)), | 175 switches::kAshDisableSmoothScreenRotation)), |
| 186 root_window_(GetRootWindow(display_id_)), | 176 root_window_(GetRootWindow(display_id_)), |
| 187 screen_rotation_container_layer_( | 177 screen_rotation_container_layer_( |
| 188 GetScreenRotationContainer(root_window_)->layer()), | 178 GetScreenRotationContainer(root_window_)->layer()), |
| 189 weak_factory_(this) {} | 179 weak_factory_(this) {} |
| 190 | 180 |
| 191 ScreenRotationAnimator::~ScreenRotationAnimator() { | 181 ScreenRotationAnimator::~ScreenRotationAnimator() { |
| 192 // To prevent a call to |AnimationEndedCallback()| from calling a method on | 182 // To prevent a call to |AnimationEndedCallback()| from calling a method on |
| 193 // the |animator_|. | 183 // the |animator_|. |
| 194 weak_factory_.InvalidateWeakPtrs(); | 184 weak_factory_.InvalidateWeakPtrs(); |
| 195 | 185 |
| 196 // Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in | 186 // Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in |
| 197 // order to make sure |metrics_reporter_| outlives the attached animation | 187 // order to make sure |metrics_reporter_| outlives the attached animation |
| 198 // sequence. | 188 // sequence. |
| 199 old_layer_tree_owner_.reset(); | 189 old_layer_tree_owner_.reset(); |
| 200 metrics_reporter_.reset(); | 190 metrics_reporter_.reset(); |
| 201 } | 191 } |
| 202 | 192 |
| 203 void ScreenRotationAnimator::StartRotationAnimation( | 193 void ScreenRotationAnimator::StartRotationAnimation( |
| 204 std::unique_ptr<ScreenRotationRequest> rotation_request) { | 194 std::unique_ptr<ScreenRotationRequest> rotation_request) { |
| 205 const display::Display::Rotation current_rotation = | 195 const display::Display::Rotation current_rotation = |
| 206 GetCurrentScreenRotation(display_id_); | 196 GetCurrentScreenRotation(display_id_); |
| 207 if (current_rotation == rotation_request->new_rotation) { | 197 if (current_rotation == rotation_request->new_rotation) { |
| 208 // We need to call |ProcessAnimationQueue()| to prepare for next rotation | 198 // We need to call |ProcessAnimationQueue()| to prepare for next rotation |
| 209 // request. | 199 // request. |
| 210 ProcessAnimationQueue(); | 200 ProcessAnimationQueue(); |
| 211 return; | 201 return; |
| 212 } | 202 } |
| 213 | 203 |
| 214 rotation_request->old_rotation = current_rotation; | 204 rotation_request->old_rotation = current_rotation; |
| 215 if (has_switch_ash_enable_smooth_screen_rotation_) { | 205 if (has_switch_ash_disable_smooth_screen_rotation_) { |
| 206 StartSlowAnimation(std::move(rotation_request)); |
| 207 } else { |
| 216 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = | 208 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = |
| 217 cc::CopyOutputRequest::CreateRequest( | 209 cc::CopyOutputRequest::CreateRequest( |
| 218 CreateAfterCopyCallbackBeforeRotation(std::move(rotation_request))); | 210 CreateAfterCopyCallbackBeforeRotation(std::move(rotation_request))); |
| 219 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); | 211 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); |
| 220 screen_rotation_state_ = COPY_REQUESTED; | 212 screen_rotation_state_ = COPY_REQUESTED; |
| 221 } else { | |
| 222 StartSlowAnimation(std::move(rotation_request)); | |
| 223 } | 213 } |
| 224 } | 214 } |
| 225 | 215 |
| 226 void ScreenRotationAnimator::StartSlowAnimation( | 216 void ScreenRotationAnimator::StartSlowAnimation( |
| 227 std::unique_ptr<ScreenRotationRequest> rotation_request) { | 217 std::unique_ptr<ScreenRotationRequest> rotation_request) { |
| 228 CreateOldLayerTreeForSlowAnimation(); | 218 CreateOldLayerTreeForSlowAnimation(); |
| 229 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, | 219 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, |
| 230 rotation_request->source); | 220 rotation_request->source); |
| 231 AnimateRotation(std::move(rotation_request)); | 221 AnimateRotation(std::move(rotation_request)); |
| 232 } | 222 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 OnScreenRotationContainerLayerCopiedAfterRotation, | 258 OnScreenRotationContainerLayerCopiedAfterRotation, |
| 269 weak_factory_.GetWeakPtr(), | 259 weak_factory_.GetWeakPtr(), |
| 270 base::Passed(&rotation_request)); | 260 base::Passed(&rotation_request)); |
| 271 } | 261 } |
| 272 | 262 |
| 273 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedBeforeRotation( | 263 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedBeforeRotation( |
| 274 std::unique_ptr<ScreenRotationRequest> rotation_request, | 264 std::unique_ptr<ScreenRotationRequest> rotation_request, |
| 275 std::unique_ptr<cc::CopyOutputResult> result) { | 265 std::unique_ptr<cc::CopyOutputResult> result) { |
| 276 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) | 266 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) |
| 277 return; | 267 return; |
| 278 if (AbortRotation(display_id_, result.get())) { | 268 // Abort rotation and animation if the display was removed. |
| 269 if (!IsDisplayIdValid(display_id_)) { |
| 279 ProcessAnimationQueue(); | 270 ProcessAnimationQueue(); |
| 280 return; | 271 return; |
| 281 } | 272 } |
| 273 // Abort animation and set the rotation to target rotation when the copy |
| 274 // request has been canceled or failed. It would fail if, for examples: a) The |
| 275 // layer is removed from the compositor and destroye before committing the |
| 276 // request to the compositor. b) The compositor is shutdown. |
| 277 if (result->IsEmpty()) { |
| 278 Shell::Get()->display_manager()->SetDisplayRotation( |
| 279 display_id_, rotation_request->new_rotation, rotation_request->source); |
| 280 ProcessAnimationQueue(); |
| 281 return; |
| 282 } |
| 282 | 283 |
| 283 old_layer_tree_owner_ = CopyLayerTree(std::move(result)); | 284 old_layer_tree_owner_ = CopyLayerTree(std::move(result)); |
| 284 AddLayerAtTopOfWindowLayers(root_window_, old_layer_tree_owner_->root()); | 285 AddLayerAtTopOfWindowLayers(root_window_, old_layer_tree_owner_->root()); |
| 285 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, | 286 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, |
| 286 rotation_request->source); | 287 rotation_request->source); |
| 287 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = | 288 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = |
| 288 cc::CopyOutputRequest::CreateRequest( | 289 cc::CopyOutputRequest::CreateRequest( |
| 289 CreateAfterCopyCallbackAfterRotation(std::move(rotation_request))); | 290 CreateAfterCopyCallbackAfterRotation(std::move(rotation_request))); |
| 290 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); | 291 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); |
| 291 } | 292 } |
| 292 | 293 |
| 293 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedAfterRotation( | 294 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedAfterRotation( |
| 294 std::unique_ptr<ScreenRotationRequest> rotation_request, | 295 std::unique_ptr<ScreenRotationRequest> rotation_request, |
| 295 std::unique_ptr<cc::CopyOutputResult> result) { | 296 std::unique_ptr<cc::CopyOutputResult> result) { |
| 296 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) | 297 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) |
| 297 return; | 298 return; |
| 298 if (AbortRotation(display_id_, result.get())) { | 299 // In the following cases, abort animation: |
| 300 // 1) if the display was removed, |
| 301 // 2) the copy request has been canceled or failed. It would fail if, |
| 302 // for examples: a) The layer is removed from the compositor and destroye |
| 303 // before committing the request to the compositor. b) The compositor is |
| 304 // shutdown. |
| 305 if (!IsDisplayIdValid(display_id_) || result->IsEmpty()) { |
| 299 ProcessAnimationQueue(); | 306 ProcessAnimationQueue(); |
| 300 return; | 307 return; |
| 301 } | 308 } |
| 302 | 309 |
| 303 new_layer_tree_owner_ = CopyLayerTree(std::move(result)); | 310 new_layer_tree_owner_ = CopyLayerTree(std::move(result)); |
| 304 AddLayerBelowWindowLayer(root_window_, old_layer_tree_owner_->root(), | 311 AddLayerBelowWindowLayer(root_window_, old_layer_tree_owner_->root(), |
| 305 new_layer_tree_owner_->root()); | 312 new_layer_tree_owner_->root()); |
| 306 AnimateRotation(std::move(rotation_request)); | 313 AnimateRotation(std::move(rotation_request)); |
| 307 } | 314 } |
| 308 | 315 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 337 const int old_layer_initial_rotation_degrees = GetInitialDegrees( | 344 const int old_layer_initial_rotation_degrees = GetInitialDegrees( |
| 338 rotation_request->old_rotation, rotation_request->new_rotation); | 345 rotation_request->old_rotation, rotation_request->new_rotation); |
| 339 const base::TimeDelta duration = | 346 const base::TimeDelta duration = |
| 340 base::TimeDelta::FromMilliseconds(kRotationDurationInMs); | 347 base::TimeDelta::FromMilliseconds(kRotationDurationInMs); |
| 341 const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN; | 348 const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN; |
| 342 const gfx::Rect rotated_screen_bounds = root_window_->GetTargetBounds(); | 349 const gfx::Rect rotated_screen_bounds = root_window_->GetTargetBounds(); |
| 343 const gfx::Point pivot = gfx::Point(rotated_screen_bounds.width() / 2, | 350 const gfx::Point pivot = gfx::Point(rotated_screen_bounds.width() / 2, |
| 344 rotated_screen_bounds.height() / 2); | 351 rotated_screen_bounds.height() / 2); |
| 345 | 352 |
| 346 ui::Layer* new_root_layer; | 353 ui::Layer* new_root_layer; |
| 347 if (new_layer_tree_owner_ && has_switch_ash_enable_smooth_screen_rotation_) { | 354 if (!new_layer_tree_owner_ || |
| 355 has_switch_ash_disable_smooth_screen_rotation_) { |
| 356 new_root_layer = screen_rotation_container_layer_; |
| 357 } else { |
| 348 new_root_layer = new_layer_tree_owner_->root(); | 358 new_root_layer = new_layer_tree_owner_->root(); |
| 349 // Add a black mask layer on top of |screen_rotation_container_layer_|. | 359 // Add a black mask layer on top of |screen_rotation_container_layer_|. |
| 350 black_mask_layer_owner_ = CreateBlackMaskLayerOwner( | 360 black_mask_layer_owner_ = CreateBlackMaskLayerOwner( |
| 351 gfx::Rect(screen_rotation_container_layer_->size())); | 361 gfx::Rect(screen_rotation_container_layer_->size())); |
| 352 AddLayerBelowWindowLayer(root_window_, new_root_layer, | 362 AddLayerBelowWindowLayer(root_window_, new_root_layer, |
| 353 black_mask_layer_owner_->layer()); | 363 black_mask_layer_owner_->layer()); |
| 354 } else { | |
| 355 new_root_layer = screen_rotation_container_layer_; | |
| 356 } | 364 } |
| 357 | 365 |
| 358 std::unique_ptr<ScreenRotationAnimation> new_layer_screen_rotation = | 366 std::unique_ptr<ScreenRotationAnimation> new_layer_screen_rotation = |
| 359 base::MakeUnique<ScreenRotationAnimation>( | 367 base::MakeUnique<ScreenRotationAnimation>( |
| 360 new_root_layer, kRotationDegrees * rotation_factor, | 368 new_root_layer, kRotationDegrees * rotation_factor, |
| 361 0 /* end_degrees */, new_root_layer->opacity(), | 369 0 /* end_degrees */, new_root_layer->opacity(), |
| 362 new_root_layer->opacity() /* target_opacity */, pivot, duration, | 370 new_root_layer->opacity() /* target_opacity */, pivot, duration, |
| 363 tween_type); | 371 tween_type); |
| 364 | 372 |
| 365 ui::LayerAnimator* new_layer_animator = new_root_layer->GetAnimator(); | 373 ui::LayerAnimator* new_layer_animator = new_root_layer->GetAnimator(); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 // the rotation request comes before the copy request finished. | 484 // the rotation request comes before the copy request finished. |
| 477 if (old_layer_tree_owner_) | 485 if (old_layer_tree_owner_) |
| 478 old_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); | 486 old_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); |
| 479 if (new_layer_tree_owner_) | 487 if (new_layer_tree_owner_) |
| 480 new_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); | 488 new_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); |
| 481 if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) | 489 if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) |
| 482 root_window_->layer()->Remove(black_mask_layer_owner_->layer()); | 490 root_window_->layer()->Remove(black_mask_layer_owner_->layer()); |
| 483 } | 491 } |
| 484 | 492 |
| 485 } // namespace ash | 493 } // namespace ash |
| OLD | NEW |