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

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

Issue 2780823002: Uses copy request to flatten the layers to do screen rotation animation. (Closed)
Patch Set: Resolve merge conflicts. Created 3 years, 8 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 <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "ash/common/ash_switches.h"
11 #include "ash/display/window_tree_host_manager.h" 12 #include "ash/display/window_tree_host_manager.h"
12 #include "ash/rotator/screen_rotation_animation.h" 13 #include "ash/rotator/screen_rotation_animation.h"
13 #include "ash/rotator/screen_rotation_animator_observer.h" 14 #include "ash/rotator/screen_rotation_animator_observer.h"
14 #include "ash/shell.h" 15 #include "ash/shell.h"
15 #include "base/command_line.h" 16 #include "base/command_line.h"
16 #include "base/memory/ptr_util.h" 17 #include "base/memory/ptr_util.h"
17 #include "base/metrics/histogram_macros.h" 18 #include "base/metrics/histogram_macros.h"
18 #include "base/time/time.h" 19 #include "base/time/time.h"
20 #include "cc/output/copy_output_request.h"
21 #include "cc/output/copy_output_result.h"
19 #include "ui/aura/window.h" 22 #include "ui/aura/window.h"
20 #include "ui/compositor/layer.h" 23 #include "ui/compositor/layer.h"
21 #include "ui/compositor/layer_animation_element.h" 24 #include "ui/compositor/layer_animation_element.h"
22 #include "ui/compositor/layer_animation_observer.h" 25 #include "ui/compositor/layer_animation_observer.h"
23 #include "ui/compositor/layer_animation_sequence.h" 26 #include "ui/compositor/layer_animation_sequence.h"
24 #include "ui/compositor/layer_animator.h" 27 #include "ui/compositor/layer_animator.h"
25 #include "ui/compositor/layer_owner.h" 28 #include "ui/compositor/layer_owner.h"
26 #include "ui/compositor/layer_tree_owner.h" 29 #include "ui/compositor/layer_tree_owner.h"
27 #include "ui/display/display.h" 30 #include "ui/display/display.h"
28 #include "ui/display/manager/display_manager.h" 31 #include "ui/display/manager/display_manager.h"
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 void Report(int value) override { 180 void Report(int value) override {
178 UMA_HISTOGRAM_PERCENTAGE("Ash.Rotation.AnimationSmoothness", value); 181 UMA_HISTOGRAM_PERCENTAGE("Ash.Rotation.AnimationSmoothness", value);
179 } 182 }
180 183
181 private: 184 private:
182 DISALLOW_COPY_AND_ASSIGN(ScreenRotationAnimationMetricsReporter); 185 DISALLOW_COPY_AND_ASSIGN(ScreenRotationAnimationMetricsReporter);
183 }; 186 };
184 187
185 } // namespace 188 } // namespace
186 189
187 struct ScreenRotationAnimator::ScreenRotationRequest {
188 ScreenRotationRequest(display::Display::Rotation to_rotation,
189 display::Display::RotationSource from_source)
190 : new_rotation(to_rotation), source(from_source) {}
191 display::Display::Rotation new_rotation;
192 display::Display::RotationSource source;
193 };
194
195 ScreenRotationAnimator::ScreenRotationAnimator(int64_t display_id) 190 ScreenRotationAnimator::ScreenRotationAnimator(int64_t display_id)
196 : display_id_(display_id), 191 : display_id_(display_id),
197 is_rotating_(false), 192 is_rotating_(false),
198 metrics_reporter_( 193 metrics_reporter_(
199 base::MakeUnique<ScreenRotationAnimationMetricsReporter>()), 194 base::MakeUnique<ScreenRotationAnimationMetricsReporter>()),
200 disable_animation_timers_for_test_(false), 195 disable_animation_timers_for_test_(false),
201 weak_factory_(this) {} 196 weak_factory_(this) {}
202 197
203 ScreenRotationAnimator::~ScreenRotationAnimator() { 198 ScreenRotationAnimator::~ScreenRotationAnimator() {
204 // To prevent a call to |LayerCleanupObserver::OnLayerAnimationAborted()| from 199 // To prevent a call to |LayerCleanupObserver::OnLayerAnimationAborted()| from
205 // calling a method on the |animator_|. 200 // calling a method on the |animator_|.
206 weak_factory_.InvalidateWeakPtrs(); 201 weak_factory_.InvalidateWeakPtrs();
207 202
208 // Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in 203 // Explicitly reset the |old_layer_tree_owner_| and |metrics_reporter_| in
209 // order to make sure |metrics_reporter_| outlives the attached animation 204 // order to make sure |metrics_reporter_| outlives the attached animation
210 // sequence. 205 // sequence.
211 old_layer_tree_owner_.reset(); 206 old_layer_tree_owner_.reset();
212 metrics_reporter_.reset(); 207 metrics_reporter_.reset();
213 } 208 }
214 209
210 void ScreenRotationAnimator::StartRotationAnimation(
211 std::unique_ptr<ScreenRotationRequest> rotation_request) {
212 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
213 switches::kAshEnableSmoothScreenRotation)) {
214 RequestCopyRootLayerAndAnimateRotation(std::move(rotation_request));
215 } else {
216 CreateOldLayerTree();
217 AnimateRotation(std::move(rotation_request));
218 }
219 }
220
221 void ScreenRotationAnimator::RequestCopyRootLayerAndAnimateRotation(
222 std::unique_ptr<ScreenRotationRequest> rotation_request) {
223 std::unique_ptr<cc::CopyOutputRequest> copy_output_request =
224 cc::CopyOutputRequest::CreateRequest(
225 CreateAfterCopyCallback(std::move(rotation_request)));
226 ui::Layer* layer = GetRootWindow(display_id_)->layer();
227 copy_output_request->set_area(gfx::Rect(layer->size()));
228 layer->RequestCopyOfOutput(std::move(copy_output_request));
229 }
230
231 ScreenRotationAnimator::CopyCallback
232 ScreenRotationAnimator::CreateAfterCopyCallback(
233 std::unique_ptr<ScreenRotationRequest> rotation_request) {
234 return base::Bind(&ScreenRotationAnimator::OnRootLayerCopiedBeforeRotation,
235 weak_factory_.GetWeakPtr(),
236 base::Passed(&rotation_request));
237 }
238
239 void ScreenRotationAnimator::OnRootLayerCopiedBeforeRotation(
240 std::unique_ptr<ScreenRotationRequest> rotation_request,
241 std::unique_ptr<cc::CopyOutputResult> result) {
242 // If display was removed, should abort rotation.
243 if (!IsDisplayIdValid(display_id_)) {
244 ProcessAnimationQueue();
245 return;
246 }
247
248 // Fall back to recreate layers solution when the copy request has been
249 // canceled or failed. It would fail if, for examples: a) The layer is removed
250 // from the compositor and destroyed before committing the request to the
251 // compositor. b) The compositor is shutdown.
252 if (result->IsEmpty())
253 CreateOldLayerTree();
254 else
255 CopyOldLayerTree(std::move(result));
256 AnimateRotation(std::move(rotation_request));
257 }
258
259 void ScreenRotationAnimator::CreateOldLayerTree() {
260 old_layer_tree_owner_ = ::wm::RecreateLayers(GetRootWindow(display_id_));
261 }
262
263 void ScreenRotationAnimator::CopyOldLayerTree(
264 std::unique_ptr<cc::CopyOutputResult> result) {
265 cc::TextureMailbox texture_mailbox;
266 std::unique_ptr<cc::SingleReleaseCallback> release_callback;
267 result->TakeTexture(&texture_mailbox, &release_callback);
268 DCHECK(texture_mailbox.IsTexture());
269
270 aura::Window* root_window = GetRootWindow(display_id_);
271 gfx::Rect rect(root_window->layer()->size());
272 std::unique_ptr<ui::Layer> copy_layer = base::MakeUnique<ui::Layer>();
273 copy_layer->SetBounds(rect);
274 copy_layer->SetTextureMailbox(texture_mailbox, std::move(release_callback),
275 rect.size());
276 old_layer_tree_owner_ =
277 base::MakeUnique<ui::LayerTreeOwner>(std::move(copy_layer));
278 }
279
215 void ScreenRotationAnimator::AnimateRotation( 280 void ScreenRotationAnimator::AnimateRotation(
216 std::unique_ptr<ScreenRotationRequest> rotation_request) { 281 std::unique_ptr<ScreenRotationRequest> rotation_request) {
217 aura::Window* root_window = GetRootWindow(display_id_); 282 aura::Window* root_window = GetRootWindow(display_id_);
283 std::unique_ptr<LayerCleanupObserver> old_layer_cleanup_observer(
284 new LayerCleanupObserver(weak_factory_.GetWeakPtr()));
285 ui::Layer* old_root_layer = old_layer_tree_owner_->root();
286 old_root_layer->set_name("ScreenRotationAnimator:old_layer_tree");
287 // Add the cloned layer tree in to the root, so it will be rendered.
288 root_window->layer()->Add(old_root_layer);
289 root_window->layer()->StackAtTop(old_root_layer);
218 290
219 const gfx::Rect original_screen_bounds = root_window->GetTargetBounds(); 291 const gfx::Rect original_screen_bounds = root_window->GetTargetBounds();
220 292
221 const int rotation_factor = GetRotationFactor( 293 const int rotation_factor = GetRotationFactor(
222 GetCurrentScreenRotation(display_id_), rotation_request->new_rotation); 294 GetCurrentScreenRotation(display_id_), rotation_request->new_rotation);
223 295
224 const int old_layer_initial_rotation_degrees = GetInitialDegrees( 296 const int old_layer_initial_rotation_degrees = GetInitialDegrees(
225 GetCurrentScreenRotation(display_id_), rotation_request->new_rotation); 297 GetCurrentScreenRotation(display_id_), rotation_request->new_rotation);
226 298
227 const base::TimeDelta duration = 299 const base::TimeDelta duration =
228 base::TimeDelta::FromMilliseconds(kRotationDurationInMs); 300 base::TimeDelta::FromMilliseconds(kRotationDurationInMs);
229 301
230 const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN; 302 const gfx::Tween::Type tween_type = gfx::Tween::FAST_OUT_LINEAR_IN;
231 303
232 std::unique_ptr<ui::LayerTreeOwner> old_layer_tree =
233 ::wm::RecreateLayers(root_window);
234 old_layer_tree->root()->set_name("ScreenRotationAnimator:old_layer_tree");
235
236 // Add the cloned layer tree in to the root, so it will be rendered.
237 root_window->layer()->Add(old_layer_tree->root());
238 root_window->layer()->StackAtTop(old_layer_tree->root());
239
240 old_layer_tree_owner_ = std::move(old_layer_tree);
241 std::unique_ptr<LayerCleanupObserver> old_layer_cleanup_observer(
242 new LayerCleanupObserver(weak_factory_.GetWeakPtr()));
243
244 Shell::Get()->display_manager()->SetDisplayRotation( 304 Shell::Get()->display_manager()->SetDisplayRotation(
245 display_id_, rotation_request->new_rotation, rotation_request->source); 305 display_id_, rotation_request->new_rotation, rotation_request->source);
246 306
247 const gfx::Rect rotated_screen_bounds = root_window->GetTargetBounds(); 307 const gfx::Rect rotated_screen_bounds = root_window->GetTargetBounds();
248 const gfx::Point pivot = gfx::Point(rotated_screen_bounds.width() / 2, 308 const gfx::Point pivot = gfx::Point(rotated_screen_bounds.width() / 2,
249 rotated_screen_bounds.height() / 2); 309 rotated_screen_bounds.height() / 2);
250 310
251 ui::Layer* old_root_layer = old_layer_tree_owner_->root();
252 // We must animate each non-cloned child layer individually because the cloned 311 // We must animate each non-cloned child layer individually because the cloned
253 // layer was added as a child to |root_window|'s layer so that it will be 312 // layer was added as a child to |root_window|'s layer so that it will be
254 // rendered. 313 // rendered.
255 // TODO(bruthig): Add a NOT_DRAWN layer in between the root_window's layer and 314 // TODO(bruthig): Add a NOT_DRAWN layer in between the root_window's layer and
256 // its current children so that we only need to initiate two 315 // its current children so that we only need to initiate two
257 // LayerAnimationSequences. One for the new layers and one for the old layer. 316 // LayerAnimationSequences. One for the new layers and one for the old layer.
258 for (ui::Layer* child_layer : root_window->layer()->children()) { 317 for (ui::Layer* child_layer : root_window->layer()->children()) {
259 // Skip the cloned layer because it has a different animation. 318 // Skip the cloned layer because it has a different animation.
260 if (child_layer == old_root_layer) 319 if (child_layer == old_root_layer)
261 continue; 320 continue;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 base::MakeUnique<ScreenRotationRequest>(new_rotation, source); 379 base::MakeUnique<ScreenRotationRequest>(new_rotation, source);
321 380
322 if (is_rotating_) { 381 if (is_rotating_) {
323 last_pending_request_ = std::move(rotation_request); 382 last_pending_request_ = std::move(rotation_request);
324 // The pending request will be processed when the 383 // The pending request will be processed when the
325 // OnLayerAnimation(Ended|Aborted) methods should be called after 384 // OnLayerAnimation(Ended|Aborted) methods should be called after
326 // StopAnimating(). 385 // StopAnimating().
327 StopAnimating(); 386 StopAnimating();
328 } else { 387 } else {
329 is_rotating_ = true; 388 is_rotating_ = true;
330 AnimateRotation(std::move(rotation_request)); 389 StartRotationAnimation(std::move(rotation_request));
331 } 390 }
332 } 391 }
333 392
334 void ScreenRotationAnimator::AddScreenRotationAnimatorObserver( 393 void ScreenRotationAnimator::AddScreenRotationAnimatorObserver(
335 ScreenRotationAnimatorObserver* observer) { 394 ScreenRotationAnimatorObserver* observer) {
336 screen_rotation_animator_observers_.AddObserver(observer); 395 screen_rotation_animator_observers_.AddObserver(observer);
337 } 396 }
338 397
339 void ScreenRotationAnimator::RemoveScreenRotationAnimatorObserver( 398 void ScreenRotationAnimator::RemoveScreenRotationAnimatorObserver(
340 ScreenRotationAnimatorObserver* observer) { 399 ScreenRotationAnimatorObserver* observer) {
(...skipping 26 matching lines...) Expand all
367 if (child_layer == old_layer_tree_owner_->root()) 426 if (child_layer == old_layer_tree_owner_->root())
368 continue; 427 continue;
369 428
370 child_layer->GetAnimator()->StopAnimating(); 429 child_layer->GetAnimator()->StopAnimating();
371 } 430 }
372 431
373 old_layer_tree_owner_->root()->GetAnimator()->StopAnimating(); 432 old_layer_tree_owner_->root()->GetAnimator()->StopAnimating();
374 } 433 }
375 434
376 } // namespace ash 435 } // 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