// 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/platform/graphics/paint/paint_chunker.h"

#include "cc/base/features.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h"

namespace blink {

void PaintChunker::ResetChunks(Vector<PaintChunk>* chunks) {
  if (chunks_) {
    FinalizeLastChunkProperties();
    SetWillForceNewChunk(true);
    current_properties_ = PropertyTreeState::Uninitialized();
  }
  chunks_ = chunks;
#if DCHECK_IS_ON()
  DCHECK(!chunks || chunks->IsEmpty());
  DCHECK(IsInInitialState());
#endif
}

#if DCHECK_IS_ON()
bool PaintChunker::IsInInitialState() const {
  if (current_properties_ != PropertyTreeState::Uninitialized())
    return false;
  DCHECK_EQ(candidate_background_color_.Rgb(), Color::kTransparent);
  DCHECK_EQ(candidate_background_area_, 0u);
  DCHECK(will_force_new_chunk_);
  DCHECK(!chunks_ || chunks_->IsEmpty());
  return true;
}
#endif

void PaintChunker::UpdateCurrentPaintChunkProperties(
    const PaintChunk::Id* chunk_id,
    const PropertyTreeStateOrAlias& properties) {
  // If properties are the same, continue to use the previously set
  // |next_chunk_id_| because the id of the outer painting is likely to be
  // more stable to reduce invalidation because of chunk id changes.
  if (!next_chunk_id_ || current_properties_ != properties) {
    if (chunk_id)
      next_chunk_id_.emplace(*chunk_id);
    else
      next_chunk_id_ = base::nullopt;
  }
  current_properties_ = properties;
}

void PaintChunker::AppendByMoving(PaintChunk&& chunk) {
  DCHECK(chunks_);
  FinalizeLastChunkProperties();
  wtf_size_t next_chunk_begin_index =
      chunks_->IsEmpty() ? 0 : chunks_->back().end_index;
  chunks_->emplace_back(next_chunk_begin_index, std::move(chunk));
}

bool PaintChunker::EnsureCurrentChunk(const PaintChunk::Id& id) {
#if DCHECK_IS_ON()
  DCHECK(chunks_);
  // If this DCHECKs are hit we are missing a call to update the properties.
  // See: ScopedPaintChunkProperties.
  DCHECK(!IsInInitialState());
  // At this point we should have all of the properties given to us.
  DCHECK(current_properties_.IsInitialized());
#endif

  if (WillForceNewChunk() ||
      current_properties_ != chunks_->back().properties) {
    if (!next_chunk_id_)
      next_chunk_id_.emplace(id);
    FinalizeLastChunkProperties();
    wtf_size_t begin = chunks_->IsEmpty() ? 0 : chunks_->back().end_index;
    chunks_->emplace_back(begin, begin, *next_chunk_id_, current_properties_);
    next_chunk_id_ = base::nullopt;
    will_force_new_chunk_ = false;
    return true;
  }
  return false;
}

bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) {
  DCHECK(chunks_);

  bool item_forces_new_chunk = item.IsForeignLayer() || item.IsScrollbar();
  if (item_forces_new_chunk)
    SetWillForceNewChunk(true);

  bool created_new_chunk = EnsureCurrentChunk(item.GetId());
  auto& chunk = chunks_->back();

  chunk.bounds.Unite(item.VisualRect());
  if (item.DrawsContent())
    chunk.drawable_bounds.Unite(item.VisualRect());

  // If this paints the background and it's larger than our current candidate,
  // set the candidate to be this item.
  if (item.IsDrawing() && item.DrawsContent()) {
    float item_area;
    Color item_color =
        static_cast<const DrawingDisplayItem&>(item).BackgroundColor(item_area);
    ProcessBackgroundColorCandidate(chunk.id, item_color, item_area);
  }

  constexpr wtf_size_t kMaxRegionComplexity = 10;
  if (should_compute_contents_opaque_ && item.IsDrawing()) {
    const DrawingDisplayItem& drawing =
        static_cast<const DrawingDisplayItem&>(item);
    if (drawing.KnownToBeOpaque() &&
        last_chunk_known_to_be_opaque_region_.Complexity() <
            kMaxRegionComplexity) {
      last_chunk_known_to_be_opaque_region_.Unite(item.VisualRect());
    }
    if (last_chunk_text_known_to_be_on_opaque_background_) {
      if (const auto* paint_record = drawing.GetPaintRecord().get()) {
        if (paint_record->has_draw_text_ops()) {
          last_chunk_text_known_to_be_on_opaque_background_ =
              last_chunk_known_to_be_opaque_region_.Contains(item.VisualRect());
        }
      }
    }
  }

  chunk.raster_effect_outset =
      std::max(chunk.raster_effect_outset, item.GetRasterEffectOutset());

  chunk.end_index++;

  // When forcing a new chunk, we still need to force new chunk for the next
  // display item. Otherwise reset force_new_chunk_ to false.
  DCHECK(!will_force_new_chunk_);
  if (item_forces_new_chunk) {
    DCHECK(created_new_chunk);
    SetWillForceNewChunk(true);
  }

  return created_new_chunk;
}

bool PaintChunker::AddHitTestDataToCurrentChunk(const PaintChunk::Id& id,
                                                const IntRect& rect,
                                                TouchAction touch_action,
                                                bool blocking_wheel) {
  // In CompositeAfterPaint, we ensure a paint chunk for correct composited
  // hit testing. In pre-CompositeAfterPaint, this is unnecessary, except that
  // there is special touch action or blocking wheel event handler, and that we
  // have a non-root effect so that PaintChunksToCcLayer will emit paint
  // operations for filters.
  if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
      touch_action == TouchAction::kAuto && !blocking_wheel &&
      &current_properties_.Effect() == &EffectPaintPropertyNode::Root())
    return false;

  bool created_new_chunk = EnsureCurrentChunk(id);
  auto& chunk = chunks_->back();
  chunk.bounds.Unite(rect);
  if (touch_action != TouchAction::kAuto) {
    chunk.EnsureHitTestData().touch_action_rects.push_back(
        TouchActionRect{rect, touch_action});
  }
  if (blocking_wheel) {
    DCHECK(base::FeatureList::IsEnabled(::features::kWheelEventRegions));
    chunk.EnsureHitTestData().wheel_event_rects.push_back(rect);
  }
  return created_new_chunk;
}

void PaintChunker::AddSelectionToCurrentChunk(
    base::Optional<PaintedSelectionBound> start,
    base::Optional<PaintedSelectionBound> end) {
  // We should have painted the selection when calling this method.
  DCHECK(chunks_);
  DCHECK(!chunks_->IsEmpty());

  auto& chunk = chunks_->back();

#if DCHECK_IS_ON()
  if (start) {
    IntRect edge_rect(start->edge_start, start->edge_end - start->edge_start);
    DCHECK(chunk.bounds.Contains(edge_rect));
  }

  if (end) {
    IntRect edge_rect(end->edge_start, end->edge_end - end->edge_start);
    DCHECK(chunk.bounds.Contains(edge_rect));
  }
#endif

  LayerSelectionData& selection_data = chunk.EnsureLayerSelectionData();
  if (start) {
    DCHECK(!selection_data.start);
    selection_data.start = start;
  }

  if (end) {
    DCHECK(!selection_data.end);
    selection_data.end = end;
  }
}

void PaintChunker::CreateScrollHitTestChunk(
    const PaintChunk::Id& id,
    const TransformPaintPropertyNode* scroll_translation,
    const IntRect& rect) {
#if DCHECK_IS_ON()
  if (id.type == DisplayItem::Type::kResizerScrollHitTest ||
      id.type == DisplayItem::Type::kPluginScrollHitTest ||
      id.type == DisplayItem::Type::kCustomScrollbarHitTest) {
    // Resizer and plugin scroll hit tests are only used to prevent composited
    // scrolling and should not have a scroll offset node.
    DCHECK(!scroll_translation);
  } else if (id.type == DisplayItem::Type::kScrollHitTest) {
    DCHECK(scroll_translation);
    // The scroll offset transform node should have an associated scroll node.
    DCHECK(scroll_translation->ScrollNode());
  } else {
    NOTREACHED();
  }
#endif

  SetWillForceNewChunk(true);
  bool created_new_chunk = EnsureCurrentChunk(id);
  DCHECK(created_new_chunk);

  auto& chunk = chunks_->back();
  chunk.bounds.Unite(rect);
  auto& hit_test_data = chunk.EnsureHitTestData();
  hit_test_data.scroll_translation = scroll_translation;
  hit_test_data.scroll_hit_test_rect = rect;
  SetWillForceNewChunk(true);
}

bool PaintChunker::ProcessBackgroundColorCandidate(const PaintChunk::Id& id,
                                                   Color color,
                                                   float area) {
  if (color == Color::kTransparent)
    return false;

  bool created_new_chunk = EnsureCurrentChunk(id);
  float min_background_area = kMinBackgroundColorCoverageRatio *
                              chunks_->back().bounds.Width() *
                              chunks_->back().bounds.Height();
  if (created_new_chunk || area >= candidate_background_area_ ||
      area >= min_background_area) {
    candidate_background_color_ =
        candidate_background_area_ >= min_background_area
            ? candidate_background_color_.Blend(color)
            : color;
    candidate_background_area_ = area;
  }
  return created_new_chunk;
}

void PaintChunker::FinalizeLastChunkProperties() {
  DCHECK(chunks_);
  if (chunks_->IsEmpty() || chunks_->back().is_moved_from_cached_subsequence)
    return;

  auto& chunk = chunks_->back();
  if (should_compute_contents_opaque_) {
    chunk.known_to_be_opaque =
        last_chunk_known_to_be_opaque_region_.Contains(chunk.bounds);
    chunk.text_known_to_be_on_opaque_background =
        last_chunk_text_known_to_be_on_opaque_background_;
    last_chunk_known_to_be_opaque_region_ = Region();
    last_chunk_text_known_to_be_on_opaque_background_ = true;
  }

  if (candidate_background_color_ != Color::kTransparent) {
    chunk.background_color = candidate_background_color_;
    chunk.background_color_area = candidate_background_area_;
  }
  candidate_background_color_ = Color::kTransparent;
  candidate_background_area_ = 0u;
}

}  // namespace blink
