12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2011 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/trees/tree_synchronizer.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <set>
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/containers/scoped_ptr_hash_map.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/animation/scrollbar_animation_controller.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "cc/input/scrollbar.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/layers/layer_impl.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "cc/layers/scrollbar_layer_impl_base.h"
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "cc/layers/scrollbar_layer_interface.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)typedef base::ScopedPtrHashMap<int, LayerImpl> ScopedPtrLayerImplMap;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef base::hash_map<int, LayerImpl*> RawPtrLayerImplMap;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CollectExistingLayerImplRecursive(ScopedPtrLayerImplMap* old_layers,
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       scoped_ptr<LayerImpl> layer_impl) {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_impl)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  layer_impl->ClearScrollbars();
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (ScrollbarLayerImplBase* scrollbar_layer =
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          layer_impl->ToScrollbarLayer()) {
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scrollbar_layer->ClearClipLayer();
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scrollbar_layer->ClearScrollLayer();
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  OwnedLayerImplList& children = layer_impl->children();
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (OwnedLayerImplList::iterator it = children.begin();
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != children.end();
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CollectExistingLayerImplRecursive(old_layers, children.take(it));
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CollectExistingLayerImplRecursive(old_layers, layer_impl->TakeMaskLayer());
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CollectExistingLayerImplRecursive(old_layers, layer_impl->TakeReplicaLayer());
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int id = layer_impl->id();
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  old_layers->set(id, layer_impl.Pass());
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename LayerType>
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> SynchronizeTreesInternal(
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerType* layer_root,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<LayerImpl> old_layer_impl_root,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeImpl* tree_impl) {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(tree_impl);
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("cc", "TreeSynchronizer::SynchronizeTrees");
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedPtrLayerImplMap old_layers;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RawPtrLayerImplMap new_layers;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CollectExistingLayerImplRecursive(&old_layers, old_layer_impl_root.Pass());
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<LayerImpl> new_tree = SynchronizeTreesRecursive(
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &new_layers, &old_layers, layer_root, tree_impl);
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateScrollbarLayerPointersRecursive(&new_layers, layer_root);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new_tree.Pass();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> TreeSynchronizer::SynchronizeTrees(
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layer* layer_root,
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<LayerImpl> old_layer_impl_root,
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeImpl* tree_impl) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SynchronizeTreesInternal(
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_root, old_layer_impl_root.Pass(), tree_impl);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> TreeSynchronizer::SynchronizeTrees(
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerImpl* layer_root,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<LayerImpl> old_layer_impl_root,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeImpl* tree_impl) {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SynchronizeTreesInternal(
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layer_root, old_layer_impl_root.Pass(), tree_impl);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename LayerType>
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> ReuseOrCreateLayerImpl(RawPtrLayerImplMap* new_layers,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             ScopedPtrLayerImplMap* old_layers,
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             LayerType* layer,
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             LayerTreeImpl* tree_impl) {
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<LayerImpl> layer_impl = old_layers->take(layer->id());
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer_impl)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_impl = layer->CreateLayerImpl(tree_impl);
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  (*new_layers)[layer->id()] = layer_impl.get();
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return layer_impl.Pass();
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename LayerType>
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> SynchronizeTreesRecursiveInternal(
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RawPtrLayerImplMap* new_layers,
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedPtrLayerImplMap* old_layers,
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerType* layer,
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeImpl* tree_impl) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scoped_ptr<LayerImpl>();
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<LayerImpl> layer_impl =
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ReuseOrCreateLayerImpl(new_layers, old_layers, layer, tree_impl);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_impl->ClearChildList();
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < layer->children().size(); ++i) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layer_impl->AddChild(SynchronizeTreesRecursiveInternal(
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new_layers, old_layers, layer->child_at(i), tree_impl));
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_impl->SetMaskLayer(SynchronizeTreesRecursiveInternal(
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_layers, old_layers, layer->mask_layer(), tree_impl));
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  layer_impl->SetReplicaLayer(SynchronizeTreesRecursiveInternal(
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_layers, old_layers, layer->replica_layer(), tree_impl));
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return layer_impl.Pass();
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> SynchronizeTreesRecursive(
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RawPtrLayerImplMap* new_layers,
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedPtrLayerImplMap* old_layers,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Layer* layer,
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeImpl* tree_impl) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SynchronizeTreesRecursiveInternal(
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_layers, old_layers, layer, tree_impl);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<LayerImpl> SynchronizeTreesRecursive(
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RawPtrLayerImplMap* new_layers,
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScopedPtrLayerImplMap* old_layers,
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerImpl* layer,
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerTreeImpl* tree_impl) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SynchronizeTreesRecursiveInternal(
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_layers, old_layers, layer, tree_impl);
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename LayerType, typename ScrollbarLayerType>
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UpdateScrollbarLayerPointersRecursiveInternal(
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const RawPtrLayerImplMap* new_layers,
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerType* layer) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < layer->children().size(); ++i) {
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    UpdateScrollbarLayerPointersRecursiveInternal<
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        LayerType, ScrollbarLayerType>(new_layers, layer->child_at(i));
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScrollbarLayerType* scrollbar_layer = layer->ToScrollbarLayer();
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!scrollbar_layer)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RawPtrLayerImplMap::const_iterator iter =
16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new_layers->find(layer->id());
16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ScrollbarLayerImplBase* scrollbar_layer_impl =
1643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      iter != new_layers->end()
16558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          ? static_cast<ScrollbarLayerImplBase*>(iter->second)
1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          : NULL;
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(scrollbar_layer_impl);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scrollbar_layer->PushScrollClipPropertiesTo(scrollbar_layer_impl);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers,
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           Layer* layer) {
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UpdateScrollbarLayerPointersRecursiveInternal<Layer, ScrollbarLayerInterface>(
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new_layers, layer);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           LayerImpl* layer) {
1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  UpdateScrollbarLayerPointersRecursiveInternal<
1813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      LayerImpl,
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ScrollbarLayerImplBase>(new_layers, layer);
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <typename LayerType>
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid TreeSynchronizer::PushPropertiesInternal(
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerType* layer,
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    LayerImpl* layer_impl,
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    size_t* num_dependents_need_push_properties_for_parent) {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!layer) {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!layer_impl);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_EQ(layer->id(), layer_impl->id());
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool push_layer = layer->needs_push_properties();
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool recurse_on_children_and_dependents =
2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      layer->descendant_needs_push_properties();
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (push_layer)
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    layer->PushPropertiesTo(layer_impl);
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else if (layer->ToScrollbarLayer())
2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    layer->ToScrollbarLayer()->PushScrollClipPropertiesTo(layer_impl);
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  size_t num_dependents_need_push_properties = 0;
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (recurse_on_children_and_dependents) {
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    PushPropertiesInternal(layer->mask_layer(),
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                           layer_impl->mask_layer(),
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                           &num_dependents_need_push_properties);
2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    PushPropertiesInternal(layer->replica_layer(),
2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                           layer_impl->replica_layer(),
2147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                           &num_dependents_need_push_properties);
2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const OwnedLayerImplList& impl_children = layer_impl->children();
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DCHECK_EQ(layer->children().size(), impl_children.size());
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    for (size_t i = 0; i < layer->children().size(); ++i) {
2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      PushPropertiesInternal(layer->child_at(i),
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                             impl_children[i],
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                             &num_dependents_need_push_properties);
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // When PushPropertiesTo completes for a layer, it may still keep
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // its needs_push_properties() state if the layer must push itself
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // every PushProperties tree walk. Here we keep track of those layers, and
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // ensure that their ancestors know about them for the next PushProperties
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // tree walk.
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    layer->num_dependents_need_push_properties_ =
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        num_dependents_need_push_properties;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  bool add_self_to_parent = num_dependents_need_push_properties > 0 ||
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                            layer->needs_push_properties();
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  *num_dependents_need_push_properties_for_parent += add_self_to_parent ? 1 : 0;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
239a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void CheckScrollAndClipPointersRecursive(Layer* layer,
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                LayerImpl* layer_impl) {
241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK_EQ(!!layer, !!layer_impl);
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!layer)
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Having a scroll parent on the impl thread implies having one the main
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // thread, too. The main thread may have a scroll parent that is not in the
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // tree because it's been removed but not deleted. In this case, the layer
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // impl will have no scroll parent. Same argument applies for clip parents and
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // scroll/clip children.
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!layer_impl->scroll_parent() || !!layer->scroll_parent());
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!layer_impl->clip_parent() || !!layer->clip_parent());
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!layer_impl->scroll_children() || !!layer->scroll_children());
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(!layer_impl->clip_children() || !!layer->clip_children());
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (layer_impl->scroll_parent())
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_EQ(layer->scroll_parent()->id(), layer_impl->scroll_parent()->id());
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (layer_impl->clip_parent())
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DCHECK_EQ(layer->clip_parent()->id(), layer_impl->clip_parent()->id());
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (layer_impl->scroll_children()) {
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (std::set<Layer*>::iterator it = layer->scroll_children()->begin();
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         it != layer->scroll_children()->end();
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         ++it) {
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ((*it)->scroll_parent(), layer);
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (std::set<LayerImpl*>::iterator it =
268a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             layer_impl->scroll_children()->begin();
269a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         it != layer_impl->scroll_children()->end();
270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         ++it) {
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ((*it)->scroll_parent(), layer_impl);
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (layer_impl->clip_children()) {
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (std::set<Layer*>::iterator it = layer->clip_children()->begin();
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         it != layer->clip_children()->end();
278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         ++it) {
279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ((*it)->clip_parent(), layer);
280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (std::set<LayerImpl*>::iterator it =
282a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)             layer_impl->clip_children()->begin();
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         it != layer_impl->clip_children()->end();
284a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         ++it) {
285a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DCHECK_EQ((*it)->clip_parent(), layer_impl);
286a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
287a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0u; i < layer->children().size(); ++i) {
290a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    CheckScrollAndClipPointersRecursive(layer->child_at(i),
291a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                        layer_impl->child_at(i));
292a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
294a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid TreeSynchronizer::PushProperties(Layer* layer,
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                      LayerImpl* layer_impl) {
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  size_t num_dependents_need_push_properties = 0;
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PushPropertiesInternal(
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      layer, layer_impl, &num_dependents_need_push_properties);
300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if DCHECK_IS_ON
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CheckScrollAndClipPointersRecursive(layer, layer_impl);
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TreeSynchronizer::PushProperties(LayerImpl* layer, LayerImpl* layer_impl) {
3067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  size_t num_dependents_need_push_properties = 0;
3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  PushPropertiesInternal(
3087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      layer, layer_impl, &num_dependents_need_push_properties);
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
312