• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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