summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-27 16:37:18 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-27 16:37:18 +0000
commit7c4b1b92b65a7ce6cf8a2a37a3ff97f300e4801a (patch)
tree0c0f2f5f2add4e81f7d6220394396986de62f74a
parenta6e349a6368c997c13512eff8e78304a6e2119b0 (diff)
downloadchromium_src-7c4b1b92b65a7ce6cf8a2a37a3ff97f300e4801a.zip
chromium_src-7c4b1b92b65a7ce6cf8a2a37a3ff97f300e4801a.tar.gz
chromium_src-7c4b1b92b65a7ce6cf8a2a37a3ff97f300e4801a.tar.bz2
Moves acclerated painting related fields from View to LayerHelper.
BUG=none TEST=none R=ben@chromium.org Review URL: http://codereview.chromium.org/7242025 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90589 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--views/layer_helper.cc63
-rw-r--r--views/layer_helper.h111
-rw-r--r--views/view.cc180
-rw-r--r--views/view.h38
-rw-r--r--views/view_unittest.cc16
-rw-r--r--views/views.gyp2
6 files changed, 302 insertions, 108 deletions
diff --git a/views/layer_helper.cc b/views/layer_helper.cc
new file mode 100644
index 0000000..e6b03ce
--- /dev/null
+++ b/views/layer_helper.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2011 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 "views/layer_helper.h"
+
+#include "views/layer_property_setter.h"
+#include "ui/gfx/compositor/layer.h"
+#include "ui/gfx/transform.h"
+
+namespace views {
+
+namespace internal {
+
+LayerHelper::LayerHelper()
+ : bitmap_needs_updating_(true),
+ layer_updated_externally_(false),
+ paint_to_layer_(false),
+ property_setter_explicitly_set_(false) {
+}
+
+LayerHelper::~LayerHelper() {
+ if (property_setter_.get() && layer_.get())
+ property_setter_->Uninstalled(layer_.get());
+ property_setter_.reset();
+ layer_.reset();
+}
+
+void LayerHelper::SetTransform(const ui::Transform& transform) {
+ transform_.reset(transform.HasChange() ? new ui::Transform(transform) : NULL);
+}
+
+void LayerHelper::SetLayer(ui::Layer* layer) {
+ if (property_setter_.get() && this->layer())
+ property_setter_->Uninstalled(this->layer());
+ layer_.reset(layer);
+ if (layer) {
+ if (!property_setter_.get())
+ property_setter_.reset(LayerPropertySetter::CreateDefaultSetter());
+ property_setter_->Installed(this->layer());
+ } else if (!property_setter_explicitly_set_) {
+ property_setter_.reset(NULL);
+ }
+}
+
+void LayerHelper::SetPropertySetter(LayerPropertySetter* setter) {
+ if (property_setter_.get() && layer())
+ property_setter_->Uninstalled(layer());
+ property_setter_.reset(setter);
+ if (layer()) {
+ if (!setter)
+ property_setter_.reset(LayerPropertySetter::CreateDefaultSetter());
+ property_setter_->Installed(layer());
+ }
+}
+
+bool LayerHelper::ShouldPaintToLayer() const {
+ return paint_to_layer_ || (transform_.get() && transform_->HasChange());
+}
+
+} // namespace internal
+
+} // namespace views
diff --git a/views/layer_helper.h b/views/layer_helper.h
new file mode 100644
index 0000000..bc6a177
--- /dev/null
+++ b/views/layer_helper.h
@@ -0,0 +1,111 @@
+// Copyright (c) 2011 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.
+
+#ifndef VIEWS_LAYER_HELPER_H_
+#define VIEWS_LAYER_HELPER_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/gfx/rect.h"
+
+namespace ui {
+class Layer;
+class Transform;
+}
+
+namespace views {
+
+class LayerPropertySetter;
+
+// This is a views-internal API and should not be used externally. View uses
+// this class to manage fields related to accelerated painting.
+namespace internal {
+
+class LayerHelper {
+ public:
+ LayerHelper();
+ ~LayerHelper();
+
+ void SetTransform(const ui::Transform& transform);
+
+ // Only returns non-null if a non-identity transform has been set.
+ const ui::Transform* transform() const { return transform_.get(); }
+
+ void SetLayer(ui::Layer* layer);
+ ui::Layer* layer() { return layer_.get(); }
+
+ // Rectangle that needs to be painted.
+ void set_clip_rect(const gfx::Rect& rect) {
+ clip_rect_ = rect;
+ }
+ const gfx::Rect& clip_rect() const { return clip_rect_; }
+
+ // If true, the layer's bitmap is out of date and needs to be updated.
+ void set_bitmap_needs_updating(bool value) {
+ bitmap_needs_updating_ = value;
+ }
+ bool bitmap_needs_updating() const {
+ return bitmap_needs_updating_;
+ }
+
+ // If true the layer was explicitly turned on.
+ void set_paint_to_layer(bool value) { paint_to_layer_ = value; }
+ bool paint_to_layer() const { return paint_to_layer_; }
+
+ void SetPropertySetter(LayerPropertySetter* setter);
+ LayerPropertySetter* property_setter() {
+ return property_setter_.get();
+ }
+
+ // If true the LayerPropertySetter was explicitly set.
+ void set_property_setter_explicitly_set(bool value) {
+ property_setter_explicitly_set_ = value;
+ }
+ bool property_setter_explicitly_set() {
+ return property_setter_explicitly_set_;
+ }
+
+ // See View::SetExternalTexture for details.
+ void set_layer_updated_externally(bool value) {
+ layer_updated_externally_ = value;
+ }
+ bool layer_updated_externally() const { return layer_updated_externally_; }
+
+ // Returns true if the layer needs to be used.
+ bool ShouldPaintToLayer() const;
+
+ private:
+ // The transformation matrix (rotation, translate, scale). If non-null the
+ // transform is not the identity transform.
+ scoped_ptr<ui::Transform> transform_;
+
+ scoped_ptr<ui::Layer> layer_;
+
+ scoped_ptr<LayerPropertySetter> property_setter_;
+
+ // Used during painting. If not empty and View::Paint() is invoked, the canvas
+ // is created with the specified size.
+ // TODO(sky): this should be passed into paint.
+ gfx::Rect clip_rect_;
+
+ // Is the layers bitmap out of date?
+ bool bitmap_needs_updating_;
+
+ // If true the bitmap is always up to date.
+ bool layer_updated_externally_;
+
+ // Should the View paint to a layer?
+ bool paint_to_layer_;
+
+ bool property_setter_explicitly_set_;
+
+ DISALLOW_COPY_AND_ASSIGN(LayerHelper);
+};
+
+} // namespace internal
+
+} // namespace views
+
+#endif // VIEWS_LAYER_HELPER_H_
diff --git a/views/view.cc b/views/view.cc
index 84bb6ea..bb9f641 100644
--- a/views/view.cc
+++ b/views/view.cc
@@ -107,9 +107,6 @@ View::View()
clip_y_(0.0),
needs_layout_(true),
flip_canvas_on_paint_for_rtl_ui_(false),
- layer_needs_updating_(true),
- layer_updated_externally_(false),
- paint_to_layer_(false),
accelerator_registration_delayed_(false),
accelerator_focus_manager_(NULL),
registered_accelerator_count_(0),
@@ -330,8 +327,8 @@ gfx::Rect View::GetVisibleBounds() const {
ui::Transform transform;
while (view != NULL && !vis_bounds.IsEmpty()) {
- if (view->transform_.get())
- transform.ConcatTransform(*view->transform_);
+ if (view->transform())
+ transform.ConcatTransform(*view->transform());
transform.ConcatTranslate(static_cast<float>(view->GetMirroredX()),
static_cast<float>(view->y()));
@@ -432,21 +429,19 @@ void View::OnEnabledChanged() {
const ui::Transform& View::GetTransform() const {
static const ui::Transform* no_op = new ui::Transform;
- if (transform_.get())
- return *transform_.get();
- return *no_op;
+ return transform() ? *transform() : *no_op;
}
void View::SetTransform(const ui::Transform& transform) {
if (!transform.HasChange()) {
- if (!transform_.get())
+ if (!layer_helper_.get() || !this->transform())
return;
- transform_.reset();
+ layer_helper_->SetTransform(transform);
if (!ShouldPaintToLayer())
DestroyLayerAndReparent();
- else if (layer_.get())
- layer_property_setter_->SetTransform(layer_.get(), transform);
+ else if (layer())
+ layer_helper_->property_setter()->SetTransform(layer(), transform);
SchedulePaint();
} else {
@@ -455,12 +450,14 @@ void View::SetTransform(const ui::Transform& transform) {
if (!ShouldPaintToLayer())
MarkLayerDirty();
- transform_.reset(new ui::Transform(transform));
- if (!layer_.get()) {
+ if (!layer_helper_.get())
+ layer_helper_.reset(new internal::LayerHelper());
+ layer_helper_->SetTransform(transform);
+ if (!layer()) {
CreateLayer();
SchedulePaint();
} else {
- layer_property_setter_->SetTransform(layer_.get(), transform);
+ 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
@@ -475,27 +472,32 @@ void View::SetTransform(const ui::Transform& transform) {
}
void View::SetPaintToLayer(bool value) {
- if (value == paint_to_layer_)
+ bool paint_to_layer = layer_helper_.get() && layer_helper_->paint_to_layer();
+ if (value == paint_to_layer)
return;
- paint_to_layer_ = value;
- if (!ShouldPaintToLayer())
- DestroyLayerAndReparent();
- else if (!layer_.get())
+ if (value) {
+ if (!layer_helper_.get())
+ layer_helper_.reset(new internal::LayerHelper());
+ layer_helper_->set_paint_to_layer(true);
CreateLayer();
+ } else if (layer_helper_.get()) {
+ layer_helper_->set_paint_to_layer(false);
+ if (!ShouldPaintToLayer())
+ DestroyLayerAndReparent();
+ }
}
void View::SetLayerPropertySetter(LayerPropertySetter* setter) {
- if (layer_property_setter_.get() == setter)
+ if ((layer_helper_.get() && layer_helper_->property_setter() == setter) ||
+ (!layer_helper_.get() && setter == NULL)) {
return;
+ }
- if (layer_property_setter_.get() && layer_.get())
- layer_property_setter_->Uninstalled(layer_.get());
- layer_property_setter_.reset(setter);
- if (!setter && layer_.get())
- layer_property_setter_.reset(LayerPropertySetter::CreateDefaultSetter());
- if (layer_property_setter_.get() && layer_.get())
- layer_property_setter_->Installed(layer_.get());
+ if (!layer_helper_.get())
+ layer_helper_.reset(new internal::LayerHelper());
+ layer_helper_->set_property_setter_explicitly_set(setter != NULL);
+ layer_helper_->SetPropertySetter(setter);
}
// RTL positioning -------------------------------------------------------------
@@ -670,10 +672,10 @@ void View::ConvertPointToScreen(const View* src, gfx::Point* p) {
}
gfx::Rect View::ConvertRectToParent(const gfx::Rect& rect) const {
- if (!transform_.get() || !transform_->HasChange())
+ if (!transform())
return rect;
gfx::Rect x_rect = rect;
- transform_->TransformRect(&x_rect);
+ transform()->TransformRect(&x_rect);
return x_rect;
}
@@ -699,10 +701,10 @@ void View::Paint(gfx::Canvas* canvas) {
scoped_ptr<gfx::Canvas> layer_canvas;
gfx::Rect layer_rect;
- if (layer_.get()) {
+ if (layer()) {
gfx::Rect dirty_rect;
- if (!layer_clip_rect_.IsEmpty()) {
- dirty_rect = layer_clip_rect_;
+ if (!layer_helper_->clip_rect().IsEmpty()) {
+ dirty_rect = layer_helper_->clip_rect();
} else {
// TODO: clip against dirty rect of canvas (if canvas is non-null).
dirty_rect = gfx::Rect(0, 0, width(), height());
@@ -710,7 +712,7 @@ void View::Paint(gfx::Canvas* canvas) {
if (dirty_rect.IsEmpty())
return;
- if (!layer_needs_updating_) {
+ if (!layer_helper_->bitmap_needs_updating()) {
// We don't need to be painted. Iterate over descendants in case one of
// them is dirty.
PaintToLayer(dirty_rect);
@@ -744,8 +746,8 @@ void View::Paint(gfx::Canvas* canvas) {
// where this view is located (related to its parent).
canvas->TranslateInt(GetMirroredX(), y());
- if (transform_.get() && transform_->HasChange())
- canvas->Transform(*transform_.get());
+ if (transform())
+ canvas->Transform(*transform());
}
{
@@ -767,10 +769,10 @@ void View::Paint(gfx::Canvas* canvas) {
PaintChildren(canvas);
if (layer_canvas.get()) {
- layer_->SetBitmap(
+ layer()->SetBitmap(
layer_canvas->AsCanvasSkia()->getDevice()->accessBitmap(false),
layer_rect.origin());
- layer_needs_updating_ = false;
+ layer_helper_->set_bitmap_needs_updating(false);
}
}
@@ -1172,9 +1174,9 @@ void View::PaintComposite() {
if (!IsVisible())
return;
- if (layer_.get()) {
+ if (layer()) {
OnWillCompositeLayer();
- layer_->Draw();
+ layer()->Draw();
}
for (int i = 0, count = child_count(); i < count; ++i)
@@ -1195,10 +1197,10 @@ void View::PaintToLayer(const gfx::Rect& dirty_region) {
if (!IsVisible())
return;
- if (layer_.get() && layer_needs_updating_) {
- layer_clip_rect_ = dirty_region;
+ if (layer() && layer_helper_->bitmap_needs_updating()) {
+ layer_helper_->set_clip_rect(dirty_region);
Paint(NULL);
- layer_clip_rect_.SetRect(0, 0, 0, 0);
+ layer_helper_->set_clip_rect(gfx::Rect());
} else {
// Forward to all children as a descendant may be dirty and have a layer.
for (int i = child_count() - 1; i >= 0; --i) {
@@ -1224,19 +1226,24 @@ bool View::SetExternalTexture(ui::Texture* texture) {
// The desired use case is where there are no children.
DCHECK_EQ(child_count(), 0);
+ if (!texture && !layer_helper_.get())
+ return true;
+
+ if (!layer_helper_.get())
+ layer_helper_.reset(new internal::LayerHelper());
bool use_external = (texture != NULL);
- if (use_external != paint_to_layer_)
+ if (use_external != layer_helper_->paint_to_layer())
SetPaintToLayer(use_external);
- else if (use_external && !layer_.get())
+ else if (use_external && !layer())
CreateLayer();
- if (use_external && !layer_.get())
+ if (use_external && !layer())
return false;
- layer_updated_externally_ = use_external;
- layer_needs_updating_ = !use_external;
- if (layer_.get())
- layer_->SetTexture(texture);
+ layer_helper_->set_layer_updated_externally(use_external);
+ layer_helper_->set_bitmap_needs_updating(!use_external);
+ if (layer())
+ layer()->SetTexture(texture);
if (IsVisible())
SchedulePaintInternal(GetLocalBounds());
@@ -1354,7 +1361,7 @@ void View::DragInfo::PossibleDrag(const gfx::Point& p) {
// Painting --------------------------------------------------------------------
void View::SchedulePaintBoundsChanged(SchedulePaintType type) {
- if (layer_.get() && type == SCHEDULE_PAINT_SIZE_SAME) {
+ if (layer() && type == SCHEDULE_PAINT_SIZE_SAME) {
// If only the positions changes and we have a layer, we don't need to mark
// the layer as dirty (which SchedulePaint does), only paint the bounds.
SchedulePaintInternal(gfx::Rect(0, 0, width(), height()));
@@ -1477,14 +1484,14 @@ void View::BoundsChanged(const gfx::Rect& previous_bounds) {
SCHEDULE_PAINT_SIZE_CHANGED);
if (use_acceleration_when_possible) {
- if (layer_.get()) {
+ if (layer()) {
if (parent_) {
gfx::Point offset(parent_->CalculateOffsetToAncestorWithLayer(NULL));
offset.Offset(x(), y());
- layer_property_setter_->SetBounds(layer_.get(),
- gfx::Rect(offset, size()));
+ layer_helper_->property_setter()->SetBounds(
+ layer(), gfx::Rect(offset, size()));
} else {
- layer_property_setter_->SetBounds(layer_.get(), bounds_);
+ layer_helper_->property_setter()->SetBounds(layer(), bounds_);
}
} else if (GetCompositor()) {
// If our bounds have changed, then any descendant layer bounds may
@@ -1577,8 +1584,8 @@ bool View::GetTransformRelativeTo(const View* ancestor,
const View* p = this;
while (p && p != ancestor) {
- if (p->transform_.get())
- transform->ConcatTransform(*p->transform_);
+ if (p->transform())
+ transform->ConcatTransform(*p->transform());
transform->ConcatTranslate(static_cast<float>(p->GetMirroredX()),
static_cast<float>(p->y()));
@@ -1639,17 +1646,17 @@ bool View::ConvertPointFromAncestor(const View* ancestor,
bool View::ShouldPaintToLayer() const {
return use_acceleration_when_possible &&
- (paint_to_layer_ || (transform_.get() && transform_->HasChange()));
+ layer_helper_.get() && layer_helper_->ShouldPaintToLayer();
}
void View::MarkLayerDirty() {
- if (layer_updated_externally_)
- return;
View* owner = this;
- while (!((owner->transform_.get() && owner->transform_->HasChange()) ||
- owner->paint_to_layer_) && owner->parent_)
+ while (!owner->ShouldPaintToLayer() && owner->parent_)
owner = owner->parent_;
- owner->layer_needs_updating_ = true;
+ if (owner->layer_helper_.get() &&
+ !owner->layer_helper_->layer_updated_externally()) {
+ owner->layer_helper_->set_bitmap_needs_updating(true);
+ }
}
void View::CreateLayerIfNecessary() {
@@ -1661,29 +1668,28 @@ void View::CreateLayerIfNecessary() {
}
void View::CreateLayer() {
- if (!ShouldPaintToLayer() || layer_.get())
+ if (!ShouldPaintToLayer() || layer())
return;
ui::Compositor* compositor = GetCompositor();
if (!compositor)
return;
+ DCHECK(layer_helper_.get());
+
View* ancestor_with_layer = NULL;
gfx::Point offset(CalculateOffsetToAncestorWithLayer(&ancestor_with_layer));
DCHECK(ancestor_with_layer || parent_ == NULL);
- layer_.reset(new ui::Layer(compositor));
- if (!layer_property_setter_.get())
- layer_property_setter_.reset(LayerPropertySetter::CreateDefaultSetter());
- layer_property_setter_->Installed(layer_.get());
- layer_->set_bounds(gfx::Rect(offset.x(), offset.y(), width(), height()));
+ layer_helper_->SetLayer(new ui::Layer(compositor));
+ layer()->set_bounds(gfx::Rect(offset.x(), offset.y(), width(), height()));
if (ancestor_with_layer)
- ancestor_with_layer->layer_->Add(layer_.get());
- layer_needs_updating_ = true;
+ ancestor_with_layer->layer()->Add(layer());
+ layer_helper_->set_bitmap_needs_updating(true);
for (int i = 0, count = child_count(); i < count; ++i)
- GetChildViewAt(i)->MoveLayerToParent(layer_.get(), gfx::Point());
+ GetChildViewAt(i)->MoveLayerToParent(layer(), gfx::Point());
}
void View::DestroyLayerRecurse() {
@@ -1693,11 +1699,11 @@ void View::DestroyLayerRecurse() {
}
void View::DestroyLayerAndReparent() {
- if (!layer_.get())
+ if (!layer())
return;
- ui::Layer* new_parent = layer_->parent();
- std::vector<ui::Layer*> children = layer_->children();
+ 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]);
@@ -1709,17 +1715,21 @@ void View::DestroyLayerAndReparent() {
}
void View::DestroyLayer() {
- if (layer_property_setter_.get())
- layer_property_setter_->Uninstalled(layer_.get());
- layer_.reset();
+ if (!layer_helper_.get())
+ return;
+
+ if (!layer_helper_->property_setter_explicitly_set() && !ShouldPaintToLayer())
+ layer_helper_.reset();
+ else
+ layer_helper_->SetLayer(NULL);
}
void View::MoveLayerToParent(ui::Layer* parent_layer,
const gfx::Point& point) {
gfx::Point local_point(point.x() + x(), point.y() + y());
- if (layer_.get()) {
- parent_layer->Add(layer_.get());
- layer_->set_bounds(
+ if (layer()) {
+ parent_layer->Add(layer());
+ layer()->set_bounds(
gfx::Rect(local_point.x(), local_point.y(), width(), height()));
} else {
for (int i = 0, count = child_count(); i < count; ++i)
@@ -1728,9 +1738,9 @@ void View::MoveLayerToParent(ui::Layer* parent_layer,
}
void View::UpdateLayerBounds(const gfx::Point& offset) {
- if (layer_.get()) {
- layer_property_setter_->SetBounds(
- layer_.get(),
+ if (layer()) {
+ layer_helper_->property_setter()->SetBounds(
+ layer(),
gfx::Rect(offset.x() + x(), offset.y() + y(), width(), height()));
} else {
gfx::Point new_offset(offset.x() + x(), offset.y() + y());
@@ -1996,7 +2006,7 @@ std::string View::PrintViewGraph(bool first) {
result.append("\"");
if (!parent_)
result.append(", shape=box");
- if (layer_.get())
+ if (layer())
result.append(", color=green");
result.append("]\n");
diff --git a/views/view.h b/views/view.h
index e510d53..03374bc 100644
--- a/views/view.h
+++ b/views/view.h
@@ -21,6 +21,7 @@
#include "views/accelerator.h"
#include "views/background.h"
#include "views/border.h"
+#include "views/layer_helper.h"
using ui::OSExchangeData;
@@ -276,8 +277,12 @@ class View : public AcceleratorTarget {
// LayerPropertySetter to the default (immediate).
void SetLayerPropertySetter(LayerPropertySetter* setter);
- const ui::Layer* layer() const { return layer_.get(); }
- ui::Layer* layer() { return layer_.get(); }
+ const ui::Layer* layer() const {
+ return layer_helper_.get() ? layer_helper_->layer() : NULL;
+ }
+ ui::Layer* layer() {
+ return layer_helper_.get() ? layer_helper_->layer() : NULL;
+ }
// RTL positioning -----------------------------------------------------------
@@ -1223,6 +1228,13 @@ class View : public AcceleratorTarget {
// If |ancestor| is non-NULL it is set to the nearset ancestor with a layer.
gfx::Point CalculateOffsetToAncestorWithLayer(View** ancestor);
+ // Returns the transform, or NULL if no transform has been set or the identity
+ // transform was set. Be careful in using this as it may return NULL. Use
+ // GetTransform() if you always want a non-NULL transform.
+ const ui::Transform* transform() const {
+ return layer_helper_.get() ? layer_helper_->transform() : NULL;
+ }
+
// Input ---------------------------------------------------------------------
// RootView invokes these. These in turn invoke the appropriate OnMouseXXX
@@ -1336,9 +1348,6 @@ class View : public AcceleratorTarget {
// Transformations -----------------------------------------------------------
- // The transformation matrix (rotation, translate, scale).
- scoped_ptr<ui::Transform> transform_;
-
// Clipping parameters. skia transformation matrix does not give us clipping.
// So we do it ourselves.
float clip_x_;
@@ -1370,24 +1379,7 @@ class View : public AcceleratorTarget {
// Accelerated painting ------------------------------------------------------
- scoped_ptr<ui::Layer> layer_;
-
- // If not empty and Paint() is invoked, the canvas is created with the
- // specified size.
- // TODO(sky): this should be passed in.
- gfx::Rect layer_clip_rect_;
-
- // Is the layer out of date?
- bool layer_needs_updating_;
-
- // Is the texture backing the layer being updated externally?
- // (i.e. by the GPU process when rendering 3D CSS)
- bool layer_updated_externally_;
-
- // Should we paint to a layer? See description above setter for details.
- bool paint_to_layer_;
-
- scoped_ptr<LayerPropertySetter> layer_property_setter_;
+ scoped_ptr<internal::LayerHelper> layer_helper_;
// Accelerators --------------------------------------------------------------
diff --git a/views/view_unittest.cc b/views/view_unittest.cc
index 4052eb6..729b0c2 100644
--- a/views/view_unittest.cc
+++ b/views/view_unittest.cc
@@ -2482,6 +2482,22 @@ TEST_F(ViewLayerTest, BoundsChangeWithLayer) {
EXPECT_EQ(gfx::Rect(36, 48, 40, 50), v2->layer()->bounds());
}
+// Makes sure a transform persists after toggling the visibility.
+TEST_F(ViewLayerTest, ToggleVisibilityWithTransform) {
+ View* view = new View;
+ ui::Transform transform;
+ transform.SetScale(2.0f, 2.0f);
+ view->SetTransform(transform);
+ widget()->SetContentsView(view);
+ EXPECT_EQ(2.0f, view->GetTransform().matrix()[0]);
+
+ view->SetVisible(false);
+ EXPECT_EQ(2.0f, view->GetTransform().matrix()[0]);
+
+ view->SetVisible(true);
+ EXPECT_EQ(2.0f, view->GetTransform().matrix()[0]);
+}
+
#endif // VIEWS_COMPOSITOR || TOUCH_UI
} // namespace views
diff --git a/views/views.gyp b/views/views.gyp
index 5d099ba..c16835e 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -300,6 +300,8 @@
'ime/input_method_win.cc',
'ime/input_method_win.h',
'ime/text_input_client.h',
+ 'layer_helper.cc',
+ 'layer_helper.h',
'layer_property_setter.cc',
'layer_property_setter.h',
'layout/box_layout.cc',