Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: ash/rotator/screen_rotation_animator.cc

Issue 2910413002: cros: Do not cache |root_window| in ScreenRotationAnimator. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 } 98 }
99 99
100 void AddLayerBelowWindowLayer(aura::Window* root_window, 100 void AddLayerBelowWindowLayer(aura::Window* root_window,
101 ui::Layer* top_layer, 101 ui::Layer* top_layer,
102 ui::Layer* layer) { 102 ui::Layer* layer) {
103 // Add the cloned/copied layer tree into the root, so it will be rendered. 103 // Add the cloned/copied layer tree into the root, so it will be rendered.
104 root_window->layer()->Add(layer); 104 root_window->layer()->Add(layer);
105 root_window->layer()->StackBelow(layer, top_layer); 105 root_window->layer()->StackBelow(layer, top_layer);
106 } 106 }
107 107
108 void RemoveLayerFromRootWindowForDisplayId(int64_t display_id,
109 ui::Layer* layer) {
110 if (IsDisplayIdValid(display_id)) {
111 ui::Layer* root_layer = GetRootWindow(display_id)->layer();
112 if (root_layer->Contains(layer))
113 root_layer->Remove(layer);
114 }
115 }
116
108 // The Callback will be invoked when all animation sequences have 117 // The Callback will be invoked when all animation sequences have
109 // finished. |observer| will be destroyed after invoking the Callback if it 118 // finished. |observer| will be destroyed after invoking the Callback if it
110 // returns true. 119 // returns true.
111 bool AnimationEndedCallback( 120 bool AnimationEndedCallback(
112 base::WeakPtr<ScreenRotationAnimator> animator, 121 base::WeakPtr<ScreenRotationAnimator> animator,
113 const ui::CallbackLayerAnimationObserver& observer) { 122 const ui::CallbackLayerAnimationObserver& observer) {
114 if (animator) 123 if (animator)
115 animator->ProcessAnimationQueue(); 124 animator->ProcessAnimationQueue();
116 return true; 125 return true;
117 } 126 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 ScreenRotationAnimator::ScreenRotationAnimator(int64_t display_id) 175 ScreenRotationAnimator::ScreenRotationAnimator(int64_t display_id)
167 : display_id_(display_id), 176 : display_id_(display_id),
168 screen_rotation_state_(IDLE), 177 screen_rotation_state_(IDLE),
169 rotation_request_id_(0), 178 rotation_request_id_(0),
170 metrics_reporter_( 179 metrics_reporter_(
171 base::MakeUnique<ScreenRotationAnimationMetricsReporter>()), 180 base::MakeUnique<ScreenRotationAnimationMetricsReporter>()),
172 disable_animation_timers_for_test_(false), 181 disable_animation_timers_for_test_(false),
173 has_switch_ash_disable_smooth_screen_rotation_( 182 has_switch_ash_disable_smooth_screen_rotation_(
174 base::CommandLine::ForCurrentProcess()->HasSwitch( 183 base::CommandLine::ForCurrentProcess()->HasSwitch(
175 switches::kAshDisableSmoothScreenRotation)), 184 switches::kAshDisableSmoothScreenRotation)),
176 root_window_(GetRootWindow(display_id_)),
177 screen_rotation_container_layer_(
178 GetScreenRotationContainer(root_window_)->layer()),
179 weak_factory_(this) {} 185 weak_factory_(this) {}
180 186
181 ScreenRotationAnimator::~ScreenRotationAnimator() { 187 ScreenRotationAnimator::~ScreenRotationAnimator() {
182 // To prevent a call to |AnimationEndedCallback()| from calling a method on 188 // To prevent a call to |AnimationEndedCallback()| from calling a method on
183 // the |animator_|. 189 // the |animator_|.
184 weak_factory_.InvalidateWeakPtrs(); 190 weak_factory_.InvalidateWeakPtrs();
185 191
186 // Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in 192 // Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in
187 // order to make sure |metrics_reporter_| outlives the attached animation 193 // order to make sure |metrics_reporter_| outlives the attached animation
188 // sequence. 194 // sequence.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 AnimateRotation(std::move(rotation_request)); 227 AnimateRotation(std::move(rotation_request));
222 } 228 }
223 229
224 void ScreenRotationAnimator::SetRotation( 230 void ScreenRotationAnimator::SetRotation(
225 display::Display::Rotation old_rotation, 231 display::Display::Rotation old_rotation,
226 display::Display::Rotation new_rotation, 232 display::Display::Rotation new_rotation,
227 display::Display::RotationSource source) { 233 display::Display::RotationSource source) {
228 // Allow compositor locks to extend timeout, so that screen rotation only 234 // Allow compositor locks to extend timeout, so that screen rotation only
229 // takes output copy after contents are properlly resized, such as wallpaper 235 // takes output copy after contents are properlly resized, such as wallpaper
230 // and ARC apps. 236 // and ARC apps.
231 ui::Compositor* compositor = root_window_->layer()->GetCompositor(); 237 ui::Compositor* compositor =
238 GetRootWindow(display_id_)->layer()->GetCompositor();
232 compositor->set_allow_locks_to_extend_timeout(true); 239 compositor->set_allow_locks_to_extend_timeout(true);
233 Shell::Get()->display_manager()->SetDisplayRotation(display_id_, new_rotation, 240 Shell::Get()->display_manager()->SetDisplayRotation(display_id_, new_rotation,
234 source); 241 source);
235 compositor->set_allow_locks_to_extend_timeout(false); 242 compositor->set_allow_locks_to_extend_timeout(false);
236 const display::Display display = 243 const display::Display display =
237 Shell::Get()->display_manager()->GetDisplayForId(display_id_); 244 Shell::Get()->display_manager()->GetDisplayForId(display_id_);
238 old_layer_tree_owner_->root()->SetTransform( 245 old_layer_tree_owner_->root()->SetTransform(
239 CreateScreenRotationOldLayerTransformForDisplay(old_rotation, 246 CreateScreenRotationOldLayerTransformForDisplay(old_rotation,
240 new_rotation, display)); 247 new_rotation, display));
241 } 248 }
242 249
243 void ScreenRotationAnimator::RequestCopyScreenRotationContainerLayer( 250 void ScreenRotationAnimator::RequestCopyScreenRotationContainerLayer(
244 std::unique_ptr<cc::CopyOutputRequest> copy_output_request) { 251 std::unique_ptr<cc::CopyOutputRequest> copy_output_request) {
252 ui::Layer* screen_rotation_container_layer =
253 GetScreenRotationContainer(GetRootWindow(display_id_))->layer();
245 copy_output_request->set_area( 254 copy_output_request->set_area(
246 gfx::Rect(screen_rotation_container_layer_->size())); 255 gfx::Rect(screen_rotation_container_layer->size()));
247 screen_rotation_container_layer_->RequestCopyOfOutput( 256 screen_rotation_container_layer->RequestCopyOfOutput(
248 std::move(copy_output_request)); 257 std::move(copy_output_request));
249 } 258 }
250 259
251 ScreenRotationAnimator::CopyCallback 260 ScreenRotationAnimator::CopyCallback
252 ScreenRotationAnimator::CreateAfterCopyCallbackBeforeRotation( 261 ScreenRotationAnimator::CreateAfterCopyCallbackBeforeRotation(
253 std::unique_ptr<ScreenRotationRequest> rotation_request) { 262 std::unique_ptr<ScreenRotationRequest> rotation_request) {
254 return base::Bind(&ScreenRotationAnimator:: 263 return base::Bind(&ScreenRotationAnimator::
255 OnScreenRotationContainerLayerCopiedBeforeRotation, 264 OnScreenRotationContainerLayerCopiedBeforeRotation,
256 weak_factory_.GetWeakPtr(), 265 weak_factory_.GetWeakPtr(),
257 base::Passed(&rotation_request)); 266 base::Passed(&rotation_request));
(...skipping 23 matching lines...) Expand all
281 // layer is removed from the compositor and destroye before committing the 290 // layer is removed from the compositor and destroye before committing the
282 // request to the compositor. b) The compositor is shutdown. 291 // request to the compositor. b) The compositor is shutdown.
283 if (result->IsEmpty()) { 292 if (result->IsEmpty()) {
284 Shell::Get()->display_manager()->SetDisplayRotation( 293 Shell::Get()->display_manager()->SetDisplayRotation(
285 display_id_, rotation_request->new_rotation, rotation_request->source); 294 display_id_, rotation_request->new_rotation, rotation_request->source);
286 ProcessAnimationQueue(); 295 ProcessAnimationQueue();
287 return; 296 return;
288 } 297 }
289 298
290 old_layer_tree_owner_ = CopyLayerTree(std::move(result)); 299 old_layer_tree_owner_ = CopyLayerTree(std::move(result));
291 AddLayerAtTopOfWindowLayers(root_window_, old_layer_tree_owner_->root()); 300 AddLayerAtTopOfWindowLayers(GetRootWindow(display_id_),
301 old_layer_tree_owner_->root());
292 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation, 302 SetRotation(rotation_request->old_rotation, rotation_request->new_rotation,
293 rotation_request->source); 303 rotation_request->source);
294 std::unique_ptr<cc::CopyOutputRequest> copy_output_request = 304 std::unique_ptr<cc::CopyOutputRequest> copy_output_request =
295 cc::CopyOutputRequest::CreateRequest( 305 cc::CopyOutputRequest::CreateRequest(
296 CreateAfterCopyCallbackAfterRotation(std::move(rotation_request))); 306 CreateAfterCopyCallbackAfterRotation(std::move(rotation_request)));
297 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request)); 307 RequestCopyScreenRotationContainerLayer(std::move(copy_output_request));
298 } 308 }
299 309
300 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedAfterRotation( 310 void ScreenRotationAnimator::OnScreenRotationContainerLayerCopiedAfterRotation(
301 std::unique_ptr<ScreenRotationRequest> rotation_request, 311 std::unique_ptr<ScreenRotationRequest> rotation_request,
302 std::unique_ptr<cc::CopyOutputResult> result) { 312 std::unique_ptr<cc::CopyOutputResult> result) {
303 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_)) 313 if (IgnoreCopyResult(rotation_request->id, rotation_request_id_))
304 return; 314 return;
305 // In the following cases, abort animation: 315 // In the following cases, abort animation:
306 // 1) if the display was removed, 316 // 1) if the display was removed,
307 // 2) the copy request has been canceled or failed. It would fail if, 317 // 2) the copy request has been canceled or failed. It would fail if,
308 // for examples: a) The layer is removed from the compositor and destroye 318 // for examples: a) The layer is removed from the compositor and destroye
309 // before committing the request to the compositor. b) The compositor is 319 // before committing the request to the compositor. b) The compositor is
310 // shutdown. 320 // shutdown.
311 if (!IsDisplayIdValid(display_id_) || result->IsEmpty()) { 321 if (!IsDisplayIdValid(display_id_) || result->IsEmpty()) {
312 ProcessAnimationQueue(); 322 ProcessAnimationQueue();
313 return; 323 return;
314 } 324 }
315 325
326 aura::Window* root_window = GetRootWindow(display_id_);
327 // |root_window| changed while waiting for the copy request.
328 if (!root_window->layer()->Contains(old_layer_tree_owner_->root())) {
oshima 2017/05/31 22:37:57 Hmm, I probably made a bad recommendation. I'm ver
329 ProcessAnimationQueue();
330 return;
331 }
332
316 new_layer_tree_owner_ = CopyLayerTree(std::move(result)); 333 new_layer_tree_owner_ = CopyLayerTree(std::move(result));
317 AddLayerBelowWindowLayer(root_window_, old_layer_tree_owner_->root(), 334 AddLayerBelowWindowLayer(root_window, old_layer_tree_owner_->root(),
318 new_layer_tree_owner_->root()); 335 new_layer_tree_owner_->root());
319 AnimateRotation(std::move(rotation_request)); 336 AnimateRotation(std::move(rotation_request));
320 } 337 }
321 338
322 void ScreenRotationAnimator::CreateOldLayerTreeForSlowAnimation() { 339 void ScreenRotationAnimator::CreateOldLayerTreeForSlowAnimation() {
323 old_layer_tree_owner_ = ::wm::RecreateLayers(root_window_); 340 aura::Window* root_window = GetRootWindow(display_id_);
324 // |screen_rotation_container_layer_| needs update after |RecreateLayers()|. 341 old_layer_tree_owner_ = ::wm::RecreateLayers(root_window);
325 screen_rotation_container_layer_ = 342 AddLayerAtTopOfWindowLayers(root_window, old_layer_tree_owner_->root());
326 GetScreenRotationContainer(root_window_)->layer();
327 AddLayerAtTopOfWindowLayers(root_window_, old_layer_tree_owner_->root());
328 } 343 }
329 344
330 std::unique_ptr<ui::LayerTreeOwner> ScreenRotationAnimator::CopyLayerTree( 345 std::unique_ptr<ui::LayerTreeOwner> ScreenRotationAnimator::CopyLayerTree(
331 std::unique_ptr<cc::CopyOutputResult> result) { 346 std::unique_ptr<cc::CopyOutputResult> result) {
332 cc::TextureMailbox texture_mailbox; 347 cc::TextureMailbox texture_mailbox;
333 std::unique_ptr<cc::SingleReleaseCallback> release_callback; 348 std::unique_ptr<cc::SingleReleaseCallback> release_callback;
334 result->TakeTexture(&texture_mailbox, &release_callback); 349 result->TakeTexture(&texture_mailbox, &release_callback);
335 DCHECK(texture_mailbox.IsTexture()); 350 DCHECK(texture_mailbox.IsTexture());
336 351 const gfx::Rect rect(
337 const gfx::Rect rect(screen_rotation_container_layer_->size()); 352 GetScreenRotationContainer(GetRootWindow(display_id_))->layer()->size());
338 std::unique_ptr<ui::Layer> copy_layer = base::MakeUnique<ui::Layer>(); 353 std::unique_ptr<ui::Layer> copy_layer = base::MakeUnique<ui::Layer>();
339 copy_layer->SetBounds(rect); 354 copy_layer->SetBounds(rect);
340 copy_layer->SetTextureMailbox(texture_mailbox, std::move(release_callback), 355 copy_layer->SetTextureMailbox(texture_mailbox, std::move(release_callback),
341 rect.size()); 356 rect.size());
342 return base::MakeUnique<ui::LayerTreeOwner>(std::move(copy_layer)); 357 return base::MakeUnique<ui::LayerTreeOwner>(std::move(copy_layer));
343 } 358 }
344 359
345 void ScreenRotationAnimator::AnimateRotation( 360 void ScreenRotationAnimator::AnimateRotation(
346 std::unique_ptr<ScreenRotationRequest> rotation_request) { 361 std::unique_ptr<ScreenRotationRequest> rotation_request) {
362 aura::Window* root_window = GetRootWindow(display_id_);
363 ui::Layer* screen_rotation_container_layer =
364 GetScreenRotationContainer(root_window)->layer();
365
347 screen_rotation_state_ = ROTATING; 366 screen_rotation_state_ = ROTATING;
348 const int rotation_factor = GetRotationFactor(rotation_request->old_rotation, 367 const int rotation_factor = GetRotationFactor(rotation_request->old_rotation,
349 rotation_request->new_rotation); 368 rotation_request->new_rotation);
350 const int old_layer_initial_rotation_degrees = GetInitialDegrees( 369 const int old_layer_initial_rotation_degrees = GetInitialDegrees(
351 rotation_request->old_rotation, rotation_request->new_rotation); 370 rotation_request->old_rotation, rotation_request->new_rotation);
352 const base::TimeDelta duration = 371 const base::TimeDelta duration =
353 base::TimeDelta::FromMilliseconds(kRotationDurationInMs); 372 base::TimeDelta::FromMilliseconds(kRotationDurationInMs);
354 const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN; 373 const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN;
355 const gfx::Rect rotated_screen_bounds = root_window_->GetTargetBounds(); 374 const gfx::Rect rotated_screen_bounds = root_window->GetTargetBounds();
356 const gfx::Point pivot = gfx::Point(rotated_screen_bounds.width() / 2, 375 const gfx::Point pivot = gfx::Point(rotated_screen_bounds.width() / 2,
357 rotated_screen_bounds.height() / 2); 376 rotated_screen_bounds.height() / 2);
358 377
359 ui::Layer* new_root_layer; 378 ui::Layer* new_root_layer;
360 if (!new_layer_tree_owner_ || 379 if (!new_layer_tree_owner_ ||
361 has_switch_ash_disable_smooth_screen_rotation_) { 380 has_switch_ash_disable_smooth_screen_rotation_) {
362 new_root_layer = screen_rotation_container_layer_; 381 new_root_layer = screen_rotation_container_layer;
363 } else { 382 } else {
364 new_root_layer = new_layer_tree_owner_->root(); 383 new_root_layer = new_layer_tree_owner_->root();
365 // Add a black mask layer on top of |screen_rotation_container_layer_|. 384 // Add a black mask layer on top of |screen_rotation_container_layer|.
366 black_mask_layer_owner_ = CreateBlackMaskLayerOwner( 385 black_mask_layer_owner_ = CreateBlackMaskLayerOwner(
367 gfx::Rect(screen_rotation_container_layer_->size())); 386 gfx::Rect(screen_rotation_container_layer->size()));
368 AddLayerBelowWindowLayer(root_window_, new_root_layer, 387 AddLayerBelowWindowLayer(root_window, new_root_layer,
369 black_mask_layer_owner_->layer()); 388 black_mask_layer_owner_->layer());
370 } 389 }
371 390
372 std::unique_ptr<ScreenRotationAnimation> new_layer_screen_rotation = 391 std::unique_ptr<ScreenRotationAnimation> new_layer_screen_rotation =
373 base::MakeUnique<ScreenRotationAnimation>( 392 base::MakeUnique<ScreenRotationAnimation>(
374 new_root_layer, kRotationDegrees * rotation_factor, 393 new_root_layer, kRotationDegrees * rotation_factor,
375 0 /* end_degrees */, new_root_layer->opacity(), 394 0 /* end_degrees */, new_root_layer->opacity(),
376 new_root_layer->opacity() /* target_opacity */, pivot, duration, 395 new_root_layer->opacity() /* target_opacity */, pivot, duration,
377 tween_type); 396 tween_type);
378 397
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 screen_rotation_animator_observers_.AddObserver(observer); 482 screen_rotation_animator_observers_.AddObserver(observer);
464 } 483 }
465 484
466 void ScreenRotationAnimator::RemoveScreenRotationAnimatorObserver( 485 void ScreenRotationAnimator::RemoveScreenRotationAnimatorObserver(
467 ScreenRotationAnimatorObserver* observer) { 486 ScreenRotationAnimatorObserver* observer) {
468 screen_rotation_animator_observers_.RemoveObserver(observer); 487 screen_rotation_animator_observers_.RemoveObserver(observer);
469 } 488 }
470 489
471 void ScreenRotationAnimator::ProcessAnimationQueue() { 490 void ScreenRotationAnimator::ProcessAnimationQueue() {
472 screen_rotation_state_ = IDLE; 491 screen_rotation_state_ = IDLE;
473 if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) 492 if (black_mask_layer_owner_) {
474 root_window_->layer()->Remove(black_mask_layer_owner_->layer()); 493 RemoveLayerFromRootWindowForDisplayId(display_id_,
494 black_mask_layer_owner_->layer());
495 }
475 old_layer_tree_owner_.reset(); 496 old_layer_tree_owner_.reset();
476 new_layer_tree_owner_.reset(); 497 new_layer_tree_owner_.reset();
477 black_mask_layer_owner_.reset(); 498 black_mask_layer_owner_.reset();
478 if (last_pending_request_ && IsDisplayIdValid(display_id_)) { 499 if (last_pending_request_ && IsDisplayIdValid(display_id_)) {
479 StartRotationAnimation(std::move(last_pending_request_)); 500 StartRotationAnimation(std::move(last_pending_request_));
480 return; 501 return;
481 } 502 }
482 503
483 // This is only used in test to notify animator observer. 504 // This is only used in test to notify animator observer.
484 for (auto& observer : screen_rotation_animator_observers_) 505 for (auto& observer : screen_rotation_animator_observers_)
485 observer.OnScreenRotationAnimationFinished(this); 506 observer.OnScreenRotationAnimationFinished(this);
486 } 507 }
487 508
488 void ScreenRotationAnimator::StopAnimating() { 509 void ScreenRotationAnimator::StopAnimating() {
489 // |old_layer_tree_owner_| new_layer_tree_owner_| could be nullptr if another 510 // |old_layer_tree_owner_| new_layer_tree_owner_| could be nullptr if another
490 // the rotation request comes before the copy request finished. 511 // the rotation request comes before the copy request finished.
491 if (old_layer_tree_owner_) 512 if (old_layer_tree_owner_)
492 old_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); 513 old_layer_tree_owner_->root()->GetAnimator()->StopAnimating();
493 if (new_layer_tree_owner_) 514 if (new_layer_tree_owner_)
494 new_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); 515 new_layer_tree_owner_->root()->GetAnimator()->StopAnimating();
495 if (IsDisplayIdValid(display_id_) && black_mask_layer_owner_) 516 if (black_mask_layer_owner_) {
496 root_window_->layer()->Remove(black_mask_layer_owner_->layer()); 517 RemoveLayerFromRootWindowForDisplayId(display_id_,
518 black_mask_layer_owner_->layer());
519 }
497 } 520 }
498 521
499 } // namespace ash 522 } // namespace ash
OLDNEW
« no previous file with comments | « ash/rotator/screen_rotation_animator.h ('k') | ash/rotator/screen_rotation_animator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698