// Copyright 2016 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 "core/paint/BoxPaintInvalidator.h"

#include "core/frame/Settings.h"
#include "core/layout/LayoutView.h"
#include "core/paint/ObjectPaintInvalidator.h"
#include "core/paint/PaintInvalidator.h"
#include "core/paint/PaintLayer.h"
#include "core/paint/PaintLayerScrollableArea.h"
#include "platform/geometry/LayoutRect.h"

namespace blink {

struct PreviousBoxSizes {
  LayoutSize borderBoxSize;
  LayoutRect contentBoxRect;
  LayoutRect layoutOverflowRect;
};

typedef HashMap<const LayoutBox*, PreviousBoxSizes> PreviousBoxSizesMap;
static PreviousBoxSizesMap& previousBoxSizesMap() {
  DEFINE_STATIC_LOCAL(PreviousBoxSizesMap, map, ());
  return map;
}

void BoxPaintInvalidator::boxWillBeDestroyed(const LayoutBox& box) {
  previousBoxSizesMap().remove(&box);
}

bool BoxPaintInvalidator::incrementallyInvalidatePaint() {
  bool result = ObjectPaintInvalidatorWithContext(m_box, m_context)
                    .incrementallyInvalidatePaint();

  bool hasBoxDecorations = m_box.styleRef().hasBoxDecorations();
  if (!m_box.styleRef().hasBackground() && !hasBoxDecorations)
    return result;

  const LayoutRect& oldBounds = m_context.oldBounds;
  const LayoutRect& newBounds = m_context.newBounds;

  LayoutSize oldBorderBoxSize = computePreviousBorderBoxSize(oldBounds.size());
  LayoutSize newBorderBoxSize = m_box.size();

  // If border m_box size didn't change,
  // ObjectPaintInvalidatorWithContext::incrementallyInvalidatePaint() is good.
  if (oldBorderBoxSize == newBorderBoxSize)
    return result;

  // If size of the paint invalidation rect equals to size of border box,
  // ObjectPaintInvalidatorWithContext::incrementallyInvalidatePaint()
  // is good for boxes having background without box decorations.
  DCHECK(
      oldBounds.location() ==
      newBounds.location());  // Otherwise we won't do incremental invalidation.
  if (!hasBoxDecorations && m_context.newLocation == newBounds.location() &&
      oldBorderBoxSize == oldBounds.size() &&
      newBorderBoxSize == newBounds.size())
    return result;

  // Invalidate the right delta part and the right border of the old or new
  // m_box which has smaller width.
  if (LayoutUnit deltaWidth =
          (oldBorderBoxSize.width() - newBorderBoxSize.width()).abs()) {
    LayoutUnit smallerWidth =
        std::min(oldBorderBoxSize.width(), newBorderBoxSize.width());
    LayoutUnit borderTopRightRadiusWidth = valueForLength(
        m_box.styleRef().borderTopRightRadius().width(), smallerWidth);
    LayoutUnit borderBottomRightRadiusWidth = valueForLength(
        m_box.styleRef().borderBottomRightRadius().width(), smallerWidth);
    LayoutUnit borderWidth = std::max(
        LayoutUnit(m_box.borderRight()),
        std::max(borderTopRightRadiusWidth, borderBottomRightRadiusWidth));
    LayoutRect rightDeltaRect(
        m_context.newLocation.x() + smallerWidth - borderWidth,
        m_context.newLocation.y(), deltaWidth + borderWidth,
        std::max(oldBorderBoxSize.height(), newBorderBoxSize.height()));
    invalidatePaintRectClippedByOldAndNewBounds(rightDeltaRect);
  }

  // Invalidate the bottom delta part and the bottom border of the old or new
  // m_box which has smaller height.
  if (LayoutUnit deltaHeight =
          (oldBorderBoxSize.height() - newBorderBoxSize.height()).abs()) {
    LayoutUnit smallerHeight =
        std::min(oldBorderBoxSize.height(), newBorderBoxSize.height());
    LayoutUnit borderBottomLeftRadiusHeight = valueForLength(
        m_box.styleRef().borderBottomLeftRadius().height(), smallerHeight);
    LayoutUnit borderBottomRightRadiusHeight = valueForLength(
        m_box.styleRef().borderBottomRightRadius().height(), smallerHeight);
    LayoutUnit borderHeight = std::max(
        LayoutUnit(m_box.borderBottom()),
        std::max(borderBottomLeftRadiusHeight, borderBottomRightRadiusHeight));
    LayoutRect bottomDeltaRect(
        m_context.newLocation.x(),
        m_context.newLocation.y() + smallerHeight - borderHeight,
        std::max(oldBorderBoxSize.width(), newBorderBoxSize.width()),
        deltaHeight + borderHeight);
    invalidatePaintRectClippedByOldAndNewBounds(bottomDeltaRect);
  }

  return true;
}

void BoxPaintInvalidator::invalidatePaintRectClippedByOldAndNewBounds(
    const LayoutRect& rect) {
  if (rect.isEmpty())
    return;

  ObjectPaintInvalidator objectPaintInvalidator(m_box);
  LayoutRect rectClippedByOldBounds = intersection(rect, m_context.oldBounds);
  LayoutRect rectClippedByNewBounds = intersection(rect, m_context.newBounds);
  // Invalidate only once if the clipped rects equal.
  if (rectClippedByOldBounds == rectClippedByNewBounds) {
    objectPaintInvalidator.invalidatePaintUsingContainer(
        *m_context.paintInvalidationContainer, rectClippedByOldBounds,
        PaintInvalidationIncremental);
    return;
  }
  // Invalidate the bigger one if one contains another. Otherwise invalidate
  // both.
  if (!rectClippedByNewBounds.contains(rectClippedByOldBounds))
    objectPaintInvalidator.invalidatePaintUsingContainer(
        *m_context.paintInvalidationContainer, rectClippedByOldBounds,
        PaintInvalidationIncremental);
  if (!rectClippedByOldBounds.contains(rectClippedByNewBounds))
    objectPaintInvalidator.invalidatePaintUsingContainer(
        *m_context.paintInvalidationContainer, rectClippedByNewBounds,
        PaintInvalidationIncremental);
}

PaintInvalidationReason BoxPaintInvalidator::computePaintInvalidationReason() {
  PaintInvalidationReason reason =
      ObjectPaintInvalidatorWithContext(m_box, m_context)
          .computePaintInvalidationReason();

  if (isImmediateFullPaintInvalidationReason(reason) ||
      reason == PaintInvalidationNone)
    return reason;

  if (m_box.mayNeedPaintInvalidationAnimatedBackgroundImage() &&
      !m_box.backgroundIsKnownToBeObscured())
    reason = PaintInvalidationDelayedFull;

  // If the current paint invalidation reason is PaintInvalidationDelayedFull,
  // then this paint invalidation can delayed if the LayoutBox in question is
  // not on-screen. The logic to decide whether this is appropriate exists at
  // the site of the original paint invalidation that chose
  // PaintInvalidationDelayedFull.
  if (reason == PaintInvalidationDelayedFull) {
    // Do regular full paint invalidation if the object is onscreen.
    return m_box.intersectsVisibleViewport() ? PaintInvalidationFull
                                             : PaintInvalidationDelayedFull;
  }

  if (m_box.isLayoutView()) {
    const LayoutView& layoutView = toLayoutView(m_box);
    // In normal compositing mode, root background doesn't need to be
    // invalidated for box changes, because the background always covers the
    // whole document rect and clipping is done by
    // compositor()->m_containerLayer. Also the scrollbars are always
    // composited. There are no other box decoration on the LayoutView thus we
    // can safely exit here.
    if (layoutView.usesCompositing() &&
        !RuntimeEnabledFeatures::rootLayerScrollingEnabled())
      return reason;
  }

  // If the transform is not identity or translation, incremental invalidation
  // is not applicable because the difference between oldBounds and newBounds
  // doesn't cover all area needing invalidation.
  // FIXME: Should also consider ancestor transforms since
  // paintInvalidationContainer. crbug.com/426111.
  if (reason == PaintInvalidationIncremental &&
      m_context.oldBounds != m_context.newBounds &&
      m_context.paintInvalidationContainer != m_box && m_box.hasLayer() &&
      m_box.layer()->transform() &&
      !m_box.layer()->transform()->isIdentityOrTranslation())
    return PaintInvalidationBoundsChange;

  const ComputedStyle& style = m_box.styleRef();
  if (style.backgroundLayers().thisOrNextLayersUseContentBox() ||
      style.maskLayers().thisOrNextLayersUseContentBox() ||
      style.boxSizing() == BoxSizingBorderBox) {
    if (previousBoxSizesMap().get(&m_box).contentBoxRect !=
        m_box.contentBoxRect())
      return PaintInvalidationContentBoxChange;
  }

  if (!style.hasBackground() && !style.hasBoxDecorations()) {
    // We could let incremental invalidation cover non-composited scrollbars,
    // but just do a full invalidation because incremental invalidation will go
    // away with slimming paint.
    if (reason == PaintInvalidationIncremental &&
        m_context.oldBounds != m_context.newBounds &&
        m_box.hasNonCompositedScrollbars())
      return PaintInvalidationBorderBoxChange;
    return reason;
  }

  if (style.backgroundLayers().thisOrNextLayersHaveLocalAttachment()) {
    if (previousBoxSizesMap().get(&m_box).layoutOverflowRect !=
        m_box.layoutOverflowRect())
      return PaintInvalidationLayoutOverflowBoxChange;
  }

  LayoutSize oldBorderBoxSize =
      computePreviousBorderBoxSize(m_context.oldBounds.size());
  LayoutSize newBorderBoxSize = m_box.size();

  if (oldBorderBoxSize == newBorderBoxSize)
    return reason;

  // See another hasNonCompositedScrollbars() callsite above.
  if (m_box.hasNonCompositedScrollbars())
    return PaintInvalidationBorderBoxChange;

  if (style.hasVisualOverflowingEffect() || style.hasAppearance() ||
      style.hasFilterInducingProperty() || style.resize() != RESIZE_NONE)
    return PaintInvalidationBorderBoxChange;

  if (style.hasBorderRadius()) {
    // If a border-radius exists and width/height is smaller than radius
    // width/height, we need to fully invalidate to cover the changed radius.
    FloatRoundedRect oldRoundedRect = style.getRoundedBorderFor(
        LayoutRect(LayoutPoint(0, 0), oldBorderBoxSize));
    FloatRoundedRect newRoundedRect = style.getRoundedBorderFor(
        LayoutRect(LayoutPoint(0, 0), newBorderBoxSize));
    if (oldRoundedRect.getRadii() != newRoundedRect.getRadii())
      return PaintInvalidationBorderBoxChange;
  }

  if (oldBorderBoxSize.width() != newBorderBoxSize.width() &&
      m_box.mustInvalidateBackgroundOrBorderPaintOnWidthChange())
    return PaintInvalidationBorderBoxChange;
  if (oldBorderBoxSize.height() != newBorderBoxSize.height() &&
      m_box.mustInvalidateBackgroundOrBorderPaintOnHeightChange())
    return PaintInvalidationBorderBoxChange;

  return reason;
}

PaintInvalidationReason BoxPaintInvalidator::invalidatePaintIfNeeded() {
  PaintInvalidationReason reason = computePaintInvalidationReason();
  if (reason == PaintInvalidationIncremental) {
    if (incrementallyInvalidatePaint()) {
      m_context.paintingLayer->setNeedsRepaint();
      m_box.invalidateDisplayItemClients(reason);
    } else {
      reason = PaintInvalidationNone;
    }
    // Though we have done our own version of incremental invalidation, we still
    // need to call ObjectPaintInvalidator with PaintInvalidationNone to do any
    // other required operations.
    reason = std::max(
        reason,
        ObjectPaintInvalidatorWithContext(m_box, m_context)
            .invalidatePaintIfNeededWithComputedReason(PaintInvalidationNone));
  } else {
    reason = ObjectPaintInvalidatorWithContext(m_box, m_context)
                 .invalidatePaintIfNeededWithComputedReason(reason);
  }

  if (PaintLayerScrollableArea* area = m_box.getScrollableArea())
    area->invalidatePaintOfScrollControlsIfNeeded(m_context);

  // This is for the next invalidatePaintIfNeeded so must be at the end.
  savePreviousBoxSizesIfNeeded();

  return reason;
}

bool BoxPaintInvalidator::needsToSavePreviousBoxSizes() {
  LayoutSize paintInvalidationSize = m_context.newBounds.size();
  // Don't save old box sizes if the paint rect is empty because we'll
  // full invalidate once the paint rect becomes non-empty.
  if (paintInvalidationSize.isEmpty())
    return false;

  const ComputedStyle& style = m_box.styleRef();

  // If we use border-box sizing we need to track changes in the size of the
  // content box.
  if (style.boxSizing() == BoxSizingBorderBox)
    return true;

  // We need the old box sizes only when the box has background, decorations, or
  // masks.
  // Main LayoutView paints base background, thus interested in box size.
  if (!m_box.isLayoutView() && !style.hasBackground() &&
      !style.hasBoxDecorations() && !style.hasMask())
    return false;

  // No need to save old border box size if we can use size of the old paint
  // rect as the old border box size in the next invalidation.
  if (paintInvalidationSize != m_box.size())
    return true;

  // Background and mask layers can depend on other boxes than border box. See
  // crbug.com/490533
  if (style.backgroundLayers().thisOrNextLayersUseContentBox() ||
      style.backgroundLayers().thisOrNextLayersHaveLocalAttachment() ||
      style.maskLayers().thisOrNextLayersUseContentBox())
    return true;

  return false;
}

void BoxPaintInvalidator::savePreviousBoxSizesIfNeeded() {
  if (!needsToSavePreviousBoxSizes()) {
    previousBoxSizesMap().remove(&m_box);
    return;
  }

  PreviousBoxSizes sizes = {m_box.size(), m_box.contentBoxRect(),
                            m_box.layoutOverflowRect()};
  previousBoxSizesMap().set(&m_box, sizes);
}

LayoutSize BoxPaintInvalidator::computePreviousBorderBoxSize(
    const LayoutSize& previousBoundsSize) {
  // PreviousBorderBoxSize is only valid when there is background or box
  // decorations.
  DCHECK(m_box.styleRef().hasBackground() ||
         m_box.styleRef().hasBoxDecorations());

  auto it = previousBoxSizesMap().find(&m_box);
  if (it != previousBoxSizesMap().end())
    return it->value.borderBoxSize;

  // We didn't save the old border box size because it was the same as the size
  // of oldBounds.
  return previousBoundsSize;
}

}  // namespace blink
