summaryrefslogtreecommitdiffstats
path: root/ui/compositor/layer_owner.cc
blob: 55ba0f3ec88e44ce3e00f33573a38ea653741463 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/compositor/layer_owner.h"

#include "ui/compositor/layer_owner_delegate.h"

namespace ui {

LayerOwner::LayerOwner() : layer_(NULL), layer_owner_delegate_(NULL) {
}

LayerOwner::~LayerOwner() {
}

void LayerOwner::SetLayer(Layer* layer) {
  DCHECK(!OwnsLayer());
  layer_owner_.reset(layer);
  layer_ = layer;
  layer_->owner_ = this;
}

scoped_ptr<Layer> LayerOwner::AcquireLayer() {
  if (layer_owner_)
    layer_owner_->owner_ = NULL;
  return layer_owner_.Pass();
}

scoped_ptr<Layer> LayerOwner::RecreateLayer() {
  scoped_ptr<ui::Layer> old_layer(AcquireLayer());
  if (!old_layer)
    return old_layer.Pass();

  LayerDelegate* old_delegate = old_layer->delegate();
  old_layer->set_delegate(NULL);

  const gfx::Rect layer_bounds(old_layer->bounds());
  Layer* new_layer = new ui::Layer(old_layer->type());
  SetLayer(new_layer);
  new_layer->SetVisible(old_layer->GetTargetVisibility());
  new_layer->SetOpacity(old_layer->GetTargetOpacity());
  new_layer->SetBounds(layer_bounds);
  new_layer->SetMasksToBounds(old_layer->GetMasksToBounds());
  new_layer->set_name(old_layer->name());
  new_layer->SetFillsBoundsOpaquely(old_layer->fills_bounds_opaquely());
  new_layer->SetFillsBoundsCompletely(old_layer->FillsBoundsCompletely());
  new_layer->SetSubpixelPositionOffset(old_layer->subpixel_position_offset());
  SkRegion* alpha_shape = old_layer->alpha_shape();
  if (alpha_shape)
    new_layer->SetAlphaShape(make_scoped_ptr(new SkRegion(*alpha_shape)));

  // Install new layer as a sibling of the old layer, stacked below it.
  if (old_layer->parent()) {
    old_layer->parent()->Add(new_layer);
    old_layer->parent()->StackBelow(new_layer, old_layer.get());
  }

  // Migrate all the child layers over to the new layer. Copy the list because
  // the items are removed during iteration.
  std::vector<ui::Layer*> children_copy = old_layer->children();
  for (std::vector<ui::Layer*>::const_iterator it = children_copy.begin();
       it != children_copy.end();
       ++it) {
    ui::Layer* child = *it;
    new_layer->Add(child);
  }

  // If old_layer was the layer tree root then we need to move the Compositor
  // over to the new root.
  const bool is_root = !old_layer->parent();
  if (is_root && old_layer->GetCompositor())
    old_layer->GetCompositor()->SetRootLayer(new_layer);

  // Install the delegate last so that the delegate isn't notified as we copy
  // state to the new layer.
  new_layer->set_delegate(old_delegate);

  if (layer_owner_delegate_)
    layer_owner_delegate_->OnLayerRecreated(old_layer.get(), new_layer);

  return old_layer.Pass();
}

void LayerOwner::DestroyLayer() {
  layer_ = NULL;
  layer_owner_.reset();
}

bool LayerOwner::OwnsLayer() const {
  return !!layer_owner_;
}

}  // namespace ui