// Copyright 2015 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/pre_paint_tree_walk.h"

#include "base/auto_reset.h"
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
#include "third_party/blink/renderer/core/frame/event_handler_registry.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/frame/visual_viewport.h"
#include "third_party/blink/renderer/core/layout/jank_tracker.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_property_tree_printer.h"
#include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"

namespace blink {

void PrePaintTreeWalk::WalkTree(LocalFrameView& root_frame_view) {
  if (root_frame_view.ShouldThrottleRendering()) {
    // Skip the throttled frame. Will update it when it becomes unthrottled.
    return;
  }

  DCHECK(root_frame_view.GetFrame().GetDocument()->Lifecycle().GetState() ==
         DocumentLifecycle::kInPrePaint);

  // Reserve 50 elements for a really deep DOM. If the nesting is deeper than
  // this, then the vector will reallocate, but it shouldn't be a big deal. This
  // is also temporary within this function.
  DCHECK_EQ(context_storage_.size(), 0u);
  context_storage_.ReserveCapacity(50);
  context_storage_.emplace_back();

  // GeometryMapper depends on paint properties.
  bool needs_tree_builder_context_update =
      NeedsTreeBuilderContextUpdate(root_frame_view, context_storage_.back());
  if (needs_tree_builder_context_update)
    GeometryMapper::ClearCache();

  VisualViewportPaintPropertyTreeBuilder::Update(
      root_frame_view.GetPage()->GetVisualViewport(),
      *context_storage_.back().tree_builder_context);

  Walk(root_frame_view);
  paint_invalidator_.ProcessPendingDelayedPaintInvalidations();
  context_storage_.pop_back();

#if DCHECK_IS_ON()
  if (!needs_tree_builder_context_update)
    return;
  if (VLOG_IS_ON(2) && root_frame_view.GetLayoutView()) {
    LOG(ERROR) << "PrePaintTreeWalk::Walk(root_frame_view=" << &root_frame_view
               << ")\nPaintLayer tree:";
    showLayerTree(root_frame_view.GetLayoutView()->Layer());
  }
  if (VLOG_IS_ON(1))
    showAllPropertyTrees(root_frame_view);
#endif
}

void PrePaintTreeWalk::Walk(LocalFrameView& frame_view) {
  if (frame_view.ShouldThrottleRendering()) {
    // Skip the throttled frame. Will update it when it becomes unthrottled.
    return;
  }

  // We need to be careful not to have a reference to the parent context, since
  // this reference will be to the context_storage_ memory which may be
  // reallocated during this function call.
  wtf_size_t parent_context_index = context_storage_.size() - 1;
  auto parent_context = [this,
                         parent_context_index]() -> PrePaintTreeWalkContext& {
    return context_storage_[parent_context_index];
  };

  bool needs_tree_builder_context_update =
      NeedsTreeBuilderContextUpdate(frame_view, parent_context());

  // Note that because we're emplacing an object constructed from
  // parent_context() (which is a reference to the vector itself), it's
  // important to first ensure that there's sufficient capacity in the vector.
  // Otherwise, it may reallocate causing parent_context() to point to invalid
  // memory.
  ResizeContextStorageIfNeeded();
  context_storage_.emplace_back(parent_context(),
                                PaintInvalidatorContext::ParentContextAccessor(
                                    this, parent_context_index),
                                needs_tree_builder_context_update);
  auto context = [this]() -> PrePaintTreeWalkContext& {
    return context_storage_.back();
  };

  // ancestor_overflow_paint_layer does not cross frame boundaries.
  context().ancestor_overflow_paint_layer = nullptr;
  if (context().tree_builder_context) {
    PaintPropertyTreeBuilder::SetupContextForFrame(
        frame_view, *context().tree_builder_context);
  }
  paint_invalidator_.InvalidatePaint(
      frame_view, base::OptionalOrNullptr(context().tree_builder_context),
      context().paint_invalidator_context);
  if (context().tree_builder_context) {
    context().tree_builder_context->supports_composited_raster_invalidation =
        frame_view.GetFrame().GetSettings()->GetAcceleratedCompositingEnabled();
  }

  if (LayoutView* view = frame_view.GetLayoutView()) {
#ifndef NDEBUG
    if (VLOG_IS_ON(3) && needs_tree_builder_context_update) {
      LOG(ERROR) << "PrePaintTreeWalk::Walk(frame_view=" << &frame_view
                 << ")\nLayout tree:";
      showLayoutTree(view);
    }
#endif

    Walk(*view);
#if DCHECK_IS_ON()
    view->AssertSubtreeClearedPaintInvalidationFlags();
#endif
  }

  if (RuntimeEnabledFeatures::JankTrackingEnabled())
    frame_view.GetJankTracker().NotifyPrePaintFinished();
  if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled()) {
    frame_view.GetPaintTimingDetector().NotifyPrePaintFinished();
  }

  context_storage_.pop_back();
}

bool PrePaintTreeWalk::NeedsEffectiveWhitelistedTouchActionUpdate(
    const LayoutObject& object,
    PrePaintTreeWalk::PrePaintTreeWalkContext& context) const {
  if (!RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
    return false;
  return context.effective_whitelisted_touch_action_changed ||
         object.EffectiveWhitelistedTouchActionChanged() ||
         object.DescendantEffectiveWhitelistedTouchActionChanged();
}

namespace {
bool HasBlockingTouchEventHandler(const LocalFrame& frame,
                                  EventTarget& target) {
  if (!target.HasEventListeners())
    return false;
  const auto& registry = frame.GetEventHandlerRegistry();
  const auto* blocking = registry.EventHandlerTargets(
      EventHandlerRegistry::kTouchStartOrMoveEventBlocking);
  const auto* blocking_low_latency = registry.EventHandlerTargets(
      EventHandlerRegistry::kTouchStartOrMoveEventBlockingLowLatency);
  return blocking->Contains(&target) || blocking_low_latency->Contains(&target);
}

bool HasBlockingTouchEventHandler(const LayoutObject& object) {
  if (object.IsLayoutView()) {
    auto* frame = object.GetFrame();
    if (HasBlockingTouchEventHandler(*frame, *frame->DomWindow()))
      return true;
  }

  auto* node = object.GetNode();
  if (!node && object.IsLayoutBlockFlow() &&
      ToLayoutBlockFlow(object).IsAnonymousBlockContinuation()) {
    // An anonymous continuation does not have handlers so we need to check the
    // DOM ancestor for handlers using |NodeForHitTest|.
    node = object.NodeForHitTest();
  }
  if (!node)
    return false;
  return HasBlockingTouchEventHandler(*object.GetFrame(), *node);
}
}  // namespace

void PrePaintTreeWalk::UpdateEffectiveWhitelistedTouchAction(
    const LayoutObject& object,
    PrePaintTreeWalk::PrePaintTreeWalkContext& context) {
  if (!RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
    return;

  if (object.EffectiveWhitelistedTouchActionChanged())
    context.effective_whitelisted_touch_action_changed = true;

  if (context.effective_whitelisted_touch_action_changed) {
    object.GetMutableForPainting().UpdateInsideBlockingTouchEventHandler(
        context.inside_blocking_touch_event_handler ||
        HasBlockingTouchEventHandler(object));
  }

  if (object.InsideBlockingTouchEventHandler())
    context.inside_blocking_touch_event_handler = true;
}

bool PrePaintTreeWalk::NeedsHitTestingPaintInvalidation(
    const LayoutObject& object,
    const PrePaintTreeWalk::PrePaintTreeWalkContext& context) const {
  if (!RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
    return false;
  return context.effective_whitelisted_touch_action_changed;
}

void PrePaintTreeWalk::InvalidatePaintForHitTesting(
    const LayoutObject& object,
    PrePaintTreeWalk::PrePaintTreeWalkContext& context) {
  if (!RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
    return;

  if (context.effective_whitelisted_touch_action_changed) {
    if (auto* paint_layer = context.paint_invalidator_context.painting_layer)
      paint_layer->SetNeedsRepaint();
    ObjectPaintInvalidator(object).InvalidateDisplayItemClient(
        object, PaintInvalidationReason::kHitTest);
  }
}

void PrePaintTreeWalk::UpdateAuxiliaryObjectProperties(
    const LayoutObject& object,
    PrePaintTreeWalk::PrePaintTreeWalkContext& context) {
  if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
    return;

  if (!object.HasLayer())
    return;

  PaintLayer* paint_layer = ToLayoutBoxModelObject(object).Layer();
  paint_layer->UpdateAncestorOverflowLayer(
      context.ancestor_overflow_paint_layer);

  if (object.StyleRef().HasStickyConstrainedPosition()) {
    paint_layer->GetLayoutObject().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).
    paint_layer->UpdateLayerPosition();
  }
  if (paint_layer->IsRootLayer() || object.HasOverflowClip())
    context.ancestor_overflow_paint_layer = paint_layer;
}

void PrePaintTreeWalk::InvalidatePaintLayerOptimizationsIfNeeded(
    const LayoutObject& object,
    PrePaintTreeWalkContext& context) {
  if (!object.HasLayer())
    return;

  PaintLayer& paint_layer = *ToLayoutBoxModelObject(object).Layer();

  if (!context.tree_builder_context->clip_changed)
    return;

  paint_layer.SetNeedsRepaint();
}

bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate(
    const LocalFrameView& frame_view,
    const PrePaintTreeWalkContext& context) {
  if ((RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() ||
       RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) &&
      frame_view.GetFrame().IsLocalRoot() &&
      frame_view.GetPage()->GetVisualViewport().NeedsPaintPropertyUpdate())
    return true;

  return frame_view.GetLayoutView() &&
         NeedsTreeBuilderContextUpdate(*frame_view.GetLayoutView(), context);
}

bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate(
    const LayoutObject& object,
    const PrePaintTreeWalkContext& parent_context) {
  if (parent_context.tree_builder_context &&
      parent_context.tree_builder_context->force_subtree_update_reasons) {
    return true;
  }
  // The following CHECKs are for debugging crbug.com/816810.
  if (object.NeedsPaintPropertyUpdate()) {
    CHECK(parent_context.tree_builder_context) << "NeedsPaintPropertyUpdate";
    return true;
  }
  if (object.DescendantNeedsPaintPropertyUpdate()) {
    CHECK(parent_context.tree_builder_context)
        << "DescendantNeedsPaintPropertyUpdate";
    return true;
  }
  if (object.DescendantNeedsPaintOffsetAndVisualRectUpdate()) {
    CHECK(parent_context.tree_builder_context)
        << "DescendantNeedsPaintOffsetAndVisualRectUpdate";
    return true;
  }
  if (parent_context.paint_invalidator_context.NeedsVisualRectUpdate(object)) {
    // If the object needs visual rect update, we should update tree
    // builder context which is needed by visual rect update.
    if (object.NeedsPaintOffsetAndVisualRectUpdate()) {
      CHECK(parent_context.tree_builder_context)
          << "NeedsPaintOffsetAndVisualRectUpdate";
    } else {
      CHECK(parent_context.tree_builder_context) << "kSubtreeVisualRectUpdate";
    }
    return true;
  }
  return false;
}

void PrePaintTreeWalk::WalkInternal(const LayoutObject& object,
                                    PrePaintTreeWalkContext& context) {
  PaintInvalidatorContext& paint_invalidator_context =
      context.paint_invalidator_context;

  // This must happen before updatePropertiesForSelf, because the latter reads
  // some of the state computed here.
  UpdateAuxiliaryObjectProperties(object, context);

  base::Optional<PaintPropertyTreeBuilder> property_tree_builder;
  bool property_changed = false;
  if (context.tree_builder_context) {
    property_tree_builder.emplace(object, *context.tree_builder_context);
    property_changed = property_tree_builder->UpdateForSelf();

    if (property_changed && !context.tree_builder_context
                                 ->supports_composited_raster_invalidation) {
      paint_invalidator_context.subtree_flags |=
          PaintInvalidatorContext::kSubtreeFullInvalidation;
    }
  }

  // This must happen before paint invalidation because background painting
  // depends on the effective whitelisted touch action.
  UpdateEffectiveWhitelistedTouchAction(object, context);

  paint_invalidator_.InvalidatePaint(
      object, base::OptionalOrNullptr(context.tree_builder_context),
      paint_invalidator_context);

  InvalidatePaintForHitTesting(object, context);

  if (context.tree_builder_context) {
    property_changed |= property_tree_builder->UpdateForChildren();
    InvalidatePaintLayerOptimizationsIfNeeded(object, context);

    if (property_changed) {
      if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
        const auto* paint_invalidation_layer =
            paint_invalidator_context.paint_invalidation_container->Layer();
        if (!paint_invalidation_layer->NeedsRepaint()) {
          auto* mapping = paint_invalidation_layer->GetCompositedLayerMapping();
          if (!mapping)
            mapping = paint_invalidation_layer->GroupedMapping();
          if (mapping)
            mapping->SetNeedsCheckRasterInvalidation();
        }
      } else if (!context.tree_builder_context
                      ->supports_composited_raster_invalidation) {
        paint_invalidator_context.subtree_flags |=
            PaintInvalidatorContext::kSubtreeFullInvalidation;
      }
    }
  }

  CompositingLayerPropertyUpdater::Update(object);

  if (RuntimeEnabledFeatures::JankTrackingEnabled()) {
    object.GetFrameView()->GetJankTracker().NotifyObjectPrePaint(
        object, paint_invalidator_context.old_visual_rect,
        *paint_invalidator_context.painting_layer);
  }
  if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled()) {
    object.GetFrameView()->GetPaintTimingDetector().NotifyObjectPrePaint(
        object, *paint_invalidator_context.painting_layer);
  }
}

void PrePaintTreeWalk::Walk(const LayoutObject& object) {
  if (object.PrePaintBlockedByDisplayLock())
    return;
  // TODO(vmpstr): Technically we should do this after prepaint finishes, but
  // due to a possible early out this is more convenient. We should change this
  // to RAII.
  object.NotifyDisplayLockDidPrePaint();

  // We need to be careful not to have a reference to the parent context, since
  // this reference will be to the context_storage_ memory which may be
  // reallocated during this function call.
  wtf_size_t parent_context_index = context_storage_.size() - 1;
  auto parent_context = [this,
                         parent_context_index]() -> PrePaintTreeWalkContext& {
    return context_storage_[parent_context_index];
  };

  bool needs_tree_builder_context_update =
      NeedsTreeBuilderContextUpdate(object, parent_context());
  // Early out from the tree walk if possible.
  if (!needs_tree_builder_context_update &&
      !object.ShouldCheckForPaintInvalidation() &&
      !parent_context().paint_invalidator_context.NeedsSubtreeWalk() &&
      !NeedsEffectiveWhitelistedTouchActionUpdate(object, parent_context()) &&
      !NeedsHitTestingPaintInvalidation(object, parent_context())) {
    return;
  }

  // Note that because we're emplacing an object constructed from
  // parent_context() (which is a reference to the vector itself), it's
  // important to first ensure that there's sufficient capacity in the vector.
  // Otherwise, it may reallocate causing parent_context() to point to invalid
  // memory.
  ResizeContextStorageIfNeeded();
  context_storage_.emplace_back(parent_context(),
                                PaintInvalidatorContext::ParentContextAccessor(
                                    this, parent_context_index),
                                needs_tree_builder_context_update);
  auto context = [this]() -> PrePaintTreeWalkContext& {
    return context_storage_.back();
  };

  // Ignore clip changes from ancestor across transform boundaries.
  if (context().tree_builder_context && object.StyleRef().HasTransform())
    context().tree_builder_context->clip_changed = false;

  WalkInternal(object, context());

  for (const LayoutObject* child = object.SlowFirstChild(); child;
       child = child->NextSibling()) {
    if (child->IsLayoutMultiColumnSpannerPlaceholder()) {
      child->GetMutableForPainting().ClearPaintFlags();
      continue;
    }
    Walk(*child);
  }

  if (object.IsLayoutEmbeddedContent()) {
    const LayoutEmbeddedContent& layout_embedded_content =
        ToLayoutEmbeddedContent(object);
    FrameView* frame_view = layout_embedded_content.ChildFrameView();
    if (frame_view && frame_view->IsLocalFrameView()) {
      LocalFrameView* local_frame_view = ToLocalFrameView(frame_view);
      if (context().tree_builder_context) {
        context().tree_builder_context->fragments[0].current.paint_offset +=
            layout_embedded_content.ReplacedContentRect().Location() -
            local_frame_view->FrameRect().Location();
        context()
            .tree_builder_context->fragments[0]
            .current.paint_offset = RoundedIntPoint(
            context().tree_builder_context->fragments[0].current.paint_offset);
      }
      Walk(*local_frame_view);
    }
    // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281).
  }

  // Because current |PrePaintTreeWalk| walks LayoutObject tree, NGPaintFragment
  // that are not mapped to LayoutObject are not updated. Ensure they are
  // updated after all descendants were updated.
  if (RuntimeEnabledFeatures::LayoutNGEnabled() && object.IsLayoutNGMixin()) {
    if (NGPaintFragment* fragment = ToLayoutBlockFlow(object).PaintFragment())
      fragment->UpdateVisualRectForNonLayoutObjectChildren();
  }

  object.GetMutableForPainting().ClearPaintFlags();
  context_storage_.pop_back();
}

void PrePaintTreeWalk::ResizeContextStorageIfNeeded() {
  if (UNLIKELY(context_storage_.size() == context_storage_.capacity())) {
    DCHECK_GT(context_storage_.size(), 0u);
    context_storage_.ReserveCapacity(context_storage_.size() * 2);
  }
}

}  // namespace blink
