summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ui/gfx/compositor/layer.cc24
-rw-r--r--ui/gfx/compositor/layer.h16
-rw-r--r--ui/gfx/compositor/layer_unittest.cc124
-rw-r--r--views/view.cc9
-rw-r--r--views/view.h2
5 files changed, 99 insertions, 76 deletions
diff --git a/ui/gfx/compositor/layer.cc b/ui/gfx/compositor/layer.cc
index b9475b1..2c9f1a7 100644
--- a/ui/gfx/compositor/layer.cc
+++ b/ui/gfx/compositor/layer.cc
@@ -23,6 +23,17 @@ Layer::Layer(Compositor* compositor)
delegate_(NULL) {
}
+Layer::Layer(Compositor* compositor, TextureParam texture_param)
+ : compositor_(compositor),
+ texture_(texture_param == LAYER_HAS_TEXTURE ?
+ compositor->CreateTexture() : NULL),
+ parent_(NULL),
+ visible_(true),
+ fills_bounds_opaquely_(false),
+ layer_updated_externally_(false),
+ delegate_(NULL) {
+}
+
Layer::~Layer() {
if (parent_)
parent_->Remove(this);
@@ -103,13 +114,9 @@ void Layer::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
}
void Layer::SetExternalTexture(ui::Texture* texture) {
- if (texture == NULL) {
- layer_updated_externally_ = false;
- texture_ = compositor_->CreateTexture();
- } else {
- layer_updated_externally_ = true;
- texture_ = texture;
- }
+ DCHECK(texture);
+ layer_updated_externally_ = true;
+ texture_ = texture;
}
void Layer::SetCanvas(const SkCanvas& canvas, const gfx::Point& origin) {
@@ -123,6 +130,9 @@ void Layer::SchedulePaint(const gfx::Rect& invalid_rect) {
}
void Layer::Draw() {
+ if (!texture_.get())
+ return;
+
UpdateLayerCanvas();
ui::TextureDrawParams texture_draw_params;
diff --git a/ui/gfx/compositor/layer.h b/ui/gfx/compositor/layer.h
index 734cb0d..2a37c2d 100644
--- a/ui/gfx/compositor/layer.h
+++ b/ui/gfx/compositor/layer.h
@@ -24,13 +24,21 @@ class Texture;
// Layer manages a texture, transform and a set of child Layers. Any View that
// has enabled layers ends up creating a Layer to manage the texture.
+// A Layer can also be created without a texture, in which case it renders
+// nothing and is simply used as a node in a hierarchy of layers.
//
// NOTE: unlike Views, each Layer does *not* own its children views. If you
// delete a Layer and it has children, the parent of each child layer is set to
// NULL, but the children are not deleted.
class COMPOSITOR_EXPORT Layer {
public:
+ enum TextureParam {
+ LAYER_HAS_NO_TEXTURE = 0,
+ LAYER_HAS_TEXTURE = 1
+ };
+
explicit Layer(Compositor* compositor);
+ Layer(Compositor* compositor, TextureParam texture_param);
~Layer();
LayerDelegate* delegate() { return delegate_; }
@@ -81,10 +89,14 @@ class COMPOSITOR_EXPORT Layer {
const Compositor* compositor() const { return compositor_; }
Compositor* compositor() { return compositor_; }
- // Passing NULL will cause the layer to get a texture from its compositor.
- void SetExternalTexture(ui::Texture* texture);
const ui::Texture* texture() const { return texture_.get(); }
+ // |texture| cannot be NULL, and this function cannot be called more than
+ // once.
+ // TODO(beng): This can be removed from the API when we are in a
+ // single-compositor world.
+ void SetExternalTexture(ui::Texture* texture);
+
// Resets the canvas of the texture.
void SetCanvas(const SkCanvas& canvas, const gfx::Point& origin);
diff --git a/ui/gfx/compositor/layer_unittest.cc b/ui/gfx/compositor/layer_unittest.cc
index fdc607b..fcac281 100644
--- a/ui/gfx/compositor/layer_unittest.cc
+++ b/ui/gfx/compositor/layer_unittest.cc
@@ -15,23 +15,8 @@ namespace ui {
namespace {
-// Simple class that exits the current message loop when compositing finishes.
-class CompositingEndedObserver : public CompositorObserver {
- public:
- CompositingEndedObserver() {}
- virtual ~CompositingEndedObserver() {}
-
- // Overridden from CompositorObserver:
- virtual void OnCompositingEnded() OVERRIDE {
- MessageLoop::current()->Quit();
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CompositingEndedObserver);
-};
-
class TestLayerDelegate : public LayerDelegate {
-public:
+ public:
explicit TestLayerDelegate(Layer* owner) : owner_(owner), color_index_(0) {}
virtual ~TestLayerDelegate() {}
@@ -52,7 +37,7 @@ public:
color_index_ = ++color_index_ % colors_.size();
}
-private:
+ private:
Layer* owner_;
std::vector<SkColor> colors_;
int color_index_;
@@ -80,17 +65,23 @@ class LayerTest : public testing::Test {
return window_->GetCompositor();
}
- Layer* CreateLayer() {
- return new Layer(GetCompositor());
+ Layer* CreateLayer(Layer::TextureParam texture_param) {
+ return new Layer(GetCompositor(), texture_param);
}
Layer* CreateColorLayer(SkColor color, const gfx::Rect& bounds) {
- Layer* layer = CreateLayer();
+ Layer* layer = CreateLayer(Layer::LAYER_HAS_TEXTURE);
layer->SetBounds(bounds);
PaintColorToLayer(layer, color);
return layer;
}
+ Layer* CreateNoTextureLayer(const gfx::Rect& bounds) {
+ Layer* layer = CreateLayer(Layer::LAYER_HAS_NO_TEXTURE);
+ layer->SetBounds(bounds);
+ return layer;
+ }
+
gfx::Canvas* CreateCanvasForLayer(const Layer* layer) {
return gfx::Canvas::CreateCanvas(layer->bounds().width(),
layer->bounds().height(),
@@ -110,7 +101,7 @@ class LayerTest : public testing::Test {
}
void RunPendingMessages() {
- MessageLoopForUI::current()->Run(NULL);
+ MessageLoopForUI::current()->RunAllPending();
}
private:
@@ -120,26 +111,26 @@ class LayerTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(LayerTest);
};
-class LayerQuitOnCompositedTest : public LayerTest {
+class DrawTreeLayerDelegate : public LayerDelegate {
public:
- LayerQuitOnCompositedTest() {}
- virtual ~LayerQuitOnCompositedTest() {}
+ DrawTreeLayerDelegate() : painted_(false) {}
+ virtual ~DrawTreeLayerDelegate() {}
- // Overridden from LayerTest:
- virtual void SetUp() OVERRIDE {
- LayerTest::SetUp();
- GetCompositor()->AddObserver(&compositor_observer_);
+ void Reset() {
+ painted_ = false;
}
- virtual void TearDown() OVERRIDE {
- LayerTest::TearDown();
- GetCompositor()->RemoveObserver(&compositor_observer_);
+ bool painted() const { return painted_; }
+
+ // Overridden from LayerDelegate:
+ virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
+ painted_ = true;
}
private:
- CompositingEndedObserver compositor_observer_;
+ bool painted_;
- DISALLOW_COPY_AND_ASSIGN(LayerQuitOnCompositedTest);
+ DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
};
}
@@ -219,7 +210,7 @@ TEST_F(LayerTest, ConvertPointToLayer_Medium) {
EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords);
}
-TEST_F(LayerQuitOnCompositedTest, Delegate) {
+TEST_F(LayerTest, Delegate) {
scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorBLACK,
gfx::Rect(20, 20, 400, 400)));
TestLayerDelegate delegate(l1.get());
@@ -246,33 +237,7 @@ TEST_F(LayerQuitOnCompositedTest, Delegate) {
EXPECT_EQ(delegate.paint_size(), gfx::Size(50, 50));
}
-namespace {
-
-class DrawTreeLayerDelegate : public LayerDelegate {
- public:
- DrawTreeLayerDelegate() : painted_(false) {}
- virtual ~DrawTreeLayerDelegate() {}
-
- void Reset() {
- painted_ = false;
- }
-
- bool painted() const { return painted_; }
-
- // Overridden from LayerDelegate:
- virtual void OnPaintLayer(gfx::Canvas* canvas) OVERRIDE {
- painted_ = true;
- }
-
- private:
- bool painted_;
-
- DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
-};
-
-} // namespace
-
-TEST_F(LayerQuitOnCompositedTest, DrawTree) {
+TEST_F(LayerTest, DrawTree) {
scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
gfx::Rect(20, 20, 400, 400)));
scoped_ptr<Layer> l2(CreateColorLayer(SK_ColorBLUE,
@@ -298,5 +263,42 @@ TEST_F(LayerQuitOnCompositedTest, DrawTree) {
EXPECT_FALSE(d3.painted());
}
+// Tests no-texture Layers.
+// Create this hierarchy:
+// L1 - red
+// +-- L2 - NO TEXTURE
+// | +-- L3 - yellow
+// +-- L4 - magenta
+//
+TEST_F(LayerTest, HierarchyNoTexture) {
+ scoped_ptr<Layer> l1(CreateColorLayer(SK_ColorRED,
+ gfx::Rect(20, 20, 400, 400)));
+ scoped_ptr<Layer> l2(CreateNoTextureLayer(gfx::Rect(10, 10, 350, 350)));
+ scoped_ptr<Layer> l3(CreateColorLayer(SK_ColorYELLOW,
+ gfx::Rect(5, 5, 25, 25)));
+ scoped_ptr<Layer> l4(CreateColorLayer(SK_ColorMAGENTA,
+ gfx::Rect(300, 300, 100, 100)));
+
+ l1->Add(l2.get());
+ l1->Add(l4.get());
+ l2->Add(l3.get());
+
+ DrawTreeLayerDelegate d2;
+ l2->set_delegate(&d2);
+ DrawTreeLayerDelegate d3;
+ l3->set_delegate(&d3);
+
+ GetCompositor()->set_root_layer(l1.get());
+
+ l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
+ l3->SchedulePaint(gfx::Rect(5, 5, 5, 5));
+ RunPendingMessages();
+
+ // |d2| should not have received a paint notification since it has no texture.
+ EXPECT_FALSE(d2.painted());
+ // |d3| should have received a paint notification.
+ EXPECT_TRUE(d3.painted());
+}
+
} // namespace ui
diff --git a/views/view.cc b/views/view.cc
index b0f0b08..57f724d 100644
--- a/views/view.cc
+++ b/views/view.cc
@@ -1111,7 +1111,8 @@ void View::SetFillsBoundsOpaquely(bool fills_bounds_opaquely) {
}
bool View::SetExternalTexture(ui::Texture* texture) {
- if (!texture && !layer_helper_.get())
+ DCHECK(texture);
+ if (!layer_helper_.get())
return true;
if (!layer_helper_.get())
@@ -1120,10 +1121,8 @@ bool View::SetExternalTexture(ui::Texture* texture) {
// Child views must not paint into the external texture. So make sure each
// child view has its own layer to paint into.
- if (texture) {
- for (Views::iterator i = children_.begin(); i != children_.end(); ++i)
- (*i)->SetPaintToLayer(true);
- }
+ for (Views::iterator i = children_.begin(); i != children_.end(); ++i)
+ (*i)->SetPaintToLayer(true);
SchedulePaintInRect(GetLocalBounds());
diff --git a/views/view.h b/views/view.h
index c12c2bd2..a9cf33a 100644
--- a/views/view.h
+++ b/views/view.h
@@ -967,7 +967,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// passes the texture to a layer associated with the view. While an external
// texture is set, the view will not update the layer contents.
//
- // Passing NULL resets to default behavior.
+ // |texture| cannot be NULL.
//
// Returns false if it cannot create a layer to which to assign the texture.
bool SetExternalTexture(ui::Texture* texture);