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

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

Powered by Google App Engine
This is Rietveld 408576698