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

#include <algorithm>
#include <limits>
#include <set>

#include "base/base64.h"
#include "base/debug/trace_event.h"
#include "base/debug/trace_event_argument.h"
#include "base/values.h"
#include "cc/base/math_util.h"
#include "cc/base/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/SkData.h"
#include "third_party/skia/include/core/SkDrawFilter.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/rect_conversions.h"
#include "ui/gfx/skia_util.h"

namespace cc {

namespace {

SkData* EncodeBitmap(size_t* offset, const SkBitmap& bm) {
  const int kJpegQuality = 80;
  std::vector<unsigned char> data;

  // If bitmap is opaque, encode as JPEG.
  // Otherwise encode as PNG.
  bool encoding_succeeded = false;
  if (bm.isOpaque()) {
    SkAutoLockPixels lock_bitmap(bm);
    if (bm.empty())
      return NULL;

    encoding_succeeded = gfx::JPEGCodec::Encode(
        reinterpret_cast<unsigned char*>(bm.getAddr32(0, 0)),
        gfx::JPEGCodec::FORMAT_SkBitmap,
        bm.width(),
        bm.height(),
        bm.rowBytes(),
        kJpegQuality,
        &data);
  } else {
    encoding_succeeded = gfx::PNGCodec::EncodeBGRASkBitmap(bm, false, &data);
  }

  if (encoding_succeeded) {
    *offset = 0;
    return SkData::NewWithCopy(&data.front(), data.size());
  }
  return NULL;
}

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 SkTileGridFactory::TileGridInfo& tile_grid_info,
    bool gather_pixel_refs,
    RecordingMode recording_mode) {
  scoped_refptr<Picture> picture = make_scoped_refptr(new Picture(layer_rect));

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

  return picture;
}

Picture::Picture(const gfx::Rect& layer_rect)
  : layer_rect_(layer_rect),
    cell_size_(layer_rect.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(skpicture->width(), skpicture->height());
  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)),
      cell_size_(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),
    cell_size_(layer_rect.size()) {
}

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

bool Picture::IsSuitableForGpuRasterization() const {
  DCHECK(picture_);

  // TODO(alokp): SkPicture::suitableForGpuRasterization needs a GrContext.
  // Ideally this GrContext should be the same as that for rasterizing this
  // picture. But we are on the main thread while the rasterization context
  // may be on the compositor or raster thread.
  // SkPicture::suitableForGpuRasterization is not implemented yet.
  // Pass a NULL context for now and discuss with skia folks if the context
  // is really needed.
  return picture_->suitableForGpuRasterization(NULL);
}

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

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

void Picture::Record(ContentLayerClient* painter,
                     const SkTileGridFactory::TileGridInfo& tile_grid_info,
                     RecordingMode recording_mode) {
  TRACE_EVENT2("cc",
               "Picture::Record",
               "data",
               AsTraceableRecordData(),
               "recording_mode",
               recording_mode);

  DCHECK(!picture_);
  DCHECK(!tile_grid_info.fTileInterval.isEmpty());

  SkTileGridFactory factory(tile_grid_info);
  SkPictureRecorder recorder;

  scoped_ptr<EXPERIMENTAL::SkRecording> recording;

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

  ContentLayerClient::GraphicsContextStatus graphics_context_status =
      ContentLayerClient::GRAPHICS_CONTEXT_ENABLED;

  switch (recording_mode) {
    case RECORD_NORMALLY:
      // Already setup for normal recording.
      break;
    case RECORD_WITH_SK_NULL_CANVAS:
      canvas = skia::AdoptRef(SkCreateNullCanvas());
      break;
    case 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());
      graphics_context_status = ContentLayerClient::GRAPHICS_CONTEXT_DISABLED;
      break;
    case RECORD_WITH_SKRECORD:
      recording.reset(new EXPERIMENTAL::SkRecording(layer_rect_.width(),
                                                    layer_rect_.height()));
      canvas = skia::SharePtr(recording->canvas());
      break;
    default:
      NOTREACHED();
  }

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

  SkRect layer_skrect = SkRect::MakeXYWH(layer_rect_.x(),
                                         layer_rect_.y(),
                                         layer_rect_.width(),
                                         layer_rect_.height());
  canvas->clipRect(layer_skrect);

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

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

  if (recording) {
    // SkRecording requires it's the only one holding onto canvas before we
    // may call releasePlayback().  (This helps enforce thread-safety.)
    canvas.clear();
    playback_.reset(recording->releasePlayback());
  }

  EmitTraceSnapshot();
}

void Picture::GatherPixelRefs(
    const SkTileGridFactory::TileGridInfo& tile_grid_info) {
  TRACE_EVENT2("cc", "Picture::GatherPixelRefs",
               "width", layer_rect_.width(),
               "height", layer_rect_.height());

  DCHECK(picture_);
  DCHECK(pixel_refs_.empty());
  if (!WillPlayBackBitmaps())
    return;
  cell_size_ = gfx::Size(
      tile_grid_info.fTileInterval.width() +
          2 * tile_grid_info.fMargin.width(),
      tile_grid_info.fTileInterval.height() +
          2 * tile_grid_info.fMargin.height());
  DCHECK_GT(cell_size_.width(), 0);
  DCHECK_GT(cell_size_.height(), 0);

  int min_x = std::numeric_limits<int>::max();
  int min_y = std::numeric_limits<int>::max();
  int max_x = 0;
  int max_y = 0;

  skia::DiscardablePixelRefList pixel_refs;
  skia::PixelRefUtils::GatherDiscardablePixelRefs(picture_.get(), &pixel_refs);
  for (skia::DiscardablePixelRefList::const_iterator it = pixel_refs.begin();
       it != pixel_refs.end();
       ++it) {
    gfx::Point min(
        RoundDown(static_cast<int>(it->pixel_ref_rect.x()),
                  cell_size_.width()),
        RoundDown(static_cast<int>(it->pixel_ref_rect.y()),
                  cell_size_.height()));
    gfx::Point max(
        RoundDown(static_cast<int>(std::ceil(it->pixel_ref_rect.right())),
                  cell_size_.width()),
        RoundDown(static_cast<int>(std::ceil(it->pixel_ref_rect.bottom())),
                  cell_size_.height()));

    for (int y = min.y(); y <= max.y(); y += cell_size_.height()) {
      for (int x = min.x(); x <= max.x(); x += cell_size_.width()) {
        PixelRefMapKey key(x, y);
        pixel_refs_[key].push_back(it->pixel_ref);
      }
    }

    min_x = std::min(min_x, min.x());
    min_y = std::min(min_y, min.y());
    max_x = std::max(max_x, max.x());
    max_y = std::max(max_y, max.y());
  }

  min_pixel_cell_ = gfx::Point(min_x, min_y);
  max_pixel_cell_ = gfx::Point(max_x, max_y);
}

int Picture::Raster(SkCanvas* canvas,
                    SkDrawPictureCallback* 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 (playback_) {
    playback_->draw(canvas);
  } else 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_->draw(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) {
  TRACE_EVENT_BEGIN0("cc", "Picture::Replay");
  DCHECK(picture_);

  if (playback_) {
    playback_->draw(canvas);
  } else {
    picture_->draw(canvas);
  }
  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 {
  SkDynamicMemoryWStream stream;

  if (playback_) {
    // SkPlayback can't serialize itself, so re-record into an SkPicture.
    SkPictureRecorder recorder;
    skia::RefPtr<SkCanvas> canvas(skia::SharePtr(recorder.beginRecording(
        layer_rect_.width(),
        layer_rect_.height(),
        NULL)));  // Default (no) bounding-box hierarchy is fastest.
    playback_->draw(canvas.get());
    skia::RefPtr<SkPicture> picture(skia::AdoptRef(recorder.endRecording()));
    picture->serialize(&stream, &EncodeBitmap);
  } else {
    // Serialize the picture.
    picture_->serialize(&stream, &EncodeBitmap);
  }

  // Encode the picture as base64.
  scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
  res->Set("params.layer_rect", MathUtil::AsValue(layer_rect_).release());

  size_t serialized_size = stream.bytesWritten();
  scoped_ptr<char[]> serialized_picture(new char[serialized_size]);
  stream.copyTo(serialized_picture.get());
  std::string b64_picture;
  base::Base64Encode(std::string(serialized_picture.get(), serialized_size),
                     &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") "," 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") "," TRACE_DISABLED_BY_DEFAULT(
          "devtools.timeline.picture"),
      "cc::Picture",
      this,
      TracedPicture::AsTraceablePictureAlias(original));
}

base::LazyInstance<Picture::PixelRefs>
    Picture::PixelRefIterator::empty_pixel_refs_;

Picture::PixelRefIterator::PixelRefIterator()
    : picture_(NULL),
      current_pixel_refs_(empty_pixel_refs_.Pointer()),
      current_index_(0),
      min_point_(-1, -1),
      max_point_(-1, -1),
      current_x_(0),
      current_y_(0) {
}

Picture::PixelRefIterator::PixelRefIterator(
    const gfx::Rect& rect,
    const Picture* picture)
    : picture_(picture),
      current_pixel_refs_(empty_pixel_refs_.Pointer()),
      current_index_(0) {
  gfx::Rect layer_rect = picture->layer_rect_;
  gfx::Size cell_size = picture->cell_size_;
  DCHECK(!cell_size.IsEmpty());

  gfx::Rect query_rect(rect);
  // Early out if the query rect doesn't intersect this picture.
  if (!query_rect.Intersects(layer_rect)) {
    min_point_ = gfx::Point(0, 0);
    max_point_ = gfx::Point(0, 0);
    current_x_ = 1;
    current_y_ = 1;
    return;
  }

  // First, subtract the layer origin as cells are stored in layer space.
  query_rect.Offset(-layer_rect.OffsetFromOrigin());

  // We have to find a cell_size aligned point that corresponds to
  // query_rect. Point is a multiple of cell_size.
  min_point_ = gfx::Point(
      RoundDown(query_rect.x(), cell_size.width()),
      RoundDown(query_rect.y(), cell_size.height()));
  max_point_ = gfx::Point(
      RoundDown(query_rect.right() - 1, cell_size.width()),
      RoundDown(query_rect.bottom() - 1, cell_size.height()));

  // Limit the points to known pixel ref boundaries.
  min_point_ = gfx::Point(
      std::max(min_point_.x(), picture->min_pixel_cell_.x()),
      std::max(min_point_.y(), picture->min_pixel_cell_.y()));
  max_point_ = gfx::Point(
      std::min(max_point_.x(), picture->max_pixel_cell_.x()),
      std::min(max_point_.y(), picture->max_pixel_cell_.y()));

  // Make the current x be cell_size.width() less than min point, so that
  // the first increment will point at min_point_.
  current_x_ = min_point_.x() - cell_size.width();
  current_y_ = min_point_.y();
  if (current_y_ <= max_point_.y())
    ++(*this);
}

Picture::PixelRefIterator::~PixelRefIterator() {
}

Picture::PixelRefIterator& Picture::PixelRefIterator::operator++() {
  ++current_index_;
  // If we're not at the end of the list, then we have the next item.
  if (current_index_ < current_pixel_refs_->size())
    return *this;

  DCHECK(current_y_ <= max_point_.y());
  while (true) {
    gfx::Size cell_size = picture_->cell_size_;

    // Advance the current grid cell.
    current_x_ += cell_size.width();
    if (current_x_ > max_point_.x()) {
      current_y_ += cell_size.height();
      current_x_ = min_point_.x();
      if (current_y_ > max_point_.y()) {
        current_pixel_refs_ = empty_pixel_refs_.Pointer();
        current_index_ = 0;
        break;
      }
    }

    // If there are no pixel refs at this grid cell, keep incrementing.
    PixelRefMapKey key(current_x_, current_y_);
    PixelRefMap::const_iterator iter = picture_->pixel_refs_.find(key);
    if (iter == picture_->pixel_refs_.end())
      continue;

    // We found a non-empty list: store it and get the first pixel ref.
    current_pixel_refs_ = &iter->second;
    current_index_ = 0;
    break;
  }
  return *this;
}

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

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

}  // namespace cc
