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/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 std::vector<gfx::Rect>& occluding_screen_space_rects,
     33     const std::vector<gfx::Rect>& non_occluding_screen_space_rects,
     34     const LayerTreeDebugState& debug_state) {
     35   // For now, clear all rects from previous frames. In the future we may want to
     36   // store all debug rects for a history of many frames.
     37   debug_rects_.clear();
     38 
     39   if (debug_state.show_touch_event_handler_rects)
     40     SaveTouchEventHandlerRects(root_layer);
     41 
     42   if (debug_state.show_wheel_event_handler_rects)
     43     SaveWheelEventHandlerRects(root_layer);
     44 
     45   if (debug_state.show_scroll_event_handler_rects)
     46     SaveScrollEventHandlerRects(root_layer);
     47 
     48   if (debug_state.show_non_fast_scrollable_rects)
     49     SaveNonFastScrollableRects(root_layer);
     50 
     51   if (debug_state.show_paint_rects)
     52     SavePaintRects(root_layer);
     53 
     54   if (debug_state.show_property_changed_rects)
     55     SavePropertyChangedRects(render_surface_layer_list, hud_layer);
     56 
     57   if (debug_state.show_surface_damage_rects)
     58     SaveSurfaceDamageRects(render_surface_layer_list);
     59 
     60   if (debug_state.show_screen_space_rects)
     61     SaveScreenSpaceRects(render_surface_layer_list);
     62 
     63   if (debug_state.show_occluding_rects)
     64     SaveOccludingRects(occluding_screen_space_rects);
     65 
     66   if (debug_state.show_non_occluding_rects)
     67     SaveNonOccludingRects(non_occluding_screen_space_rects);
     68 
     69   if (debug_state.show_layer_animation_bounds_rects)
     70     SaveLayerAnimationBoundsRects(render_surface_layer_list);
     71 }
     72 
     73 void DebugRectHistory::SavePaintRects(LayerImpl* layer) {
     74   // We would like to visualize where any layer's paint rect (update rect) has
     75   // changed, regardless of whether this layer is skipped for actual drawing or
     76   // not. Therefore we traverse recursively over all layers, not just the render
     77   // surface list.
     78 
     79   if (!layer->update_rect().IsEmpty() && layer->DrawsContent()) {
     80     float width_scale = layer->content_bounds().width() /
     81                         static_cast<float>(layer->bounds().width());
     82     float height_scale = layer->content_bounds().height() /
     83                          static_cast<float>(layer->bounds().height());
     84     gfx::Rect update_content_rect = gfx::ScaleToEnclosingRect(
     85         gfx::ToEnclosingRect(layer->update_rect()), width_scale, height_scale);
     86     debug_rects_.push_back(
     87         DebugRect(PAINT_RECT_TYPE,
     88                   MathUtil::MapEnclosingClippedRect(
     89                       layer->screen_space_transform(), update_content_rect)));
     90   }
     91 
     92   for (unsigned i = 0; i < layer->children().size(); ++i)
     93     SavePaintRects(layer->children()[i]);
     94 }
     95 
     96 void DebugRectHistory::SavePropertyChangedRects(
     97     const LayerImplList& render_surface_layer_list,
     98     LayerImpl* hud_layer) {
     99   for (int surface_index = render_surface_layer_list.size() - 1;
    100        surface_index >= 0;
    101        --surface_index) {
    102     LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
    103     RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
    104     DCHECK(render_surface);
    105 
    106     const LayerImplList& layer_list = render_surface->layer_list();
    107     for (unsigned layer_index = 0;
    108          layer_index < layer_list.size();
    109          ++layer_index) {
    110       LayerImpl* layer = layer_list[layer_index];
    111 
    112       if (LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerImpl>(
    113               layer, render_surface_layer->id()))
    114         continue;
    115 
    116       if (layer == hud_layer)
    117         continue;
    118 
    119       if (!layer->LayerPropertyChanged())
    120         continue;
    121 
    122       debug_rects_.push_back(
    123           DebugRect(PROPERTY_CHANGED_RECT_TYPE,
    124                     MathUtil::MapEnclosingClippedRect(
    125                         layer->screen_space_transform(),
    126                         gfx::Rect(layer->content_bounds()))));
    127     }
    128   }
    129 }
    130 
    131 void DebugRectHistory::SaveSurfaceDamageRects(
    132     const LayerImplList& render_surface_layer_list) {
    133   for (int surface_index = render_surface_layer_list.size() - 1;
    134        surface_index >= 0;
    135        --surface_index) {
    136     LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
    137     RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
    138     DCHECK(render_surface);
    139 
    140     debug_rects_.push_back(DebugRect(
    141         SURFACE_DAMAGE_RECT_TYPE,
    142         MathUtil::MapEnclosingClippedRect(
    143             render_surface->screen_space_transform(),
    144             render_surface->damage_tracker()->current_damage_rect())));
    145   }
    146 }
    147 
    148 void DebugRectHistory::SaveScreenSpaceRects(
    149     const LayerImplList& render_surface_layer_list) {
    150   for (int surface_index = render_surface_layer_list.size() - 1;
    151        surface_index >= 0;
    152        --surface_index) {
    153     LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
    154     RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
    155     DCHECK(render_surface);
    156 
    157     debug_rects_.push_back(
    158         DebugRect(SCREEN_SPACE_RECT_TYPE,
    159                   MathUtil::MapEnclosingClippedRect(
    160                       render_surface->screen_space_transform(),
    161                       render_surface->content_rect())));
    162 
    163     if (render_surface_layer->replica_layer()) {
    164       debug_rects_.push_back(
    165           DebugRect(REPLICA_SCREEN_SPACE_RECT_TYPE,
    166                     MathUtil::MapEnclosingClippedRect(
    167                         render_surface->replica_screen_space_transform(),
    168                         render_surface->content_rect())));
    169     }
    170   }
    171 }
    172 
    173 void DebugRectHistory::SaveOccludingRects(
    174     const std::vector<gfx::Rect>& occluding_rects) {
    175   for (size_t i = 0; i < occluding_rects.size(); ++i)
    176     debug_rects_.push_back(DebugRect(OCCLUDING_RECT_TYPE, occluding_rects[i]));
    177 }
    178 
    179 void DebugRectHistory::SaveNonOccludingRects(
    180     const std::vector<gfx::Rect>& non_occluding_rects) {
    181   for (size_t i = 0; i < non_occluding_rects.size(); ++i) {
    182     debug_rects_.push_back(
    183         DebugRect(NONOCCLUDING_RECT_TYPE, non_occluding_rects[i]));
    184   }
    185 }
    186 
    187 void DebugRectHistory::SaveTouchEventHandlerRects(LayerImpl* layer) {
    188   LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
    189       layer,
    190       base::Bind(&DebugRectHistory::SaveTouchEventHandlerRectsCallback,
    191                  base::Unretained(this)));
    192 }
    193 
    194 void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) {
    195   for (Region::Iterator iter(layer->touch_event_handler_region());
    196        iter.has_rect();
    197        iter.next()) {
    198     gfx::Rect touch_rect = gfx::ScaleToEnclosingRect(
    199         iter.rect(), layer->contents_scale_x(), layer->contents_scale_y());
    200     debug_rects_.push_back(
    201         DebugRect(TOUCH_EVENT_HANDLER_RECT_TYPE,
    202                   MathUtil::MapEnclosingClippedRect(
    203                       layer->screen_space_transform(), touch_rect)));
    204   }
    205 }
    206 
    207 void DebugRectHistory::SaveWheelEventHandlerRects(LayerImpl* layer) {
    208   LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
    209       layer,
    210       base::Bind(&DebugRectHistory::SaveWheelEventHandlerRectsCallback,
    211                  base::Unretained(this)));
    212 }
    213 
    214 void DebugRectHistory::SaveWheelEventHandlerRectsCallback(LayerImpl* layer) {
    215   if (!layer->have_wheel_event_handlers())
    216     return;
    217 
    218   gfx::Rect wheel_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(WHEEL_EVENT_HANDLER_RECT_TYPE,
    224                 MathUtil::MapEnclosingClippedRect(
    225                     layer->screen_space_transform(), wheel_rect)));
    226 }
    227 
    228 void DebugRectHistory::SaveScrollEventHandlerRects(LayerImpl* layer) {
    229   LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
    230       layer,
    231       base::Bind(&DebugRectHistory::SaveScrollEventHandlerRectsCallback,
    232                  base::Unretained(this)));
    233 }
    234 
    235 void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) {
    236   if (!layer->have_scroll_event_handlers())
    237     return;
    238 
    239   gfx::Rect scroll_rect =
    240       gfx::ScaleToEnclosingRect(gfx::Rect(layer->content_bounds()),
    241                                 layer->contents_scale_x(),
    242                                 layer->contents_scale_y());
    243   debug_rects_.push_back(
    244       DebugRect(SCROLL_EVENT_HANDLER_RECT_TYPE,
    245                 MathUtil::MapEnclosingClippedRect(
    246                     layer->screen_space_transform(), scroll_rect)));
    247 }
    248 
    249 void DebugRectHistory::SaveNonFastScrollableRects(LayerImpl* layer) {
    250   LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
    251       layer,
    252       base::Bind(&DebugRectHistory::SaveNonFastScrollableRectsCallback,
    253                  base::Unretained(this)));
    254 }
    255 
    256 void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) {
    257   for (Region::Iterator iter(layer->non_fast_scrollable_region());
    258        iter.has_rect();
    259        iter.next()) {
    260     gfx::Rect scroll_rect = gfx::ScaleToEnclosingRect(
    261         iter.rect(), layer->contents_scale_x(), layer->contents_scale_y());
    262     debug_rects_.push_back(
    263         DebugRect(NON_FAST_SCROLLABLE_RECT_TYPE,
    264                   MathUtil::MapEnclosingClippedRect(
    265                       layer->screen_space_transform(), scroll_rect)));
    266   }
    267 }
    268 
    269 void DebugRectHistory::SaveLayerAnimationBoundsRects(
    270     const LayerImplList& render_surface_layer_list) {
    271   typedef LayerIterator<LayerImpl> LayerIteratorType;
    272   LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
    273   for (LayerIteratorType it =
    274            LayerIteratorType::Begin(&render_surface_layer_list);
    275        it != end; ++it) {
    276     if (!it.represents_itself())
    277       continue;
    278 
    279     // TODO(avallee): Figure out if we should show something for a layer who's
    280     // animating bounds but that we can't compute them.
    281     gfx::BoxF inflated_bounds;
    282     if (!LayerUtils::GetAnimationBounds(**it, &inflated_bounds))
    283       continue;
    284 
    285     debug_rects_.push_back(
    286         DebugRect(ANIMATION_BOUNDS_RECT_TYPE,
    287                   gfx::ToEnclosingRect(gfx::RectF(inflated_bounds.x(),
    288                                                   inflated_bounds.y(),
    289                                                   inflated_bounds.width(),
    290                                                   inflated_bounds.height()))));
    291   }
    292 }
    293 
    294 }  // namespace cc
    295