// Copyright 2016 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 <stddef.h>

#include "build/build_config.h"
#include "cc/input/scrollbar.h"
#include "cc/layers/painted_overlay_scrollbar_layer.h"
#include "cc/layers/painted_scrollbar_layer.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/paint/paint_canvas.h"
#include "cc/paint/paint_flags.h"
#include "cc/test/fake_scrollbar.h"
#include "cc/test/layer_tree_pixel_test.h"
#include "cc/test/pixel_comparator.h"
#include "cc/trees/layer_tree_impl.h"
#include "components/viz/test/test_in_process_context_provider.h"
#include "gpu/command_buffer/client/gles2_interface.h"

#if !defined(OS_ANDROID)

namespace cc {
namespace {

class LayerTreeHostScrollbarsPixelTest
    : public LayerTreePixelTest,
      public ::testing::WithParamInterface<LayerTreeTest::RendererType> {
 protected:
  LayerTreeHostScrollbarsPixelTest() = default;

  RendererType renderer_type() { return GetParam(); }

  void SetupTree() override {
    SetInitialDeviceScaleFactor(device_scale_factor_);
    LayerTreePixelTest::SetupTree();
  }

  float device_scale_factor_ = 1.f;
};

class PaintedScrollbar : public FakeScrollbar {
 public:
  explicit PaintedScrollbar(const gfx::Size& size)
      : FakeScrollbar(/*paint*/ true,
                      /*has_thumb*/ false,
                      HORIZONTAL,
                      /*is_left_side_vertical_scrollbar*/ false,
                      /*is_overlay*/ false) {
    set_track_rect(gfx::Rect(size));
  }

  void PaintPart(PaintCanvas* canvas,
                 ScrollbarPart part,
                 const gfx::Rect& rect) override {
    PaintFlags flags;
    flags.setStyle(PaintFlags::kStroke_Style);
    flags.setStrokeWidth(SkIntToScalar(paint_scale_));
    flags.setColor(color_);
    gfx::Rect inset_rect = rect;
    while (!inset_rect.IsEmpty()) {
      int big = paint_scale_ + 2;
      int small = paint_scale_;
      inset_rect.Inset(big, big, small, small);
      canvas->drawRect(RectToSkRect(inset_rect), flags);
      inset_rect.Inset(big, big, small, small);
    }
  }

  void set_paint_scale(int scale) { paint_scale_ = scale; }

 private:
  ~PaintedScrollbar() override = default;

  int paint_scale_ = 4;
  SkColor color_ = SK_ColorGREEN;
};

LayerTreeTest::RendererType const kRendererTypes[] = {
    LayerTreeTest::RENDERER_GL,
    LayerTreeTest::RENDERER_SKIA_GL,
#if defined(ENABLE_CC_VULKAN_TESTS)
    LayerTreeTest::RENDERER_SKIA_VK,
#endif
};

INSTANTIATE_TEST_SUITE_P(All,
                         LayerTreeHostScrollbarsPixelTest,
                         ::testing::ValuesIn(kRendererTypes));

TEST_P(LayerTreeHostScrollbarsPixelTest, NoScale) {
  scoped_refptr<SolidColorLayer> background =
      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);

  auto scrollbar = base::MakeRefCounted<PaintedScrollbar>(gfx::Size(200, 200));
  scoped_refptr<PaintedScrollbarLayer> layer =
      PaintedScrollbarLayer::Create(std::move(scrollbar));
  layer->SetIsDrawable(true);
  layer->SetBounds(gfx::Size(200, 200));
  background->AddChild(layer);

  RunPixelTest(renderer_type(), background,
               base::FilePath(FILE_PATH_LITERAL("spiral.png")));
}

TEST_P(LayerTreeHostScrollbarsPixelTest, DeviceScaleFactor) {
  // With a device scale of 2, the scrollbar should still be rendered
  // pixel-perfect, not show scaling artifacts
  device_scale_factor_ = 2.f;

  scoped_refptr<SolidColorLayer> background =
      CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE);

  auto scrollbar = base::MakeRefCounted<PaintedScrollbar>(gfx::Size(100, 100));
  scoped_refptr<PaintedScrollbarLayer> layer =
      PaintedScrollbarLayer::Create(std::move(scrollbar));
  layer->SetIsDrawable(true);
  layer->SetBounds(gfx::Size(100, 100));
  background->AddChild(layer);

  RunPixelTest(renderer_type(), background,
               base::FilePath(FILE_PATH_LITERAL("spiral_double_scale.png")));
}

TEST_P(LayerTreeHostScrollbarsPixelTest, TransformScale) {
  scoped_refptr<SolidColorLayer> background =
      CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);

  auto scrollbar = base::MakeRefCounted<PaintedScrollbar>(gfx::Size(100, 100));
  scoped_refptr<PaintedScrollbarLayer> layer =
      PaintedScrollbarLayer::Create(std::move(scrollbar));
  layer->SetIsDrawable(true);
  layer->SetBounds(gfx::Size(100, 100));
  background->AddChild(layer);

  // This has a scale of 2, it should still be rendered pixel-perfect, not show
  // scaling artifacts
  gfx::Transform scale_transform;
  scale_transform.Scale(2.0, 2.0);
  layer->SetTransform(scale_transform);

  RunPixelTest(renderer_type(), background,
               base::FilePath(FILE_PATH_LITERAL("spiral_double_scale.png")));
}

// Disabled on TSan due to frequent timeouts. crbug.com/848994
#if defined(THREAD_SANITIZER)
#define MAYBE_HugeTransformScale DISABLED_HugeTransformScale
#else
#define MAYBE_HugeTransformScale HugeTransformScale
#endif
TEST_P(LayerTreeHostScrollbarsPixelTest, MAYBE_HugeTransformScale) {
  scoped_refptr<SolidColorLayer> background =
      CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE);

  auto scrollbar = base::MakeRefCounted<PaintedScrollbar>(gfx::Size(10, 400));
  scrollbar->set_paint_scale(1);
  scoped_refptr<PaintedScrollbarLayer> layer =
      PaintedScrollbarLayer::Create(std::move(scrollbar));
  layer->SetIsDrawable(true);
  layer->SetBounds(gfx::Size(10, 400));
  background->AddChild(layer);

  auto context = base::MakeRefCounted<viz::TestInProcessContextProvider>(
      /*enable_oop_rasterization=*/false,
      /*support_locking=*/false);
  gpu::ContextResult result = context->BindToCurrentThread();
  DCHECK_EQ(result, gpu::ContextResult::kSuccess);
  int max_texture_size = 0;
  context->ContextGL()->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);

  // We want a scale that creates a texture taller than the max texture size. If
  // there's no clamping, the texture will be invalid and we'll just get black.
  double scale = 64.0;
  ASSERT_GT(scale * layer->bounds().height(), max_texture_size);

  // Let's show the bottom right of the layer, so we know the texture wasn't
  // just cut off.
  layer->SetPosition(
      gfx::PointF(-10.f * scale + 400.f, -400.f * scale + 400.f));

  gfx::Transform scale_transform;
  scale_transform.Scale(scale, scale);
  layer->SetTransform(scale_transform);

  if (renderer_type() == RENDERER_SKIA_GL ||
      renderer_type() == RENDERER_SKIA_VK)
    pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true);

  RunPixelTest(renderer_type(), background,
               base::FilePath(FILE_PATH_LITERAL("spiral_64_scale.png")));
}

class LayerTreeHostOverlayScrollbarsPixelTest
    : public LayerTreeHostScrollbarsPixelTest {
 protected:
  LayerTreeHostOverlayScrollbarsPixelTest() = default;

  void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
    LayerImpl* layer = host_impl->active_tree()->LayerById(scrollbar_layer_id_);
    ScrollbarLayerImplBase* scrollbar = layer->ToScrollbarLayer();
    scrollbar->SetThumbThicknessScaleFactor(thickness_scale_);
  }

  int scrollbar_layer_id_;
  float thickness_scale_;
};

class PaintedOverlayScrollbar : public FakeScrollbar {
 public:
  PaintedOverlayScrollbar()
      : FakeScrollbar(/*paint*/ true,
                      /*has_thumb*/ true,
                      VERTICAL,
                      /*is_left_side_vertical_scrollbar*/ false,
                      /*is_overlay*/ true) {
    set_thumb_size(gfx::Size(15, 50));
    set_track_rect(gfx::Rect(0, 0, 15, 400));
  }

  void PaintPart(PaintCanvas* canvas,
                 ScrollbarPart part,
                 const gfx::Rect& rect) override {
    // The outside of the rect will be painted with a 1 pixel black, red, then
    // blue border. The inside will be solid blue. This will allow the test to
    // ensure that scaling the thumb doesn't scale the border at all.  Note
    // that the inside of the border must be the same color as the center tile
    // to prevent an interpolation from being applied.
    PaintFlags flags;
    flags.setStyle(PaintFlags::kFill_Style);
    flags.setStrokeWidth(SkIntToScalar(1));
    flags.setColor(SK_ColorBLACK);

    gfx::Rect inset_rect = rect;
    canvas->drawRect(RectToSkRect(inset_rect), flags);

    flags.setColor(SK_ColorRED);
    inset_rect.Inset(1, 1);
    canvas->drawRect(RectToSkRect(inset_rect), flags);

    flags.setColor(SK_ColorBLUE);
    inset_rect.Inset(1, 1);
    canvas->drawRect(RectToSkRect(inset_rect), flags);
  }

  bool UsesNinePatchThumbResource() const override { return true; }
  gfx::Size NinePatchThumbCanvasSize() const override {
    return gfx::Size(7, 7);
  }
  gfx::Rect NinePatchThumbAperture() const override {
    return gfx::Rect(3, 3, 1, 1);
  }

 private:
  ~PaintedOverlayScrollbar() override = default;
};

INSTANTIATE_TEST_SUITE_P(All,
                         LayerTreeHostOverlayScrollbarsPixelTest,
                         ::testing::ValuesIn(kRendererTypes));

// Simulate increasing the thickness of a painted overlay scrollbar. Ensure that
// the scrollbar border remains crisp.
TEST_P(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledUp) {
  scoped_refptr<SolidColorLayer> background =
      CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE);

  auto scrollbar = base::MakeRefCounted<PaintedOverlayScrollbar>();
  scoped_refptr<PaintedOverlayScrollbarLayer> layer =
      PaintedOverlayScrollbarLayer::Create(std::move(scrollbar));

  scrollbar_layer_id_ = layer->id();
  thickness_scale_ = 5.f;

  layer->SetIsDrawable(true);
  layer->SetBounds(gfx::Size(10, 300));
  background->AddChild(layer);

  layer->SetPosition(gfx::PointF(185, 10));

  RunPixelTest(
      renderer_type(), background,
      base::FilePath(FILE_PATH_LITERAL("overlay_scrollbar_scaled_up.png")));
}

// Simulate decreasing the thickness of a painted overlay scrollbar. Ensure that
// the scrollbar border remains crisp.
TEST_P(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledDown) {
  scoped_refptr<SolidColorLayer> background =
      CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE);

  auto scrollbar = base::MakeRefCounted<PaintedOverlayScrollbar>();
  scoped_refptr<PaintedOverlayScrollbarLayer> layer =
      PaintedOverlayScrollbarLayer::Create(std::move(scrollbar));

  scrollbar_layer_id_ = layer->id();
  thickness_scale_ = 0.4f;

  layer->SetIsDrawable(true);
  layer->SetBounds(gfx::Size(10, 300));
  background->AddChild(layer);

  layer->SetPosition(gfx::PointF(185, 10));

  RunPixelTest(
      renderer_type(), background,
      base::FilePath(FILE_PATH_LITERAL("overlay_scrollbar_scaled_down.png")));
}

}  // namespace
}  // namespace cc

#endif  // OS_ANDROID
