// Copyright 2011 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/bitmap_content_layer_updater.h"

#include "cc/debug/devtools_instrumentation.h"
#include "cc/debug/rendering_stats_instrumentation.h"
#include "cc/resources/layer_painter.h"
#include "cc/resources/prioritized_resource.h"
#include "cc/resources/resource_update.h"
#include "cc/resources/resource_update_queue.h"
#include "skia/ext/platform_canvas.h"

namespace cc {

BitmapContentLayerUpdater::Resource::Resource(
    BitmapContentLayerUpdater* updater,
    scoped_ptr<PrioritizedResource> texture)
    : LayerUpdater::Resource(texture.Pass()), updater_(updater) {}

BitmapContentLayerUpdater::Resource::~Resource() {}

void BitmapContentLayerUpdater::Resource::Update(
    ResourceUpdateQueue* queue,
    const gfx::Rect& source_rect,
    const gfx::Vector2d& dest_offset,
    bool partial_update) {
  updater_->UpdateTexture(
      queue, texture(), source_rect, dest_offset, partial_update);
}

scoped_refptr<BitmapContentLayerUpdater> BitmapContentLayerUpdater::Create(
    scoped_ptr<LayerPainter> painter,
    int layer_id) {
  return make_scoped_refptr(
      new BitmapContentLayerUpdater(painter.Pass(),
                                    layer_id));
}

BitmapContentLayerUpdater::BitmapContentLayerUpdater(
    scoped_ptr<LayerPainter> painter,
    int layer_id)
    : ContentLayerUpdater(painter.Pass(), layer_id) {
}

BitmapContentLayerUpdater::~BitmapContentLayerUpdater() {}

scoped_ptr<LayerUpdater::Resource> BitmapContentLayerUpdater::CreateResource(
    PrioritizedResourceManager* manager) {
  return make_scoped_ptr(
      new Resource(this, PrioritizedResource::Create(manager)));
}

void BitmapContentLayerUpdater::PrepareToUpdate(const gfx::Size& content_size,
                                                const gfx::Rect& paint_rect,
                                                const gfx::Size& tile_size,
                                                float contents_width_scale,
                                                float contents_height_scale) {
  if (canvas_size_ != paint_rect.size()) {
    devtools_instrumentation::ScopedLayerTask paint_setup(
        devtools_instrumentation::kPaintSetup, layer_id_);
    canvas_size_ = paint_rect.size();
    bitmap_backing_.allocN32Pixels(
        canvas_size_.width(), canvas_size_.height(), layer_is_opaque_);
    // TODO(danak): Remove when skia does the check for us: crbug.com/360384
    canvas_ = skia::AdoptRef(new SkCanvas(bitmap_backing_));
    DCHECK_EQ(paint_rect.width(), canvas_->getBaseLayerSize().width());
    DCHECK_EQ(paint_rect.height(), canvas_->getBaseLayerSize().height());
  }

  PaintContents(canvas_.get(),
                content_size,
                paint_rect,
                contents_width_scale,
                contents_height_scale);
}

void BitmapContentLayerUpdater::UpdateTexture(ResourceUpdateQueue* queue,
                                              PrioritizedResource* texture,
                                              const gfx::Rect& source_rect,
                                              const gfx::Vector2d& dest_offset,
                                              bool partial_update) {
  CHECK(canvas_);
  ResourceUpdate upload = ResourceUpdate::Create(
      texture, &bitmap_backing_, paint_rect(), source_rect, dest_offset);
  if (partial_update)
    queue->AppendPartialUpload(upload);
  else
    queue->AppendFullUpload(upload);
}

void BitmapContentLayerUpdater::ReduceMemoryUsage() {
  canvas_.clear();
  canvas_size_ = gfx::Size();
}

void BitmapContentLayerUpdater::SetOpaque(bool opaque) {
  if (opaque != layer_is_opaque_) {
    canvas_.clear();
    canvas_size_ = gfx::Size();
  }

  ContentLayerUpdater::SetOpaque(opaque);
}

}  // namespace cc
