// 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/playback/picture.h"

#include <set>
#include <string>

#include "base/base64.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
#include "base/values.h"
#include "cc/base/math_util.h"
#include "cc/debug/picture_debug_util.h"
#include "cc/debug/traced_picture.h"
#include "cc/debug/traced_value.h"
#include "cc/layers/content_layer_client.h"
#include "skia/ext/pixel_ref_utils.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkStream.h"
#include "third_party/skia/include/utils/SkNullCanvas.h"
#include "third_party/skia/include/utils/SkPictureUtils.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/skia_util.h"

namespace cc {

namespace {

// We don't perform per-layer solid color analysis when there are too many skia
// operations.
const int kOpCountThatIsOkToAnalyze = 10;

bool DecodeBitmap(const void* buffer, size_t size, SkBitmap* bm) {
  const unsigned char* data = static_cast<const unsigned char *>(buffer);

  // Try PNG first.
  if (gfx::PNGCodec::Decode(data, size, bm))
    return true;

  // Try JPEG.
  scoped_ptr<SkBitmap> decoded_jpeg(gfx::JPEGCodec::Decode(data, size));
  if (decoded_jpeg) {
    *bm = *decoded_jpeg;
    return true;
  }
  return false;
}

}  // namespace

scoped_refptr<Picture> Picture::Create(
    const gfx::Rect& layer_rect,
    ContentLayerClient* client,
    const gfx::Size& tile_grid_size,
    bool gather_pixel_refs,
    RecordingSource::RecordingMode recording_mode) {
  scoped_refptr<Picture> picture =
      make_scoped_refptr(new Picture(layer_rect, tile_grid_size));

  picture->Record(client, recording_mode);
  if (gather_pixel_refs)
    picture->GatherPixelRefs();

  return picture;
}

Picture::Picture(const gfx::Rect& layer_rect, const gfx::Size& tile_grid_size)
    : layer_rect_(layer_rect), pixel_refs_(tile_grid_size) {
  // Instead of recording a trace event for object creation here, we wait for
  // the picture to be recorded in Picture::Record.
}

scoped_refptr<Picture> Picture::CreateFromSkpValue(const base::Value* value) {
  // Decode the picture from base64.
  std::string encoded;
  if (!value->GetAsString(&encoded))
    return NULL;

  std::string decoded;
  base::Base64Decode(encoded, &decoded);
  SkMemoryStream stream(decoded.data(), decoded.size());

  // Read the picture. This creates an empty picture on failure.
  SkPicture* skpicture = SkPicture::CreateFromStream(&stream, &DecodeBitmap);
  if (skpicture == NULL)
    return NULL;

  gfx::Rect layer_rect(gfx::SkIRectToRect(skpicture->cullRect().roundOut()));
  return make_scoped_refptr(new Picture(skpicture, layer_rect));
}

scoped_refptr<Picture> Picture::CreateFromValue(const base::Value* raw_value) {
  const base::DictionaryValue* value = NULL;
  if (!raw_value->GetAsDictionary(&value))
    return NULL;

  // Decode the picture from base64.
  std::string encoded;
  if (!value->GetString("skp64", &encoded))
    return NULL;

  std::string decoded;
  base::Base64Decode(encoded, &decoded);
  SkMemoryStream stream(decoded.data(), decoded.size());

  const base::Value* layer_rect_value = NULL;
  if (!value->Get("params.layer_rect", &layer_rect_value))
    return NULL;

  gfx::Rect layer_rect;
  if (!MathUtil::FromValue(layer_rect_value, &layer_rect))
    return NULL;

  // Read the picture. This creates an empty picture on failure.
  SkPicture* skpicture = SkPicture::CreateFromStream(&stream, &DecodeBitmap);
  if (skpicture == NULL)
    return NULL;

  return make_scoped_refptr(new Picture(skpicture, layer_rect));
}

Picture::Picture(SkPicture* picture, const gfx::Rect& layer_rect)
    : layer_rect_(layer_rect),
      picture_(skia::AdoptRef(picture)),
      pixel_refs_(layer_rect.size()) {
}

Picture::Picture(const skia::RefPtr<SkPicture>& picture,
                 const gfx::Rect& layer_rect,
                 const PixelRefMap& pixel_refs)
    : layer_rect_(layer_rect), picture_(picture), pixel_refs_(pixel_refs) {
}

Picture::~Picture() {
  TRACE_EVENT_OBJECT_DELETED_WITH_ID(
      TRACE_DISABLED_BY_DEFAULT("cc.debug.picture"), "cc::Picture", this);
}

bool Picture::IsSuitableForGpuRasterization(const char** reason) const {
  DCHECK(picture_);

  // TODO(hendrikw): SkPicture::suitableForGpuRasterization takes a GrContext.
  // Currently the GrContext isn't used, and should probably be removed from
  // skia.
  return picture_->suitableForGpuRasterization(nullptr, reason);
}

int Picture::ApproximateOpCount() const {
  DCHECK(picture_);
  return picture_->approximateOpCount();
}

size_t Picture::ApproximateMemoryUsage() const {
  DCHECK(picture_);
  return SkPictureUtils::ApproximateBytesUsed(picture_.get());
}

bool Picture::ShouldBeAnalyzedForSolidColor() const {
  return ApproximateOpCount() <= kOpCountThatIsOkToAnalyze;
}

bool Picture::HasText() const {
  DCHECK(picture_);
  return picture_->hasText();
}

void Picture::Record(ContentLayerClient* painter,
                     RecordingSource::RecordingMode recording_mode) {
  TRACE_EVENT2("cc",
               "Picture::Record",
               "data",
               AsTraceableRecordData(),
               "recording_mode",
               recording_mode);

  DCHECK(!picture_);

  SkRTreeFactory factory;
  SkPictureRecorder recorder;

  skia::RefPtr<SkCanvas> canvas;
  canvas = skia::SharePtr(recorder.beginRecording(
      layer_rect_.width(), layer_rect_.height(), &factory,
      SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag));

  ContentLayerClient::PaintingControlSetting painting_control =
      ContentLayerClient::PAINTING_BEHAVIOR_NORMAL;

  switch (recording_mode) {
    case RecordingSource::RECORD_NORMALLY:
      // Already setup for normal recording.
      break;
    case RecordingSource::RECORD_WITH_SK_NULL_CANVAS:
      canvas = skia::AdoptRef(SkCreateNullCanvas());
      break;
    case RecordingSource::RECORD_WITH_PAINTING_DISABLED:
      // We pass a disable flag through the paint calls when perfromance
      // testing (the only time this case should ever arise) when we want to
      // prevent the Blink GraphicsContext object from consuming any compute
      // time.
      canvas = skia::AdoptRef(SkCreateNullCanvas());
      painting_control = ContentLayerClient::DISPLAY_LIST_PAINTING_DISABLED;
      break;
    case RecordingSource::RECORD_WITH_CACHING_DISABLED:
      // This mode should give the same results as RECORD_NORMALLY.
      painting_control = ContentLayerClient::DISPLAY_LIST_CACHING_DISABLED;
      break;
    default:
      // case RecordingSource::RECORD_WITH_CONSTRUCTION_DISABLED should
      // not be reached
      NOTREACHED();
  }

  canvas->save();
  canvas->translate(SkFloatToScalar(-layer_rect_.x()),
                    SkFloatToScalar(-layer_rect_.y()));

  canvas->clipRect(gfx::RectToSkRect(layer_rect_));

  painter->PaintContents(canvas.get(), layer_rect_, painting_control);

  canvas->restore();
  picture_ = skia::AdoptRef(recorder.endRecordingAsPicture());
  DCHECK(picture_);

  EmitTraceSnapshot();
}

void Picture::GatherPixelRefs() {
  TRACE_EVENT2("cc", "Picture::GatherPixelRefs",
               "width", layer_rect_.width(),
               "height", layer_rect_.height());

  DCHECK(picture_);
  DCHECK(pixel_refs_.empty());
  if (!WillPlayBackBitmaps())
    return;

  pixel_refs_.GatherPixelRefsFromPicture(picture_.get(), layer_rect_);
}

int Picture::Raster(SkCanvas* canvas,
                    SkPicture::AbortCallback* callback,
                    const Region& negated_content_region,
                    float contents_scale) const {
  TRACE_EVENT_BEGIN1(
      "cc",
      "Picture::Raster",
      "data",
      AsTraceableRasterData(contents_scale));

  DCHECK(picture_);

  canvas->save();

  for (Region::Iterator it(negated_content_region); it.has_rect(); it.next())
    canvas->clipRect(gfx::RectToSkRect(it.rect()), SkRegion::kDifference_Op);

  canvas->scale(contents_scale, contents_scale);
  canvas->translate(layer_rect_.x(), layer_rect_.y());
  if (callback) {
    // If we have a callback, we need to call |draw()|, |drawPicture()| doesn't
    // take a callback.  This is used by |AnalysisCanvas| to early out.
    picture_->playback(canvas, callback);
  } else {
    // Prefer to call |drawPicture()| on the canvas since it could place the
    // entire picture on the canvas instead of parsing the skia operations.
    canvas->drawPicture(picture_.get());
  }
  SkIRect bounds;
  canvas->getClipDeviceBounds(&bounds);
  canvas->restore();
  TRACE_EVENT_END1(
      "cc", "Picture::Raster",
      "num_pixels_rasterized", bounds.width() * bounds.height());
  return bounds.width() * bounds.height();
}

void Picture::Replay(SkCanvas* canvas, SkPicture::AbortCallback* callback) {
  TRACE_EVENT_BEGIN0("cc", "Picture::Replay");
  DCHECK(picture_);
  picture_->playback(canvas, callback);
  SkIRect bounds;
  canvas->getClipDeviceBounds(&bounds);
  TRACE_EVENT_END1("cc", "Picture::Replay",
                   "num_pixels_replayed", bounds.width() * bounds.height());
}

scoped_ptr<base::Value> Picture::AsValue() const {
  // Encode the picture as base64.
  scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
  res->Set("params.layer_rect", MathUtil::AsValue(layer_rect_).release());
  std::string b64_picture;
  PictureDebugUtil::SerializeAsBase64(picture_.get(), &b64_picture);
  res->SetString("skp64", b64_picture);
  return res.Pass();
}

void Picture::EmitTraceSnapshot() const {
  TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
      TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") ","
          TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"),
      "cc::Picture",
      this,
      TracedPicture::AsTraceablePicture(this));
}

void Picture::EmitTraceSnapshotAlias(Picture* original) const {
  TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
      TRACE_DISABLED_BY_DEFAULT("cc.debug.picture") ","
          TRACE_DISABLED_BY_DEFAULT("devtools.timeline.picture"),
      "cc::Picture",
      this,
      TracedPicture::AsTraceablePictureAlias(original));
}

PixelRefMap::Iterator Picture::GetPixelRefMapIterator(
    const gfx::Rect& layer_rect) const {
  return PixelRefMap::Iterator(layer_rect, this);
}

scoped_refptr<base::trace_event::ConvertableToTraceFormat>
    Picture::AsTraceableRasterData(float scale) const {
  scoped_refptr<base::trace_event::TracedValue> raster_data =
      new base::trace_event::TracedValue();
  TracedValue::SetIDRef(this, raster_data.get(), "picture_id");
  raster_data->SetDouble("scale", scale);
  return raster_data;
}

scoped_refptr<base::trace_event::ConvertableToTraceFormat>
    Picture::AsTraceableRecordData() const {
  scoped_refptr<base::trace_event::TracedValue> record_data =
      new base::trace_event::TracedValue();
  TracedValue::SetIDRef(this, record_data.get(), "picture_id");
  MathUtil::AddToTracedValue("layer_rect", layer_rect_, record_data.get());
  return record_data;
}

}  // namespace cc
