// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/viz/service/display/software_renderer.h"

#include <stdint.h>

#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>

#include "base/functional/bind.h"
#include "cc/test/pixel_test_utils.h"
#include "cc/test/render_pass_test_utils.h"
#include "cc/test/resource_provider_test_utils.h"
#include "components/viz/client/client_resource_provider.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/common/quads/compositor_render_pass.h"
#include "components/viz/common/quads/debug_border_draw_quad.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/tile_draw_quad.h"
#include "components/viz/service/display/software_output_device.h"
#include "components/viz/service/display/viz_pixel_test.h"
#include "gpu/command_buffer/client/client_shared_image.h"
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/utils/SkNWayCanvas.h"
#include "ui/gfx/geometry/skia_conversions.h"

namespace viz {
namespace {
void DeleteSharedImage(scoped_refptr<gpu::ClientSharedImage> shared_image,
                       const gpu::SyncToken& sync_token,
                       bool is_lost) {
  shared_image->UpdateDestructionSyncToken(sync_token);
}

// A single rect drawn into `GenerateExpectedImage`.
struct ExpectedImageRect {
  gfx::Rect rect;
  SkColor4f color;
  bool debug_border = false;
};

SkBitmap GenerateExpectedImage(
    const gfx::Size& size,
    std::vector<ExpectedImageRect> back_to_front_rects) {
  SkBitmap bitmap;
  bitmap.allocN32Pixels(size.width(), size.height());
  bitmap.eraseColor(SkColors::kTransparent);

  SkCanvas canvas(bitmap);

  for (const auto& filled_rect : back_to_front_rects) {
    SkPaint paint;
    paint.setColor(filled_rect.color);

    if (filled_rect.debug_border) {
      // `SoftwareRenderer` draws debug borders as a path with a miter join.
      paint.setStyle(SkPaint::kStroke_Style);
      paint.setStrokeJoin(SkPaint::kMiter_Join);
      canvas.drawPath(SkPath::Rect(gfx::RectToSkRect(filled_rect.rect)), paint);
    } else {
      canvas.drawRect(gfx::RectToSkRect(filled_rect.rect), paint);
    }
  }

  return bitmap;
}

class SoftwareRendererTest : public VizPixelTest {
 public:
  SoftwareRendererTest() : VizPixelTest(RendererType::kSoftware) {}

  void SetUp() override {
    this->device_viewport_size_ = gfx::Size(100, 100);
    VizPixelTest::SetUp();
  }

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

  ClientResourceProvider* child_resource_provider() const {
    return child_resource_provider_.get();
  }

  ResourceId AllocateAndFillSoftwareResource(const gfx::Size& size,
                                             const SkBitmap& source) {
    auto* shared_image_interface =
        child_context_provider_->SharedImageInterface();
    auto shared_image =
        shared_image_interface->CreateSharedImageForSoftwareCompositor(
            {SinglePlaneFormat::kBGRA_8888, size, gfx::ColorSpace(),
             gpu::SHARED_IMAGE_USAGE_CPU_WRITE_ONLY,
             "SoftwareRendererTestSharedBitmap"});
    auto mapping = shared_image->Map();

    SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height());
    source.readPixels(info, mapping->GetMemoryForPlane(0).data(),
                      info.minRowBytes(), 0, 0);

    auto transferable_resource = TransferableResource::Make(
        shared_image, TransferableResource::ResourceSource::kTileRasterTask,
        shared_image->creation_sync_token());
    auto release_callback =
        base::BindOnce(&DeleteSharedImage, std::move(shared_image));

    return child_resource_provider_->ImportResource(
        std::move(transferable_resource), std::move(release_callback));
  }
};

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));

  AggregatedRenderPassId root_render_pass_id{1};
  auto root_render_pass = std::make_unique<AggregatedRenderPass>();
  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_rect, outer_rect,
                            gfx::MaskFilterInfo(), /*clip=*/std::nullopt,
                            /*contents_opaque=*/true, /*opacity_f=*/1.0,
                            SkBlendMode::kSrcOver, /*sorting_context=*/0,
                            /*layer_id=*/0u, /*fast_rounded_corner=*/false);
  auto* inner_quad =
      root_render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  inner_quad->SetNew(shared_quad_state, inner_rect, inner_rect, SkColors::kCyan,
                     false);
  inner_quad->visible_rect = visible_rect;
  auto* outer_quad =
      root_render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
  outer_quad->SetNew(shared_quad_state, outer_rect, outer_rect,
                     SkColors::kYellow, false);

  AggregatedRenderPassList list;
  list.push_back(std::move(root_render_pass));

  EXPECT_TRUE(
      RunPixelTest(&list,
                   GenerateExpectedImage(
                       outer_size,
                       {
                           {.rect = outer_rect, .color = SkColors::kYellow},
                           {.rect = visible_rect, .color = SkColors::kCyan},
                       }),
                   cc::ExactPixelComparator()));
}

TEST_F(SoftwareRendererTest, DebugBorderDrawQuad) {
  gfx::Size rect_size(10, 10);
  gfx::Size full_size(100, 100);
  gfx::Rect screen_rect(full_size);
  gfx::Rect rect_1(rect_size);
  gfx::Rect rect_2(gfx::Point(1, 1), rect_size);
  gfx::Rect rect_3(gfx::Point(2, 2), rect_size);
  gfx::Rect rect_4(gfx::Point(3, 3), rect_size);

  AggregatedRenderPassId root_render_pass_id{1};
  auto root_render_pass = std::make_unique<AggregatedRenderPass>();
  root_render_pass->SetNew(root_render_pass_id, screen_rect, screen_rect,
                           gfx::Transform());
  SharedQuadState* shared_quad_state =
      root_render_pass->CreateAndAppendSharedQuadState();
  shared_quad_state->SetAll(gfx::Transform(), screen_rect, screen_rect,
                            gfx::MaskFilterInfo(), /*clip=*/std::nullopt,
                            /*contents_opaque=*/true, /*opacity_f=*/1.0,
                            SkBlendMode::kSrcOver, /*sorting_context=*/0,
                            /*layer_id=*/0u, /*fast_rounded_corner=*/false);

  auto* quad_1 =
      root_render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
  quad_1->SetNew(shared_quad_state, rect_1, rect_1, SkColors::kCyan, false);
  auto* quad_2 =
      root_render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
  quad_2->SetNew(shared_quad_state, rect_2, rect_2, SkColors::kMagenta, false);

  auto* quad_3 =
      root_render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
  quad_3->SetNew(shared_quad_state, rect_3, rect_3, SkColors::kYellow, false);

  // Test one non-opaque color.
  // TODO(crbug.com/40219248): Colors clearly get transformed into ints at some
  // point in the pipeline, so we need to use values n/255 for now.
  SkColor4f semi_transparent_white =
      SkColor4f{1.0f, 1.0f, 1.0f, 128.0 / 255.0f};
  auto* quad_4 =
      root_render_pass->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
  quad_4->SetNew(shared_quad_state, rect_4, rect_4, semi_transparent_white,
                 false);

  AggregatedRenderPassList list;
  list.push_back(std::move(root_render_pass));

  EXPECT_TRUE(RunPixelTest(
      &list,
      GenerateExpectedImage(
          full_size,
          {
              {.rect = rect_4,
               .color = semi_transparent_white,
               .debug_border = true},
              {.rect = rect_3,
               .color = SkColors::kYellow,
               .debug_border = true},
              {.rect = rect_2,
               .color = SkColors::kMagenta,
               .debug_border = true},
              {.rect = rect_1, .color = SkColors::kCyan, .debug_border = true},
          }),
      cc::ExactPixelComparator()));
}

#if !BUILDFLAG(IS_ANDROID)
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);
  bool needs_blending = false;

  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);

  ResourceId resource_yellow =
      this->AllocateAndFillSoftwareResource(outer_size, yellow_tile);
  ResourceId resource_cyan =
      this->AllocateAndFillSoftwareResource(inner_size, cyan_tile);

  // Transfer resources to the parent, and get the resource map.
  std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map =
      cc::SendResourceAndGetChildToParentMap(
          {resource_yellow, resource_cyan}, resource_provider(),
          child_resource_provider(),
          child_context_provider_->SharedImageInterface());
  ResourceId mapped_resource_yellow = resource_map[resource_yellow];
  ResourceId mapped_resource_cyan = resource_map[resource_cyan];

  gfx::Rect root_rect = outer_rect;

  AggregatedRenderPassId root_render_pass_id{1};
  auto root_render_pass = std::make_unique<AggregatedRenderPass>();
  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_rect, outer_rect,
                            gfx::MaskFilterInfo(), /*clip=*/std::nullopt,
                            /*contents_opaque=*/true, /*opacity_f=*/1.0,
                            SkBlendMode::kSrcOver, /*sorting_context=*/0,
                            /*layer_id=*/0u, /*fast_rounded_corner=*/false);
  auto* inner_quad = root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
  inner_quad->SetNew(shared_quad_state, inner_rect, inner_rect, needs_blending,
                     mapped_resource_cyan, gfx::RectF(gfx::SizeF(inner_size)),
                     false, false);
  auto* outer_quad = root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
  outer_quad->SetNew(shared_quad_state, outer_rect, outer_rect, needs_blending,
                     mapped_resource_yellow, gfx::RectF(gfx::SizeF(outer_size)),
                     false, false);

  AggregatedRenderPassList list;
  list.push_back(std::move(root_render_pass));

  EXPECT_TRUE(
      RunPixelTest(&list,
                   GenerateExpectedImage(
                       outer_size,
                       {
                           {.rect = outer_rect, .color = SkColors::kYellow},
                           {.rect = inner_rect, .color = SkColors::kCyan},
                       }),
                   cc::ExactPixelComparator()));
}

TEST_F(SoftwareRendererTest, TileQuadVisibleRect) {
  gfx::Size tile_size(100, 100);
  gfx::Rect tile_rect(tile_size);
  gfx::Rect visible_rect = tile_rect;
  bool needs_blending = false;
  visible_rect.Inset(gfx::Insets::TLBR(2, 1, 4, 3));

  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);

  ResourceId resource_cyan =
      AllocateAndFillSoftwareResource(tile_size, cyan_tile);

  // Transfer resources to the parent, and get the resource map.
  std::unordered_map<ResourceId, ResourceId, ResourceIdHasher> resource_map =
      cc::SendResourceAndGetChildToParentMap(
          {resource_cyan}, resource_provider(), child_resource_provider(),
          child_context_provider_->SharedImageInterface());
  ResourceId mapped_resource_cyan = resource_map[resource_cyan];

  gfx::Rect root_rect(tile_size);
  AggregatedRenderPassId root_render_pass_id{1};
  std::unique_ptr<AggregatedRenderPass> root_render_pass =
      std::make_unique<AggregatedRenderPass>();
  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_rect, tile_rect,
                            gfx::MaskFilterInfo(), /*clip=*/std::nullopt,
                            /*contents_opaque=*/true, /*opacity_f=*/1.0,
                            SkBlendMode::kSrcOver, /*sorting_context=*/0,
                            /*layer_id=*/0u, /*fast_rounded_corner=*/false);
  auto* quad = root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
  quad->SetNew(shared_quad_state, tile_rect, tile_rect, needs_blending,
               mapped_resource_cyan, gfx::RectF(gfx::SizeF(tile_size)), false,
               false);
  quad->visible_rect = visible_rect;

  AggregatedRenderPassList list;
  list.push_back(std::move(root_render_pass));

  EXPECT_TRUE(RunPixelTest(
      &list,
      GenerateExpectedImage(
          root_rect.size(),
          {
              {.rect = visible_rect, .color = SkColors::kCyan},
              // Ensure last visible line is correct.
              {.rect = gfx::Rect(visible_rect.x(), visible_rect.bottom() - 1,
                                 visible_rect.width(), 1),
               .color = SkColors::kYellow},
          }),
      cc::ExactPixelComparator()));
}
#endif  // BUILDFLAG(IS_ANDROID)

class SoftwareRendererTestShouldClearRootRenderPass
    : public SoftwareRendererTest {
 public:
  void SetUp() override {
    renderer_settings_.should_clear_root_render_pass = false;
    SoftwareRendererTest::SetUp();
  }
};

TEST_F(SoftwareRendererTestShouldClearRootRenderPass,
       ShouldClearRootRenderPass) {
  gfx::Size viewport_size(100, 100);

  AggregatedRenderPassList list;

  // Draw a fullscreen green quad in a first frame.
  AggregatedRenderPassId root_clear_pass_id{1};
  AggregatedRenderPass* root_clear_pass =
      cc::AddRenderPass(&list, root_clear_pass_id, gfx::Rect(viewport_size),
                        gfx::Transform(), cc::FilterOperations());
  cc::AddQuad(root_clear_pass, gfx::Rect(viewport_size), SkColors::kGreen);

  EXPECT_TRUE(RunPixelTest(
      &list,
      GenerateExpectedImage(
          viewport_size,
          {
              {.rect = gfx::Rect(viewport_size), .color = SkColors::kGreen},
          }),
      cc::ExactPixelComparator()));

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

  AggregatedRenderPassId root_smaller_pass_id{2};
  AggregatedRenderPass* root_smaller_pass =
      cc::AddRenderPass(&list, root_smaller_pass_id, gfx::Rect(viewport_size),
                        gfx::Transform(), cc::FilterOperations());
  cc::AddQuad(root_smaller_pass, smaller_rect, SkColors::kMagenta);

  EXPECT_TRUE(RunPixelTest(
      &list,
      GenerateExpectedImage(
          viewport_size,
          {
              // If we didn't clear, the borders should still be green.
              {.rect = gfx::Rect(viewport_size), .color = SkColors::kGreen},
              {.rect = smaller_rect, .color = SkColors::kMagenta},
          }),
      cc::ExactPixelComparator()));
}

TEST_F(SoftwareRendererTest, RenderPassVisibleRect) {
  gfx::Size viewport_size(100, 100);

  AggregatedRenderPassList list;

  // Pass drawn as inner quad is magenta.
  gfx::Rect smaller_rect(20, 20, 60, 60);
  AggregatedRenderPassId smaller_pass_id{2};
  auto* smaller_pass =
      cc::AddRenderPass(&list, smaller_pass_id, smaller_rect, gfx::Transform(),
                        cc::FilterOperations());
  cc::AddQuad(smaller_pass, smaller_rect, SkColors::kMagenta);

  // Root pass is green.
  AggregatedRenderPassId root_clear_pass_id{1};
  AggregatedRenderPass* root_clear_pass =
      AddRenderPass(&list, root_clear_pass_id, gfx::Rect(viewport_size),
                    gfx::Transform(), cc::FilterOperations());
  cc::AddRenderPassQuad(root_clear_pass, smaller_pass);
  cc::AddQuad(root_clear_pass, gfx::Rect(viewport_size), SkColors::kGreen);

  // 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;

  EXPECT_TRUE(RunPixelTest(
      &list,
      GenerateExpectedImage(
          viewport_size,
          {
              {.rect = gfx::Rect(viewport_size), .color = SkColors::kGreen},
              {.rect = interior_visible_rect, .color = SkColors::kMagenta},
          }),
      cc::ExactPixelComparator()));
}

TEST_F(SoftwareRendererTest, ClipRoundRect) {
  gfx::Size viewport_size(100, 100);
  gfx::Rect clip_rect = gfx::Rect(1, 1, 30, 30);

  AggregatedRenderPassList list;
  AggregatedRenderPassId root_pass_id{1};
  AggregatedRenderPass* root_pass =
      AddRenderPass(&list, root_pass_id, gfx::Rect(viewport_size),
                    gfx::Transform(), cc::FilterOperations());

  // Draw outer rect with clipping.
  {
    gfx::Size outer_size(50, 50);
    gfx::Rect outer_rect(outer_size);

    SharedQuadState* shared_quad_state =
        root_pass->CreateAndAppendSharedQuadState();
    shared_quad_state->SetAll(gfx::Transform(), outer_rect, outer_rect,
                              gfx::MaskFilterInfo(), clip_rect,
                              /*contents_opaque=*/true, /*opacity_f=*/1.0,
                              SkBlendMode::kSrcOver, /*sorting_context=*/0,
                              /*layer_id=*/0u, /*fast_rounded_corner=*/false);
    auto* outer_quad = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    outer_quad->SetNew(shared_quad_state, outer_rect, outer_rect,
                       SkColors::kGreen, false);
  }

  // Draw inner round rect.
  {
    gfx::Size inner_size(20, 20);
    gfx::Rect inner_rect(inner_size);

    SharedQuadState* shared_quad_state =
        root_pass->CreateAndAppendSharedQuadState();
    shared_quad_state->SetAll(
        gfx::Transform(), inner_rect, inner_rect,
        gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(5, 5, 10, 10), 2)),
        /*clip=*/std::nullopt, /*contents_opaque=*/true, /*opacity_f=*/1.0,
        SkBlendMode::kSrcOver, /*sorting_context=*/0,
        /*layer_id=*/0u, /*fast_rounded_corner=*/false);
    auto* inner_quad = root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
    inner_quad->SetNew(shared_quad_state, inner_rect, inner_rect,
                       SkColors::kRed, false);
  }

  EXPECT_TRUE(RunPixelTest(
      &list,
      GenerateExpectedImage(viewport_size,
                            {
                                {.rect = clip_rect, .color = SkColors::kGreen},
                            }),
      cc::ExactPixelComparator()));
}

class SoftwareRendererTestPartialSwap : public SoftwareRendererTest {
  void SetUp() override {
    renderer_settings_.partial_swap_enabled = true;
    SoftwareRendererTest::SetUp();
  }
};

TEST_F(SoftwareRendererTestPartialSwap, PartialSwap) {
  gfx::Size viewport_size(100, 100);

  {
    // Draw one black frame to make sure output surface is reshaped before
    // tests.
    AggregatedRenderPassList list;
    AggregatedRenderPassId root_pass_id{1};
    SurfaceDamageRectList surface_damage_rect_list;
    auto* root_pass =
        AddRenderPass(&list, root_pass_id, gfx::Rect(viewport_size),
                      gfx::Transform(), cc::FilterOperations());
    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SkColors::kBlack);

    // Partial frame, we should pass this rect to the SoftwareOutputDevice.
    // partial swap is enabled.
    root_pass->damage_rect = gfx::Rect(viewport_size);

    EXPECT_TRUE(RunPixelTest(
        &list,
        GenerateExpectedImage(
            viewport_size,
            {
                {.rect = gfx::Rect(viewport_size), .color = SkColors::kBlack},
            }),
        cc::ExactPixelComparator()));
  }
  {
    AggregatedRenderPassList list;
    AggregatedRenderPassId root_pass_id{1};
    SurfaceDamageRectList surface_damage_rect_list;
    auto* root_pass =
        AddRenderPass(&list, root_pass_id, gfx::Rect(viewport_size),
                      gfx::Transform(), cc::FilterOperations());
    cc::AddQuad(root_pass, gfx::Rect(viewport_size), SkColors::kGreen);

    // Partial frame, only this region will draw, even though the quad covers
    // the whole frame.
    gfx::Rect damage_rect = gfx::Rect(2, 2, 3, 3);
    root_pass->damage_rect = damage_rect;

    EXPECT_TRUE(RunPixelTest(
        &list,
        GenerateExpectedImage(
            viewport_size,
            {
                {.rect = gfx::Rect(viewport_size), .color = SkColors::kBlack},
                {.rect = damage_rect, .color = SkColors::kGreen},
            }),
        cc::ExactPixelComparator()));
  }
}

}  // namespace
}  // namespace viz
