Home | History | Annotate | Download | only in debug
      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
     17 scoped_ptr<DebugRectHistory> DebugRectHistory::Create() {
     18   return make_scoped_ptr(new DebugRectHistory());
     19 }
     20 
     21 DebugRectHistory::DebugRectHistory() {}
     22 
     23 DebugRectHistory::~DebugRectHistory() {}
     24 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    177 void DebugRectHistory::SaveTouchEventHandlerRects(LayerImpl* layer) {
    178   LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
    179       layer,
    180       base::Bind(&DebugRectHistory::SaveTouchEventHandlerRectsCallback,
    181                  base::Unretained(this)));
    182 }
    183 
    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 
    198 void DebugRectHistory::SaveWheelEventHandlerRects(LayerImpl* layer) {
    199   LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
    200       layer,
    201       base::Bind(&DebugRectHistory::SaveWheelEventHandlerRectsCallback,
    202                  base::Unretained(this)));
    203 }
    204 
    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 
    217 void DebugRectHistory::SaveNonFastScrollableRects(LayerImpl* layer) {
    218   LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
    219       layer,
    220       base::Bind(&DebugRectHistory::SaveNonFastScrollableRectsCallback,
    221                  base::Unretained(this)));
    222 }
    223 
    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 
    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