| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "cc/layers/layer_utils.h" | |
| 6 | |
| 7 #include "cc/layers/layer_impl.h" | |
| 8 #include "cc/trees/layer_tree_host_common.h" | |
| 9 #include "ui/gfx/geometry/box_f.h" | |
| 10 | |
| 11 namespace cc { | |
| 12 | |
| 13 namespace { | |
| 14 | |
| 15 bool HasAnimationThatInflatesBounds(const LayerImpl& layer) { | |
| 16 return layer.layer_animation_controller()->HasAnimationThatInflatesBounds(); | |
| 17 } | |
| 18 | |
| 19 bool HasFilterAnimationThatInflatesBounds(const LayerImpl& layer) { | |
| 20 return layer.layer_animation_controller() | |
| 21 ->HasFilterAnimationThatInflatesBounds(); | |
| 22 } | |
| 23 | |
| 24 bool HasTransformAnimationThatInflatesBounds(const LayerImpl& layer) { | |
| 25 return layer.layer_animation_controller() | |
| 26 ->HasTransformAnimationThatInflatesBounds(); | |
| 27 } | |
| 28 | |
| 29 inline bool HasAncestorTransformAnimation(const LayerImpl& layer) { | |
| 30 return layer.screen_space_transform_is_animating(); | |
| 31 } | |
| 32 | |
| 33 inline bool HasAncestorFilterAnimation(const LayerImpl& layer) { | |
| 34 for (const LayerImpl* current = &layer; current; | |
| 35 current = current->parent()) { | |
| 36 if (HasFilterAnimationThatInflatesBounds(*current)) | |
| 37 return true; | |
| 38 } | |
| 39 | |
| 40 return false; | |
| 41 } | |
| 42 | |
| 43 } // namespace | |
| 44 | |
| 45 bool LayerUtils::GetAnimationBounds(const LayerImpl& layer_in, gfx::BoxF* out) { | |
| 46 // We don't care about animated bounds for invisible layers. | |
| 47 if (!layer_in.DrawsContent()) | |
| 48 return false; | |
| 49 | |
| 50 // We also don't care for layers that are not animated or a child of an | |
| 51 // animated layer. | |
| 52 if (!HasAncestorTransformAnimation(layer_in) && | |
| 53 !HasAncestorFilterAnimation(layer_in)) | |
| 54 return false; | |
| 55 | |
| 56 // To compute the inflated bounds for a layer, we start by taking its bounds | |
| 57 // and converting it to a 3d box, and then we transform or inflate it | |
| 58 // repeatedly as we walk up the layer tree to the root. | |
| 59 // | |
| 60 // At each layer we apply the following transformations to the box: | |
| 61 // 1) We translate so that the anchor point is the origin. | |
| 62 // 2) We either apply the layer's transform or inflate if the layer's | |
| 63 // transform is animated. | |
| 64 // 3) We undo the translation from step 1 and apply a second translation | |
| 65 // to account for the layer's position. | |
| 66 // | |
| 67 gfx::BoxF box(layer_in.bounds().width(), layer_in.bounds().height(), 0.f); | |
| 68 | |
| 69 // We want to inflate/transform the box as few times as possible. Each time | |
| 70 // we do this, we have to make the box axis aligned again, so if we make many | |
| 71 // small adjustments to the box by transforming it repeatedly rather than | |
| 72 // once by the product of all these matrices, we will accumulate a bunch of | |
| 73 // unnecessary inflation because of the the many axis-alignment fixes. This | |
| 74 // matrix stores said product. | |
| 75 gfx::Transform coalesced_transform; | |
| 76 | |
| 77 for (const LayerImpl* layer = &layer_in; layer; layer = layer->parent()) { | |
| 78 int transform_origin_x = layer->transform_origin().x(); | |
| 79 int transform_origin_y = layer->transform_origin().y(); | |
| 80 int transform_origin_z = layer->transform_origin().z(); | |
| 81 | |
| 82 gfx::PointF position = layer->position(); | |
| 83 if (layer->parent() && !HasAnimationThatInflatesBounds(*layer)) { | |
| 84 // |composite_layer_transform| contains 1 - 4 mentioned above. We compute | |
| 85 // it separately and apply afterwards because it's a bit more efficient | |
| 86 // because post-multiplication appears a bit more expensive, so we want | |
| 87 // to do it only once. | |
| 88 gfx::Transform composite_layer_transform; | |
| 89 | |
| 90 composite_layer_transform.Translate3d(transform_origin_x + position.x(), | |
| 91 transform_origin_y + position.y(), | |
| 92 transform_origin_z); | |
| 93 composite_layer_transform.PreconcatTransform(layer->transform()); | |
| 94 composite_layer_transform.Translate3d( | |
| 95 -transform_origin_x, -transform_origin_y, -transform_origin_z); | |
| 96 | |
| 97 // Add this layer's contributions to the |coalesced_transform|. | |
| 98 coalesced_transform.ConcatTransform(composite_layer_transform); | |
| 99 continue; | |
| 100 } | |
| 101 | |
| 102 // First, apply coalesced transform we've been building and reset it. | |
| 103 coalesced_transform.TransformBox(&box); | |
| 104 coalesced_transform.MakeIdentity(); | |
| 105 | |
| 106 // We need to apply the inflation about the layer's anchor point. Rather | |
| 107 // than doing this via transforms, we'll just shift the box directly. | |
| 108 box.set_origin(box.origin() + gfx::Vector3dF(-transform_origin_x, | |
| 109 -transform_origin_y, | |
| 110 -transform_origin_z)); | |
| 111 | |
| 112 // Perform the inflation | |
| 113 if (HasFilterAnimationThatInflatesBounds(*layer)) { | |
| 114 gfx::BoxF inflated; | |
| 115 if (!layer->layer_animation_controller()->FilterAnimationBoundsForBox( | |
| 116 box, &inflated)) | |
| 117 return false; | |
| 118 box = inflated; | |
| 119 } | |
| 120 | |
| 121 if (HasTransformAnimationThatInflatesBounds(*layer)) { | |
| 122 gfx::BoxF inflated; | |
| 123 if (!layer->layer_animation_controller()->TransformAnimationBoundsForBox( | |
| 124 box, &inflated)) | |
| 125 return false; | |
| 126 box = inflated; | |
| 127 } | |
| 128 | |
| 129 // Apply step 3) mentioned above. | |
| 130 box.set_origin(box.origin() + | |
| 131 gfx::Vector3dF(transform_origin_x + position.x(), | |
| 132 transform_origin_y + position.y(), | |
| 133 transform_origin_z)); | |
| 134 } | |
| 135 | |
| 136 // If we've got an unapplied coalesced transform at this point, it must still | |
| 137 // be applied. | |
| 138 if (!coalesced_transform.IsIdentity()) | |
| 139 coalesced_transform.TransformBox(&box); | |
| 140 | |
| 141 *out = box; | |
| 142 | |
| 143 return true; | |
| 144 } | |
| 145 | |
| 146 } // namespace cc | |
| OLD | NEW |