// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/debug/debug_rect_history.h"

#include "cc/base/math_util.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/layer_iterator.h"
#include "cc/layers/layer_utils.h"
#include "cc/layers/render_surface_impl.h"
#include "cc/trees/damage_tracker.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_common.h"
#include "ui/gfx/geometry/rect_conversions.h"

namespace cc {

// static
scoped_ptr<DebugRectHistory> DebugRectHistory::Create() {
  return make_scoped_ptr(new DebugRectHistory());
}

DebugRectHistory::DebugRectHistory() {}

DebugRectHistory::~DebugRectHistory() {}

void DebugRectHistory::SaveDebugRectsForCurrentFrame(
    LayerImpl* root_layer,
    LayerImpl* hud_layer,
    const LayerImplList& render_surface_layer_list,
    const LayerTreeDebugState& debug_state) {
  // For now, clear all rects from previous frames. In the future we may want to
  // store all debug rects for a history of many frames.
  debug_rects_.clear();

  if (debug_state.show_touch_event_handler_rects)
    SaveTouchEventHandlerRects(root_layer);

  if (debug_state.show_wheel_event_handler_rects)
    SaveWheelEventHandlerRects(root_layer);

  if (debug_state.show_scroll_event_handler_rects)
    SaveScrollEventHandlerRects(root_layer);

  if (debug_state.show_non_fast_scrollable_rects)
    SaveNonFastScrollableRects(root_layer);

  if (debug_state.show_paint_rects)
    SavePaintRects(root_layer);

  if (debug_state.show_property_changed_rects)
    SavePropertyChangedRects(render_surface_layer_list, hud_layer);

  if (debug_state.show_surface_damage_rects)
    SaveSurfaceDamageRects(render_surface_layer_list);

  if (debug_state.show_screen_space_rects)
    SaveScreenSpaceRects(render_surface_layer_list);

  if (debug_state.show_layer_animation_bounds_rects)
    SaveLayerAnimationBoundsRects(render_surface_layer_list);
}

void DebugRectHistory::SavePaintRects(LayerImpl* layer) {
  // We would like to visualize where any layer's paint rect (update rect) has
  // changed, regardless of whether this layer is skipped for actual drawing or
  // not. Therefore we traverse recursively over all layers, not just the render
  // surface list.

  if (!layer->update_rect().IsEmpty() && layer->DrawsContent()) {
    float width_scale = layer->content_bounds().width() /
                        static_cast<float>(layer->bounds().width());
    float height_scale = layer->content_bounds().height() /
                         static_cast<float>(layer->bounds().height());
    gfx::Rect update_content_rect = gfx::ScaleToEnclosingRect(
        layer->update_rect(), width_scale, height_scale);
    debug_rects_.push_back(
        DebugRect(PAINT_RECT_TYPE,
                  MathUtil::MapEnclosingClippedRect(
                      layer->screen_space_transform(), update_content_rect)));
  }

  for (unsigned i = 0; i < layer->children().size(); ++i)
    SavePaintRects(layer->children()[i]);
}

void DebugRectHistory::SavePropertyChangedRects(
    const LayerImplList& render_surface_layer_list,
    LayerImpl* hud_layer) {
  for (int surface_index = render_surface_layer_list.size() - 1;
       surface_index >= 0;
       --surface_index) {
    LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
    RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
    DCHECK(render_surface);

    const LayerImplList& layer_list = render_surface->layer_list();
    for (unsigned layer_index = 0;
         layer_index < layer_list.size();
         ++layer_index) {
      LayerImpl* layer = layer_list[layer_index];

      if (LayerTreeHostCommon::RenderSurfaceContributesToTarget<LayerImpl>(
              layer, render_surface_layer->id()))
        continue;

      if (layer == hud_layer)
        continue;

      if (!layer->LayerPropertyChanged())
        continue;

      debug_rects_.push_back(
          DebugRect(PROPERTY_CHANGED_RECT_TYPE,
                    MathUtil::MapEnclosingClippedRect(
                        layer->screen_space_transform(),
                        gfx::Rect(layer->content_bounds()))));
    }
  }
}

void DebugRectHistory::SaveSurfaceDamageRects(
    const LayerImplList& render_surface_layer_list) {
  for (int surface_index = render_surface_layer_list.size() - 1;
       surface_index >= 0;
       --surface_index) {
    LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
    RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
    DCHECK(render_surface);

    debug_rects_.push_back(DebugRect(
        SURFACE_DAMAGE_RECT_TYPE,
        MathUtil::MapEnclosingClippedRect(
            render_surface->screen_space_transform(),
            render_surface->damage_tracker()->current_damage_rect())));
  }
}

void DebugRectHistory::SaveScreenSpaceRects(
    const LayerImplList& render_surface_layer_list) {
  for (int surface_index = render_surface_layer_list.size() - 1;
       surface_index >= 0;
       --surface_index) {
    LayerImpl* render_surface_layer = render_surface_layer_list[surface_index];
    RenderSurfaceImpl* render_surface = render_surface_layer->render_surface();
    DCHECK(render_surface);

    debug_rects_.push_back(
        DebugRect(SCREEN_SPACE_RECT_TYPE,
                  MathUtil::MapEnclosingClippedRect(
                      render_surface->screen_space_transform(),
                      render_surface->content_rect())));

    if (render_surface_layer->replica_layer()) {
      debug_rects_.push_back(
          DebugRect(REPLICA_SCREEN_SPACE_RECT_TYPE,
                    MathUtil::MapEnclosingClippedRect(
                        render_surface->replica_screen_space_transform(),
                        render_surface->content_rect())));
    }
  }
}

void DebugRectHistory::SaveTouchEventHandlerRects(LayerImpl* layer) {
  LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
      layer,
      base::Bind(&DebugRectHistory::SaveTouchEventHandlerRectsCallback,
                 base::Unretained(this)));
}

void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) {
  for (Region::Iterator iter(layer->touch_event_handler_region());
       iter.has_rect();
       iter.next()) {
    gfx::Rect touch_rect = gfx::ScaleToEnclosingRect(
        iter.rect(), layer->contents_scale_x(), layer->contents_scale_y());
    debug_rects_.push_back(
        DebugRect(TOUCH_EVENT_HANDLER_RECT_TYPE,
                  MathUtil::MapEnclosingClippedRect(
                      layer->screen_space_transform(), touch_rect)));
  }
}

void DebugRectHistory::SaveWheelEventHandlerRects(LayerImpl* layer) {
  LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
      layer,
      base::Bind(&DebugRectHistory::SaveWheelEventHandlerRectsCallback,
                 base::Unretained(this)));
}

void DebugRectHistory::SaveWheelEventHandlerRectsCallback(LayerImpl* layer) {
  if (!layer->have_wheel_event_handlers())
    return;

  gfx::Rect wheel_rect =
      gfx::ScaleToEnclosingRect(gfx::Rect(layer->content_bounds()),
                                layer->contents_scale_x(),
                                layer->contents_scale_y());
  debug_rects_.push_back(
      DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE,
                MathUtil::MapEnclosingClippedRect(
                    layer->screen_space_transform(), wheel_rect)));
}

void DebugRectHistory::SaveScrollEventHandlerRects(LayerImpl* layer) {
  LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
      layer,
      base::Bind(&DebugRectHistory::SaveScrollEventHandlerRectsCallback,
                 base::Unretained(this)));
}

void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) {
  if (!layer->have_scroll_event_handlers())
    return;

  gfx::Rect scroll_rect =
      gfx::ScaleToEnclosingRect(gfx::Rect(layer->content_bounds()),
                                layer->contents_scale_x(),
                                layer->contents_scale_y());
  debug_rects_.push_back(
      DebugRect(SCROLL_EVENT_HANDLER_RECT_TYPE,
                MathUtil::MapEnclosingClippedRect(
                    layer->screen_space_transform(), scroll_rect)));
}

void DebugRectHistory::SaveNonFastScrollableRects(LayerImpl* layer) {
  LayerTreeHostCommon::CallFunctionForSubtree<LayerImpl>(
      layer,
      base::Bind(&DebugRectHistory::SaveNonFastScrollableRectsCallback,
                 base::Unretained(this)));
}

void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) {
  for (Region::Iterator iter(layer->non_fast_scrollable_region());
       iter.has_rect();
       iter.next()) {
    gfx::Rect scroll_rect = gfx::ScaleToEnclosingRect(
        iter.rect(), layer->contents_scale_x(), layer->contents_scale_y());
    debug_rects_.push_back(
        DebugRect(NON_FAST_SCROLLABLE_RECT_TYPE,
                  MathUtil::MapEnclosingClippedRect(
                      layer->screen_space_transform(), scroll_rect)));
  }
}

void DebugRectHistory::SaveLayerAnimationBoundsRects(
    const LayerImplList& render_surface_layer_list) {
  typedef LayerIterator<LayerImpl> LayerIteratorType;
  LayerIteratorType end = LayerIteratorType::End(&render_surface_layer_list);
  for (LayerIteratorType it =
           LayerIteratorType::Begin(&render_surface_layer_list);
       it != end; ++it) {
    if (!it.represents_itself())
      continue;

    // TODO(avallee): Figure out if we should show something for a layer who's
    // animating bounds but that we can't compute them.
    gfx::BoxF inflated_bounds;
    if (!LayerUtils::GetAnimationBounds(**it, &inflated_bounds))
      continue;

    debug_rects_.push_back(
        DebugRect(ANIMATION_BOUNDS_RECT_TYPE,
                  gfx::ToEnclosingRect(gfx::RectF(inflated_bounds.x(),
                                                  inflated_bounds.y(),
                                                  inflated_bounds.width(),
                                                  inflated_bounds.height()))));
  }
}

}  // namespace cc
