| Index: cc/trees/layer_tree_impl.cc
 | 
| diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
 | 
| index 74603d51fbc0f1016e5cc45cfd7ffa8a6b09b4a4..705fbd17b8ff118a06895724f0c6e592cdace9ad 100644
 | 
| --- a/cc/trees/layer_tree_impl.cc
 | 
| +++ b/cc/trees/layer_tree_impl.cc
 | 
| @@ -448,6 +448,45 @@ LayerListReverseIterator<LayerImpl> LayerTreeImpl::rend() {
 | 
|    return LayerListReverseIterator<LayerImpl>(nullptr);
 | 
|  }
 | 
|  
 | 
| +void LayerTreeImpl::RegisterLayerForElementId(LayerImpl* layer) {
 | 
| +  DCHECK(layer->element_id());
 | 
| +  ElementLayers& element_layers = element_id_to_layer_map_[layer->element_id()];
 | 
| +  if (layer->scrollable()) {
 | 
| +    DCHECK(!element_layers.scroll);
 | 
| +    element_layers.scroll = layer;
 | 
| +  } else {
 | 
| +    DCHECK(!element_layers.main);
 | 
| +    element_layers.main = layer;
 | 
| +  }
 | 
| +  layer_tree_host_impl_->animation_host()->RegisterElement(
 | 
| +      layer->element_id(),
 | 
| +      IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING);
 | 
| +}
 | 
| +
 | 
| +void LayerTreeImpl::UnregisterLayerForElementId(LayerImpl* layer) {
 | 
| +  DCHECK(layer->element_id());
 | 
| +
 | 
| +  layer_tree_host_impl_->animation_host()->UnregisterElement(
 | 
| +      layer->element_id(),
 | 
| +      IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING);
 | 
| +
 | 
| +  auto iter = element_id_to_layer_map_.find(layer->element_id());
 | 
| +  if (iter == element_id_to_layer_map_.end())
 | 
| +    return;
 | 
| +
 | 
| +  ElementLayers& element_layers = iter->second;
 | 
| +  if (layer->scrollable()) {
 | 
| +    DCHECK_EQ(element_layers.scroll, layer);
 | 
| +    element_layers.scroll = nullptr;
 | 
| +  } else {
 | 
| +    DCHECK_EQ(element_layers.main, layer);
 | 
| +    element_layers.main = nullptr;
 | 
| +  }
 | 
| +
 | 
| +  if (!element_layers.main && !element_layers.scroll)
 | 
| +    element_id_to_layer_map_.erase(layer->element_id());
 | 
| +}
 | 
| +
 | 
|  void LayerTreeImpl::AddToElementMap(LayerImpl* layer) {
 | 
|    if (!layer->element_id() || !layer->mutable_properties())
 | 
|      return;
 | 
| @@ -485,7 +524,7 @@ void LayerTreeImpl::RemoveFromElementMap(LayerImpl* layer) {
 | 
|  }
 | 
|  
 | 
|  LayerTreeImpl::ElementLayers LayerTreeImpl::GetMutableLayers(
 | 
| -    uint64_t element_id) {
 | 
| +    ElementId element_id) {
 | 
|    auto iter = element_layers_map_.find(element_id);
 | 
|    if (iter == element_layers_map_.end())
 | 
|      return ElementLayers();
 | 
| @@ -998,6 +1037,21 @@ LayerImpl* LayerTreeImpl::LayerById(int id) const {
 | 
|    return iter != layer_id_map_.end() ? iter->second : NULL;
 | 
|  }
 | 
|  
 | 
| +LayerImpl* LayerTreeImpl::LayerForElementId(ElementId element_id) const {
 | 
| +  auto iter = element_id_to_layer_map_.find(element_id);
 | 
| +  return iter != element_id_to_layer_map_.end() ? iter->second.main : nullptr;
 | 
| +}
 | 
| +
 | 
| +LayerImpl* LayerTreeImpl::ScrollLayerForElementId(ElementId element_id) const {
 | 
| +  auto iter = element_id_to_layer_map_.find(element_id);
 | 
| +  return iter != element_id_to_layer_map_.end() ? iter->second.scroll : nullptr;
 | 
| +}
 | 
| +
 | 
| +bool LayerTreeImpl::HasAnyLayerForElementId(ElementId element_id) const {
 | 
| +  return element_id_to_layer_map_.find(element_id) !=
 | 
| +         element_id_to_layer_map_.end();
 | 
| +}
 | 
| +
 | 
|  void LayerTreeImpl::AddLayerShouldPushProperties(LayerImpl* layer) {
 | 
|    layers_that_should_push_properties_.insert(layer);
 | 
|  }
 | 
| @@ -1019,16 +1073,10 @@ bool LayerTreeImpl::LayerNeedsPushPropertiesForTesting(LayerImpl* layer) {
 | 
|  void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
 | 
|    DCHECK(!LayerById(layer->id()));
 | 
|    layer_id_map_[layer->id()] = layer;
 | 
| -  layer_tree_host_impl_->animation_host()->RegisterElement(
 | 
| -      layer->id(),
 | 
| -      IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING);
 | 
|  }
 | 
|  
 | 
|  void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
 | 
|    DCHECK(LayerById(layer->id()));
 | 
| -  layer_tree_host_impl_->animation_host()->UnregisterElement(
 | 
| -      layer->id(),
 | 
| -      IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING);
 | 
|    layer_id_map_.erase(layer->id());
 | 
|    DCHECK_NE(root_layer_, layer);
 | 
|  }
 | 
| @@ -1946,141 +1994,201 @@ LayerTreeImpl::TakePendingPageScaleAnimation() {
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::IsAnimatingFilterProperty(const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    ElementListType list_type =
 | 
|        IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
 | 
|    return layer_tree_host_impl_->animation_host()->IsAnimatingFilterProperty(
 | 
| -      layer->id(), list_type);
 | 
| +      layer->element_id(), list_type);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::IsAnimatingOpacityProperty(const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    ElementListType list_type =
 | 
|        IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
 | 
|    return layer_tree_host_impl_->animation_host()->IsAnimatingOpacityProperty(
 | 
| -      layer->id(), list_type);
 | 
| +      layer->element_id(), list_type);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::IsAnimatingTransformProperty(const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    ElementListType list_type =
 | 
|        IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
 | 
|    return layer_tree_host_impl_->animation_host()->IsAnimatingTransformProperty(
 | 
| -      layer->id(), list_type);
 | 
| +      layer->element_id(), list_type);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::HasPotentiallyRunningFilterAnimation(
 | 
|      const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    ElementListType list_type =
 | 
|        IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->HasPotentiallyRunningFilterAnimation(layer->id(), list_type);
 | 
| +      ->HasPotentiallyRunningFilterAnimation(layer->element_id(), list_type);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::HasPotentiallyRunningOpacityAnimation(
 | 
|      const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    ElementListType list_type =
 | 
|        IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->HasPotentiallyRunningOpacityAnimation(layer->id(), list_type);
 | 
| +      ->HasPotentiallyRunningOpacityAnimation(layer->element_id(), list_type);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::HasPotentiallyRunningTransformAnimation(
 | 
|      const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    ElementListType list_type =
 | 
|        IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->HasPotentiallyRunningTransformAnimation(layer->id(), list_type);
 | 
| +      ->HasPotentiallyRunningTransformAnimation(layer->element_id(), list_type);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::HasAnyAnimationTargetingProperty(
 | 
|      const LayerImpl* layer,
 | 
|      TargetProperty::Type property) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->HasAnyAnimationTargetingProperty(layer->id(), property);
 | 
| +      ->HasAnyAnimationTargetingProperty(layer->element_id(), property);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::FilterIsAnimatingOnImplOnly(const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()->FilterIsAnimatingOnImplOnly(
 | 
| -      layer->id());
 | 
| +      layer->element_id());
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::OpacityIsAnimatingOnImplOnly(const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()->OpacityIsAnimatingOnImplOnly(
 | 
| -      layer->id());
 | 
| +      layer->element_id());
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::ScrollOffsetIsAnimatingOnImplOnly(
 | 
|      const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->ScrollOffsetIsAnimatingOnImplOnly(layer->id());
 | 
| +      ->ScrollOffsetIsAnimatingOnImplOnly(layer->element_id());
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::TransformIsAnimatingOnImplOnly(
 | 
|      const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->TransformIsAnimatingOnImplOnly(layer->id());
 | 
| +      ->TransformIsAnimatingOnImplOnly(layer->element_id());
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::AnimationsPreserveAxisAlignment(
 | 
|      const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return true;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->AnimationsPreserveAxisAlignment(layer->id());
 | 
| +      ->AnimationsPreserveAxisAlignment(layer->element_id());
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::HasOnlyTranslationTransforms(const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return true;
 | 
| +
 | 
|    ElementListType list_type =
 | 
|        IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
 | 
|    return layer_tree_host_impl_->animation_host()->HasOnlyTranslationTransforms(
 | 
| -      layer->id(), list_type);
 | 
| +      layer->element_id(), list_type);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::MaximumTargetScale(const LayerImpl* layer,
 | 
|                                         float* max_scale) const {
 | 
|    *max_scale = 0.f;
 | 
| +  if (!layer->element_id())
 | 
| +    return true;
 | 
| +
 | 
|    ElementListType list_type =
 | 
|        IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
 | 
|    return layer_tree_host_impl_->animation_host()->MaximumTargetScale(
 | 
| -      layer->id(), list_type, max_scale);
 | 
| +      layer->element_id(), list_type, max_scale);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::AnimationStartScale(const LayerImpl* layer,
 | 
|                                          float* start_scale) const {
 | 
|    *start_scale = 0.f;
 | 
| +  if (!layer->element_id())
 | 
| +    return true;
 | 
| +
 | 
|    ElementListType list_type =
 | 
|        IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
 | 
|    return layer_tree_host_impl_->animation_host()->AnimationStartScale(
 | 
| -      layer->id(), list_type, start_scale);
 | 
| +      layer->element_id(), list_type, start_scale);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::HasFilterAnimationThatInflatesBounds(
 | 
|      const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->HasFilterAnimationThatInflatesBounds(layer->id());
 | 
| +      ->HasFilterAnimationThatInflatesBounds(layer->element_id());
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::HasTransformAnimationThatInflatesBounds(
 | 
|      const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->HasTransformAnimationThatInflatesBounds(layer->id());
 | 
| +      ->HasTransformAnimationThatInflatesBounds(layer->element_id());
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::HasAnimationThatInflatesBounds(
 | 
|      const LayerImpl* layer) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->HasAnimationThatInflatesBounds(layer->id());
 | 
| +      ->HasAnimationThatInflatesBounds(layer->element_id());
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::FilterAnimationBoundsForBox(const LayerImpl* layer,
 | 
|                                                  const gfx::BoxF& box,
 | 
|                                                  gfx::BoxF* bounds) const {
 | 
| +  if (!layer->element_id())
 | 
| +    return false;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()->FilterAnimationBoundsForBox(
 | 
| -      layer->id(), box, bounds);
 | 
| +      layer->element_id(), box, bounds);
 | 
|  }
 | 
|  
 | 
|  bool LayerTreeImpl::TransformAnimationBoundsForBox(const LayerImpl* layer,
 | 
|                                                     const gfx::BoxF& box,
 | 
|                                                     gfx::BoxF* bounds) const {
 | 
|    *bounds = gfx::BoxF();
 | 
| +  if (!layer->element_id())
 | 
| +    return true;
 | 
| +
 | 
|    return layer_tree_host_impl_->animation_host()
 | 
| -      ->TransformAnimationBoundsForBox(layer->id(), box, bounds);
 | 
| +      ->TransformAnimationBoundsForBox(layer->element_id(), box, bounds);
 | 
|  }
 | 
|  
 | 
|  void LayerTreeImpl::ScrollAnimationAbort(bool needs_completion) {
 | 
| 
 |