| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 #include "chrome/renderer/paint_aggregator.h" | 5 #include "chrome/renderer/paint_aggregator.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 | 9 |
| 10 // ---------------------------------------------------------------------------- | 10 // ---------------------------------------------------------------------------- |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 // This constant sets the max ratio of paint rect area to scroll rect area that | 27 // This constant sets the max ratio of paint rect area to scroll rect area that |
| 28 // we will tolerate before dograding the scroll into a repaint. | 28 // we will tolerate before dograding the scroll into a repaint. |
| 29 static const float kMaxRedundantPaintToScrollArea = 0.8f; | 29 static const float kMaxRedundantPaintToScrollArea = 0.8f; |
| 30 | 30 |
| 31 // The maximum number of paint rects. If we exceed this limit, then we'll | 31 // The maximum number of paint rects. If we exceed this limit, then we'll |
| 32 // start combining paint rects (see CombinePaintRects). This limiting is | 32 // start combining paint rects (see CombinePaintRects). This limiting is |
| 33 // important since the WebKit code associated with deciding what to paint given | 33 // important since the WebKit code associated with deciding what to paint given |
| 34 // a paint rect can be significant. | 34 // a paint rect can be significant. |
| 35 static const size_t kMaxPaintRects = 5; | 35 static const size_t kMaxPaintRects = 5; |
| 36 | 36 |
| 37 // If the combined area of paint rects divided by the area of the union of all |
| 38 // paint rects exceeds this threshold, then we will combine the paint rects. |
| 39 static const float kMaxPaintRectsAreaRatio = 0.3f; |
| 40 |
| 37 PaintAggregator::PendingUpdate::PendingUpdate() {} | 41 PaintAggregator::PendingUpdate::PendingUpdate() {} |
| 38 | 42 |
| 39 PaintAggregator::PendingUpdate::~PendingUpdate() {} | 43 PaintAggregator::PendingUpdate::~PendingUpdate() {} |
| 40 | 44 |
| 41 gfx::Rect PaintAggregator::PendingUpdate::GetScrollDamage() const { | 45 gfx::Rect PaintAggregator::PendingUpdate::GetScrollDamage() const { |
| 42 // Should only be scrolling in one direction at a time. | 46 // Should only be scrolling in one direction at a time. |
| 43 DCHECK(!(scroll_delta.x() && scroll_delta.y())); | 47 DCHECK(!(scroll_delta.x() && scroll_delta.y())); |
| 44 | 48 |
| 45 gfx::Rect damaged_rect; | 49 gfx::Rect damaged_rect; |
| 46 | 50 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 } | 86 } |
| 83 | 87 |
| 84 bool PaintAggregator::HasPendingUpdate() const { | 88 bool PaintAggregator::HasPendingUpdate() const { |
| 85 return !update_.scroll_rect.IsEmpty() || !update_.paint_rects.empty(); | 89 return !update_.scroll_rect.IsEmpty() || !update_.paint_rects.empty(); |
| 86 } | 90 } |
| 87 | 91 |
| 88 void PaintAggregator::ClearPendingUpdate() { | 92 void PaintAggregator::ClearPendingUpdate() { |
| 89 update_ = PendingUpdate(); | 93 update_ = PendingUpdate(); |
| 90 } | 94 } |
| 91 | 95 |
| 96 void PaintAggregator::PopPendingUpdate(PendingUpdate* update) { |
| 97 // Combine paint rects if their combined area is not sufficiently less than |
| 98 // the area of the union of all paint rects. We skip this if there is a |
| 99 // scroll rect since scrolling benefits from smaller paint rects. |
| 100 if (update_.scroll_rect.IsEmpty() && update_.paint_rects.size() > 1) { |
| 101 int paint_area = 0; |
| 102 gfx::Rect union_rect; |
| 103 for (size_t i = 0; i < update_.paint_rects.size(); ++i) { |
| 104 paint_area += update_.paint_rects[i].size().GetArea(); |
| 105 union_rect = union_rect.Union(update_.paint_rects[i]); |
| 106 } |
| 107 int union_area = union_rect.size().GetArea(); |
| 108 if (float(paint_area) / float(union_area) > kMaxPaintRectsAreaRatio) |
| 109 CombinePaintRects(); |
| 110 } |
| 111 *update = update_; |
| 112 ClearPendingUpdate(); |
| 113 } |
| 114 |
| 92 void PaintAggregator::InvalidateRect(const gfx::Rect& rect) { | 115 void PaintAggregator::InvalidateRect(const gfx::Rect& rect) { |
| 93 // Combine overlapping paints using smallest bounding box. | 116 // Combine overlapping paints using smallest bounding box. |
| 94 for (size_t i = 0; i < update_.paint_rects.size(); ++i) { | 117 for (size_t i = 0; i < update_.paint_rects.size(); ++i) { |
| 95 const gfx::Rect& existing_rect = update_.paint_rects[i]; | 118 const gfx::Rect& existing_rect = update_.paint_rects[i]; |
| 96 if (existing_rect.Contains(rect)) // Optimize out redundancy. | 119 if (existing_rect.Contains(rect)) // Optimize out redundancy. |
| 97 return; | 120 return; |
| 98 if (rect.Intersects(existing_rect) || rect.SharesEdgeWith(existing_rect)) { | 121 if (rect.Intersects(existing_rect) || rect.SharesEdgeWith(existing_rect)) { |
| 99 // Re-invalidate in case the union intersects other paint rects. | 122 // Re-invalidate in case the union intersects other paint rects. |
| 100 gfx::Rect combined_rect = existing_rect.Union(rect); | 123 gfx::Rect combined_rect = existing_rect.Union(rect); |
| 101 update_.paint_rects.erase(update_.paint_rects.begin() + i); | 124 update_.paint_rects.erase(update_.paint_rects.begin() + i); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 120 update_.paint_rects.erase(update_.paint_rects.end() - 1); | 143 update_.paint_rects.erase(update_.paint_rects.end() - 1); |
| 121 } | 144 } |
| 122 } | 145 } |
| 123 | 146 |
| 124 if (update_.paint_rects.size() > kMaxPaintRects) | 147 if (update_.paint_rects.size() > kMaxPaintRects) |
| 125 CombinePaintRects(); | 148 CombinePaintRects(); |
| 126 | 149 |
| 127 // Track how large the paint_rects vector grows during an invalidation | 150 // Track how large the paint_rects vector grows during an invalidation |
| 128 // sequence. Note: A subsequent invalidation may end up being combined | 151 // sequence. Note: A subsequent invalidation may end up being combined |
| 129 // with all existing paints, which means that tracking the size of | 152 // with all existing paints, which means that tracking the size of |
| 130 // paint_rects at the time when GetPendingUpdate() is called may mask | 153 // paint_rects at the time when PopPendingUpdate() is called may mask |
| 131 // certain performance problems. | 154 // certain performance problems. |
| 132 HISTOGRAM_COUNTS_100("MPArch.RW_IntermediatePaintRectCount", | 155 HISTOGRAM_COUNTS_100("MPArch.RW_IntermediatePaintRectCount", |
| 133 update_.paint_rects.size()); | 156 update_.paint_rects.size()); |
| 134 } | 157 } |
| 135 | 158 |
| 136 void PaintAggregator::ScrollRect(int dx, int dy, const gfx::Rect& clip_rect) { | 159 void PaintAggregator::ScrollRect(int dx, int dy, const gfx::Rect& clip_rect) { |
| 137 // We only support scrolling along one axis at a time. | 160 // We only support scrolling along one axis at a time. |
| 138 if (dx != 0 && dy != 0) { | 161 if (dx != 0 && dy != 0) { |
| 139 InvalidateRect(clip_rect); | 162 InvalidateRect(clip_rect); |
| 140 return; | 163 return; |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 inner = inner.Union(existing_rect); | 275 inner = inner.Union(existing_rect); |
| 253 } else { | 276 } else { |
| 254 outer = outer.Union(existing_rect); | 277 outer = outer.Union(existing_rect); |
| 255 } | 278 } |
| 256 } | 279 } |
| 257 update_.paint_rects.clear(); | 280 update_.paint_rects.clear(); |
| 258 update_.paint_rects.push_back(inner); | 281 update_.paint_rects.push_back(inner); |
| 259 update_.paint_rects.push_back(outer); | 282 update_.paint_rects.push_back(outer); |
| 260 } | 283 } |
| 261 } | 284 } |
| OLD | NEW |