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

Side by Side Diff: ui/views/view.cc

Issue 342723002: Repairs crash in RTreeBase::Node::LeastAreaEnlargement (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: crash fix and test added Created 6 years, 6 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 unified diff | Download patch
« no previous file with comments | « ui/views/view.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #define _USE_MATH_DEFINES // For VC++ to get M_PI. This has to be first. 5 #define _USE_MATH_DEFINES // For VC++ to get M_PI. This has to be first.
6 6
7 #include "ui/views/view.h" 7 #include "ui/views/view.h"
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cmath> 10 #include <cmath>
(...skipping 764 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 775
776 // Non-empty clip, translate the graphics such that 0,0 corresponds to where 776 // Non-empty clip, translate the graphics such that 0,0 corresponds to where
777 // this view is located (related to its parent). 777 // this view is located (related to its parent).
778 canvas->Translate(GetMirroredPosition().OffsetFromOrigin()); 778 canvas->Translate(GetMirroredPosition().OffsetFromOrigin());
779 canvas->Transform(GetTransform()); 779 canvas->Transform(GetTransform());
780 780
781 // If we are a paint root, we need to construct our own CullSet object for 781 // If we are a paint root, we need to construct our own CullSet object for
782 // propagation to our children. 782 // propagation to our children.
783 if (IsPaintRoot()) { 783 if (IsPaintRoot()) {
784 if (!bounds_tree_) 784 if (!bounds_tree_)
785 bounds_tree_.reset(new gfx::RTree(2, 5)); 785 bounds_tree_.reset(new BoundsTree(2, 5));
786 786
787 // Recompute our bounds tree as needed. 787 // Recompute our bounds tree as needed.
788 UpdateRootBounds(bounds_tree_.get(), gfx::Vector2d()); 788 UpdateRootBounds(bounds_tree_.get(), gfx::Vector2d());
789 789
790 // Grab the clip rect from the supplied canvas to use as the query rect. 790 // Grab the clip rect from the supplied canvas to use as the query rect.
791 gfx::Rect canvas_bounds; 791 gfx::Rect canvas_bounds;
792 if (!canvas->GetClipBounds(&canvas_bounds)) { 792 if (!canvas->GetClipBounds(&canvas_bounds)) {
793 NOTREACHED() << "Failed to get clip bounds from the canvas!"; 793 NOTREACHED() << "Failed to get clip bounds from the canvas!";
794 return; 794 return;
795 } 795 }
796 796
797 // Now query our bounds_tree_ for a set of damaged views that intersect 797 // Now query our bounds_tree_ for a set of damaged views that intersect
798 // our canvas bounds. 798 // our canvas bounds.
799 scoped_ptr<base::hash_set<intptr_t> > damaged_views( 799 scoped_ptr<base::hash_set<intptr_t> > damaged_views(
800 new base::hash_set<intptr_t>()); 800 new base::hash_set<intptr_t>());
801 bounds_tree_->Query(canvas_bounds, damaged_views.get()); 801 bounds_tree_->AppendIntersectingRecords(
802 canvas_bounds, damaged_views.get());
802 // Construct a CullSet to wrap the damaged views set, it will delete it 803 // Construct a CullSet to wrap the damaged views set, it will delete it
803 // for us on scope exit. 804 // for us on scope exit.
804 CullSet paint_root_cull_set(damaged_views.Pass()); 805 CullSet paint_root_cull_set(damaged_views.Pass());
805 // Paint all descendents using our new cull set. 806 // Paint all descendents using our new cull set.
806 PaintCommon(canvas, paint_root_cull_set); 807 PaintCommon(canvas, paint_root_cull_set);
807 } else { 808 } else {
808 // Not a paint root, so we can proceed as normal. 809 // Not a paint root, so we can proceed as normal.
809 PaintCommon(canvas, cull_set); 810 PaintCommon(canvas, cull_set);
810 } 811 }
811 } 812 }
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after
1860 1861
1861 if (GetWidget()) { 1862 if (GetWidget()) {
1862 UnregisterChildrenForVisibleBoundsNotification(view); 1863 UnregisterChildrenForVisibleBoundsNotification(view);
1863 if (view->visible()) 1864 if (view->visible())
1864 view->SchedulePaint(); 1865 view->SchedulePaint();
1865 GetWidget()->NotifyWillRemoveView(view); 1866 GetWidget()->NotifyWillRemoveView(view);
1866 } 1867 }
1867 1868
1868 // Remove the bounds of this child and any of its descendants from our 1869 // Remove the bounds of this child and any of its descendants from our
1869 // paint root bounds tree. 1870 // paint root bounds tree.
1870 gfx::RTree* bounds_tree = GetBoundsTreeFromPaintRoot(); 1871 BoundsTree* bounds_tree = GetBoundsTreeFromPaintRoot();
1871 if (bounds_tree) 1872 if (bounds_tree)
1872 view->RemoveRootBounds(bounds_tree); 1873 view->RemoveRootBounds(bounds_tree);
1873 1874
1874 view->PropagateRemoveNotifications(this, new_parent); 1875 view->PropagateRemoveNotifications(this, new_parent);
1875 view->parent_ = NULL; 1876 view->parent_ = NULL;
1876 view->UpdateLayerVisibility(); 1877 view->UpdateLayerVisibility();
1877 1878
1878 if (delete_removed_view && !view->owned_by_client_) 1879 if (delete_removed_view && !view->owned_by_client_)
1879 view_to_be_deleted.reset(view); 1880 view_to_be_deleted.reset(view);
1880 1881
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2071 // Inform our children that their root bounds are dirty, as their relative 2072 // Inform our children that their root bounds are dirty, as their relative
2072 // coordinates in paint root space have changed since ours have changed. 2073 // coordinates in paint root space have changed since ours have changed.
2073 for (Views::const_iterator i(children_.begin()); i != children_.end(); 2074 for (Views::const_iterator i(children_.begin()); i != children_.end();
2074 ++i) { 2075 ++i) {
2075 if (!(*i)->IsPaintRoot()) 2076 if (!(*i)->IsPaintRoot())
2076 (*i)->SetRootBoundsDirty(origin_changed); 2077 (*i)->SetRootBoundsDirty(origin_changed);
2077 } 2078 }
2078 } 2079 }
2079 } 2080 }
2080 2081
2081 void View::UpdateRootBounds(gfx::RTree* tree, const gfx::Vector2d& offset) { 2082 void View::UpdateRootBounds(BoundsTree* tree, const gfx::Vector2d& offset) {
2082 // No need to recompute bounds if we haven't flagged ours as dirty. 2083 // No need to recompute bounds if we haven't flagged ours as dirty.
2083 TRACE_EVENT1("views", "View::UpdateRootBounds", "class", GetClassName()); 2084 TRACE_EVENT1("views", "View::UpdateRootBounds", "class", GetClassName());
2084 2085
2085 // Add our own offset to the provided offset, for our own bounds update and 2086 // Add our own offset to the provided offset, for our own bounds update and
2086 // for propagation to our children if needed. 2087 // for propagation to our children if needed.
2087 gfx::Vector2d view_offset = offset + GetMirroredBounds().OffsetFromOrigin(); 2088 gfx::Vector2d view_offset = offset + GetMirroredBounds().OffsetFromOrigin();
2088 2089
2089 // If our bounds have changed we must re-insert our new bounds to the tree. 2090 // If our bounds have changed we must re-insert our new bounds to the tree.
2090 if (root_bounds_dirty_) { 2091 if (root_bounds_dirty_) {
2091 root_bounds_dirty_ = false; 2092 root_bounds_dirty_ = false;
2092 gfx::Rect bounds( 2093 gfx::Rect bounds(
2093 view_offset.x(), view_offset.y(), bounds_.width(), bounds_.height()); 2094 view_offset.x(), view_offset.y(), bounds_.width(), bounds_.height());
2094 tree->Insert(bounds, reinterpret_cast<intptr_t>(this)); 2095 tree->Insert(bounds, reinterpret_cast<intptr_t>(this));
2095 } 2096 }
2096 2097
2097 // Update our children's bounds if needed. 2098 // Update our children's bounds if needed.
2098 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { 2099 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) {
2099 // We don't descend in to layer views for bounds recomputation, as they 2100 // We don't descend in to layer views for bounds recomputation, as they
2100 // manage their own RTree as paint roots. 2101 // manage their own RTree as paint roots.
2101 if (!(*i)->IsPaintRoot()) 2102 if (!(*i)->IsPaintRoot())
2102 (*i)->UpdateRootBounds(tree, view_offset); 2103 (*i)->UpdateRootBounds(tree, view_offset);
2103 } 2104 }
2104 } 2105 }
2105 2106
2106 void View::RemoveRootBounds(gfx::RTree* tree) { 2107 void View::RemoveRootBounds(BoundsTree* tree) {
2107 tree->Remove(reinterpret_cast<intptr_t>(this)); 2108 tree->Remove(reinterpret_cast<intptr_t>(this));
2108 2109
2109 root_bounds_dirty_ = true; 2110 root_bounds_dirty_ = true;
2110 2111
2111 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) { 2112 for (Views::const_iterator i(children_.begin()); i != children_.end(); ++i) {
2112 if (!(*i)->IsPaintRoot()) 2113 if (!(*i)->IsPaintRoot())
2113 (*i)->RemoveRootBounds(tree); 2114 (*i)->RemoveRootBounds(tree);
2114 } 2115 }
2115 } 2116 }
2116 2117
2117 gfx::RTree* View::GetBoundsTreeFromPaintRoot() { 2118 View::BoundsTree* View::GetBoundsTreeFromPaintRoot() {
2118 gfx::RTree* bounds_tree = bounds_tree_.get(); 2119 BoundsTree* bounds_tree = bounds_tree_.get();
2119 View* paint_root = this; 2120 View* paint_root = this;
2120 while (!bounds_tree && !paint_root->IsPaintRoot()) { 2121 while (!bounds_tree && !paint_root->IsPaintRoot()) {
2121 // Assumption is that if IsPaintRoot() is false then parent_ is valid. 2122 // Assumption is that if IsPaintRoot() is false then parent_ is valid.
2122 DCHECK(paint_root); 2123 DCHECK(paint_root);
2123 paint_root = paint_root->parent_; 2124 paint_root = paint_root->parent_;
2124 bounds_tree = paint_root->bounds_tree_.get(); 2125 bounds_tree = paint_root->bounds_tree_.get();
2125 } 2126 }
2126 2127
2127 return bounds_tree; 2128 return bounds_tree;
2128 } 2129 }
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 // Message the RootView to do the drag and drop. That way if we're removed 2498 // Message the RootView to do the drag and drop. That way if we're removed
2498 // the RootView can detect it and avoid calling us back. 2499 // the RootView can detect it and avoid calling us back.
2499 gfx::Point widget_location(event.location()); 2500 gfx::Point widget_location(event.location());
2500 ConvertPointToWidget(this, &widget_location); 2501 ConvertPointToWidget(this, &widget_location);
2501 widget->RunShellDrag(this, data, widget_location, drag_operations, source); 2502 widget->RunShellDrag(this, data, widget_location, drag_operations, source);
2502 // WARNING: we may have been deleted. 2503 // WARNING: we may have been deleted.
2503 return true; 2504 return true;
2504 } 2505 }
2505 2506
2506 } // namespace views 2507 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698