| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "cc/debug/debug_rect_history.h" | |
| 6 | |
| 7 #include "cc/base/math_util.h" | |
| 8 #include "cc/layers/layer_impl.h" | |
| 9 #include "cc/layers/layer_iterator.h" | |
| 10 #include "cc/layers/layer_utils.h" | |
| 11 #include "cc/layers/render_surface_impl.h" | |
| 12 #include "cc/trees/damage_tracker.h" | |
| 13 #include "cc/trees/layer_tree_host.h" | |
| 14 #include "cc/trees/layer_tree_host_common.h" | |
| 15 #include "ui/gfx/geometry/rect_conversions.h" | |
| 16 | |
| 17 namespace cc { | |
| 18 | |
| 19 // static | |
| 20 scoped_ptr<DebugRectHistory> DebugRectHistory::Create() { | |
| 21 return make_scoped_ptr(new DebugRectHistory()); | |
| 22 } | |
| 23 | |
| 24 DebugRectHistory::DebugRectHistory() {} | |
| 25 | |
| 26 DebugRectHistory::~DebugRectHistory() {} | |
| 27 | |
| 28 void DebugRectHistory::SaveDebugRectsForCurrentFrame( | |
| 29 LayerImpl* root_layer, | |
| 30 LayerImpl* hud_layer, | |
| 31 const LayerImplList& render_surface_layer_list, | |
| 32 const LayerTreeDebugState& debug_state) { | |
| 33 // For now, clear all rects from previous frames. In the future we may want to | |
| 34 // store all debug rects for a history of many frames. | |
| 35 debug_rects_.clear(); | |
| 36 | |
| 37 if (debug_state.show_touch_event_handler_rects) | |
| 38 SaveTouchEventHandlerRects(root_layer); | |
| 39 | |
| 40 if (debug_state.show_wheel_event_handler_rects) | |
| 41 SaveWheelEventHandlerRects(root_layer); | |
| 42 | |
| 43 if (debug_state.show_scroll_event_handler_rects) | |
| 44 SaveScrollEventHandlerRects(root_layer); | |
| 45 | |
| 46 if (debug_state.show_non_fast_scrollable_rects) | |
| 47 SaveNonFastScrollableRects(root_layer); | |
| 48 | |
| 49 if (debug_state.show_paint_rects) | |
| 50 SavePaintRects(root_layer); | |
| 51 | |
| 52 if (debug_state.show_property_changed_rects) | |
| 53 SavePropertyChangedRects(render_surface_layer_list, hud_layer); | |
| 54 | |
| 55 if (debug_state.show_surface_damage_rects) | |
| 56 SaveSurfaceDamageRects(render_surface_layer_list); | |
| 57 | |
| 58 if (debug_state.show_screen_space_rects) | |
| 59 SaveScreenSpaceRects(render_surface_layer_list); | |
| 60 | |
| 61 if (debug_state.show_layer_animation_bounds_rects) | |
| 62 SaveLayerAnimationBoundsRects(render_surface_layer_list); | |
| 63 } | |
| 64 | |
| 65 void DebugRectHistory::SavePaintRects(LayerImpl* layer) { | |
| 66 // We would like to visualize where any layer's paint rect (update rect) has | |
| 67 // changed, regardless of whether this layer is skipped for actual drawing or | |
| 68 // not. Therefore we traverse recursively over all layers, not just the render | |
| 69 // surface list. | |
| 70 | |
| 71 Region invalidation_region = layer->GetInvalidationRegion(); | |
| 72 if (!invalidation_region.IsEmpty() && layer->DrawsContent()) { | |
| 73 float width_scale = layer->content_bounds().width() / | |
| 74 static_cast<float>(layer->bounds().width()); | |
| 75 float height_scale = layer->content_bounds().height() / | |
| 76 static_cast<float>(layer->bounds().height()); | |
| 77 | |
| 78 for (Region::Iterator it(invalidation_region); it.has_rect(); it.next()) { | |
| 79 gfx::Rect update_content_rect = | |
| 80 gfx::ScaleToEnclosingRect(it.rect(), width_scale, height_scale); | |
| 81 debug_rects_.push_back( | |
| 82 DebugRect(PAINT_RECT_TYPE, | |
| 83 MathUtil::MapEnclosingClippedRect( | |
| 84 layer->screen_space_transform(), update_content_rect))); | |
| 85 } | |
| 86 } | |
| 87 | |
| 88 for (unsigned i = 0; i < layer->children().size(); ++i) | |
| 89 SavePaintRects(layer->children()[i]); | |
| 90 } | |
| 91 | |
| 92 void DebugRectHistory::SavePropertyChangedRects( | |
| 93 const LayerImplList& render_surface_layer_list, | |
| 94 LayerImpl* hud_layer) { | |
| 95 for (int surface_index = render_surface_layer_list.size() - 1; | |
| 96 surface_index >= 0; | |
| 97 --surface_index) { | |
| 98 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index]; | |
| 99 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface(); | |
| 100 DCHECK(render_surface); | |
| 101 | |
| 102 const LayerImplList& layer_list = render_surface->layer_list(); | |
| 103 for (unsigned layer_index = 0; | |
| 104 layer_index < layer_list.size(); | |
| 105 ++layer_index) { | |
| 106 LayerImpl* layer = layer_list[layer_index]; | |
| 107 | |
| 108 if (LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerImpl>( | |
| 109 layer, render_surface_layer->id())) | |
| 110 continue; | |
| 111 | |
| 112 if (layer == hud_layer) | |
| 113 continue; | |
| 114 | |
| 115 if (!layer->LayerPropertyChanged()) | |
| 116 continue; | |
| 117 | |
| 118 debug_rects_.push_back( | |
| 119 DebugRect(PROPERTY_CHANGED_RECT_TYPE, | |
| 120 MathUtil::MapEnclosingClippedRect( | |
| 121 layer->screen_space_transform(), | |
| 122 gfx::Rect(layer->content_bounds())))); | |
| 123 } | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 void DebugRectHistory::SaveSurfaceDamageRects( | |
| 128 const LayerImplList& render_surface_layer_list) { | |
| 129 for (int surface_index = render_surface_layer_list.size() - 1; | |
| 130 surface_index >= 0; | |
| 131 --surface_index) { | |
| 132 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index]; | |
| 133 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface(); | |
| 134 DCHECK(render_surface); | |
| 135 | |
| 136 debug_rects_.push_back(DebugRect( | |
| 137 SURFACE_DAMAGE_RECT_TYPE, | |
| 138 MathUtil::MapEnclosingClippedRect( | |
| 139 render_surface->screen_space_transform(), | |
| 140 render_surface->damage_tracker()->current_damage_rect()))); | |
| 141 } | |
| 142 } | |
| 143 | |
| 144 void DebugRectHistory::SaveScreenSpaceRects( | |
| 145 const LayerImplList& render_surface_layer_list) { | |
| 146 for (int surface_index = render_surface_layer_list.size() - 1; | |
| 147 surface_index >= 0; | |
| 148 --surface_index) { | |
| 149 LayerImpl* render_surface_layer = render_surface_layer_list[surface_index]; | |
| 150 RenderSurfaceImpl* render_surface = render_surface_layer->render_surface(); | |
| 151 DCHECK(render_surface); | |
| 152 | |
| 153 debug_rects_.push_back( | |
| 154 DebugRect(SCREEN_SPACE_RECT_TYPE, | |
| 155 MathUtil::MapEnclosingClippedRect( | |
| 156 render_surface->screen_space_transform(), | |
| 157 render_surface->content_rect()))); | |
| 158 | |
| 159 if (render_surface_layer->replica_layer()) { | |
| 160 debug_rects_.push_back( | |
| 161 DebugRect(REPLICA_SCREEN_SPACE_RECT_TYPE, | |
| 162 MathUtil::MapEnclosingClippedRect( | |
| 163 render_surface->replica_screen_space_transform(), | |
| 164 render_surface->content_rect()))); | |
| 165 } | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 void DebugRectHistory::SaveTouchEventHandlerRects(LayerImpl* layer) { | |
| 170 LayerTreeHostCommon::CallFunctionForSubtree(layer, [this](LayerImpl* layer) { | |
| 171 SaveTouchEventHandlerRectsCallback(layer); | |
| 172 }); | |
| 173 } | |
| 174 | |
| 175 void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) { | |
| 176 for (Region::Iterator iter(layer->touch_event_handler_region()); | |
| 177 iter.has_rect(); | |
| 178 iter.next()) { | |
| 179 gfx::Rect touch_rect = gfx::ScaleToEnclosingRect( | |
| 180 iter.rect(), layer->contents_scale_x(), layer->contents_scale_y()); | |
| 181 debug_rects_.push_back( | |
| 182 DebugRect(TOUCH_EVENT_HANDLER_RECT_TYPE, | |
| 183 MathUtil::MapEnclosingClippedRect( | |
| 184 layer->screen_space_transform(), touch_rect))); | |
| 185 } | |
| 186 } | |
| 187 | |
| 188 void DebugRectHistory::SaveWheelEventHandlerRects(LayerImpl* layer) { | |
| 189 LayerTreeHostCommon::CallFunctionForSubtree(layer, [this](LayerImpl* layer) { | |
| 190 SaveWheelEventHandlerRectsCallback(layer); | |
| 191 }); | |
| 192 } | |
| 193 | |
| 194 void DebugRectHistory::SaveWheelEventHandlerRectsCallback(LayerImpl* layer) { | |
| 195 if (!layer->have_wheel_event_handlers()) | |
| 196 return; | |
| 197 | |
| 198 gfx::Rect wheel_rect = | |
| 199 gfx::ScaleToEnclosingRect(gfx::Rect(layer->content_bounds()), | |
| 200 layer->contents_scale_x(), | |
| 201 layer->contents_scale_y()); | |
| 202 debug_rects_.push_back( | |
| 203 DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE, | |
| 204 MathUtil::MapEnclosingClippedRect( | |
| 205 layer->screen_space_transform(), wheel_rect))); | |
| 206 } | |
| 207 | |
| 208 void DebugRectHistory::SaveScrollEventHandlerRects(LayerImpl* layer) { | |
| 209 LayerTreeHostCommon::CallFunctionForSubtree(layer, [this](LayerImpl* layer) { | |
| 210 SaveScrollEventHandlerRectsCallback(layer); | |
| 211 }); | |
| 212 } | |
| 213 | |
| 214 void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) { | |
| 215 if (!layer->have_scroll_event_handlers()) | |
| 216 return; | |
| 217 | |
| 218 gfx::Rect scroll_rect = | |
| 219 gfx::ScaleToEnclosingRect(gfx::Rect(layer->content_bounds()), | |
| 220 layer->contents_scale_x(), | |
| 221 layer->contents_scale_y()); | |
| 222 debug_rects_.push_back( | |
| 223 DebugRect(SCROLL_EVENT_HANDLER_RECT_TYPE, | |
| 224 MathUtil::MapEnclosingClippedRect( | |
| 225 layer->screen_space_transform(), scroll_rect))); | |
| 226 } | |
| 227 | |
| 228 void DebugRectHistory::SaveNonFastScrollableRects(LayerImpl* layer) { | |
| 229 LayerTreeHostCommon::CallFunctionForSubtree(layer, [this](LayerImpl* layer) { | |
| 230 SaveNonFastScrollableRectsCallback(layer); | |
| 231 }); | |
| 232 } | |
| 233 | |
| 234 void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) { | |
| 235 for (Region::Iterator iter(layer->non_fast_scrollable_region()); | |
| 236 iter.has_rect(); | |
| 237 iter.next()) { | |
| 238 gfx::Rect scroll_rect = gfx::ScaleToEnclosingRect( | |
| 239 iter.rect(), layer->contents_scale_x(), layer->contents_scale_y()); | |
| 240 debug_rects_.push_back( | |
| 241 DebugRect(NON_FAST_SCROLLABLE_RECT_TYPE, | |
| 242 MathUtil::MapEnclosingClippedRect( | |
| 243 layer->screen_space_transform(), scroll_rect))); | |
| 244 } | |
| 245 } | |
| 246 | |
| 247 void DebugRectHistory::SaveLayerAnimationBoundsRects( | |
| 248 const LayerImplList& render_surface_layer_list) { | |
| 249 typedef LayerIterator<LayerImpl> LayerIteratorType; | |
| 250 LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list); | |
| 251 for (LayerIteratorType it = | |
| 252 LayerIteratorType::Begin(&render_surface_layer_list); | |
| 253 it != end; ++it) { | |
| 254 if (!it.represents_itself()) | |
| 255 continue; | |
| 256 | |
| 257 // TODO(avallee): Figure out if we should show something for a layer who's | |
| 258 // animating bounds but that we can't compute them. | |
| 259 gfx::BoxF inflated_bounds; | |
| 260 if (!LayerUtils::GetAnimationBounds(**it, &inflated_bounds)) | |
| 261 continue; | |
| 262 | |
| 263 debug_rects_.push_back( | |
| 264 DebugRect(ANIMATION_BOUNDS_RECT_TYPE, | |
| 265 gfx::ToEnclosingRect(gfx::RectF(inflated_bounds.x(), | |
| 266 inflated_bounds.y(), | |
| 267 inflated_bounds.width(), | |
| 268 inflated_bounds.height())))); | |
| 269 } | |
| 270 } | |
| 271 | |
| 272 } // namespace cc | |
| OLD | NEW |