// 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 "cc/blink/web_display_item_list_impl.h"

#include <stddef.h>
#include <stdint.h>

#include <vector>

#include "cc/paint/paint_filter.h"
#include "cc/paint/paint_op_buffer.h"
#include "cc/paint/render_surface_filters.h"
#include "third_party/WebKit/public/platform/WebFloatRect.h"
#include "third_party/WebKit/public/platform/WebRect.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkMatrix44.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/safe_integer_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/transform.h"

namespace cc_blink {

namespace {

}  // namespace

WebDisplayItemListImpl::WebDisplayItemListImpl()
    : display_item_list_(base::MakeRefCounted<cc::DisplayItemList>()) {}

WebDisplayItemListImpl::WebDisplayItemListImpl(
    cc::DisplayItemList* display_list)
    : display_item_list_(display_list) {
}

WebDisplayItemListImpl::~WebDisplayItemListImpl() = default;

void WebDisplayItemListImpl::AppendDrawingItem(
    const blink::WebRect& visual_rect,
    sk_sp<const cc::PaintOpBuffer> record) {
  display_item_list_->StartPaint();
  display_item_list_->push<cc::DrawRecordOp>(std::move(record));
  display_item_list_->EndPaintOfUnpaired(visual_rect);
}

void WebDisplayItemListImpl::AppendClipItem(
    const blink::WebRect& clip_rect,
    const blink::WebVector<SkRRect>& rounded_clip_rects) {
  bool antialias = true;
  display_item_list_->StartPaint();
  display_item_list_->push<cc::SaveOp>();
  display_item_list_->push<cc::ClipRectOp>(gfx::RectToSkRect(clip_rect),
                                           SkClipOp::kIntersect, antialias);
  for (const SkRRect& rrect : rounded_clip_rects) {
    if (rrect.isRect()) {
      display_item_list_->push<cc::ClipRectOp>(rrect.rect(),
                                               SkClipOp::kIntersect, antialias);
    } else {
      display_item_list_->push<cc::ClipRRectOp>(rrect, SkClipOp::kIntersect,
                                                antialias);
    }
  }
  display_item_list_->EndPaintOfPairedBegin();
}

void WebDisplayItemListImpl::AppendEndClipItem() {
  AppendRestore();
}

void WebDisplayItemListImpl::AppendClipPathItem(const SkPath& clip_path,
                                                bool antialias) {
  display_item_list_->StartPaint();
  display_item_list_->push<cc::SaveOp>();
  display_item_list_->push<cc::ClipPathOp>(clip_path, SkClipOp::kIntersect,
                                           antialias);
  display_item_list_->EndPaintOfPairedBegin();
}

void WebDisplayItemListImpl::AppendEndClipPathItem() {
  AppendRestore();
}

void WebDisplayItemListImpl::AppendFloatClipItem(
    const blink::WebFloatRect& clip_rect) {
  bool antialias = false;
  display_item_list_->StartPaint();
  display_item_list_->push<cc::SaveOp>();
  display_item_list_->push<cc::ClipRectOp>(gfx::RectFToSkRect(clip_rect),
                                           SkClipOp::kIntersect, antialias);
  display_item_list_->EndPaintOfPairedBegin();
}

void WebDisplayItemListImpl::AppendEndFloatClipItem() {
  AppendRestore();
}

void WebDisplayItemListImpl::AppendTransformItem(const SkMatrix44& matrix) {
  display_item_list_->StartPaint();
  display_item_list_->push<cc::SaveOp>();
  if (!matrix.isIdentity())
    display_item_list_->push<cc::ConcatOp>(static_cast<SkMatrix>(matrix));
  display_item_list_->EndPaintOfPairedBegin();
}

void WebDisplayItemListImpl::AppendEndTransformItem() {
  AppendRestore();
}

void WebDisplayItemListImpl::AppendCompositingItem(
    float opacity,
    SkBlendMode xfermode,
    SkRect* bounds,
    SkColorFilter* color_filter) {
  DCHECK_GE(opacity, 0.f);
  DCHECK_LE(opacity, 1.f);

  // TODO(ajuma): This should really be rounding instead of flooring the alpha
  // value, but that breaks slimming paint reftests.
  auto alpha = static_cast<uint8_t>(gfx::ToFlooredInt(255 * opacity));

  if (xfermode == SkBlendMode::kSrcOver && !color_filter) {
    display_item_list_->StartPaint();
    display_item_list_->push<cc::SaveLayerAlphaOp>(bounds, alpha, false);
    if (bounds) {
      display_item_list_->push<cc::ClipRectOp>(*bounds, SkClipOp::kIntersect,
                                               false);
    }
    display_item_list_->EndPaintOfPairedBegin();
    return;
  }

  cc::PaintFlags flags;
  flags.setBlendMode(xfermode);
  flags.setAlpha(alpha);
  flags.setColorFilter(sk_ref_sp(color_filter));

  display_item_list_->StartPaint();
  display_item_list_->push<cc::SaveLayerOp>(bounds, &flags);
  if (bounds) {
    display_item_list_->push<cc::ClipRectOp>(*bounds, SkClipOp::kIntersect,
                                             false);
  }
  display_item_list_->EndPaintOfPairedBegin();
}

void WebDisplayItemListImpl::AppendEndCompositingItem() {
  AppendRestore();
}

void WebDisplayItemListImpl::AppendFilterItem(
    const cc::FilterOperations& filters,
    const blink::WebFloatRect& filter_bounds,
    const blink::WebFloatPoint& origin) {
  display_item_list_->StartPaint();

  // TODO(danakj): Skip the save+translate+restore if the origin is 0,0. This
  // should be easier to do when this code is part of the blink DisplayItem
  // which can keep related state.
  display_item_list_->push<cc::SaveOp>();
  display_item_list_->push<cc::TranslateOp>(origin.x, origin.y);

  cc::PaintFlags flags;
  flags.setImageFilter(cc::RenderSurfaceFilters::BuildImageFilter(
      filters, gfx::SizeF(filter_bounds.width, filter_bounds.height)));

  SkRect layer_bounds = gfx::RectFToSkRect(filter_bounds);
  layer_bounds.offset(-origin.x, -origin.y);
  display_item_list_->push<cc::SaveLayerOp>(&layer_bounds, &flags);
  display_item_list_->push<cc::TranslateOp>(-origin.x, -origin.y);

  display_item_list_->EndPaintOfPairedBegin(
      gfx::ToEnclosingRect(filter_bounds));
}

void WebDisplayItemListImpl::AppendEndFilterItem() {
  display_item_list_->StartPaint();
  display_item_list_->push<cc::RestoreOp>();  // For SaveLayerOp.
  display_item_list_->push<cc::RestoreOp>();  // For SaveOp.
  display_item_list_->EndPaintOfPairedEnd();
}

void WebDisplayItemListImpl::AppendScrollItem(
    const blink::WebSize& scroll_offset,
    ScrollContainerId) {
  display_item_list_->StartPaint();
  display_item_list_->push<cc::SaveOp>();
  display_item_list_->push<cc::TranslateOp>(
      static_cast<float>(-scroll_offset.width),
      static_cast<float>(-scroll_offset.height));
  display_item_list_->EndPaintOfPairedBegin();
}

void WebDisplayItemListImpl::AppendEndScrollItem() {
  AppendRestore();
}

void WebDisplayItemListImpl::AppendRestore() {
  display_item_list_->StartPaint();
  display_item_list_->push<cc::RestoreOp>();
  display_item_list_->EndPaintOfPairedEnd();
}

cc::DisplayItemList* WebDisplayItemListImpl::GetCcDisplayItemList() {
  return display_item_list_.get();
}

}  // namespace cc_blink
