// 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/output/software_renderer.h"

#include "base/run_loop.h"
#include "cc/output/compositor_frame_metadata.h"
#include "cc/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "cc/output/software_output_device.h"
#include "cc/quads/render_pass.h"
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/solid_color_draw_quad.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/test/animation_test_common.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/geometry_test_utils.h"
#include "cc/test/render_pass_test_common.h"
#include "cc/test/render_pass_test_utils.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkCanvas.h"

namespace cc {
namespace {

class SoftwareRendererTest : public testing::Test, public RendererClient {
 public:
  void InitializeRenderer(
      scoped_ptr<SoftwareOutputDevice> software_output_device) {
    output_surface_ = FakeOutputSurface::CreateSoftware(
        software_output_device.Pass());
    CHECK(output_surface_->BindToClient(&output_surface_client_));

    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
    resource_provider_ = ResourceProvider::Create(output_surface_.get(),
                                                  shared_bitmap_manager_.get(),
                                                  NULL,
                                                  NULL,
                                                  0,
                                                  false,
                                                  1);
    renderer_ = SoftwareRenderer::Create(
        this, &settings_, output_surface_.get(), resource_provider());
  }

  ResourceProvider* resource_provider() const {
    return resource_provider_.get();
  }

  SoftwareRenderer* renderer() const { return renderer_.get(); }

  // RendererClient implementation.
  void SetFullRootLayerDamage() override {}

  scoped_ptr<SkBitmap> DrawAndCopyOutput(RenderPassList* list,
                                         float device_scale_factor,
                                         gfx::Rect device_viewport_rect) {
    scoped_ptr<SkBitmap> bitmap_result;
    base::RunLoop loop;

    list->back()->copy_requests.push_back(
        CopyOutputRequest::CreateBitmapRequest(
            base::Bind(&SoftwareRendererTest::SaveBitmapResult,
                       base::Unretained(&bitmap_result),
                       loop.QuitClosure())));

    renderer()->DrawFrame(list,
                          device_scale_factor,
                          device_viewport_rect,
                          device_viewport_rect,
                          false);
    loop.Run();
    return bitmap_result.Pass();
  }

  static void SaveBitmapResult(scoped_ptr<SkBitmap>* bitmap_result,
                               const base::Closure& quit_closure,
                               scoped_ptr<CopyOutputResult> result) {
    DCHECK(result->HasBitmap());
    *bitmap_result = result->TakeBitmap();
    quit_closure.Run();
  }

 protected:
  RendererSettings settings_;
  FakeOutputSurfaceClient output_surface_client_;
  scoped_ptr<FakeOutputSurface> output_surface_;
  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
  scoped_ptr<ResourceProvider> resource_provider_;
  scoped_ptr<SoftwareRenderer> renderer_;
};

TEST_F(SoftwareRendererTest, SolidColorQuad) {
  gfx::Size outer_size(100, 100);
  gfx::Size inner_size(98, 98);
  gfx::Rect outer_rect(outer_size);
  gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
  gfx::Rect visible_rect(gfx::Point(1, 2), gfx::Size(98, 97));

  InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));

  RenderPassId root_render_pass_id = RenderPassId(1, 1);
  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
  root_render_pass->SetNew(
      root_render_pass_id, outer_rect, outer_rect, gfx::Transform());
  SharedQuadState* shared_quad_state =
      root_render_pass->CreateAndAppendSharedQuadState();
  shared_quad_state->SetAll(gfx::Transform(),
                            outer_size,
                            outer_rect,
                            outer_rect,
                            false,
                            1.0,
                            SkXfermode::kSrcOver_Mode,
                            0);
  SolidColorDrawQuad* inner_quad =
      root_render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  inner_quad->SetNew(
      shared_quad_state, inner_rect, inner_rect, SK_ColorCYAN, false);
  inner_quad->visible_rect = visible_rect;
  SolidColorDrawQuad* outer_quad =
      root_render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  outer_quad->SetNew(
      shared_quad_state, outer_rect, outer_rect, SK_ColorYELLOW, false);

  RenderPassList list;
  list.push_back(root_render_pass.Pass());

  float device_scale_factor = 1.f;
  gfx::Rect device_viewport_rect(outer_size);
  scoped_ptr<SkBitmap> output =
      DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
  EXPECT_EQ(outer_rect.width(), output->info().fWidth);
  EXPECT_EQ(outer_rect.height(), output->info().fHeight);

  EXPECT_EQ(SK_ColorYELLOW, output->getColor(0, 0));
  EXPECT_EQ(SK_ColorYELLOW,
            output->getColor(outer_size.width() - 1, outer_size.height() - 1));
  EXPECT_EQ(SK_ColorYELLOW, output->getColor(1, 1));
  EXPECT_EQ(SK_ColorCYAN, output->getColor(1, 2));
  EXPECT_EQ(SK_ColorCYAN,
            output->getColor(inner_size.width() - 1, inner_size.height() - 1));
}

TEST_F(SoftwareRendererTest, TileQuad) {
  gfx::Size outer_size(100, 100);
  gfx::Size inner_size(98, 98);
  gfx::Rect outer_rect(outer_size);
  gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
  InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));

  ResourceProvider::ResourceId resource_yellow =
      resource_provider()->CreateResource(
          outer_size,
          GL_CLAMP_TO_EDGE,
          ResourceProvider::TextureHintImmutable,
          RGBA_8888);
  ResourceProvider::ResourceId resource_cyan =
      resource_provider()->CreateResource(
          inner_size,
          GL_CLAMP_TO_EDGE,
          ResourceProvider::TextureHintImmutable,
          RGBA_8888);

  SkBitmap yellow_tile;
  yellow_tile.allocN32Pixels(outer_size.width(), outer_size.height());
  yellow_tile.eraseColor(SK_ColorYELLOW);

  SkBitmap cyan_tile;
  cyan_tile.allocN32Pixels(inner_size.width(), inner_size.height());
  cyan_tile.eraseColor(SK_ColorCYAN);

  resource_provider()->SetPixels(
      resource_yellow,
      static_cast<uint8_t*>(yellow_tile.getPixels()),
      gfx::Rect(outer_size),
      gfx::Rect(outer_size),
      gfx::Vector2d());
  resource_provider()->SetPixels(resource_cyan,
                                 static_cast<uint8_t*>(cyan_tile.getPixels()),
                                 gfx::Rect(inner_size),
                                 gfx::Rect(inner_size),
                                 gfx::Vector2d());

  gfx::Rect root_rect = outer_rect;

  RenderPassId root_render_pass_id = RenderPassId(1, 1);
  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
  root_render_pass->SetNew(
      root_render_pass_id, root_rect, root_rect, gfx::Transform());
  SharedQuadState* shared_quad_state =
      root_render_pass->CreateAndAppendSharedQuadState();
  shared_quad_state->SetAll(gfx::Transform(),
                            outer_size,
                            outer_rect,
                            outer_rect,
                            false,
                            1.0,
                            SkXfermode::kSrcOver_Mode,
                            0);
  TileDrawQuad* inner_quad =
      root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
  inner_quad->SetNew(shared_quad_state,
                     inner_rect,
                     inner_rect,
                     inner_rect,
                     resource_cyan,
                     gfx::RectF(inner_size),
                     inner_size,
                     false,
                     false);
  TileDrawQuad* outer_quad =
      root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
  outer_quad->SetNew(shared_quad_state,
                     outer_rect,
                     outer_rect,
                     outer_rect,
                     resource_yellow,
                     gfx::RectF(outer_size),
                     outer_size,
                     false,
                     false);

  RenderPassList list;
  list.push_back(root_render_pass.Pass());

  float device_scale_factor = 1.f;
  gfx::Rect device_viewport_rect(outer_size);
  scoped_ptr<SkBitmap> output =
      DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
  EXPECT_EQ(outer_rect.width(), output->info().fWidth);
  EXPECT_EQ(outer_rect.height(), output->info().fHeight);

  EXPECT_EQ(SK_ColorYELLOW, output->getColor(0, 0));
  EXPECT_EQ(SK_ColorYELLOW,
            output->getColor(outer_size.width() - 1, outer_size.height() - 1));
  EXPECT_EQ(SK_ColorCYAN, output->getColor(1, 1));
  EXPECT_EQ(SK_ColorCYAN,
            output->getColor(inner_size.width() - 1, inner_size.height() - 1));
}

TEST_F(SoftwareRendererTest, TileQuadVisibleRect) {
  gfx::Size tile_size(100, 100);
  gfx::Rect tile_rect(tile_size);
  gfx::Rect visible_rect = tile_rect;
  visible_rect.Inset(1, 2, 3, 4);
  InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));

  ResourceProvider::ResourceId resource_cyan =
      resource_provider()->CreateResource(
          tile_size,
          GL_CLAMP_TO_EDGE,
          ResourceProvider::TextureHintImmutable,
          RGBA_8888);

  SkBitmap cyan_tile;  // The lowest five rows are yellow.
  cyan_tile.allocN32Pixels(tile_size.width(), tile_size.height());
  cyan_tile.eraseColor(SK_ColorCYAN);
  cyan_tile.eraseArea(
      SkIRect::MakeLTRB(
          0, visible_rect.bottom() - 1, tile_rect.width(), tile_rect.bottom()),
      SK_ColorYELLOW);

  resource_provider()->SetPixels(resource_cyan,
                                 static_cast<uint8_t*>(cyan_tile.getPixels()),
                                 gfx::Rect(tile_size),
                                 gfx::Rect(tile_size),
                                 gfx::Vector2d());

  gfx::Rect root_rect(tile_size);

  RenderPassId root_render_pass_id = RenderPassId(1, 1);
  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
  root_render_pass->SetNew(
      root_render_pass_id, root_rect, root_rect, gfx::Transform());
  SharedQuadState* shared_quad_state =
      root_render_pass->CreateAndAppendSharedQuadState();
  shared_quad_state->SetAll(gfx::Transform(),
                            tile_size,
                            tile_rect,
                            tile_rect,
                            false,
                            1.0,
                            SkXfermode::kSrcOver_Mode,
                            0);
  TileDrawQuad* quad =
      root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
  quad->SetNew(shared_quad_state,
               tile_rect,
               tile_rect,
               tile_rect,
               resource_cyan,
               gfx::RectF(tile_size),
               tile_size,
               false,
               false);
  quad->visible_rect = visible_rect;

  RenderPassList list;
  list.push_back(root_render_pass.Pass());

  float device_scale_factor = 1.f;
  gfx::Rect device_viewport_rect(tile_size);
  scoped_ptr<SkBitmap> output =
      DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
  EXPECT_EQ(tile_rect.width(), output->info().fWidth);
  EXPECT_EQ(tile_rect.height(), output->info().fHeight);

  // Check portion of tile not in visible rect isn't drawn.
  const unsigned int kTransparent = SK_ColorTRANSPARENT;
  EXPECT_EQ(kTransparent, output->getColor(0, 0));
  EXPECT_EQ(kTransparent,
            output->getColor(tile_rect.width() - 1, tile_rect.height() - 1));
  EXPECT_EQ(kTransparent,
            output->getColor(visible_rect.x() - 1, visible_rect.y() - 1));
  EXPECT_EQ(kTransparent,
            output->getColor(visible_rect.right(), visible_rect.bottom()));
  // Ensure visible part is drawn correctly.
  EXPECT_EQ(SK_ColorCYAN, output->getColor(visible_rect.x(), visible_rect.y()));
  EXPECT_EQ(
      SK_ColorCYAN,
      output->getColor(visible_rect.right() - 2, visible_rect.bottom() - 2));
  // Ensure last visible line is correct.
  EXPECT_EQ(
      SK_ColorYELLOW,
      output->getColor(visible_rect.right() - 1, visible_rect.bottom() - 1));
}

TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) {
  float device_scale_factor = 1.f;
  gfx::Rect device_viewport_rect(0, 0, 100, 100);

  settings_.should_clear_root_render_pass = false;
  InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));

  RenderPassList list;

  // Draw a fullscreen green quad in a first frame.
  RenderPassId root_clear_pass_id(1, 0);
  TestRenderPass* root_clear_pass = AddRenderPass(
      &list, root_clear_pass_id, device_viewport_rect, gfx::Transform());
  AddQuad(root_clear_pass, device_viewport_rect, SK_ColorGREEN);

  renderer()->DecideRenderPassAllocationsForFrame(list);

  scoped_ptr<SkBitmap> output =
      DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
  EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth);
  EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight);

  EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0));
  EXPECT_EQ(SK_ColorGREEN,
            output->getColor(device_viewport_rect.width() - 1,
                             device_viewport_rect.height() - 1));

  list.clear();

  // Draw a smaller magenta rect without filling the viewport in a separate
  // frame.
  gfx::Rect smaller_rect(20, 20, 60, 60);

  RenderPassId root_smaller_pass_id(2, 0);
  TestRenderPass* root_smaller_pass = AddRenderPass(
      &list, root_smaller_pass_id, device_viewport_rect, gfx::Transform());
  AddQuad(root_smaller_pass, smaller_rect, SK_ColorMAGENTA);

  renderer()->DecideRenderPassAllocationsForFrame(list);

  output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
  EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth);
  EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight);

  // If we didn't clear, the borders should still be green.
  EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0));
  EXPECT_EQ(SK_ColorGREEN,
            output->getColor(device_viewport_rect.width() - 1,
                             device_viewport_rect.height() - 1));

  EXPECT_EQ(SK_ColorMAGENTA,
            output->getColor(smaller_rect.x(), smaller_rect.y()));
  EXPECT_EQ(
      SK_ColorMAGENTA,
      output->getColor(smaller_rect.right() - 1, smaller_rect.bottom() - 1));
}

TEST_F(SoftwareRendererTest, RenderPassVisibleRect) {
  float device_scale_factor = 1.f;
  gfx::Rect device_viewport_rect(0, 0, 100, 100);
  InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));

  RenderPassList list;

  // Pass drawn as inner quad is magenta.
  gfx::Rect smaller_rect(20, 20, 60, 60);
  RenderPassId smaller_pass_id(2, 1);
  TestRenderPass* smaller_pass =
      AddRenderPass(&list, smaller_pass_id, smaller_rect, gfx::Transform());
  AddQuad(smaller_pass, smaller_rect, SK_ColorMAGENTA);

  // Root pass is green.
  RenderPassId root_clear_pass_id(1, 0);
  TestRenderPass* root_clear_pass = AddRenderPass(
      &list, root_clear_pass_id, device_viewport_rect, gfx::Transform());
  AddRenderPassQuad(root_clear_pass, smaller_pass);
  AddQuad(root_clear_pass, device_viewport_rect, SK_ColorGREEN);

  // Interior pass quad has smaller visible rect.
  gfx::Rect interior_visible_rect(30, 30, 40, 40);
  root_clear_pass->quad_list.front()->visible_rect = interior_visible_rect;

  renderer()->DecideRenderPassAllocationsForFrame(list);

  scoped_ptr<SkBitmap> output =
      DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
  EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth);
  EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight);

  EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0));
  EXPECT_EQ(SK_ColorGREEN,
            output->getColor(device_viewport_rect.width() - 1,
                             device_viewport_rect.height() - 1));

  // Part outside visible rect should remain green.
  EXPECT_EQ(SK_ColorGREEN,
            output->getColor(smaller_rect.x(), smaller_rect.y()));
  EXPECT_EQ(
      SK_ColorGREEN,
      output->getColor(smaller_rect.right() - 1, smaller_rect.bottom() - 1));

  EXPECT_EQ(
      SK_ColorMAGENTA,
      output->getColor(interior_visible_rect.x(), interior_visible_rect.y()));
  EXPECT_EQ(SK_ColorMAGENTA,
            output->getColor(interior_visible_rect.right() - 1,
                             interior_visible_rect.bottom() - 1));
}

}  // namespace
}  // namespace cc
