// 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 "cc/layers/content_layer_client.h"
#include "cc/layers/picture_layer_impl.h"
#include "cc/resources/display_list_recording_source.h"
#include "cc/resources/picture_pile.h"
#include "cc/trees/layer_tree_impl.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "ui/gfx/geometry/rect_conversions.h"

namespace cc {

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

PictureLayer::PictureLayer(ContentLayerClient* client)
    : client_(client),
      instrumentation_object_tracker_(id()),
      update_source_frame_number_(-1),
      can_use_lcd_text_for_update_(true),
      is_mask_(false),
      nearest_neighbor_(false) {
}

PictureLayer::PictureLayer(ContentLayerClient* client,
                           scoped_ptr<RecordingSource> source)
    : PictureLayer(client) {
  recording_source_ = source.Pass();
}

PictureLayer::~PictureLayer() {
}

scoped_ptr<LayerImpl> PictureLayer::CreateLayerImpl(LayerTreeImpl* tree_impl) {
  return PictureLayerImpl::Create(tree_impl, id(), is_mask_,
                                  new LayerImpl::SyncedScrollOffset);
}

void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) {
  Layer::PushPropertiesTo(base_layer);
  PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
  // TODO(danakj): Make is_mask_ a constructor parameter for PictureLayer.
  DCHECK_EQ(layer_impl->is_mask(), is_mask_);

  int source_frame_number = layer_tree_host()->source_frame_number();
  gfx::Size impl_bounds = layer_impl->bounds();
  gfx::Size recording_source_bounds = recording_source_->GetSize();

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

  if (update_source_frame_number_ != source_frame_number &&
      recording_source_bounds != impl_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();
  }

  layer_impl->SetNearestNeighbor(nearest_neighbor_);

  scoped_refptr<RasterSource> raster_source =
      recording_source_->CreateRasterSource();
  raster_source->SetBackgoundColor(SafeOpaqueBackgroundColor());
  raster_source->SetRequiresClear(!contents_opaque() &&
                                  !client_->FillsBoundsCompletely());
  layer_impl->UpdateRasterSource(raster_source, &recording_invalidation_,
                                 nullptr);
  DCHECK(recording_invalidation_.IsEmpty());
}

void PictureLayer::SetLayerTreeHost(LayerTreeHost* host) {
  Layer::SetLayerTreeHost(host);
  if (host) {
    if (!recording_source_) {
      if (host->settings().use_display_lists) {
        recording_source_.reset(new DisplayListRecordingSource);
      } else {
        recording_source_.reset(
            new PicturePile(host->settings().minimum_contents_scale,
                            host->settings().default_tile_grid_size));
      }
    }
    recording_source_->SetSlowdownRasterScaleFactor(
        host->debug_state().slow_down_raster_scale_factor);
  }
}

void PictureLayer::SetNeedsDisplayRect(const gfx::Rect& layer_rect) {
  if (!layer_rect.IsEmpty()) {
    // Clamp invalidation to the layer bounds.
    pending_invalidation_.Union(
        gfx::IntersectRects(layer_rect, gfx::Rect(bounds())));
  }
  Layer::SetNeedsDisplayRect(layer_rect);
}

bool PictureLayer::Update(ResourceUpdateQueue* queue,
                          const OcclusionTracker<Layer>* occlusion) {
  update_source_frame_number_ = layer_tree_host()->source_frame_number();
  bool updated = Layer::Update(queue, occlusion);

  bool can_use_lcd_text_changed = UpdateCanUseLCDText();

  gfx::Rect visible_layer_rect = gfx::ScaleToEnclosingRect(
      visible_content_rect(), 1.f / contents_scale_x());
  gfx::Size layer_size = paint_properties().bounds;

  if (last_updated_visible_content_rect_ == visible_content_rect() &&
      recording_source_->GetSize() == layer_size && !can_use_lcd_text_changed &&
      pending_invalidation_.IsEmpty()) {
    // Only early out if the visible content rect of this layer hasn't changed.
    return updated;
  }

  TRACE_EVENT1("cc", "PictureLayer::Update",
               "source_frame_number",
               layer_tree_host()->source_frame_number());
  devtools_instrumentation::ScopedLayerTreeTask update_layer(
      devtools_instrumentation::kUpdateLayer, id(), layer_tree_host()->id());

  // Calling paint in WebKit can sometimes cause invalidations, so save
  // off the invalidation prior to calling update.
  pending_invalidation_.Swap(&recording_invalidation_);
  pending_invalidation_.Clear();

  if (layer_tree_host()->settings().record_full_layer) {
    // Workaround for http://crbug.com/235910 - to retain backwards compat
    // the full page content must always be provided in the picture layer.
    visible_layer_rect = gfx::Rect(layer_size);
  }

  // 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(client_);
  updated |= recording_source_->UpdateAndExpandInvalidation(
      client_, &recording_invalidation_, can_use_lcd_text_for_update_,
      layer_size, visible_layer_rect, update_source_frame_number_,
      RecordingSource::RECORD_NORMALLY);
  last_updated_visible_content_rect_ = visible_content_rect();

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

  return updated;
}

void PictureLayer::SetIsMask(bool is_mask) {
  is_mask_ = is_mask;
}

bool PictureLayer::SupportsLCDText() const {
  return true;
}

bool PictureLayer::UpdateCanUseLCDText() {
  if (!can_use_lcd_text_for_update_)
    return false;  // Don't allow the LCD text state to change once disabled.
  if (can_use_lcd_text_for_update_ == can_use_lcd_text())
    return false;

  can_use_lcd_text_for_update_ = can_use_lcd_text();
  return true;
}

skia::RefPtr<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 the
  // picture. For now we just paint a fresh one to get consistent results.
  if (!DrawsContent())
    return skia::RefPtr<SkPicture>();

  int width = bounds().width();
  int height = bounds().height();

  SkPictureRecorder recorder;
  SkCanvas* canvas = recorder.beginRecording(width, height, nullptr, 0);
  client_->PaintContents(canvas, gfx::Rect(width, height),
                         ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
  skia::RefPtr<SkPicture> picture = skia::AdoptRef(recorder.endRecording());
  return picture;
}

bool PictureLayer::IsSuitableForGpuRasterization() const {
  return recording_source_->IsSuitableForGpuRasterization();
}

void PictureLayer::ClearClient() {
  client_ = nullptr;
  UpdateDrawsContent(HasDrawableContent());
}

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

  nearest_neighbor_ = nearest_neighbor;
  SetNeedsCommit();
}

bool PictureLayer::HasDrawableContent() const {
  return client_ && Layer::HasDrawableContent();
}

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

}  // namespace cc
