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 
     63 void DebugRectHistory::SavePaintRects(LayerImpl* layer) {
     64   // We would like to visualize where any layer's paint rect (update rect) has
     65   // changed, regardless of whether this layer is skipped for actual drawing or
     66   // not. Therefore we traverse recursively over all layers, not just the render
     67   // surface list.
     68 
     69   if (!layer->update_rect().IsEmpty() && layer->DrawsContent()) {
     70     float width_scale = layer->content_bounds().width() /
     71                         static_cast<float>(layer->bounds().width());
     72     float height_scale = layer->content_bounds().height() /
     73                          static_cast<float>(layer->bounds().height());
     74     gfx::RectF update_content_rect =
     75         gfx::ScaleRect(layer->update_rect(), width_scale, height_scale);
     76     debug_rects_.push_back(
     77         DebugRect(PAINT_RECT_TYPE,
     78                   MathUtil::MapClippedRect(layer->screen_space_transform(),
     79                                            update_content_rect)));
     80   }
     81 
     82   for (unsigned i = 0; i < layer->children().size(); ++i)
     83     SavePaintRects(layer->children()[i]);
     84 }
     85 
     86 void DebugRectHistory::SavePropertyChangedRects(
     87     const LayerImplList& render_surface_layer_list) {
     88   for (int surface_index = render_surface_layer_list.size() - 1;
     89        surface_index >= 0;
     90        --surface_index) {
     91     LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
     92     RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
     93     DCHECK(render_surface);
     94 
     95     const LayerImplList& layer_list = render_surface->layer_list();
     96     for (unsigned layer_index = 0;
     97          layer_index < layer_list.size();
     98          ++layer_index) {
     99       LayerImpl* layer = layer_list[layer_index];
    100 
    101       if (LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerImpl>(
    102               layer, render_surface_layer->id()))
    103         continue;
    104 
    105       if (layer->LayerIsAlwaysDamaged())
    106         continue;
    107 
    108       if (layer->LayerPropertyChanged() ||
    109           layer->LayerSurfacePropertyChanged()) {
    110         debug_rects_.push_back(
    111             DebugRect(PROPERTY_CHANGED_RECT_TYPE,
    112                       MathUtil::MapClippedRect(
    113                           layer->screen_space_transform(),
    114                           gfx::RectF(gfx::PointF(), layer->content_bounds()))));
    115       }
    116     }
    117   }
    118 }
    119 
    120 void DebugRectHistory::SaveSurfaceDamageRects(
    121     const LayerImplList& render_surface_layer_list) {
    122   for (int surface_index = render_surface_layer_list.size() - 1;
    123        surface_index >= 0;
    124        --surface_index) {
    125     LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
    126     RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
    127     DCHECK(render_surface);
    128 
    129     debug_rects_.push_back(DebugRect(
    130         SURFACE_DAMAGE_RECT_TYPE,
    131         MathUtil::MapClippedRect(
    132             render_surface->screen_space_transform(),
    133             render_surface->damage_tracker()->current_damage_rect())));
    134   }
    135 }
    136 
    137 void DebugRectHistory::SaveScreenSpaceRects(
    138     const LayerImplList& render_surface_layer_list) {
    139   for (int surface_index = render_surface_layer_list.size() - 1;
    140        surface_index >= 0;
    141        --surface_index) {
    142     LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
    143     RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
    144     DCHECK(render_surface);
    145 
    146     debug_rects_.push_back(DebugRect(
    147         SCREEN_SPACE_RECT_TYPE,
    148         MathUtil::MapClippedRect(render_surface->screen_space_transform(),
    149                                  render_surface->content_rect())));
    150 
    151     if (render_surface_layer->replica_layer()) {
    152       debug_rects_.push_back(
    153           DebugRect(REPLICA_SCREEN_SPACE_RECT_TYPE,
    154                     MathUtil::MapClippedRect(
    155                         render_surface->replica_screen_space_transform(),
    156                         render_surface->content_rect())));
    157     }
    158   }
    159 }
    160 
    161 void DebugRectHistory::SaveOccludingRects(
    162     const std::vector<gfx::Rect>& occluding_rects) {
    163   for (size_t i = 0; i < occluding_rects.size(); ++i)
    164     debug_rects_.push_back(DebugRect(OCCLUDING_RECT_TYPE, occluding_rects[i]));
    165 }
    166 
    167 void DebugRectHistory::SaveNonOccludingRects(
    168     const std::vector<gfx::Rect>& non_occluding_rects) {
    169   for (size_t i = 0; i < non_occluding_rects.size(); ++i) {
    170     debug_rects_.push_back(
    171         DebugRect(NONOCCLUDING_RECT_TYPE, non_occluding_rects[i]));
    172   }
    173 }
    174 
    175 void DebugRectHistory::SaveTouchEventHandlerRects(LayerImpl* layer) {
    176   LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
    177       layer,
    178       base::Bind(&DebugRectHistory::SaveTouchEventHandlerRectsCallback,
    179                  base::Unretained(this)));
    180 }
    181 
    182 void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) {
    183   for (Region::Iterator iter(layer->touch_event_handler_region());
    184        iter.has_rect();
    185        iter.next()) {
    186     gfx::RectF touch_rect = gfx::ScaleRect(iter.rect(),
    187                                            layer->contents_scale_x(),
    188                                            layer->contents_scale_y());
    189     debug_rects_.push_back(DebugRect(TOUCH_EVENT_HANDLER_RECT_TYPE,
    190                                      MathUtil::MapClippedRect(
    191                                          layer->screen_space_transform(),
    192                                          touch_rect)));
    193   }
    194 }
    195 
    196 void DebugRectHistory::SaveWheelEventHandlerRects(LayerImpl* layer) {
    197   LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
    198       layer,
    199       base::Bind(&DebugRectHistory::SaveWheelEventHandlerRectsCallback,
    200                  base::Unretained(this)));
    201 }
    202 
    203 void DebugRectHistory::SaveWheelEventHandlerRectsCallback(LayerImpl* layer) {
    204   if (!layer->have_wheel_event_handlers())
    205     return;
    206 
    207   gfx::RectF wheel_rect = gfx::RectF(layer->content_bounds());
    208   wheel_rect.Scale(layer->contents_scale_x(), layer->contents_scale_y());
    209   debug_rects_.push_back(DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE,
    210                                    MathUtil::MapClippedRect(
    211                                        layer->screen_space_transform(),
    212                                        wheel_rect)));
    213 }
    214 
    215 void DebugRectHistory::SaveNonFastScrollableRects(LayerImpl* layer) {
    216   LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
    217       layer,
    218       base::Bind(&DebugRectHistory::SaveNonFastScrollableRectsCallback,
    219                  base::Unretained(this)));
    220 }
    221 
    222 void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) {
    223   for (Region::Iterator iter(layer->non_fast_scrollable_region());
    224        iter.has_rect();
    225        iter.next()) {
    226     gfx::RectF scroll_rect = gfx::ScaleRect(iter.rect(),
    227                                             layer->contents_scale_x(),
    228                                             layer->contents_scale_y());
    229     debug_rects_.push_back(DebugRect(NON_FAST_SCROLLABLE_RECT_TYPE,
    230                                      MathUtil::MapClippedRect(
    231                                          layer->screen_space_transform(),
    232                                          scroll_rect)));
    233   }
    234 }
    235 
    236 }  // namespace cc
    237