// Copyright 2011 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/layer_tree_host_common.h"

#include <stddef.h>

#include <algorithm>

#include "base/containers/adapters.h"
#include "base/trace_event/trace_event.h"
#include "cc/base/math_util.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer.h"
#include "cc/layers/layer_impl.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/effect_node.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/property_tree_builder.h"
#include "cc/trees/scroll_node.h"
#include "cc/trees/transform_node.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
#include "ui/gfx/transform.h"
#include "ui/gfx/transform_util.h"

namespace cc {

LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting::
    CalcDrawPropsMainInputsForTesting(Layer* root_layer,
                                      const gfx::Rect& device_viewport_rect,
                                      const gfx::Transform& device_transform,
                                      float device_scale_factor,
                                      float page_scale_factor,
                                      const Layer* page_scale_layer,
                                      const Layer* inner_viewport_scroll_layer,
                                      const Layer* outer_viewport_scroll_layer)
    : root_layer(root_layer),
      device_viewport_rect(device_viewport_rect),
      device_transform(device_transform),
      device_scale_factor(device_scale_factor),
      page_scale_factor(page_scale_factor),
      page_scale_layer(page_scale_layer),
      inner_viewport_scroll_layer(inner_viewport_scroll_layer),
      outer_viewport_scroll_layer(outer_viewport_scroll_layer) {}

LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting::
    CalcDrawPropsMainInputsForTesting(Layer* root_layer,
                                      const gfx::Rect& device_viewport_rect,
                                      const gfx::Transform& device_transform)
    : CalcDrawPropsMainInputsForTesting(root_layer,
                                        device_viewport_rect,
                                        device_transform,
                                        1.f,
                                        1.f,
                                        nullptr,
                                        nullptr,
                                        nullptr) {}

LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting::
    CalcDrawPropsMainInputsForTesting(Layer* root_layer,
                                      const gfx::Rect& device_viewport_rect)
    : CalcDrawPropsMainInputsForTesting(root_layer,
                                        device_viewport_rect,
                                        gfx::Transform()) {}

LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs(
    LayerImpl* root_layer,
    const gfx::Rect& device_viewport_rect,
    const gfx::Transform& device_transform,
    float device_scale_factor,
    float page_scale_factor,
    const LayerImpl* page_scale_layer,
    const LayerImpl* inner_viewport_scroll_layer,
    const LayerImpl* outer_viewport_scroll_layer,
    const gfx::Vector2dF& elastic_overscroll,
    const ElementId elastic_overscroll_element_id,
    int max_texture_size,
    RenderSurfaceList* render_surface_list,
    PropertyTrees* property_trees,
    TransformNode* page_scale_transform_node)
    : root_layer(root_layer),
      device_viewport_rect(device_viewport_rect),
      device_transform(device_transform),
      device_scale_factor(device_scale_factor),
      page_scale_factor(page_scale_factor),
      page_scale_layer(page_scale_layer),
      inner_viewport_scroll_layer(inner_viewport_scroll_layer),
      outer_viewport_scroll_layer(outer_viewport_scroll_layer),
      elastic_overscroll(elastic_overscroll),
      elastic_overscroll_element_id(elastic_overscroll_element_id),
      max_texture_size(max_texture_size),
      render_surface_list(render_surface_list),
      property_trees(property_trees),
      page_scale_transform_node(page_scale_transform_node) {}

LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting::
    CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer,
                                      const gfx::Rect& device_viewport_rect,
                                      const gfx::Transform& device_transform,
                                      float device_scale_factor,
                                      RenderSurfaceList* render_surface_list)
    : CalcDrawPropsImplInputs(root_layer,
                              device_viewport_rect,
                              device_transform,
                              device_scale_factor,
                              1.f,
                              nullptr,
                              nullptr,
                              nullptr,
                              gfx::Vector2dF(),
                              ElementId(),
                              std::numeric_limits<int>::max() / 2,
                              render_surface_list,
                              GetPropertyTrees(root_layer),
                              nullptr) {
  DCHECK(root_layer);
  DCHECK(render_surface_list);
}

LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting::
    CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer,
                                      const gfx::Rect& device_viewport_rect,
                                      const gfx::Transform& device_transform,
                                      RenderSurfaceList* render_surface_list)
    : CalcDrawPropsImplInputsForTesting(root_layer,
                                        device_viewport_rect,
                                        device_transform,
                                        1.f,
                                        render_surface_list) {}

LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting::
    CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer,
                                      const gfx::Rect& device_viewport_rect,
                                      RenderSurfaceList* render_surface_list)
    : CalcDrawPropsImplInputsForTesting(root_layer,
                                        device_viewport_rect,
                                        gfx::Transform(),
                                        1.f,
                                        render_surface_list) {}

LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting::
    CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer,
                                      const gfx::Rect& device_viewport_rect,
                                      float device_scale_factor,
                                      RenderSurfaceList* render_surface_list)
    : CalcDrawPropsImplInputsForTesting(root_layer,
                                        device_viewport_rect,
                                        gfx::Transform(),
                                        device_scale_factor,
                                        render_surface_list) {}

bool LayerTreeHostCommon::ScrollUpdateInfo::operator==(
    const LayerTreeHostCommon::ScrollUpdateInfo& other) const {
  return element_id == other.element_id && scroll_delta == other.scroll_delta;
}

LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo()
    : element_id(), hidden(true) {}

LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo(ElementId id,
                                                                bool hidden)
    : element_id(id), hidden(hidden) {}

bool LayerTreeHostCommon::ScrollbarsUpdateInfo::operator==(
    const LayerTreeHostCommon::ScrollbarsUpdateInfo& other) const {
  return element_id == other.element_id && hidden == other.hidden;
}

ScrollAndScaleSet::ScrollAndScaleSet()
    : page_scale_delta(1.f),
      is_pinch_gesture_active(false),
      top_controls_delta(0.f),
      browser_controls_constraint(BrowserControlsState::kBoth),
      browser_controls_constraint_changed(false),
      scroll_gesture_did_end(false),
      manipulation_info(kManipulationInfoNone) {}

ScrollAndScaleSet::~ScrollAndScaleSet() = default;

static inline void SetMaskLayersContributeToDrawnRenderSurface(
    RenderSurfaceImpl* surface,
    PropertyTrees* property_trees) {
  LayerImpl* mask_layer = surface->MaskLayer();
  if (mask_layer) {
    mask_layer->set_contributes_to_drawn_render_surface(true);
    draw_property_utils::ComputeMaskDrawProperties(mask_layer, property_trees);
  }
}

static inline void ClearMaskLayersContributeToDrawnRenderSurface(
    RenderSurfaceImpl* surface) {
  LayerImpl* mask_layer = surface->MaskLayer();
  if (mask_layer)
    mask_layer->set_contributes_to_drawn_render_surface(false);
}

static float TranslationFromActiveTreeLayerScreenSpaceTransform(
    LayerImpl* pending_tree_layer) {
  LayerTreeImpl* layer_tree_impl = pending_tree_layer->layer_tree_impl();
  if (layer_tree_impl) {
    LayerImpl* active_tree_layer =
        layer_tree_impl->FindActiveTreeLayerById(pending_tree_layer->id());
    if (active_tree_layer) {
      gfx::Transform active_tree_screen_space_transform =
          active_tree_layer->draw_properties().screen_space_transform;
      if (active_tree_screen_space_transform.IsIdentity())
        return 0.f;
      if (active_tree_screen_space_transform.ApproximatelyEqual(
              pending_tree_layer->draw_properties().screen_space_transform))
        return 0.f;
      return (active_tree_layer->draw_properties()
                  .screen_space_transform.To2dTranslation() -
              pending_tree_layer->draw_properties()
                  .screen_space_transform.To2dTranslation())
          .Length();
    }
  }
  return 0.f;
}

// A layer jitters if its screen space transform is same on two successive
// commits, but has changed in between the commits. CalculateLayerJitter
// computes the jitter for the layer.
int LayerTreeHostCommon::CalculateLayerJitter(LayerImpl* layer) {
  float jitter = 0.f;
  layer->performance_properties().translation_from_last_frame = 0.f;
  layer->performance_properties().last_commit_screen_space_transform =
      layer->draw_properties().screen_space_transform;

  if (!layer->visible_layer_rect().IsEmpty()) {
    if (layer->draw_properties().screen_space_transform.ApproximatelyEqual(
            layer->performance_properties()
                .last_commit_screen_space_transform)) {
      float translation_from_last_commit =
          TranslationFromActiveTreeLayerScreenSpaceTransform(layer);
      if (translation_from_last_commit > 0.f) {
        layer->performance_properties().num_fixed_point_hits++;
        layer->performance_properties().translation_from_last_frame =
            translation_from_last_commit;
        if (layer->performance_properties().num_fixed_point_hits >
            layer->layer_tree_impl()->kFixedPointHitsThreshold) {
          // Jitter = Translation from fixed point * sqrt(Area of the layer).
          // The square root of the area is used instead of the area to match
          // the dimensions of both terms on the rhs.
          jitter += translation_from_last_commit *
                    sqrt(layer->visible_layer_rect().size().GetArea());
        }
      } else {
        layer->performance_properties().num_fixed_point_hits = 0;
      }
    }
  }
  return jitter;
}

enum PropertyTreeOption { BUILD_PROPERTY_TREES, DONT_BUILD_PROPERTY_TREES };

static void AddSurfaceToRenderSurfaceList(
    RenderSurfaceImpl* render_surface,
    RenderSurfaceList* render_surface_list,
    PropertyTrees* property_trees) {
  // |render_surface| must appear after its target, so first make sure its
  // target is in the list.
  RenderSurfaceImpl* target = render_surface->render_target();
  bool is_root =
      render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId;
  if (!is_root && !target->is_render_surface_list_member()) {
    AddSurfaceToRenderSurfaceList(target, render_surface_list, property_trees);
  }
  render_surface->ClearAccumulatedContentRect();
  render_surface_list->push_back(render_surface);
  render_surface->set_is_render_surface_list_member(true);
  if (is_root) {
    // The root surface does not contribute to any other surface, it has no
    // target.
    render_surface->set_contributes_to_drawn_surface(false);
  } else {
    bool contributes_to_drawn_surface =
        property_trees->effect_tree.ContributesToDrawnSurface(
            render_surface->EffectTreeIndex());
    render_surface->set_contributes_to_drawn_surface(
        contributes_to_drawn_surface);
  }

  draw_property_utils::ComputeSurfaceDrawProperties(property_trees,
                                                    render_surface);

  // Ignore occlusion from outside the surface when surface contents need to be
  // fully drawn. Layers with copy-request need to be complete.  We could be
  // smarter about layers with filters that move pixels and exclude regions
  // where both layers and the filters are occluded, but this seems like
  // overkill.
  // TODO(senorblanco): make this smarter for the SkImageFilter case (check for
  // pixel-moving filters)
  const FilterOperations& filters = render_surface->Filters();
  bool is_occlusion_immune = render_surface->HasCopyRequest() ||
                             render_surface->ShouldCacheRenderSurface() ||
                             filters.HasReferenceFilter() ||
                             filters.HasFilterThatMovesPixels();
  if (is_occlusion_immune) {
    render_surface->SetNearestOcclusionImmuneAncestor(render_surface);
  } else if (is_root) {
    render_surface->SetNearestOcclusionImmuneAncestor(nullptr);
  } else {
    render_surface->SetNearestOcclusionImmuneAncestor(
        render_surface->render_target()->nearest_occlusion_immune_ancestor());
  }
}

static bool SkipForInvertibility(const LayerImpl* layer,
                                 PropertyTrees* property_trees) {
  const TransformNode* transform_node =
      property_trees->transform_tree.Node(layer->transform_tree_index());
  const EffectNode* effect_node =
      property_trees->effect_tree.Node(layer->effect_tree_index());
  bool non_root_copy_request =
      effect_node->closest_ancestor_with_copy_request_id >
      EffectTree::kContentsRootNodeId;
  gfx::Transform from_target;
  // If there is a copy request, we check the invertibility of the transform
  // between the node corresponding to the layer and the node corresponding to
  // the copy request. Otherwise, we are interested in the invertibility of
  // screen space transform which is already cached on the transform node.
  return non_root_copy_request
             ? !property_trees->GetFromTarget(
                   layer->transform_tree_index(),
                   effect_node->closest_ancestor_with_copy_request_id,
                   &from_target)
             : !transform_node->ancestors_are_invertible;
}

static void ComputeInitialRenderSurfaceList(
    LayerTreeImpl* layer_tree_impl,
    PropertyTrees* property_trees,
    RenderSurfaceList* render_surface_list) {
  EffectTree& effect_tree = property_trees->effect_tree;
  for (int i = EffectTree::kContentsRootNodeId;
       i < static_cast<int>(effect_tree.size()); ++i) {
    if (RenderSurfaceImpl* render_surface = effect_tree.GetRenderSurface(i)) {
      render_surface->set_is_render_surface_list_member(false);
      render_surface->reset_num_contributors();
      ClearMaskLayersContributeToDrawnRenderSurface(render_surface);
    }
  }

  RenderSurfaceImpl* root_surface =
      effect_tree.GetRenderSurface(EffectTree::kContentsRootNodeId);
  // The root surface always gets added to the render surface  list.
  AddSurfaceToRenderSurfaceList(root_surface, render_surface_list,
                                property_trees);
  // For all non-skipped layers, add their target to the render surface list if
  // it's not already been added, and add their content rect to the target
  // surface's accumulated content rect.
  for (LayerImpl* layer : *layer_tree_impl) {
    DCHECK(layer);
    layer->EnsureValidPropertyTreeIndices();

    layer->set_contributes_to_drawn_render_surface(false);
    layer->set_raster_even_if_not_drawn(false);

    bool is_root = layer_tree_impl->IsRootLayer(layer);

    bool skip_draw_properties_computation =
        draw_property_utils::LayerShouldBeSkippedForDrawPropertiesComputation(
            layer, property_trees->transform_tree, property_trees->effect_tree);

    bool skip_for_invertibility = SkipForInvertibility(layer, property_trees);

    bool skip_layer = !is_root && (skip_draw_properties_computation ||
                                   skip_for_invertibility);

    layer->set_raster_even_if_not_drawn(skip_for_invertibility &&
                                        !skip_draw_properties_computation);
    if (skip_layer)
      continue;

    bool layer_is_drawn =
        property_trees->effect_tree.Node(layer->effect_tree_index())->is_drawn;
    bool layer_should_be_drawn = draw_property_utils::LayerNeedsUpdate(
        layer, layer_is_drawn, property_trees);
    if (!layer_should_be_drawn)
      continue;

    RenderSurfaceImpl* render_target = layer->render_target();
    if (!render_target->is_render_surface_list_member()) {
      AddSurfaceToRenderSurfaceList(render_target, render_surface_list,
                                    property_trees);
    }

    layer->set_contributes_to_drawn_render_surface(true);

    // The layer contributes its drawable content rect to its render target.
    render_target->AccumulateContentRectFromContributingLayer(layer);
    render_target->increment_num_contributors();
  }
}

static void ComputeSurfaceContentRects(PropertyTrees* property_trees,
                                       RenderSurfaceList* render_surface_list,
                                       int max_texture_size) {
  // Walk the list backwards, accumulating each surface's content rect into its
  // target's content rect.
  for (RenderSurfaceImpl* render_surface :
       base::Reversed(*render_surface_list)) {
    if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) {
      // The root surface's content rect is always the entire viewport.
      render_surface->SetContentRectToViewport();
      continue;
    }

    // Now all contributing drawable content rect has been accumulated to this
    // render surface, calculate the content rect.
    render_surface->CalculateContentRectFromAccumulatedContentRect(
        max_texture_size);

    // Now the render surface's content rect is calculated correctly, it could
    // contribute to its render target.
    RenderSurfaceImpl* render_target = render_surface->render_target();
    DCHECK(render_target->is_render_surface_list_member());
    render_target->AccumulateContentRectFromContributingRenderSurface(
        render_surface);
    render_target->increment_num_contributors();
  }
}

static void ComputeListOfNonEmptySurfaces(
    LayerTreeImpl* layer_tree_impl,
    PropertyTrees* property_trees,
    RenderSurfaceList* initial_surface_list,
    RenderSurfaceList* final_surface_list) {
  // Walk the initial surface list forwards. The root surface and each
  // surface with a non-empty content rect go into the final render surface
  // layer list. Surfaces with empty content rects or whose target isn't in
  // the final list do not get added to the final list.
  bool removed_surface = false;
  for (RenderSurfaceImpl* surface : *initial_surface_list) {
    bool is_root =
        surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId;
    RenderSurfaceImpl* target_surface = surface->render_target();
    if (!is_root && (surface->content_rect().IsEmpty() ||
                     !target_surface->is_render_surface_list_member())) {
      surface->set_is_render_surface_list_member(false);
      removed_surface = true;
      target_surface->decrement_num_contributors();
      continue;
    }
    SetMaskLayersContributeToDrawnRenderSurface(surface, property_trees);
    final_surface_list->push_back(surface);
  }
  if (removed_surface) {
    for (LayerImpl* layer : *layer_tree_impl) {
      if (layer->contributes_to_drawn_render_surface()) {
        RenderSurfaceImpl* render_target = layer->render_target();
        if (!render_target->is_render_surface_list_member()) {
          layer->set_contributes_to_drawn_render_surface(false);
          render_target->decrement_num_contributors();
        }
      }
    }
  }
}

static void CalculateRenderSurfaceLayerList(
    LayerTreeImpl* layer_tree_impl,
    PropertyTrees* property_trees,
    RenderSurfaceList* render_surface_list,
    const int max_texture_size) {
  RenderSurfaceList initial_render_surface_list;

  // First compute a list that might include surfaces that later turn out to
  // have an empty content rect. After surface content rects are computed,
  // produce a final list that omits empty surfaces.
  ComputeInitialRenderSurfaceList(layer_tree_impl, property_trees,
                                  &initial_render_surface_list);
  ComputeSurfaceContentRects(property_trees, &initial_render_surface_list,
                             max_texture_size);
  ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees,
                                &initial_render_surface_list,
                                render_surface_list);
}

static void RecordRenderSurfaceReasonsForTracing(
    const PropertyTrees* property_trees,
    const RenderSurfaceList* render_surface_list) {
  static const auto* tracing_enabled =
      TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("cc");
  if (!*tracing_enabled ||
      // Don't output single root render surface.
      render_surface_list->size() <= 1)
    return;

  TRACE_EVENT_INSTANT1("cc", "RenderSurfaceReasonCount",
                       TRACE_EVENT_SCOPE_THREAD, "total",
                       render_surface_list->size());

  // kTest is the last value which is not included for tracing.
  constexpr auto kNumReasons = static_cast<size_t>(RenderSurfaceReason::kTest);
  int reason_counts[kNumReasons] = {0};
  for (const auto* render_surface : *render_surface_list) {
    const auto* effect_node =
        property_trees->effect_tree.Node(render_surface->EffectTreeIndex());
    reason_counts[static_cast<size_t>(effect_node->render_surface_reason)]++;
  }
  for (size_t i = 0; i < kNumReasons; i++) {
    if (!reason_counts[i])
      continue;
    TRACE_EVENT_INSTANT1(
        "cc", "RenderSurfaceReasonCount", TRACE_EVENT_SCOPE_THREAD,
        RenderSurfaceReasonToString(static_cast<RenderSurfaceReason>(i)),
        reason_counts[i]);
  }
}

static void CalculateDrawPropertiesInternal(
    LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs,
    PropertyTreeOption property_tree_option,
    LayerImplList* output_update_layer_list) {
  inputs->render_surface_list->clear();

  LayerImplList visible_layer_list;
  switch (property_tree_option) {
    case BUILD_PROPERTY_TREES: {
      // The translation from layer to property trees is an intermediate
      // state. We will eventually get these data passed directly to the
      // compositor.
      PropertyTreeBuilder::BuildPropertyTrees(
          inputs->root_layer, inputs->page_scale_layer,
          inputs->inner_viewport_scroll_layer,
          inputs->outer_viewport_scroll_layer,
          inputs->elastic_overscroll_element_id, inputs->elastic_overscroll,
          inputs->page_scale_factor, inputs->device_scale_factor,
          inputs->device_viewport_rect, inputs->device_transform,
          inputs->property_trees);
      draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
          inputs->root_layer, inputs->property_trees);
      break;
    }
    case DONT_BUILD_PROPERTY_TREES: {
      // Since page scale and elastic overscroll are SyncedProperties, changes
      // on the active tree immediately affect the pending tree, so instead of
      // trying to update property trees whenever these values change, we
      // update property trees before using them.

      // We should never be setting a non-unit page scale factor on an oopif
      // subframe ... if we attempt this log it and fail.
      // TODO(wjmaclean): Remove as part of conditions for closing the bug.
      // https://crbug.com/845097
      if (inputs->page_scale_factor !=
              inputs->property_trees->transform_tree.page_scale_factor() &&
          !inputs->page_scale_transform_node) {
        LOG(ERROR) << "Setting PageScale on subframe: new psf = "
                   << inputs->page_scale_factor << ", old psf = "
                   << inputs->property_trees->transform_tree.page_scale_factor()
                   << ", in_oopif = "
                   << inputs->root_layer->layer_tree_impl()
                          ->settings()
                          .is_layer_tree_for_subframe;
        NOTREACHED();
      }

      DCHECK_NE(inputs->page_scale_layer, inputs->root_layer);
      draw_property_utils::UpdatePageScaleFactor(
          inputs->property_trees, inputs->page_scale_transform_node,
          inputs->page_scale_factor);
      draw_property_utils::UpdateElasticOverscroll(
          inputs->property_trees, inputs->elastic_overscroll_element_id,
          inputs->elastic_overscroll);
      // Similarly, the device viewport and device transform are shared
      // by both trees.
      PropertyTrees* property_trees = inputs->property_trees;
      property_trees->clip_tree.SetViewportClip(
          gfx::RectF(inputs->device_viewport_rect));
      property_trees->transform_tree.SetRootScaleAndTransform(
          inputs->device_scale_factor, inputs->device_transform);
      draw_property_utils::UpdatePropertyTreesAndRenderSurfaces(
          inputs->root_layer, inputs->property_trees);
      break;
    }
  }

  {
    TRACE_EVENT0("cc", "draw_property_utils::FindLayersThatNeedUpdates");
    draw_property_utils::FindLayersThatNeedUpdates(
        inputs->root_layer->layer_tree_impl(), inputs->property_trees,
        &visible_layer_list);
  }

  {
    TRACE_EVENT1("cc",
                 "draw_property_utils::ComputeDrawPropertiesOfVisibleLayers",
                 "visible_layers", visible_layer_list.size());
    draw_property_utils::ComputeDrawPropertiesOfVisibleLayers(
        &visible_layer_list, inputs->property_trees);
  }

  {
    TRACE_EVENT0("cc", "CalculateRenderSurfaceLayerList");
    CalculateRenderSurfaceLayerList(
        inputs->root_layer->layer_tree_impl(), inputs->property_trees,
        inputs->render_surface_list, inputs->max_texture_size);
  }
  RecordRenderSurfaceReasonsForTracing(inputs->property_trees,
                                       inputs->render_surface_list);

  // A root layer render_surface should always exist after
  // CalculateDrawProperties.
  DCHECK(inputs->property_trees->effect_tree.GetRenderSurface(
      EffectTree::kContentsRootNodeId));

  if (output_update_layer_list)
    *output_update_layer_list = std::move(visible_layer_list);
}

void LayerTreeHostCommon::CalculateDrawPropertiesForTesting(
    CalcDrawPropsMainInputsForTesting* inputs) {
  LayerList update_layer_list;
  PropertyTrees* property_trees =
      inputs->root_layer->layer_tree_host()->property_trees();
  if (inputs->root_layer->layer_tree_host()->IsUsingLayerLists()) {
    // TODO(wangxianzhu): We should DCHECK(!needs_rebuild) after we remove all
    // unnecessary setting of the flag in layer list mode.
    property_trees->needs_rebuild = false;
  } else {
    gfx::Vector2dF elastic_overscroll;
    PropertyTreeBuilder::BuildPropertyTrees(
        inputs->root_layer, inputs->page_scale_layer,
        inputs->inner_viewport_scroll_layer,
        inputs->outer_viewport_scroll_layer, ElementId(), elastic_overscroll,
        inputs->page_scale_factor, inputs->device_scale_factor,
        inputs->device_viewport_rect, inputs->device_transform, property_trees);
  }
  draw_property_utils::UpdatePropertyTrees(
      inputs->root_layer->layer_tree_host(), property_trees);
  draw_property_utils::FindLayersThatNeedUpdates(
      inputs->root_layer->layer_tree_host(), property_trees,
      &update_layer_list);

  if (inputs->update_layer_list)
    *inputs->update_layer_list = std::move(update_layer_list);
}

void LayerTreeHostCommon::CalculateDrawProperties(
    CalcDrawPropsImplInputs* inputs) {
  CalculateDrawPropertiesInternal(inputs, DONT_BUILD_PROPERTY_TREES, nullptr);
}

void LayerTreeHostCommon::PrepareForUpdateDrawPropertiesForTesting(
    LayerTreeImpl* layer_tree_impl) {
  if (layer_tree_impl->settings().use_layer_lists) {
    // TODO(wangxianzhu): We should DCHECK(!needs_rebuild) after we remove all
    // unnecessary setting of the flag in layer list mode.
    auto* property_trees = layer_tree_impl->property_trees();
    property_trees->needs_rebuild = false;
    // The following are needed for tests that modify impl-side property trees.
    // In production code impl-side property trees are pushed from the main
    // thread and the following are done in other ways.
    std::vector<std::unique_ptr<RenderSurfaceImpl>> old_render_surfaces;
    property_trees->effect_tree.TakeRenderSurfaces(&old_render_surfaces);
    property_trees->effect_tree.CreateOrReuseRenderSurfaces(
        &old_render_surfaces, layer_tree_impl);
    property_trees->ResetCachedData();
  }
}

void LayerTreeHostCommon::CalculateDrawPropertiesForTesting(
    CalcDrawPropsImplInputsForTesting* inputs) {
  PrepareForUpdateDrawPropertiesForTesting(
      inputs->root_layer->layer_tree_impl());
  CalculateDrawPropertiesInternal(inputs,
                                  inputs->property_trees->needs_rebuild
                                      ? BUILD_PROPERTY_TREES
                                      : DONT_BUILD_PROPERTY_TREES,
                                  inputs->update_layer_list);
}

PropertyTrees* GetPropertyTrees(const Layer* layer) {
  return layer->layer_tree_host()->property_trees();
}

PropertyTrees* GetPropertyTrees(const LayerImpl* layer) {
  return layer->layer_tree_impl()->property_trees();
}

}  // namespace cc
