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

Side by Side Diff: ui/gfx/compositor/layer.cc

Issue 8247009: Explicit animation support (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated views desktop demo. Created 9 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "ui/gfx/compositor/layer.h" 5 #include "ui/gfx/compositor/layer.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "ui/base/animation/animation.h"
12 #include "ui/gfx/compositor/layer_animator.h" 11 #include "ui/gfx/compositor/layer_animator.h"
13 #include "ui/gfx/canvas_skia.h" 12 #include "ui/gfx/canvas_skia.h"
14 #include "ui/gfx/interpolated_transform.h" 13 #include "ui/gfx/interpolated_transform.h"
15 #include "ui/gfx/point3.h" 14 #include "ui/gfx/point3.h"
16 15
17 namespace { 16 namespace {
18 17
19 const float EPSILON = 1e-3f; 18 const float EPSILON = 1e-3f;
20 19
21 bool IsApproximateMultilpleOf(float value, float base) { 20 bool IsApproximateMultilpleOf(float value, float base) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 } 98 }
100 99
101 bool Layer::Contains(const Layer* other) const { 100 bool Layer::Contains(const Layer* other) const {
102 for (const Layer* parent = other; parent; parent = parent->parent()) { 101 for (const Layer* parent = other; parent; parent = parent->parent()) {
103 if (parent == this) 102 if (parent == this)
104 return true; 103 return true;
105 } 104 }
106 return false; 105 return false;
107 } 106 }
108 107
109 void Layer::SetAnimation(Animation* animation) { 108 void Layer::SetAnimator(LayerAnimator* animator) {
110 if (animation) { 109 animator->SetLayer(this);
111 if (!animator_.get()) 110 animator_.reset(animator);
112 animator_.reset(new LayerAnimator(this)); 111 }
113 animation->Start(); 112
114 animator_->SetAnimation(animation); 113 LayerAnimator& Layer::GetAnimator() {
115 } else { 114 if (!animator_.get()) {
116 animator_.reset(); 115 SetAnimator(LayerAnimator::CreateDefaultAnimator());
117 } 116 }
117 return *animator_;
118 } 118 }
119 119
120 void Layer::SetTransform(const ui::Transform& transform) { 120 void Layer::SetTransform(const ui::Transform& transform) {
121 StopAnimatingIfNecessary(LayerAnimator::TRANSFORM); 121 if (animator_.get())
122 if (animator_.get() && animator_->IsRunning()) { 122 animator_->SetTransform(transform);
123 animator_->AnimateTransform(transform); 123 else
124 return; 124 SetTransformImmediately(transform);
125 }
126 SetTransformImmediately(transform);
127 } 125 }
128 126
129 void Layer::SetBounds(const gfx::Rect& bounds) { 127 void Layer::SetBounds(const gfx::Rect& bounds) {
130 StopAnimatingIfNecessary(LayerAnimator::LOCATION); 128 if (animator_.get())
131 if (animator_.get() && animator_->IsRunning() && 129 animator_->SetBounds(bounds);
132 bounds.size() == bounds_.size()) { 130 else
133 animator_->AnimateToPoint(bounds.origin()); 131 SetBoundsImmediately(bounds);
134 return;
135 }
136 SetBoundsImmediately(bounds);
137 } 132 }
138 133
139 void Layer::SetOpacity(float opacity) { 134 void Layer::SetOpacity(float opacity) {
140 StopAnimatingIfNecessary(LayerAnimator::OPACITY); 135 if (animator_.get())
141 if (animator_.get() && animator_->IsRunning()) { 136 animator_->SetOpacity(opacity);
142 animator_->AnimateOpacity(opacity); 137 else
143 return; 138 SetOpacityImmediately(opacity);
144 }
145 SetOpacityImmediately(opacity);
146 } 139 }
147 140
148 void Layer::SetVisible(bool visible) { 141 void Layer::SetVisible(bool visible) {
149 if (visible_ == visible) 142 if (visible_ == visible)
150 return; 143 return;
151 144
152 bool was_drawn = IsDrawn(); 145 bool was_drawn = IsDrawn();
153 visible_ = visible; 146 visible_ = visible;
154 bool is_drawn = IsDrawn(); 147 bool is_drawn = IsDrawn();
155 if (was_drawn == is_drawn) 148 if (was_drawn == is_drawn)
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 if (!children_[i]->IsCompletelyOpaque() || !children_[i]->visible_) 314 if (!children_[i]->IsCompletelyOpaque() || !children_[i]->visible_)
322 continue; 315 continue;
323 316
324 // Ignore children that aren't rotated by multiples of 90 degrees. 317 // Ignore children that aren't rotated by multiples of 90 degrees.
325 float degrees; 318 float degrees;
326 if (!InterpolatedTransform::FactorTRS(children_[i]->transform(), 319 if (!InterpolatedTransform::FactorTRS(children_[i]->transform(),
327 NULL, &degrees, NULL) || 320 NULL, &degrees, NULL) ||
328 !IsApproximateMultilpleOf(degrees, 90.0f)) 321 !IsApproximateMultilpleOf(degrees, 90.0f))
329 continue; 322 continue;
330 323
331 gfx::Rect candidate_hole = children_[i]->bounds(); 324 // The reason why we don't just take the bounds and apply the transform is
332 children_[i]->transform().TransformRect(&candidate_hole); 325 // that the bounds encodes a position, too, so the effective transformation
326 // matrix is actually different that the one reported. As well, the bounds
327 // will not necessarily be at the origin.
328 gfx::Rect candidate_hole(children_[i]->bounds_.size());
329 ui::Transform transform = children_[i]->transform();
330 transform.ConcatTranslate(static_cast<float>(children_[i]->bounds_.x()),
331 static_cast<float>(children_[i]->bounds_.y()));
332 transform.TransformRect(&candidate_hole);
333 333
334 // This layer might not contain the child (e.g., a portion of the child may 334 // This layer might not contain the child (e.g., a portion of the child may
335 // be offscreen). Only the portion of the child that overlaps this layer is 335 // be offscreen). Only the portion of the child that overlaps this layer is
336 // of any importance, so take the intersection. 336 // of any importance, so take the intersection.
337 candidate_hole = bounds().Intersect(candidate_hole); 337 candidate_hole = bounds().Intersect(candidate_hole);
338 338
339 // Ensure we have the largest hole. 339 // Ensure we have the largest hole.
340 if (candidate_hole.size().GetArea() > hole_rect_.size().GetArea()) 340 if (candidate_hole.size().GetArea() > hole_rect_.size().GetArea())
341 hole_rect_ = candidate_hole; 341 hole_rect_ = candidate_hole;
342 } 342 }
343 343
344 // Free up texture memory if the hole fills bounds of layer. 344 // Free up texture memory if the hole fills bounds of layer.
345 if (!ShouldDraw() && !layer_updated_externally_) 345 if (!ShouldDraw() && !layer_updated_externally_)
346 texture_ = NULL; 346 DropTextures();
347 } 347 }
348 348
349 bool Layer::IsCompletelyOpaque() const { 349 bool Layer::IsCompletelyOpaque() const {
350 return fills_bounds_opaquely() && GetCombinedOpacity() == 1.0f; 350 return fills_bounds_opaquely() && GetCombinedOpacity() == 1.0f;
351 } 351 }
352 352
353 // static 353 // static
354 void Layer::PunchHole(const gfx::Rect& rect, 354 void Layer::PunchHole(const gfx::Rect& rect,
355 const gfx::Rect& region_to_punch_out, 355 const gfx::Rect& region_to_punch_out,
356 std::vector<gfx::Rect>* sides) { 356 std::vector<gfx::Rect>* sides) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 const Layer* p = this; 418 const Layer* p = this;
419 for (; p && p != ancestor; p = p->parent()) { 419 for (; p && p != ancestor; p = p->parent()) {
420 if (p->transform().HasChange()) 420 if (p->transform().HasChange())
421 transform->ConcatTransform(p->transform()); 421 transform->ConcatTransform(p->transform());
422 transform->ConcatTranslate(static_cast<float>(p->bounds().x()), 422 transform->ConcatTranslate(static_cast<float>(p->bounds().x()),
423 static_cast<float>(p->bounds().y())); 423 static_cast<float>(p->bounds().y()));
424 } 424 }
425 return p == ancestor; 425 return p == ancestor;
426 } 426 }
427 427
428 void Layer::StopAnimatingIfNecessary(
429 LayerAnimator::AnimationProperty property) {
430 if (!animator_.get() || !animator_->IsRunning() ||
431 !animator_->got_initial_tick()) {
432 return;
433 }
434
435 if (property != LayerAnimator::LOCATION &&
436 animator_->IsAnimating(LayerAnimator::LOCATION)) {
437 SetBoundsImmediately(
438 gfx::Rect(animator_->GetTargetPoint(), bounds_.size()));
439 }
440 if (property != LayerAnimator::OPACITY &&
441 animator_->IsAnimating(LayerAnimator::OPACITY)) {
442 SetOpacityImmediately(animator_->GetTargetOpacity());
443 }
444 if (property != LayerAnimator::TRANSFORM &&
445 animator_->IsAnimating(LayerAnimator::TRANSFORM)) {
446 SetTransformImmediately(animator_->GetTargetTransform());
447 }
448 animator_.reset();
449 }
450
451 void Layer::SetBoundsImmediately(const gfx::Rect& bounds) { 428 void Layer::SetBoundsImmediately(const gfx::Rect& bounds) {
452 bounds_ = bounds; 429 bounds_ = bounds;
453 430
454 if (parent()) 431 if (parent())
455 parent()->RecomputeHole(); 432 parent()->RecomputeHole();
456 } 433 }
457 434
458 void Layer::SetTransformImmediately(const ui::Transform& transform) { 435 void Layer::SetTransformImmediately(const ui::Transform& transform) {
459 transform_ = transform; 436 transform_ = transform;
460 437
(...skipping 16 matching lines...) Expand all
477 while (!to_process.empty()) { 454 while (!to_process.empty()) {
478 Layer* current = to_process.front(); 455 Layer* current = to_process.front();
479 to_process.pop(); 456 to_process.pop();
480 current->RecomputeHole(); 457 current->RecomputeHole();
481 for (size_t i = 0; i < current->children_.size(); ++i) 458 for (size_t i = 0; i < current->children_.size(); ++i)
482 to_process.push(current->children_.at(i)); 459 to_process.push(current->children_.at(i));
483 } 460 }
484 } 461 }
485 } 462 }
486 463
487 void Layer::SetBoundsFromAnimator(const gfx::Rect& bounds) { 464 void Layer::SetBoundsFromAnimation(const gfx::Rect& bounds) {
488 SetBoundsImmediately(bounds); 465 SetBoundsImmediately(bounds);
489 } 466 }
490 467
491 void Layer::SetTransformFromAnimator(const Transform& transform) { 468 void Layer::SetTransformFromAnimation(const Transform& transform) {
492 SetTransformImmediately(transform); 469 SetTransformImmediately(transform);
493 } 470 }
494 471
495 void Layer::SetOpacityFromAnimator(float opacity) { 472 void Layer::SetOpacityFromAnimation(float opacity) {
496 SetOpacityImmediately(opacity); 473 SetOpacityImmediately(opacity);
497 } 474 }
498 475
476 void Layer::ScheduleDrawForAnimation() {
477 ScheduleDraw();
478 }
479
480 const gfx::Rect& Layer::GetBoundsForAnimation() const {
481 return bounds();
482 }
483
484 const Transform& Layer::GetTransformForAnimation() const {
485 return transform();
486 }
487
488 const float Layer::GetOpacityForAnimation() const {
489 return opacity();
490 }
491
499 } // namespace ui 492 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698