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