// 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 "content/renderer/child_frame_compositing_helper.h"

#include <utility>

#include "build/build_config.h"
#include "cc/layers/picture_layer.h"
#include "cc/layers/surface_layer.h"
#include "cc/paint/paint_image.h"
#include "cc/paint/paint_image_builder.h"
#include "content/renderer/child_frame_compositor.h"
#include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkImage.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/skia_util.h"

namespace content {

ChildFrameCompositingHelper::ChildFrameCompositingHelper(
    ChildFrameCompositor* child_frame_compositor)
    : child_frame_compositor_(child_frame_compositor) {
  DCHECK(child_frame_compositor_);
}

ChildFrameCompositingHelper::~ChildFrameCompositingHelper() = default;

void ChildFrameCompositingHelper::ChildFrameGone(
    const gfx::Size& frame_size_in_dip,
    float device_scale_factor) {
  surface_id_ = viz::SurfaceId();
  crashed_ = true;
  device_scale_factor_ = device_scale_factor;

  auto crash_ui_layer = cc::PictureLayer::Create(this);
  crash_ui_layer->SetMasksToBounds(true);

  bool prevent_contents_opaque_changes = false;
  bool is_surface_layer = false;
  child_frame_compositor_->SetLayer(std::move(crash_ui_layer),
                                    prevent_contents_opaque_changes,
                                    is_surface_layer);
  UpdateVisibility(true);
}

void ChildFrameCompositingHelper::SetSurfaceId(
    const viz::SurfaceId& surface_id,
    const gfx::Size& frame_size_in_dip,
    const cc::DeadlinePolicy& deadline) {
  if (surface_id_ == surface_id)
    return;

  surface_id_ = surface_id;

  surface_layer_ = cc::SurfaceLayer::Create();
  surface_layer_->SetMasksToBounds(true);
  surface_layer_->SetSurfaceHitTestable(true);
  surface_layer_->SetBackgroundColor(SK_ColorTRANSPARENT);

  surface_layer_->SetSurfaceId(surface_id, deadline);

  // TODO(lfg): Investigate if it's possible to propagate the information
  // about the child surface's opacity. https://crbug.com/629851.
  bool prevent_contents_opaque_changes = true;
  child_frame_compositor_->SetLayer(surface_layer_,
                                    prevent_contents_opaque_changes,
                                    true /* is_surface_layer */);

  UpdateVisibility(true);

  surface_layer_->SetBounds(frame_size_in_dip);
}

void ChildFrameCompositingHelper::UpdateVisibility(bool visible) {
  cc::Layer* layer = child_frame_compositor_->GetLayer();
  if (layer)
    layer->SetIsDrawable(visible);
}

gfx::Rect ChildFrameCompositingHelper::PaintableRegion() {
  DCHECK(crashed_);
  return gfx::Rect(child_frame_compositor_->GetLayer()->bounds());
}

scoped_refptr<cc::DisplayItemList>
ChildFrameCompositingHelper::PaintContentsToDisplayList(
    PaintingControlSetting) {
  DCHECK(crashed_);
  auto layer_size = child_frame_compositor_->GetLayer()->bounds();
  auto display_list = base::MakeRefCounted<cc::DisplayItemList>();
  display_list->StartPaint();
  display_list->push<cc::DrawColorOp>(SK_ColorGRAY, SkBlendMode::kSrc);

  SkBitmap* sad_bitmap = child_frame_compositor_->GetSadPageBitmap();
  if (sad_bitmap) {
    int paint_width = sad_bitmap->width() * device_scale_factor_;
    int paint_height = sad_bitmap->height() * device_scale_factor_;
    if (layer_size.width() >= paint_width &&
        layer_size.height() >= paint_height) {
      int x = (layer_size.width() - paint_width) / 2;
      int y = (layer_size.height() - paint_height) / 2;
      if (device_scale_factor_ != 1.f) {
        display_list->push<cc::SaveOp>();
        display_list->push<cc::TranslateOp>(x, y);
        display_list->push<cc::ScaleOp>(device_scale_factor_,
                                        device_scale_factor_);
        x = 0;
        y = 0;
      }

      auto image = cc::PaintImageBuilder::WithDefault()
                       .set_id(cc::PaintImage::GetNextId())
                       .set_image(SkImage::MakeFromBitmap(*sad_bitmap),
                                  cc::PaintImage::GetNextContentId())
                       .TakePaintImage();
      display_list->push<cc::DrawImageOp>(image, x, y, nullptr);

      if (device_scale_factor_ != 1.f)
        display_list->push<cc::RestoreOp>();
    }
  }
  display_list->EndPaintOfUnpaired(gfx::Rect(layer_size));
  display_list->Finalize();
  return display_list;
}

bool ChildFrameCompositingHelper::FillsBoundsCompletely() const {
  // Because we paint a full opaque gray background.
  return true;
}

size_t ChildFrameCompositingHelper::GetApproximateUnsharedMemoryUsage() const {
  return sizeof(*this);
}

}  // namespace content
