// 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 "third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h"

#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/layout/layout_block.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h"

namespace blink {

static const LayoutBoxModelObject* ClippingContainerFromClipChainParent(
    const PaintLayer* clip_chain_parent) {
  return clip_chain_parent->GetLayoutObject().HasClipRelatedProperty()
             ? &clip_chain_parent->GetLayoutObject()
             : clip_chain_parent->ClippingContainer();
}

CompositingInputsUpdater::CompositingInputsUpdater(
    PaintLayer* root_layer,
    CompositingReasonFinder& compositing_reason_finder)
    : geometry_map_(kUseTransforms),
      root_layer_(root_layer),
      compositing_reason_finder_(compositing_reason_finder) {}

CompositingInputsUpdater::~CompositingInputsUpdater() = default;

void CompositingInputsUpdater::Update() {
  TRACE_EVENT0("blink", "CompositingInputsUpdater::update");
  UpdateRecursive(root_layer_, kDoNotForceUpdate, AncestorInfo());
}

void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer,
                                               UpdateType update_type,
                                               AncestorInfo info) {
  LayoutBoxModelObject& layout_object = layer->GetLayoutObject();
  const ComputedStyle& style = layout_object.StyleRef();

  const PaintLayer* previous_overflow_layer = layer->AncestorOverflowLayer();
  layer->UpdateAncestorOverflowLayer(info.last_overflow_clip_layer);
  if (info.last_overflow_clip_layer && layer->NeedsCompositingInputsUpdate() &&
      style.HasStickyConstrainedPosition()) {
    if (info.last_overflow_clip_layer != previous_overflow_layer) {
      // Old ancestor scroller should no longer have these constraints.
      DCHECK(!previous_overflow_layer ||
             !previous_overflow_layer->GetScrollableArea() ||
             !previous_overflow_layer->GetScrollableArea()
                  ->GetStickyConstraintsMap()
                  .Contains(layer));

      // If our ancestor scroller has changed and the previous one was the
      // root layer, we are no longer viewport constrained.
      if (previous_overflow_layer && previous_overflow_layer->IsRootLayer()) {
        layout_object.View()->GetFrameView()->RemoveViewportConstrainedObject(
            layout_object);
      }
    }

    if (info.last_overflow_clip_layer->IsRootLayer()) {
      layout_object.View()->GetFrameView()->AddViewportConstrainedObject(
          layout_object);
    }
    layout_object.UpdateStickyPositionConstraints();

    // Sticky position constraints and ancestor overflow scroller affect
    // the sticky layer position, so we need to update it again here.
    // TODO(flackr): This should be refactored in the future to be clearer
    // (i.e. update layer position and ancestor inputs updates in the
    // same walk)
    layer->UpdateLayerPosition();
  }

  geometry_map_.PushMappingsToAncestor(layer, layer->Parent());

  PaintLayer* enclosing_composited_layer =
      layer->HasCompositedLayerMapping() ? layer
                                         : info.enclosing_composited_layer;
  if (layer->NeedsCompositingInputsUpdate()) {
    if (enclosing_composited_layer) {
      enclosing_composited_layer->GetCompositedLayerMapping()
          ->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateSubtree);
    }
    update_type = kForceUpdate;
  }

  if (style.GetPosition() == EPosition::kAbsolute) {
    info.escape_clip_to = info.escape_clip_to_for_absolute;
    info.scrolling_ancestor = info.scrolling_ancestor_for_absolute;
    info.needs_reparent_scroll = info.needs_reparent_scroll_for_absolute;
  } else if (style.GetPosition() == EPosition::kFixed) {
    info.escape_clip_to = info.escape_clip_to_for_fixed;
    info.scrolling_ancestor = info.scrolling_ancestor_for_fixed;
    info.needs_reparent_scroll = info.needs_reparent_scroll_for_fixed;
  }

  if (update_type == kForceUpdate)
    UpdateAncestorDependentCompositingInputs(layer, info);

  info.enclosing_composited_layer = enclosing_composited_layer;

  if (layer->IsRootLayer() || layout_object.HasOverflowClip())
    info.last_overflow_clip_layer = layer;

  // Handles sibling scroll problem, i.e. a non-stacking context scroller
  // needs to propagate scroll to its descendants that are siblings in
  // paint order. For example:
  // <div style="overflow:scroll;">
  //   <div style="position:relative;">Paint sibling.</div>
  // </div>
  if (layer->ScrollsOverflow()) {
    info.scrolling_ancestor = layer;
    info.needs_reparent_scroll = true;
  }
  if (layout_object.CanContainAbsolutePositionObjects()) {
    info.clip_chain_parent_for_absolute = layer;
    info.escape_clip_to_for_absolute = info.escape_clip_to;
    info.scrolling_ancestor_for_absolute = info.scrolling_ancestor;
    info.needs_reparent_scroll_for_absolute = info.needs_reparent_scroll;
  }

  // LayoutView isn't really the containing block for fixed-pos descendants
  // in the sense that they don't scroll along with its in-flow contents.
  // However LayoutView does clip them.
  if (layout_object.CanContainFixedPositionObjects() &&
      !layout_object.IsLayoutView()) {
    info.clip_chain_parent_for_fixed = layer;
    info.escape_clip_to_for_fixed = info.escape_clip_to;
    info.scrolling_ancestor_for_fixed = info.scrolling_ancestor;
    info.needs_reparent_scroll_for_fixed = info.needs_reparent_scroll;
  }
  if (layout_object.IsLayoutView())
    info.clip_chain_parent_for_fixed = layer;

  // CSS clip affects all descendants, not just containing-block descendants.
  // We don't have to set clip_chain_parent_for_absolute here because CSS clip
  // requires position:absolute, so the element must contain absolute-positioned
  // descendants.
  // However it is incorrect to let fixed-positioned descendants to inherit the
  // clip state from this element either, because the overflow clip and the
  // inherited clip of the current element shouldn't apply to them if the
  // current element is not a fixed-pos container. This is a known bug but too
  // difficult to fix in SPv1 compositing.
  if (layout_object.HasClip())
    info.clip_chain_parent_for_fixed = layer;

  if (style.IsStackingContext()) {
    info.escape_clip_to = nullptr;
    const LayoutBoxModelObject* clipping_container =
        ClippingContainerFromClipChainParent(layer);
    info.escape_clip_to_for_absolute =
        ClippingContainerFromClipChainParent(
            info.clip_chain_parent_for_absolute) != clipping_container
            ? info.clip_chain_parent_for_absolute
            : nullptr;
    info.escape_clip_to_for_fixed =
        ClippingContainerFromClipChainParent(
            info.clip_chain_parent_for_fixed) != clipping_container
            ? info.clip_chain_parent_for_fixed
            : nullptr;
    // Workaround crbug.com/817175
    // We can't escape clip to a layer that paints after us, because in SPv1*
    // cc needs to reverse engineer clip tree from the layer tree, and we
    // can't refer to a clip node that hasn't been built yet.
    // This will result in wrong clip in some rare cases, for example:
    // <div style="display:grid;">
    //   <div style="z-index:-1; overflow:hidden;">
    //     <div style="position:absolute;"></div>
    //   </div>
    // </div>
    if (info.escape_clip_to_for_absolute && style.ZIndex() < 0 &&
        !info.escape_clip_to_for_absolute->GetLayoutObject()
             .StyleRef()
             .IsStackingContext())
      info.escape_clip_to_for_absolute = nullptr;
    if (info.escape_clip_to_for_fixed && style.ZIndex() < 0 &&
        !info.escape_clip_to_for_fixed->GetLayoutObject()
             .StyleRef()
             .IsStackingContext())
      info.escape_clip_to_for_fixed = nullptr;

    info.needs_reparent_scroll = info.needs_reparent_scroll_for_absolute =
        info.needs_reparent_scroll_for_fixed = false;
  }

  // The sequence of updates to compositing triggers goes like this:
  // 1. Apply all triggers from kComboAllDirectNonStyleDeterminedReasons for
  //    |layer|. This may depend on ancestor composited scrolling (i.e. step
  //    2 for an ancestor PaintLayer).
  // 2. Put |layer| in composited scrolling mode if needed.
  // 3. Reset DescendantHasDirectCompositingReason to false for |layer|.
  // 4. Recurse into child PaintLayers.
  // 5. Set DescendantHasDirectCompositingReason to true if it was for any
  //    child.
  // 6. If |layer| is the root, composite if
  //    DescendantHasDirectCompositingReason is true for |layer|.
  bool ignore_lcd_text =
      (layer->AncestorScrollingLayer() &&
       !layer->AncestorScrollingLayer()->IsRootLayer() &&
       layer->AncestorScrollingLayer()->NeedsCompositedScrolling());

  layer->SetPotentialCompositingReasonsFromNonStyle(
      compositing_reason_finder_.NonStyleDeterminedDirectReasons(
          layer, ignore_lcd_text));

  if (layer->GetScrollableArea()) {
    layer->GetScrollableArea()->UpdateNeedsCompositedScrolling(
        layer->GetLayoutObject().View()->Compositor()->CanBeComposited(layer) &&
        layer->DirectCompositingReasons());
    layer->GetScrollableArea()->SetHasPaintLayerScrollChild(false);
  }

  bool should_recurse =
      layer->ChildNeedsCompositingInputsUpdate() || update_type == kForceUpdate;

  layer->SetDescendantHasDirectOrScrollingCompositingReason(false);
  bool descendant_has_direct_compositing_reason = false;
  for (PaintLayer* child = layer->FirstChild(); child;
       child = child->NextSibling()) {
    if (should_recurse)
      UpdateRecursive(child, update_type, info);
    descendant_has_direct_compositing_reason |=
        child->DescendantHasDirectOrScrollingCompositingReason() ||
        child->DirectCompositingReasons() || child->NeedsCompositedScrolling();
  }
  layer->SetDescendantHasDirectOrScrollingCompositingReason(
      descendant_has_direct_compositing_reason);

  if (layer->IsRootLayer() && layer->ScrollsOverflow() &&
      layer->DescendantHasDirectOrScrollingCompositingReason() &&
      !layer->NeedsCompositedScrolling())
    layer->GetScrollableArea()->UpdateNeedsCompositedScrolling(true);

  layer->ClearChildNeedsCompositingInputsUpdate();

  geometry_map_.PopMappingsToAncestor(layer->Parent());

  if (layer->SelfPaintingStatusChanged()) {
    layer->ClearSelfPaintingStatusChanged();
    // If the floating object becomes non-self-painting, so some ancestor should
    // paint it; if it becomes self-painting, it should paint itself and no
    // ancestor should paint it.
    if (layout_object.IsFloating()) {
      LayoutBlockFlow::UpdateAncestorShouldPaintFloatingObject(
          *layer->GetLayoutBox());
    }
  }
}

void CompositingInputsUpdater::UpdateAncestorDependentCompositingInputs(
    PaintLayer* layer,
    const AncestorInfo& info) {
  if (layer->IsRootLayer()) {
    layer->UpdateAncestorDependentCompositingInputs(
        PaintLayer::AncestorDependentCompositingInputs());
    return;
  }

  PaintLayer::AncestorDependentCompositingInputs properties;
  LayoutBoxModelObject& layout_object = layer->GetLayoutObject();

  if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
    // The final value for |unclipped_absolute_bounding_box| needs to be
    // in absolute, unscrolled space, without any scroll applied.
    properties.unclipped_absolute_bounding_box =
        EnclosingIntRect(geometry_map_.AbsoluteRect(
            FloatRect(layer->BoundingBoxForCompositingOverlapTest())));

    bool affected_by_scroll = root_layer_->GetScrollableArea() &&
                              layer->IsAffectedByScrollOf(root_layer_);

    // At ths point, |unclipped_absolute_bounding_box| is in viewport space.
    // To convert to absolute space, add scroll offset for non-fixed layers.
    if (affected_by_scroll) {
      properties.unclipped_absolute_bounding_box.Move(
          RoundedIntSize(root_layer_->GetScrollableArea()->GetScrollOffset()));
    }

    ClipRect clip_rect;
    layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
        .CalculateBackgroundClipRect(
            ClipRectsContext(root_layer_,
                             kAbsoluteClipRectsIgnoringViewportClip,
                             kIgnorePlatformOverlayScrollbarSize,
                             kIgnoreOverflowClipAndScroll),
            clip_rect);
    IntRect snapped_clip_rect = PixelSnappedIntRect(clip_rect.Rect());
    // |snapped_clip_rect| is in absolute space space, but with scroll applied.
    // To convert to absolute, unscrolled space, subtract scroll offsets for
    // fixed layers.
    if (root_layer_->GetScrollableArea() && !affected_by_scroll) {
      snapped_clip_rect.Move(
          RoundedIntSize(-root_layer_->GetScrollableArea()->GetScrollOffset()));
    }

    properties.clipped_absolute_bounding_box =
        properties.unclipped_absolute_bounding_box;
    properties.clipped_absolute_bounding_box.Intersect(snapped_clip_rect);
  }

  const PaintLayer* parent = layer->Parent();
  properties.opacity_ancestor =
      parent->IsTransparent() ? parent : parent->OpacityAncestor();
  properties.transform_ancestor =
      parent->Transform() ? parent : parent->TransformAncestor();
  properties.filter_ancestor =
      parent->HasFilterInducingProperty() ? parent : parent->FilterAncestor();
  properties.clip_path_ancestor = parent->GetLayoutObject().HasClipPath()
                                      ? parent
                                      : parent->ClipPathAncestor();
  properties.mask_ancestor =
      parent->GetLayoutObject().HasMask() ? parent : parent->MaskAncestor();

  EPosition position = layout_object.StyleRef().GetPosition();
  properties.nearest_fixed_position_layer =
      position == EPosition::kFixed ? layer
                                    : parent->NearestFixedPositionLayer();

  PaintLayer* clip_chain_parent = layer->Parent();
  if (position == EPosition::kAbsolute)
    clip_chain_parent = info.clip_chain_parent_for_absolute;
  else if (position == EPosition::kFixed)
    clip_chain_parent = info.clip_chain_parent_for_fixed;
  properties.clipping_container =
      ClippingContainerFromClipChainParent(clip_chain_parent);
  properties.clip_parent = info.escape_clip_to;

  properties.ancestor_scrolling_layer = info.scrolling_ancestor;
  if (info.needs_reparent_scroll && layer->StackingNode()->IsStacked())
    properties.scroll_parent = info.scrolling_ancestor;

  if (properties.scroll_parent &&
      properties.scroll_parent->GetScrollableArea()) {
    properties.scroll_parent->GetScrollableArea()->SetHasPaintLayerScrollChild(
        true);
  }

  layer->UpdateAncestorDependentCompositingInputs(properties);
}

#if DCHECK_IS_ON()

void CompositingInputsUpdater::AssertNeedsCompositingInputsUpdateBitsCleared(
    PaintLayer* layer) {
  DCHECK(!layer->ChildNeedsCompositingInputsUpdate());
  DCHECK(!layer->NeedsCompositingInputsUpdate());

  for (PaintLayer* child = layer->FirstChild(); child;
       child = child->NextSibling())
    AssertNeedsCompositingInputsUpdateBitsCleared(child);
}

#endif

}  // namespace blink
