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 enable_animation_(true), |
| 174 has_switch_ash_disable_smooth_screen_rotation_( |
184 base::CommandLine::ForCurrentProcess()->HasSwitch( | 175 base::CommandLine::ForCurrentProcess()->HasSwitch( |
185 switches::kAshEnableSmoothScreenRotation)), | 176 switches::kAshDisableSmoothScreenRotation)), |
186 root_window_(GetRootWindow(display_id_)), | 177 root_window_(GetRootWindow(display_id_)), |
187 screen_rotation_container_layer_( | 178 screen_rotation_container_layer_( |
188 GetScreenRotationContainer(root_window_)->layer()), | 179 GetScreenRotationContainer(root_window_)->layer()), |
189 weak_factory_(this) {} | 180 weak_factory_(this) {} |
190 | 181 |
191 ScreenRotationAnimator::~ScreenRotationAnimator() { | 182 ScreenRotationAnimator::~ScreenRotationAnimator() { |
192 // To prevent a call to |AnimationEndedCallback()| from calling a method on | 183 // To prevent a call to |AnimationEndedCallback()| from calling a method on |
193 // the |animator_|. | 184 // the |animator_|. |
194 weak_factory_.InvalidateWeakPtrs(); | 185 weak_factory_.InvalidateWeakPtrs(); |
195 | 186 |
196 // Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in | 187 // Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in |
197 // order to make sure |metrics_reporter_| outlives the attached animation | 188 // order to make sure |metrics_reporter_| outlives the attached animation |
198 // sequence. | 189 // sequence. |
199 old_layer_tree_owner_.reset(); | 190 old_layer_tree_owner_.reset(); |
200 metrics_reporter_.reset(); | 191 metrics_reporter_.reset(); |
201 } | 192 } |
202 | 193 |
203 void ScreenRotationAnimator::StartRotationAnimation( | 194 void ScreenRotationAnimator::StartRotationAnimation( |
204 std::unique_ptr<ScreenRotationRequest> rotation_request) { | 195 std::unique_ptr<ScreenRotationRequest> rotation_request) { |
205 const display::Display::Rotation current_rotation = | 196 const display::Display::Rotation current_rotation = |
206 GetCurrentScreenRotation(display_id_); | 197 GetCurrentScreenRotation(display_id_); |
207 if (current_rotation == rotation_request->new_rotation) { | 198 if (current_rotation == rotation_request->new_rotation) { |
208 // We need to call |ProcessAnimationQueue()| to prepare for next rotation | 199 // We need to call |ProcessAnimationQueue()| to prepare for next rotation |
209 // request. | 200 // request. |
210 ProcessAnimationQueue(); | 201 ProcessAnimationQueue(); |
211 return; | 202 return; |
212 } | 203 } |
213 | 204 |
| 205 if (!enable_animation_) { |
| 206 Shell::Get()->display_manager()->SetDisplayRotation( |
| 207 display_id_, rotation_request->new_rotation, rotation_request->source); |
| 208 ProcessAnimationQueue(); |
| 209 return; |
| 210 } |
| 211 |
214 rotation_request->old_rotation = current_rotation; | 212 rotation_request->old_rotation = current_rotation; |
215 if (has_switch_ash_enable_smooth_screen_rotation_) { | 213 if (has_switch_ash_disable_smooth_screen_rotation_) { |
| 214 StartSlowAnimation(std::move(rotation_request)); |
| 215 } else { |
216 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = | 216 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = |
217 cc::CopyOutputRequest::CreateRequest( | 217 cc::CopyOutputRequest::CreateRequest( |
218 CreateAfterCopyCallbackBeforeRotation(std::move(rotation_request))); | 218 CreateAfterCopyCallbackBeforeRotation(std::move(rotation_request))); |
219 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); | 219 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); |
220 screen_rotation_state_ = COPY_REQUESTED; | 220 screen_rotation_state_ = COPY_REQUESTED; |
221 } else { | |
222 StartSlowAnimation(std::move(rotation_request)); | |
223 } | 221 } |
224 } | 222 } |
225 | 223 |
226 void ScreenRotationAnimator::StartSlowAnimation( | 224 void ScreenRotationAnimator::StartSlowAnimation( |
227 std::unique_ptr<ScreenRotationRequest> rotation_request) { | 225 std::unique_ptr<ScreenRotationRequest> rotation_request) { |
228 CreateOldLayerTreeForSlowAnimation(); | 226 CreateOldLayerTreeForSlowAnimation(); |
229 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, | 227 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, |
230 rotation_request->source); | 228 rotation_request->source); |
231 AnimateRotation(std::move(rotation_request)); | 229 AnimateRotation(std::move(rotation_request)); |
232 } | 230 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 OnScreenRotationContainerLayerCopiedAfterRotation, | 266 OnScreenRotationContainerLayerCopiedAfterRotation, |
269 weak_factory_.GetWeakPtr(), | 267 weak_factory_.GetWeakPtr(), |
270 base::Passed(&rotation_request)); | 268 base::Passed(&rotation_request)); |
271 } | 269 } |
272 | 270 |
273 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedBeforeRotation( | 271 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedBeforeRotation( |
274 std::unique_ptr<ScreenRotationRequest> rotation_request, | 272 std::unique_ptr<ScreenRotationRequest> rotation_request, |
275 std::unique_ptr<cc::CopyOutputResult> result) { | 273 std::unique_ptr<cc::CopyOutputResult> result) { |
276 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) | 274 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) |
277 return; | 275 return; |
278 if (AbortRotation(display_id_, result.get())) { | 276 // Abort rotation if the display was removed. |
| 277 if (!IsDisplayIdValid(display_id_)) { |
279 ProcessAnimationQueue(); | 278 ProcessAnimationQueue(); |
280 return; | 279 return; |
281 } | 280 } |
| 281 // Abort animation and set the rotation to target rotation when the copy |
| 282 // request has been canceled or failed. It would fail if, for examples: a) The |
| 283 // layer is removed from the compositor and destroye before committing the |
| 284 // request to the compositor. b) The compositor is shutdown. |
| 285 if (result->IsEmpty()) { |
| 286 Shell::Get()->display_manager()->SetDisplayRotation( |
| 287 display_id_, rotation_request->new_rotation, rotation_request->source); |
| 288 ProcessAnimationQueue(); |
| 289 return; |
| 290 } |
282 | 291 |
283 old_layer_tree_owner_ = CopyLayerTree(std::move(result)); | 292 old_layer_tree_owner_ = CopyLayerTree(std::move(result)); |
284 AddLayerAtTopOfWindowLayers(root_window_, old_layer_tree_owner_->root()); | 293 AddLayerAtTopOfWindowLayers(root_window_, old_layer_tree_owner_->root()); |
285 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, | 294 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, |
286 rotation_request->source); | 295 rotation_request->source); |
287 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = | 296 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = |
288 cc::CopyOutputRequest::CreateRequest( | 297 cc::CopyOutputRequest::CreateRequest( |
289 CreateAfterCopyCallbackAfterRotation(std::move(rotation_request))); | 298 CreateAfterCopyCallbackAfterRotation(std::move(rotation_request))); |
290 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); | 299 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); |
291 } | 300 } |
292 | 301 |
293 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedAfterRotation( | 302 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedAfterRotation( |
294 std::unique_ptr<ScreenRotationRequest> rotation_request, | 303 std::unique_ptr<ScreenRotationRequest> rotation_request, |
295 std::unique_ptr<cc::CopyOutputResult> result) { | 304 std::unique_ptr<cc::CopyOutputResult> result) { |
296 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) | 305 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) |
297 return; | 306 return; |
298 if (AbortRotation(display_id_, result.get())) { | 307 // In the following cases, abort rotation: |
| 308 // 1) if the display was removed, |
| 309 // 2) the copy request has been canceled or failed. It would fail if, |
| 310 // for examples: a) The layer is removed from the compositor and destroye |
| 311 // before committing the request to the compositor. b) The compositor is |
| 312 // shutdown. |
| 313 if (!IsDisplayIdValid(display_id_) || result->IsEmpty()) { |
299 ProcessAnimationQueue(); | 314 ProcessAnimationQueue(); |
300 return; | 315 return; |
301 } | 316 } |
302 | 317 |
303 new_layer_tree_owner_ = CopyLayerTree(std::move(result)); | 318 new_layer_tree_owner_ = CopyLayerTree(std::move(result)); |
304 AddLayerBelowWindowLayer(root_window_, old_layer_tree_owner_->root(), | 319 AddLayerBelowWindowLayer(root_window_, old_layer_tree_owner_->root(), |
305 new_layer_tree_owner_->root()); | 320 new_layer_tree_owner_->root()); |
306 AnimateRotation(std::move(rotation_request)); | 321 AnimateRotation(std::move(rotation_request)); |
307 } | 322 } |
308 | 323 |
(...skipping 28 matching lines...) Expand all Loading... |
337 const int old_layer_initial_rotation_degrees = GetInitialDegrees( | 352 const int old_layer_initial_rotation_degrees = GetInitialDegrees( |
338 rotation_request->old_rotation, rotation_request->new_rotation); | 353 rotation_request->old_rotation, rotation_request->new_rotation); |
339 const base::TimeDelta duration = | 354 const base::TimeDelta duration = |
340 base::TimeDelta::FromMilliseconds(kRotationDurationInMs); | 355 base::TimeDelta::FromMilliseconds(kRotationDurationInMs); |
341 const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN; | 356 const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN; |
342 const gfx::Rect rotated_screen_bounds = root_window_->GetTargetBounds(); | 357 const gfx::Rect rotated_screen_bounds = root_window_->GetTargetBounds(); |
343 const gfx::Point pivot = gfx::Point(rotated_screen_bounds.width() / 2, | 358 const gfx::Point pivot = gfx::Point(rotated_screen_bounds.width() / 2, |
344 rotated_screen_bounds.height() / 2); | 359 rotated_screen_bounds.height() / 2); |
345 | 360 |
346 ui::Layer* new_root_layer; | 361 ui::Layer* new_root_layer; |
347 if (new_layer_tree_owner_ && has_switch_ash_enable_smooth_screen_rotation_) { | 362 if (!new_layer_tree_owner_ || |
| 363 has_switch_ash_disable_smooth_screen_rotation_) { |
| 364 new_root_layer = screen_rotation_container_layer_; |
| 365 } else { |
348 new_root_layer = new_layer_tree_owner_->root(); | 366 new_root_layer = new_layer_tree_owner_->root(); |
349 // Add a black mask layer on top of |screen_rotation_container_layer_|. | 367 // Add a black mask layer on top of |screen_rotation_container_layer_|. |
350 black_mask_layer_owner_ = CreateBlackMaskLayerOwner( | 368 black_mask_layer_owner_ = CreateBlackMaskLayerOwner( |
351 gfx::Rect(screen_rotation_container_layer_->size())); | 369 gfx::Rect(screen_rotation_container_layer_->size())); |
352 AddLayerBelowWindowLayer(root_window_, new_root_layer, | 370 AddLayerBelowWindowLayer(root_window_, new_root_layer, |
353 black_mask_layer_owner_->layer()); | 371 black_mask_layer_owner_->layer()); |
354 } else { | |
355 new_root_layer = screen_rotation_container_layer_; | |
356 } | 372 } |
357 | 373 |
358 std::unique_ptr<ScreenRotationAnimation> new_layer_screen_rotation = | 374 std::unique_ptr<ScreenRotationAnimation> new_layer_screen_rotation = |
359 base::MakeUnique<ScreenRotationAnimation>( | 375 base::MakeUnique<ScreenRotationAnimation>( |
360 new_root_layer, kRotationDegrees * rotation_factor, | 376 new_root_layer, kRotationDegrees * rotation_factor, |
361 0 /* end_degrees */, new_root_layer->opacity(), | 377 0 /* end_degrees */, new_root_layer->opacity(), |
362 new_root_layer->opacity() /* target_opacity */, pivot, duration, | 378 new_root_layer->opacity() /* target_opacity */, pivot, duration, |
363 tween_type); | 379 tween_type); |
364 | 380 |
365 ui::LayerAnimator* new_layer_animator = new_root_layer->GetAnimator(); | 381 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. | 492 // the rotation request comes before the copy request finished. |
477 if (old_layer_tree_owner_) | 493 if (old_layer_tree_owner_) |
478 old_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); | 494 old_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); |
479 if (new_layer_tree_owner_) | 495 if (new_layer_tree_owner_) |
480 new_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); | 496 new_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); |
481 if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) | 497 if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) |
482 root_window_->layer()->Remove(black_mask_layer_owner_->layer()); | 498 root_window_->layer()->Remove(black_mask_layer_owner_->layer()); |
483 } | 499 } |
484 | 500 |
485 } // namespace ash | 501 } // namespace ash |
OLD | NEW |