// Copyright (c) 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 "ui/gfx/image/image_skia_rep_default.h"

#include "base/logging.h"
#include "cc/paint/display_item_list.h"
#include "cc/paint/record_paint_canvas.h"
#include "cc/paint/skia_paint_canvas.h"
#include "third_party/skia/include/core/SkCanvas.h"

namespace gfx {

ImageSkiaRep::ImageSkiaRep()
    : type_(ImageRepType::kImageTypeDrawable), scale_(0.0f) {}

ImageSkiaRep::ImageSkiaRep(const gfx::Size& size, float scale)
    : type_(ImageRepType::kImageTypeBitmap), scale_(scale) {
  bitmap_.allocN32Pixels(static_cast<int>(size.width() * this->scale()),
                         static_cast<int>(size.height() * this->scale()));
  bitmap_.eraseColor(SK_ColorRED);
  bitmap_.setImmutable();
  pixel_size_.SetSize(bitmap_.width(), bitmap_.height());
  paint_image_ = cc::PaintImage::CreateFromBitmap(bitmap_);
}

ImageSkiaRep::ImageSkiaRep(const SkBitmap& src, float scale)
    : type_(ImageRepType::kImageTypeBitmap),
      pixel_size_(gfx::Size(src.width(), src.height())),
      bitmap_(src),
      scale_(scale) {
  bitmap_.setImmutable();
  paint_image_ = cc::PaintImage::CreateFromBitmap(src);
}

ImageSkiaRep::ImageSkiaRep(sk_sp<cc::PaintRecord> paint_record,
                           const gfx::Size& pixel_size,
                           float scale)
    : paint_record_(std::move(paint_record)),
      type_(ImageRepType::kImageTypeDrawable),
      pixel_size_(pixel_size),
      scale_(scale) {}

ImageSkiaRep::ImageSkiaRep(const ImageSkiaRep& other)
    : paint_image_(other.paint_image_),
      paint_record_(other.paint_record_),
      type_(other.type_),
      pixel_size_(other.pixel_size_),
      bitmap_(other.bitmap_),
      scale_(other.scale_) {}

ImageSkiaRep::~ImageSkiaRep() {}

int ImageSkiaRep::GetWidth() const {
  return static_cast<int>(pixel_width() / scale());
}

int ImageSkiaRep::GetHeight() const {
  return static_cast<int>(pixel_height() / scale());
}

sk_sp<cc::PaintRecord> ImageSkiaRep::GetPaintRecord() const {
  DCHECK(type_ == ImageRepType::kImageTypeBitmap || !is_null());
  // If this image rep is of |kImageTypeDrawable| then it must have a paint
  // record.
  if (type_ == ImageRepType::kImageTypeDrawable || paint_record_)
    return paint_record_;

  // If this ImageRep was generated using a bitmap then it may not have a
  // paint record generated for it yet. We would have to generate it now.
  scoped_refptr<cc::DisplayItemList> display_item_list =
      base::MakeRefCounted<cc::DisplayItemList>(
          cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer);

  cc::RecordPaintCanvas record_canvas(
      display_item_list.get(), SkRect::MakeIWH(pixel_width(), pixel_height()));

  display_item_list->StartPaint();
  record_canvas.drawImage(paint_image(), 0, 0, nullptr);
  display_item_list->EndPaintOfPairedEnd();
  display_item_list->Finalize();

  paint_record_ = display_item_list->ReleaseAsRecord();
  return paint_record_;
}

const SkBitmap& ImageSkiaRep::GetBitmap() const {
  if (type_ == ImageRepType::kImageTypeDrawable && bitmap_.isNull() &&
      paint_record_) {
    // TODO(malaykeshav): Add a NOTREACHED() once all instances of this call
    // path is removed from the code base.

    // A request for bitmap was made even though this ImageSkiaRep is sourced
    // form a drawable(e.g. CanvasImageSource). This should not be happenning
    // as it forces a rasterization on the UI thread.
    bitmap_.allocN32Pixels(pixel_width(), pixel_height());
    bitmap_.eraseColor(SK_ColorTRANSPARENT);
    SkCanvas canvas(bitmap_);
    paint_record_->Playback(&canvas);
    bitmap_.setImmutable();
  }
  return bitmap_;
}

}  // namespace gfx
