Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Unified Diff: ui/views/view_unittest.cc

Issue 275183002: patch from issue 218843002 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/view.cc ('k') | ui/views/views.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/view_unittest.cc
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc
index b1bcb6ac817d358e23d22348a9b91bb7d7d65fcf..3685673ecc9834ee048f2dd431856c0b06de79e7 100644
--- a/ui/views/view_unittest.cc
+++ b/ui/views/view_unittest.cc
@@ -240,7 +240,7 @@ class TestView : public View {
// Ignores GestureEvent by default.
virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE;
- virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
+ virtual void Paint(gfx::Canvas* canvas, const CullSet& cull_set) OVERRIDE;
virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE;
virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE;
@@ -670,7 +670,7 @@ TEST_F(ViewTest, ScrollGestureEvent) {
// Painting
////////////////////////////////////////////////////////////////////////////////
-void TestView::Paint(gfx::Canvas* canvas) {
+void TestView::Paint(gfx::Canvas* canvas, const CullSet& cull_set) {
canvas->sk_canvas()->getClipBounds(&last_clip_);
}
@@ -3463,6 +3463,246 @@ TEST_F(ViewLayerTest, RecreateLayerMovesNonViewChildren) {
EXPECT_EQ(v.layer()->children()[1], child.layer());
}
+class BoundsTreeTestView : public View {
+ public:
+ BoundsTreeTestView() {}
+
+ virtual void PaintChildren(gfx::Canvas* canvas,
+ const CullSet& cull_set) OVERRIDE {
+ // Save out a copy of the cull_set before calling the base implementation.
+ last_cull_set_.clear();
+ if (cull_set.cull_set_) {
+ for (base::hash_set<intptr_t>::iterator it = cull_set.cull_set_->begin();
+ it != cull_set.cull_set_->end();
+ ++it) {
+ last_cull_set_.insert(reinterpret_cast<View*>(*it));
+ }
+ }
+ View::PaintChildren(canvas, cull_set);
+ }
+
+ std::set<View*> last_cull_set_;
+};
+
+TEST_F(ViewLayerTest, BoundsTreePaintUpdatesCullSet) {
+ BoundsTreeTestView* test_view = new BoundsTreeTestView;
+ widget()->SetContentsView(test_view);
+
+ View* v1 = new View();
+ v1->SetBoundsRect(gfx::Rect(10, 15, 150, 151));
+ test_view->AddChildView(v1);
+
+ View* v2 = new View();
+ v2->SetBoundsRect(gfx::Rect(20, 33, 40, 50));
+ v1->AddChildView(v2);
+
+ // Schedule a full-view paint to get everyone's rectangles updated.
+ test_view->SchedulePaintInRect(test_view->bounds());
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+
+ // Now we have test_view - v1 - v2. Damage to only test_view should only
+ // return root_view and test_view.
+ test_view->SchedulePaintInRect(gfx::Rect(0, 0, 1, 1));
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ EXPECT_EQ(2U, test_view->last_cull_set_.size());
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
+
+ // Damage to v1 only should only return root_view, test_view, and v1.
+ test_view->SchedulePaintInRect(gfx::Rect(11, 16, 1, 1));
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ EXPECT_EQ(3U, test_view->last_cull_set_.size());
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
+
+ // A Damage rect inside v2 should get all 3 views back in the |last_cull_set_|
+ // on call to TestView::Paint(), along with the widget root view.
+ test_view->SchedulePaintInRect(gfx::Rect(31, 49, 1, 1));
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ EXPECT_EQ(4U, test_view->last_cull_set_.size());
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(v2));
+}
+
+TEST_F(ViewLayerTest, BoundsTreeSetBoundsChangesCullSet) {
+ BoundsTreeTestView* test_view = new BoundsTreeTestView;
+ widget()->SetContentsView(test_view);
+
+ View* v1 = new View;
+ v1->SetBoundsRect(gfx::Rect(5, 6, 100, 101));
+ test_view->AddChildView(v1);
+
+ View* v2 = new View;
+ v2->SetBoundsRect(gfx::Rect(20, 33, 40, 50));
+ v1->AddChildView(v2);
+
+ // Schedule a full-view paint to get everyone's rectangles updated.
+ test_view->SchedulePaintInRect(test_view->bounds());
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+
+ // Move v1 to a new origin out of the way of our next query.
+ v1->SetBoundsRect(gfx::Rect(50, 60, 100, 101));
+ // The move will force a repaint.
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+
+ // Schedule a paint with damage rect where v1 used to be.
+ test_view->SchedulePaintInRect(gfx::Rect(5, 6, 10, 11));
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+
+ // Should only have picked up root_view and test_view.
+ EXPECT_EQ(2U, test_view->last_cull_set_.size());
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
+}
+
+TEST_F(ViewLayerTest, BoundsTreeLayerChangeMakesNewTree) {
+ BoundsTreeTestView* test_view = new BoundsTreeTestView;
+ widget()->SetContentsView(test_view);
+
+ View* v1 = new View;
+ v1->SetBoundsRect(gfx::Rect(5, 10, 15, 20));
+ test_view->AddChildView(v1);
+
+ View* v2 = new View;
+ v2->SetBoundsRect(gfx::Rect(1, 2, 3, 4));
+ v1->AddChildView(v2);
+
+ // Schedule a full-view paint to get everyone's rectangles updated.
+ test_view->SchedulePaintInRect(test_view->bounds());
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+
+ // Set v1 to paint to its own layer, it should remove itself from the
+ // test_view heiarchy and no longer intersect with damage rects in that cull
+ // set.
+ v1->SetPaintToLayer(true);
+
+ // Schedule another full-view paint.
+ test_view->SchedulePaintInRect(test_view->bounds());
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ // v1 and v2 should no longer be present in the test_view cull_set.
+ EXPECT_EQ(2U, test_view->last_cull_set_.size());
+ EXPECT_EQ(0U, test_view->last_cull_set_.count(v1));
+ EXPECT_EQ(0U, test_view->last_cull_set_.count(v2));
+
+ // Now set v1 back to not painting to a layer.
+ v1->SetPaintToLayer(false);
+ // Schedule another full-view paint.
+ test_view->SchedulePaintInRect(test_view->bounds());
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ // We should be back to the full cull set including v1 and v2.
+ EXPECT_EQ(4U, test_view->last_cull_set_.size());
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(v2));
+}
+
+TEST_F(ViewLayerTest, BoundsTreeRemoveChildRemovesBounds) {
+ BoundsTreeTestView* test_view = new BoundsTreeTestView;
+ widget()->SetContentsView(test_view);
+
+ View* v1 = new View;
+ v1->SetBoundsRect(gfx::Rect(5, 10, 15, 20));
+ test_view->AddChildView(v1);
+
+ View* v2 = new View;
+ v2->SetBoundsRect(gfx::Rect(1, 2, 3, 4));
+ v1->AddChildView(v2);
+
+ // Schedule a full-view paint to get everyone's rectangles updated.
+ test_view->SchedulePaintInRect(test_view->bounds());
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+
+ // Now remove v1 from the root view.
+ test_view->RemoveChildView(v1);
+
+ // Schedule another full-view paint.
+ test_view->SchedulePaintInRect(test_view->bounds());
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ // v1 and v2 should no longer be present in the test_view cull_set.
+ EXPECT_EQ(2U, test_view->last_cull_set_.size());
+ EXPECT_EQ(0U, test_view->last_cull_set_.count(v1));
+ EXPECT_EQ(0U, test_view->last_cull_set_.count(v2));
+
+ // View v1 and v2 are no longer part of view hierarchy and therefore won't be
+ // deleted with that hierarchy.
+ delete v1;
+}
+
+TEST_F(ViewLayerTest, BoundsTreeMoveViewMovesBounds) {
+ BoundsTreeTestView* test_view = new BoundsTreeTestView;
+ widget()->SetContentsView(test_view);
+
+ // Build hierarchy v1 - v2 - v3.
+ View* v1 = new View;
+ v1->SetBoundsRect(gfx::Rect(20, 30, 150, 160));
+ test_view->AddChildView(v1);
+
+ View* v2 = new View;
+ v2->SetBoundsRect(gfx::Rect(5, 10, 40, 50));
+ v1->AddChildView(v2);
+
+ View* v3 = new View;
+ v3->SetBoundsRect(gfx::Rect(1, 2, 3, 4));
+ v2->AddChildView(v3);
+
+ // Schedule a full-view paint and ensure all views are present in the cull.
+ test_view->SchedulePaintInRect(test_view->bounds());
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+ EXPECT_EQ(5U, test_view->last_cull_set_.size());
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(v2));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(v3));
+
+ // Build an unrelated view hierarchy and move v2 in to it.
+ scoped_ptr<Widget> test_widget(new Widget);
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
+ params.bounds = gfx::Rect(10, 10, 500, 500);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ test_widget->Init(params);
+ test_widget->Show();
+ BoundsTreeTestView* widget_view = new BoundsTreeTestView;
+ test_widget->SetContentsView(widget_view);
+ widget_view->AddChildView(v2);
+
+ // Now schedule full-view paints in both widgets.
+ test_view->SchedulePaintInRect(test_view->bounds());
+ widget_view->SchedulePaintInRect(widget_view->bounds());
+ GetRootLayer()->GetCompositor()->ScheduleDraw();
+ ui::DrawWaiterForTest::Wait(GetRootLayer()->GetCompositor());
+
+ // Only v1 should be present in the first cull set.
+ EXPECT_EQ(3U, test_view->last_cull_set_.size());
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(widget()->GetRootView()));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(test_view));
+ EXPECT_EQ(1U, test_view->last_cull_set_.count(v1));
+
+ // We should find v2 and v3 in the widget_view cull_set.
+ EXPECT_EQ(4U, widget_view->last_cull_set_.size());
+ EXPECT_EQ(1U, widget_view->last_cull_set_.count(test_widget->GetRootView()));
+ EXPECT_EQ(1U, widget_view->last_cull_set_.count(widget_view));
+ EXPECT_EQ(1U, widget_view->last_cull_set_.count(v2));
+ EXPECT_EQ(1U, widget_view->last_cull_set_.count(v3));
+}
+
TEST_F(ViewTest, FocusableAssertions) {
// View subclasses may change insets based on whether they are focusable,
// which effects the preferred size. To avoid preferred size changing around
« no previous file with comments | « ui/views/view.cc ('k') | ui/views/views.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698