// Copyright 2012 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/layers/picture_layer.h"

#include "base/auto_reset.h"
#include "base/trace_event/trace_event.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/picture_layer_impl.h"
#include "cc/layers/recording_source.h"
#include "cc/paint/paint_record.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/transform_node.h"
#include "ui/gfx/geometry/rect_conversions.h"

static constexpr int kMaxNumberOfSlowPathsBeforeReporting = 5;

namespace cc {

PictureLayer::PictureLayerInputs::PictureLayerInputs() = default;

PictureLayer::PictureLayerInputs::~PictureLayerInputs() = default;

scoped_refptr<PictureLayer> PictureLayer::Create(ContentLayerClient* client) {
  return base::WrapRefCounted(new PictureLayer(client));
}

PictureLayer::PictureLayer(ContentLayerClient* client)
    : instrumentation_object_tracker_(id()),
      update_source_frame_number_(-1),
      mask_type_(LayerMaskType::NOT_MASK) {
  picture_layer_inputs_.client = client;
}

PictureLayer::PictureLayer(ContentLayerClient* client,
                           std::unique_ptr<RecordingSource> source)
    : PictureLayer(client) {
  recording_source_ = std::move(source);
}

PictureLayer::~PictureLayer() = default;

std::unique_ptr<LayerImpl> PictureLayer::CreateLayerImpl(
    LayerTreeImpl* tree_impl) {
  return PictureLayerImpl::Create(tree_impl, id(), mask_type_);
}

void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) {
  Layer::PushPropertiesTo(base_layer);
  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
               "PictureLayer::PushPropertiesTo");
  PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
  layer_impl->SetLayerMaskType(mask_type());
  DropRecordingSourceContentIfInvalid();

  layer_impl->SetNearestNeighbor(picture_layer_inputs_.nearest_neighbor);
  layer_impl->SetUseTransformedRasterization(
      ShouldUseTransformedRasterization());
  layer_impl->set_gpu_raster_max_texture_size(
      layer_tree_host()->device_viewport_size());
  layer_impl->UpdateRasterSource(recording_source_->CreateRasterSource(),
                                 &last_updated_invalidation_, nullptr);
  DCHECK(last_updated_invalidation_.IsEmpty());
}

void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) {
  Layer::SetLayerTreeHost(host);

  if (!host)
    return;

  if (!host->GetSettings().enable_mask_tiling &&
      mask_type_ == LayerMaskType::MULTI_TEXTURE_MASK)
    mask_type_ = LayerMaskType::SINGLE_TEXTURE_MASK;

  if (!recording_source_)
    recording_source_.reset(new RecordingSource);
  recording_source_->SetSlowdownRasterScaleFactor(
      host->GetDebugState().slow_down_raster_scale_factor);

  // Source frame numbers are relative the LayerTreeHost, so this needs
  // to be reset.
  update_source_frame_number_ = -1;
}

void PictureLayer::SetNeedsDisplayRect(const gfx::Rect& layer_rect) {
  DCHECK(!layer_tree_host() || !layer_tree_host()->in_paint_layer_contents());
  if (recording_source_)
    recording_source_->SetNeedsDisplayRect(layer_rect);
  Layer::SetNeedsDisplayRect(layer_rect);
}

bool PictureLayer::Update() {
  update_source_frame_number_ = layer_tree_host()->SourceFrameNumber();
  bool updated = Layer::Update();

  gfx::Size layer_size = bounds();

  recording_source_->SetBackgroundColor(SafeOpaqueBackgroundColor());
  recording_source_->SetRequiresClear(
      !contents_opaque() &&
      !picture_layer_inputs_.client->FillsBoundsCompletely());

  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "PictureLayer::Update",
               "source_frame_number", layer_tree_host()->SourceFrameNumber());
  devtools_instrumentation::ScopedLayerTreeTask update_layer(
      devtools_instrumentation::kUpdateLayer, id(), layer_tree_host()->GetId());

  // UpdateAndExpandInvalidation will give us an invalidation that covers
  // anything not explicitly recorded in this frame. We give this region
  // to the impl side so that it drops tiles that may not have a recording
  // for them.
  DCHECK(picture_layer_inputs_.client);

  picture_layer_inputs_.recorded_viewport =
      picture_layer_inputs_.client->PaintableRegion();

  updated |= recording_source_->UpdateAndExpandInvalidation(
      &last_updated_invalidation_, layer_size,
      picture_layer_inputs_.recorded_viewport);

  if (updated) {
    picture_layer_inputs_.display_list =
        picture_layer_inputs_.client->PaintContentsToDisplayList(
            ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
    picture_layer_inputs_.painter_reported_memory_usage =
        picture_layer_inputs_.client->GetApproximateUnsharedMemoryUsage();
    recording_source_->UpdateDisplayItemList(
        picture_layer_inputs_.display_list,
        picture_layer_inputs_.painter_reported_memory_usage,
        layer_tree_host()->recording_scale_factor());

    SetNeedsPushProperties();
  } else {
    // If this invalidation did not affect the recording source, then it can be
    // cleared as an optimization.
    last_updated_invalidation_.Clear();
  }

  return updated;
}

void PictureLayer::SetLayerMaskType(LayerMaskType mask_type) {
  // We do not allow converting SINGLE_TEXTURE_MASK to MULTI_TEXTURE_MASK in
  // order to avoid rerastering when a mask's transform is being animated.
  if (mask_type_ == LayerMaskType::SINGLE_TEXTURE_MASK &&
      mask_type == LayerMaskType::MULTI_TEXTURE_MASK)
    return;
  mask_type_ = mask_type;
}

sk_sp<SkPicture> PictureLayer::GetPicture() const {
  // We could either flatten the RecordingSource into a single SkPicture, or
  // paint a fresh one depending on what we intend to do with it.  For now we
  // just paint a fresh one to get consistent results.
  if (!DrawsContent())
    return nullptr;

  gfx::Size layer_size = bounds();
  RecordingSource recording_source;
  Region recording_invalidation;

  gfx::Rect new_recorded_viewport =
      picture_layer_inputs_.client->PaintableRegion();
  scoped_refptr<DisplayItemList> display_list =
      picture_layer_inputs_.client->PaintContentsToDisplayList(
          ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
  size_t painter_reported_memory_usage =
      picture_layer_inputs_.client->GetApproximateUnsharedMemoryUsage();

  recording_source.UpdateAndExpandInvalidation(
      &recording_invalidation, layer_size, new_recorded_viewport);
  recording_source.UpdateDisplayItemList(
      display_list, painter_reported_memory_usage,
      layer_tree_host()->recording_scale_factor());

  scoped_refptr<RasterSource> raster_source =
      recording_source.CreateRasterSource();
  return raster_source->GetFlattenedPicture();
}

bool PictureLayer::HasSlowPaths() const {
  // The display list needs to be created (see: UpdateAndExpandInvalidation)
  // before checking for slow paths. There are cases where an update will not
  // create a display list (e.g., if the size is empty). We return false in
  // these cases because the slow paths bit sticks true.
  return picture_layer_inputs_.display_list &&
         picture_layer_inputs_.display_list->NumSlowPaths() >
             kMaxNumberOfSlowPathsBeforeReporting;
}

bool PictureLayer::HasNonAAPaint() const {
  // We return false by default, as this bit sticks true.
  return picture_layer_inputs_.display_list &&
         picture_layer_inputs_.display_list->HasNonAAPaint();
}

void PictureLayer::ClearClient() {
  picture_layer_inputs_.client = nullptr;
  UpdateDrawsContent(HasDrawableContent());
}

void PictureLayer::SetNearestNeighbor(bool nearest_neighbor) {
  if (picture_layer_inputs_.nearest_neighbor == nearest_neighbor)
    return;

  picture_layer_inputs_.nearest_neighbor = nearest_neighbor;
  SetNeedsCommit();
}

void PictureLayer::SetTransformedRasterizationAllowed(bool allowed) {
  if (picture_layer_inputs_.transformed_rasterization_allowed == allowed)
    return;

  picture_layer_inputs_.transformed_rasterization_allowed = allowed;
  SetNeedsCommit();
}

bool PictureLayer::HasDrawableContent() const {
  return picture_layer_inputs_.client && Layer::HasDrawableContent();
}

void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) {
  benchmark->RunOnLayer(this);
}

void PictureLayer::DropRecordingSourceContentIfInvalid() {
  int source_frame_number = layer_tree_host()->SourceFrameNumber();
  gfx::Size recording_source_bounds = recording_source_->GetSize();

  gfx::Size layer_bounds = bounds();

  // If update called, then recording source size must match bounds pushed to
  // impl layer.
  DCHECK(update_source_frame_number_ != source_frame_number ||
         layer_bounds == recording_source_bounds)
      << " bounds " << layer_bounds.ToString() << " recording source "
      << recording_source_bounds.ToString();

  if (update_source_frame_number_ != source_frame_number &&
      recording_source_bounds != layer_bounds) {
    // Update may not get called for the layer (if it's not in the viewport
    // for example), even though it has resized making the recording source no
    // longer valid. In this case just destroy the recording source.
    recording_source_->SetEmptyBounds();
    picture_layer_inputs_.recorded_viewport = gfx::Rect();
    picture_layer_inputs_.display_list = nullptr;
    picture_layer_inputs_.painter_reported_memory_usage = 0;
  }
}

bool PictureLayer::ShouldUseTransformedRasterization() const {
  if (!picture_layer_inputs_.transformed_rasterization_allowed)
    return false;

  // Background color overfill is undesirable with transformed rasterization.
  // However, without background overfill, the tiles will be non-opaque on
  // external edges, and layer opaque region can't be computed in layer space
  // due to rounding under extreme scaling. This defeats many opaque layer
  // optimization. Prefer optimization over quality for this particular case.
  if (contents_opaque())
    return false;

  const TransformTree& transform_tree =
      layer_tree_host()->property_trees()->transform_tree;
  DCHECK(!transform_tree.needs_update());
  auto* transform_node = transform_tree.Node(transform_tree_index());
  DCHECK(transform_node);
  // TODO(pdr): This is a workaround for https://crbug.com/708951 to avoid
  // crashing when there's no transform node. This workaround should be removed.
  if (!transform_node)
    return false;

  if (transform_node->to_screen_is_potentially_animated)
    return false;

  const gfx::Transform& to_screen =
      transform_tree.ToScreen(transform_tree_index());
  if (!to_screen.IsScaleOrTranslation())
    return false;

  float origin_x =
      to_screen.matrix().getFloat(0, 3) + offset_to_transform_parent().x();
  float origin_y =
      to_screen.matrix().getFloat(1, 3) + offset_to_transform_parent().y();
  if (origin_x - floorf(origin_x) == 0.f && origin_y - floorf(origin_y) == 0.f)
    return false;

  return true;
}

const DisplayItemList* PictureLayer::GetDisplayItemList() {
  return picture_layer_inputs_.display_list.get();
}

}  // namespace cc
