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 |