// Copyright 2014 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/trees/draw_property_utils.h"

#include <vector>

#include "cc/base/math_util.h"
#include "cc/layers/layer.h"
#include "cc/trees/property_tree.h"
#include "cc/trees/property_tree_builder.h"
#include "ui/gfx/geometry/rect_conversions.h"

namespace cc {

namespace {

void CalculateVisibleRects(
    const std::vector<Layer*>& layers_that_need_visible_rects,
    const ClipTree& clip_tree,
    const TransformTree& transform_tree) {
  for (size_t i = 0; i < layers_that_need_visible_rects.size(); ++i) {
    Layer* layer = layers_that_need_visible_rects[i];

    // TODO(ajuma): Compute content_scale rather than using it. Note that for
    // PictureLayer and PictureImageLayers, content_bounds == bounds and
    // content_scale_x == content_scale_y == 1.0, so once impl painting is on
    // everywhere, this code will be unnecessary.
    gfx::Size layer_content_bounds = layer->content_bounds();
    float contents_scale_x = layer->contents_scale_x();
    float contents_scale_y = layer->contents_scale_y();
    const bool has_clip = layer->clip_tree_index() > 0;
    const TransformNode* transform_node =
        transform_tree.Node(layer->transform_tree_index());
    if (has_clip) {
      const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index());
      const TransformNode* clip_transform_node =
          transform_tree.Node(clip_node->data.transform_id);
      const TransformNode* target_node =
          transform_tree.Node(layer->render_target()->transform_tree_index());

      gfx::Transform clip_to_target;
      gfx::Transform content_to_target;
      gfx::Transform target_to_content;
      gfx::Transform target_to_layer;

      bool success =
          transform_tree.ComputeTransform(clip_transform_node->id,
                                          target_node->id, &clip_to_target) &&
          transform_tree.ComputeTransform(transform_node->id, target_node->id,
                                          &content_to_target) &&
          transform_tree.ComputeTransform(target_node->id, transform_node->id,
                                          &target_to_layer);

      // This should only fail if we somehow got here with a singular ancestor.
      DCHECK(success);

      target_to_content.Scale(contents_scale_x, contents_scale_y);
      target_to_content.Translate(-layer->offset_to_transform_parent().x(),
                                  -layer->offset_to_transform_parent().y());
      target_to_content.PreconcatTransform(target_to_layer);

      content_to_target.Translate(layer->offset_to_transform_parent().x(),
                                  layer->offset_to_transform_parent().y());
      content_to_target.Scale(1.0 / contents_scale_x, 1.0 / contents_scale_y);

      gfx::Rect layer_content_rect = gfx::Rect(layer_content_bounds);
      gfx::RectF layer_content_bounds_in_target_space =
          MathUtil::MapClippedRect(content_to_target, layer_content_rect);
      gfx::RectF clip_rect_in_target_space;
      if (target_node->id > clip_node->id) {
        clip_rect_in_target_space = MathUtil::ProjectClippedRect(
            clip_to_target, clip_node->data.combined_clip);
      } else {
        clip_rect_in_target_space = MathUtil::MapClippedRect(
            clip_to_target, clip_node->data.combined_clip);
      }

      clip_rect_in_target_space.Intersect(layer_content_bounds_in_target_space);

      gfx::Rect visible_rect =
          gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
              target_to_content, clip_rect_in_target_space));

      visible_rect.Intersect(gfx::Rect(layer_content_bounds));

      layer->set_visible_rect_from_property_trees(visible_rect);
    } else {
      layer->set_visible_rect_from_property_trees(
          gfx::Rect(layer_content_bounds));
    }
  }
}

static bool IsRootLayerOfNewRenderingContext(Layer* layer) {
  if (layer->parent())
    return !layer->parent()->Is3dSorted() && layer->Is3dSorted();
  return layer->Is3dSorted();
}

static inline bool LayerIsInExisting3DRenderingContext(Layer* layer) {
  return layer->Is3dSorted() && layer->parent() &&
         layer->parent()->Is3dSorted();
}

static bool TransformToScreenIsKnown(Layer* layer, const TransformTree& tree) {
  const TransformNode* node = tree.Node(layer->transform_tree_index());
  return !node->data.to_screen_is_animated;
}

static bool IsLayerBackFaceExposed(Layer* layer, const TransformTree& tree) {
  if (!TransformToScreenIsKnown(layer, tree))
    return false;
  if (LayerIsInExisting3DRenderingContext(layer))
    return layer->draw_transform_from_property_trees(tree).IsBackFaceVisible();
  return layer->transform().IsBackFaceVisible();
}

static bool IsSurfaceBackFaceExposed(Layer* layer,
                                     const TransformTree& tree) {
  if (!TransformToScreenIsKnown(layer, tree))
    return false;
  if (LayerIsInExisting3DRenderingContext(layer))
    return layer->draw_transform_from_property_trees(tree).IsBackFaceVisible();

  if (IsRootLayerOfNewRenderingContext(layer))
    return layer->transform().IsBackFaceVisible();

  // If the render_surface is not part of a new or existing rendering context,
  // then the layers that contribute to this surface will decide back-face
  // visibility for themselves.
  return false;
}

static bool HasSingularTransform(Layer* layer, const TransformTree& tree) {
  const TransformNode* node = tree.Node(layer->transform_tree_index());
  return !node->data.is_invertible || !node->data.ancestors_are_invertible;
}

static bool IsBackFaceInvisible(Layer* layer, const TransformTree& tree) {
  Layer* backface_test_layer = layer;
  if (layer->use_parent_backface_visibility()) {
    DCHECK(layer->parent());
    DCHECK(!layer->parent()->use_parent_backface_visibility());
    backface_test_layer = layer->parent();
  }
  return !backface_test_layer->double_sided() &&
         IsLayerBackFaceExposed(backface_test_layer, tree);
}

static bool IsInvisibleDueToTransform(Layer* layer, const TransformTree& tree) {
  return HasSingularTransform(layer, tree) || IsBackFaceInvisible(layer, tree);
}

void FindLayersThatNeedVisibleRects(Layer* layer,
                                    const TransformTree& tree,
                                    bool subtree_is_visible_from_ancestor,
                                    std::vector<Layer*>* layers_to_update) {
  const bool subtree_is_invisble =
      layer->opacity() == 0.0f ||
      (layer->has_render_surface() && !layer->double_sided() &&
       IsSurfaceBackFaceExposed(layer, tree));

  if (subtree_is_invisble)
    return;

  bool layer_is_drawn =
      layer->HasCopyRequest() ||
      (subtree_is_visible_from_ancestor && !layer->hide_layer_and_subtree());

  if (layer_is_drawn && layer->DrawsContent()) {
    const bool visible = !IsInvisibleDueToTransform(layer, tree);
    if (visible)
      layers_to_update->push_back(layer);
  }

  for (size_t i = 0; i < layer->children().size(); ++i) {
    FindLayersThatNeedVisibleRects(layer->children()[i].get(),
                                   tree,
                                   layer_is_drawn,
                                   layers_to_update);
  }
}

}  // namespace

void ComputeClips(ClipTree* clip_tree, const TransformTree& transform_tree) {
  for (int i = 0; i < static_cast<int>(clip_tree->size()); ++i) {
    ClipNode* clip_node = clip_tree->Node(i);

    // Only descendants of a real clipping layer (i.e., not 0) may have their
    // clip adjusted due to intersecting with an ancestor clip.
    const bool is_clipped = clip_node->parent_id > 0;
    if (!is_clipped) {
      clip_node->data.combined_clip = clip_node->data.clip;
      continue;
    }

    ClipNode* parent_clip_node = clip_tree->parent(clip_node);
    const TransformNode* parent_transform_node =
        transform_tree.Node(parent_clip_node->data.transform_id);
    const TransformNode* transform_node =
        transform_tree.Node(clip_node->data.transform_id);

    // Clips must be combined in target space. We cannot, for example, combine
    // clips in the space of the child clip. The reason is non-affine
    // transforms. Say we have the following tree T->A->B->C, and B clips C, but
    // draw into target T. It may be the case that A applies a perspective
    // transform, and B and C are at different z positions. When projected into
    // target space, the relative sizes and positions of B and C can shift.
    // Since it's the relationship in target space that matters, that's where we
    // must combine clips.
    gfx::Transform parent_to_target;
    gfx::Transform clip_to_target;
    gfx::Transform target_to_clip;

    bool success =
        transform_tree.ComputeTransform(parent_transform_node->id,
                                        clip_node->data.target_id,
                                        &parent_to_target) &&
        transform_tree.ComputeTransform(
            transform_node->id, clip_node->data.target_id, &clip_to_target) &&
        transform_tree.ComputeTransform(clip_node->data.target_id,
                                        transform_node->id, &target_to_clip);

    // If we can't compute a transform, it's because we had to use the inverse
    // of a singular transform. We won't draw in this case, so there's no need
    // to compute clips.
    if (!success)
      continue;

    // In order to intersect with as small a rect as possible, we do a
    // preliminary clip in target space so that when we project back, there's
    // less likelihood of intersecting the view plane.
    gfx::RectF inherited_clip_in_target_space = MathUtil::MapClippedRect(
        parent_to_target, parent_clip_node->data.combined_clip);

    gfx::RectF clip_in_target_space =
        MathUtil::MapClippedRect(clip_to_target, clip_node->data.clip);

    gfx::RectF intersected_in_target_space = gfx::IntersectRects(
        inherited_clip_in_target_space, clip_in_target_space);

    clip_node->data.combined_clip = MathUtil::ProjectClippedRect(
        target_to_clip, intersected_in_target_space);

    clip_node->data.combined_clip.Intersect(clip_node->data.clip);
  }
}

void ComputeTransforms(TransformTree* transform_tree) {
  for (int i = 0; i < static_cast<int>(transform_tree->size()); ++i)
    transform_tree->UpdateScreenSpaceTransform(i);
}

void ComputeVisibleRectsUsingPropertyTrees(
    Layer* root_layer,
    const Layer* page_scale_layer,
    float page_scale_factor,
    float device_scale_factor,
    const gfx::Rect& viewport,
    const gfx::Transform& device_transform,
    TransformTree* transform_tree,
    ClipTree* clip_tree) {
  PropertyTreeBuilder::BuildPropertyTrees(
      root_layer, page_scale_layer, page_scale_factor, device_scale_factor,
      viewport, device_transform, transform_tree, clip_tree);
  ComputeTransforms(transform_tree);
  ComputeClips(clip_tree, *transform_tree);

  std::vector<Layer*> layers_to_update;
  const bool subtree_is_visible_from_ancestor = true;
  FindLayersThatNeedVisibleRects(root_layer, *transform_tree,
                                 subtree_is_visible_from_ancestor,
                                 &layers_to_update);
  CalculateVisibleRects(layers_to_update, *clip_tree, *transform_tree);
}

}  // namespace cc
