Reland the layer creation change since the touchui issues will be resolved in a follow up CL.
This reverts 103580 - Revert the layer creation change r103338 due to some issues with the keyboard on touch. I'll re-land later once I can get a working linux build.TBR=skyBUG=noneTEST=none
Review URL: http://codereview.chromium.org/8100015
[email protected]
Review URL: http://codereview.chromium.org/8115010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103777 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/views/view.cc b/views/view.cc
index 9b5e26bb..3bc87aa 100644
--- a/views/view.cc
+++ b/views/view.cc
@@ -113,6 +113,7 @@
clip_y_(0.0),
needs_layout_(true),
flip_canvas_on_paint_for_rtl_ui_(false),
+ paint_to_layer_(false),
accelerator_registration_delayed_(false),
accelerator_focus_manager_(NULL),
registered_accelerator_count_(0),
@@ -170,21 +171,13 @@
view->parent_ = this;
children_.insert(children_.begin() + index, view);
- if (GetWidget()) {
- // Sending out notification of insert may result in adding other views.
- // Invoke this first to make sure we know the layer is created (if needed).
- view->CreateLayerIfNecessary();
- }
-
for (View* v = this; v; v = v->parent_)
v->ViewHierarchyChangedImpl(false, true, this, view);
view->PropagateAddNotifications(this, view);
UpdateTooltip();
- if (GetWidget()) {
+ if (GetWidget())
RegisterChildrenForVisibleBoundsNotification(view);
- view->CreateLayerIfNecessary();
- }
if (layout_manager_.get())
layout_manager_->ViewAdded(this, view);
@@ -313,8 +306,7 @@
ui::Transform transform;
while (view != NULL && !vis_bounds.IsEmpty()) {
- if (view->transform())
- transform.ConcatTransform(*view->transform());
+ transform.ConcatTransform(view->GetTransform());
transform.ConcatTranslate(static_cast<float>(view->GetMirroredX()),
static_cast<float>(view->y()));
@@ -371,16 +363,13 @@
void View::SetVisible(bool visible) {
if (visible != visible_) {
// If the View is currently visible, schedule paint to refresh parent.
+ // TODO(beng): not sure we should be doing this if we have a layer.
if (visible_)
SchedulePaint();
visible_ = visible;
-
- if (visible_)
- CreateLayerIfNecessary();
- else
- // Destroy layer if the View is invisible as invisible Views never paint.
- DestroyLayerRecurse();
+ if (layer())
+ layer()->SetVisible(visible_);
// This notifies all sub-views recursively.
PropagateVisibilityNotifications(this, visible_);
@@ -418,70 +407,47 @@
const ui::Transform& View::GetTransform() const {
static const ui::Transform* no_op = new ui::Transform;
- return transform() ? *transform() : *no_op;
+ return layer() ? layer()->transform() : *no_op;
}
void View::SetTransform(const ui::Transform& transform) {
if (!transform.HasChange()) {
- if (!layer_helper_.get() || !this->transform())
- return;
- layer_helper_->SetTransform(transform);
-
- if (!ShouldPaintToLayer())
- DestroyLayerAndReparent();
- else if (layer())
- layer_helper_->property_setter()->SetTransform(layer(), transform);
-
- SchedulePaint();
- } else {
- if (!layer_helper_.get())
- layer_helper_.reset(new internal::LayerHelper());
- layer_helper_->SetTransform(transform);
- if (!layer()) {
- CreateLayer();
- SchedulePaint();
+ if (layer()) {
+ layer_property_setter_->SetTransform(layer(), transform);
+ if (!paint_to_layer_)
+ DestroyLayer();
} else {
- layer_helper_->property_setter()->SetTransform(layer(), transform);
- // We have a layer. When the transform changes and the layer is up to
- // date we don't want to SchedulePaint as it'll trigger painting to the
- // layer. Instead we tell the Widget to paint, which makes the
- // compositor draw using the existing layer.
- // We schedule paint the complete bounds as compositor generally don't
- // support partial painting.
- Widget* widget = GetWidget();
- if (widget)
- widget->SchedulePaintInRect(widget->GetRootView()->bounds());
+ // Nothing.
}
+ } else {
+ if (!layer())
+ CreateLayer();
+ layer_property_setter_->SetTransform(layer(), transform);
+ layer()->ScheduleDraw();
}
}
-void View::SetPaintToLayer(bool value) {
- bool paint_to_layer = layer_helper_.get() && layer_helper_->paint_to_layer();
- if (value == paint_to_layer)
- return;
-
- if (value) {
- if (!layer_helper_.get())
- layer_helper_.reset(new internal::LayerHelper());
- layer_helper_->set_paint_to_layer(true);
+void View::SetPaintToLayer(bool paint_to_layer) {
+ paint_to_layer_ = paint_to_layer;
+ if (paint_to_layer_ && !layer()) {
CreateLayer();
- } else if (layer_helper_.get()) {
- layer_helper_->set_paint_to_layer(false);
- if (!ShouldPaintToLayer())
- DestroyLayerAndReparent();
+ } else if (!paint_to_layer_ && layer()) {
+ DestroyLayer();
}
}
void View::SetLayerPropertySetter(LayerPropertySetter* setter) {
- if ((layer_helper_.get() && layer_helper_->property_setter() == setter) ||
- (!layer_helper_.get() && setter == NULL)) {
+ DCHECK(layer());
+ LayerPropertySetter* old_setter = layer_property_setter_.get();
+ if (!layer() || (old_setter && old_setter == setter))
return;
- }
+ if (!setter)
+ setter = LayerPropertySetter::CreateDefaultSetter();
- if (!layer_helper_.get())
- layer_helper_.reset(new internal::LayerHelper());
- layer_helper_->set_property_setter_explicitly_set(setter != NULL);
- layer_helper_->SetPropertySetter(setter);
+ if (old_setter)
+ old_setter->Uninstalled(layer());
+ layer_property_setter_.reset(setter);
+ layer_property_setter_->Installed(layer());
}
// RTL positioning -------------------------------------------------------------
@@ -657,8 +623,7 @@
gfx::Rect View::ConvertRectToParent(const gfx::Rect& rect) const {
gfx::Rect x_rect = rect;
- if (transform())
- transform()->TransformRect(&x_rect);
+ GetTransform().TransformRect(&x_rect);
x_rect.Offset(GetMirroredPosition());
return x_rect;
}
@@ -710,8 +675,7 @@
// where this view is located (related to its parent).
canvas->TranslateInt(GetMirroredX(), y());
- if (transform())
- canvas->Transform(*transform());
+ canvas->Transform(GetTransform());
PaintCommon(canvas);
}
@@ -1106,23 +1070,16 @@
// Accelerated Painting --------------------------------------------------------
void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
- if (!layer_helper_.get())
- layer_helper_.reset(new internal::LayerHelper());
-
- layer_helper_->set_fills_bounds_opaquely(fills_bounds_opaquely);
-
+ // This method should not have the side-effect of creating the layer.
if (layer())
layer()->SetFillsBoundsOpaquely(fills_bounds_opaquely);
}
bool View::SetExternalTexture(ui::Texture* texture) {
DCHECK(texture);
- if (!layer_helper_.get())
- return true;
+ SetPaintToLayer(true);
- if (!layer_helper_.get())
- layer_helper_.reset(new internal::LayerHelper());
- layer_helper_->SetExternalTexture(texture);
+ layer()->SetExternalTexture(texture);
// Child views must not paint into the external texture. So make sure each
// child view has its own layer to paint into.
@@ -1130,18 +1087,9 @@
(*i)->SetPaintToLayer(true);
SchedulePaintInRect(GetLocalBounds());
-
return true;
}
-const ui::Compositor* View::GetCompositor() const {
- return parent_ ? parent_->GetCompositor() : NULL;
-}
-
-ui::Compositor* View::GetCompositor() {
- return parent_ ? parent_->GetCompositor() : NULL;
-}
-
void View::CalculateOffsetToAncestorWithLayer(gfx::Point* offset,
ui::Layer** layer_parent) {
if (layer()) {
@@ -1156,13 +1104,6 @@
parent_->CalculateOffsetToAncestorWithLayer(offset, layer_parent);
}
-void View::CreateLayerIfNecessary() {
- if (ShouldPaintToLayer())
- CreateLayer();
-
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->CreateLayerIfNecessary();
-}
void View::MoveLayerToParent(ui::Layer* parent_layer,
const gfx::Point& point) {
@@ -1171,29 +1112,24 @@
local_point.Offset(x(), y());
if (layer() && parent_layer != layer()) {
parent_layer->Add(layer());
- layer()->SetBounds(
- gfx::Rect(local_point.x(), local_point.y(), width(), height()));
+ layer()->SetBounds(gfx::Rect(local_point.x(), local_point.y(),
+ width(), height()));
} else {
for (int i = 0, count = child_count(); i < count; ++i)
child_at(i)->MoveLayerToParent(parent_layer, local_point);
}
}
-void View::DestroyLayerRecurse() {
- for (int i = child_count() - 1; i >= 0; --i)
- child_at(i)->DestroyLayerRecurse();
- DestroyLayer();
-}
-
-void View::UpdateLayerBounds(const gfx::Point& offset) {
+void View::UpdateChildLayerBounds(const gfx::Point& offset) {
if (layer()) {
- layer_helper_->property_setter()->SetBounds(
- layer(),
- gfx::Rect(offset.x() + x(), offset.y() + y(), width(), height()));
+ layer_property_setter_->SetBounds(layer(), gfx::Rect(offset.x(), offset.y(),
+ width(), height()));
} else {
- gfx::Point new_offset(offset.x() + x(), offset.y() + y());
- for (int i = 0, count = child_count(); i < count; ++i)
- child_at(i)->UpdateLayerBounds(new_offset);
+ for (int i = 0, count = child_count(); i < count; ++i) {
+ gfx::Point new_offset(offset.x() + child_at(i)->x(),
+ offset.y() + child_at(i)->y());
+ child_at(i)->UpdateChildLayerBounds(new_offset);
+ }
}
}
@@ -1487,7 +1423,6 @@
if (GetWidget())
UnregisterChildrenForVisibleBoundsNotification(view);
- view->DestroyLayerRecurse();
view->PropagateRemoveNotifications(this);
view->parent_ = NULL;
@@ -1549,6 +1484,9 @@
}
}
+ if (is_add && layer() && !layer()->parent())
+ UpdateParentLayer();
+
ViewHierarchyChanged(is_add, parent, child);
parent->needs_layout_ = true;
}
@@ -1582,26 +1520,24 @@
gfx::Point offset;
parent_->CalculateOffsetToAncestorWithLayer(&offset, NULL);
offset.Offset(x(), y());
- layer_helper_->property_setter()->SetBounds(
- layer(), gfx::Rect(offset, size()));
+ layer_property_setter_->SetBounds(layer(), gfx::Rect(offset, size()));
} else {
- layer_helper_->property_setter()->SetBounds(layer(), bounds_);
+ layer_property_setter_->SetBounds(layer(), bounds_);
}
+ // TODO(beng): this seems redundant with the SchedulePaint at the top of
+ // this function. explore collapsing.
if (previous_bounds.size() != bounds_.size() &&
!layer()->layer_updated_externally()) {
// If our bounds have changed then we need to update the complete
// texture.
layer()->SchedulePaint(GetLocalBounds());
}
- } else if (GetCompositor()) {
+ } else {
// If our bounds have changed, then any descendant layer bounds may
// have changed. Update them accordingly.
gfx::Point offset;
CalculateOffsetToAncestorWithLayer(&offset, NULL);
- // CalculateOffsetToAncestorWithLayer includes our location as does
- // UpdateLayerBounds.
- offset.Offset(-x(), -y());
- UpdateLayerBounds(offset);
+ UpdateChildLayerBounds(offset);
}
}
}
@@ -1613,9 +1549,8 @@
Layout();
}
- if (NeedsNotificationWhenVisibleBoundsChange()) {
+ if (NeedsNotificationWhenVisibleBoundsChange())
OnVisibleBoundsChanged();
- }
// Notify interested Views that visible bounds within the root view may have
// changed.
@@ -1685,8 +1620,7 @@
const View* p = this;
while (p && p != ancestor) {
- if (p->transform())
- transform->ConcatTransform(*p->transform());
+ transform->ConcatTransform(p->GetTransform());
transform->ConcatTranslate(static_cast<float>(p->GetMirroredX()),
static_cast<float>(p->y()));
@@ -1765,69 +1699,67 @@
// Accelerated painting --------------------------------------------------------
-bool View::ShouldPaintToLayer() const {
- return use_acceleration_when_possible &&
- ((layer_helper_.get() && layer_helper_->ShouldPaintToLayer()) ||
- (parent_ && parent_->layer() &&
- parent_->layer()->layer_updated_externally()));
-}
-
void View::CreateLayer() {
- if (!ShouldPaintToLayer() || layer())
- return;
+ layer_.reset(new ui::Layer(NULL));
+ layer_->set_delegate(this);
+ if (layer_property_setter_.get())
+ layer_property_setter_->Installed(layer());
+ else
+ SetLayerPropertySetter(NULL);
- ui::Compositor* compositor = GetCompositor();
- if (!compositor)
- return;
-
- DCHECK(layer_helper_.get());
-
- ui::Layer* layer_parent = NULL;
- gfx::Point offset;
- CalculateOffsetToAncestorWithLayer(&offset, &layer_parent);
-
- DCHECK(layer_parent || parent_ == NULL);
-
- layer_helper_->SetLayer(new ui::Layer(compositor));
- layer()->set_delegate(this);
- layer()->SetFillsBoundsOpaquely(layer_helper_->fills_bounds_opaquely());
- layer()->SetBounds(gfx::Rect(offset.x(), offset.y(), width(), height()));
- layer()->SetTransform(GetTransform());
- if (layer_parent)
- layer_parent->Add(layer());
- layer()->SchedulePaint(GetLocalBounds());
-
- MoveLayerToParent(layer(), gfx::Point());
+ UpdateParentLayers();
}
-void View::DestroyLayerAndReparent() {
+void View::UpdateParentLayers() {
+ // Attach all top-level un-parented layers.
+ if (layer() && !layer()->parent()) {
+ UpdateParentLayer();
+ } else {
+ for (int i = 0, count = child_count(); i < count; ++i)
+ child_at(i)->UpdateParentLayers();
+ }
+}
+
+void View::UpdateParentLayer() {
if (!layer())
return;
- ui::Layer* new_parent = layer()->parent();
- std::vector<ui::Layer*> children = layer()->children();
- for (size_t i = 0; i < children.size(); ++i)
- new_parent->Add(children[i]);
+ ui::Layer* parent_layer = NULL;
+ gfx::Point offset(x(), y());
+ if (parent_)
+ parent_->CalculateOffsetToAncestorWithLayer(&offset, &parent_layer);
- DestroyLayer();
+ ReparentLayer(offset, parent_layer);
+}
- gfx::Point offset;
- CalculateOffsetToAncestorWithLayer(&offset, NULL);
- offset.Offset(-x(), -y());
- UpdateLayerBounds(offset);
+void View::ReparentLayer(const gfx::Point& offset, ui::Layer* parent_layer) {
+ layer_->SetBounds(gfx::Rect(offset.x(), offset.y(), width(), height()));
+ DCHECK_NE(layer(), parent_layer);
+ if (parent_layer)
+ parent_layer->Add(layer());
+ layer_->SchedulePaint(GetLocalBounds());
+ MoveLayerToParent(layer(), gfx::Point());
}
void View::DestroyLayer() {
- if (!layer_helper_.get())
- return;
+ ui::Layer* new_parent = layer()->parent();
+ std::vector<ui::Layer*> children = layer()->children();
+ for (size_t i = 0; i < children.size(); ++i) {
+ layer()->Remove(children[i]);
+ if (new_parent)
+ new_parent->Add(children[i]);
+ }
- if (!layer_helper_->property_setter_explicitly_set() &&
- !ShouldPaintToLayer() &&
- !layer_helper_->fills_bounds_opaquely() &&
- !layer_helper_->layer_updated_externally())
- layer_helper_.reset();
- else
- layer_helper_->SetLayer(NULL);
+ if (layer_property_setter_.get())
+ layer_property_setter_->Uninstalled(layer());
+
+ layer_.reset();
+
+ gfx::Point offset;
+ CalculateOffsetToAncestorWithLayer(&offset, NULL);
+ UpdateChildLayerBounds(offset);
+
+ SchedulePaint();
}
// Input -----------------------------------------------------------------------
@@ -1891,8 +1823,8 @@
}
ui::TouchStatus View::ProcessTouchEvent(const TouchEvent& event) {
- // TODO(rjkroege): Implement a grab scheme similar to as
- // as is found in MousePressed.
+ // TODO(rjkroege): Implement a grab scheme similar to as as is found in
+ // MousePressed.
return OnTouchEvent(event);
}