// Copyright 2013 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 <stdint.h>

#include "build/build_config.h"
#include "cc/layers/picture_image_layer.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/paint/paint_image.h"
#include "cc/paint/paint_image_builder.h"
#include "cc/paint/render_surface_filters.h"
#include "cc/paint/skia_paint_canvas.h"
#include "cc/test/layer_tree_pixel_resource_test.h"
#include "cc/test/pixel_comparator.h"
#include "components/viz/test/test_layer_tree_frame_sink.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSurface.h"

#if !defined(OS_ANDROID)

namespace cc {
namespace {

SkBlendMode const kBlendModes[] = {
    SkBlendMode::kSrcOver,   SkBlendMode::kScreen,
    SkBlendMode::kOverlay,   SkBlendMode::kDarken,
    SkBlendMode::kLighten,   SkBlendMode::kColorDodge,
    SkBlendMode::kColorBurn, SkBlendMode::kHardLight,
    SkBlendMode::kSoftLight, SkBlendMode::kDifference,
    SkBlendMode::kExclusion, SkBlendMode::kMultiply,
    SkBlendMode::kHue,       SkBlendMode::kSaturation,
    SkBlendMode::kColor,     SkBlendMode::kLuminosity};

SkColor kCSSTestColors[] = {
    0xffff0000,  // red
    0xff00ff00,  // lime
    0xff0000ff,  // blue
    0xff00ffff,  // aqua
    0xffff00ff,  // fuchsia
    0xffffff00,  // yellow
    0xff008000,  // green
    0xff800000,  // maroon
    0xff000080,  // navy
    0xff800080,  // purple
    0xff808000,  // olive
    0xff008080,  // teal
    0xfffa8072,  // salmon
    0xffc0c0c0,  // silver
    0xff000000,  // black
    0xff808080,  // gray
    0x80000000,  // black with transparency
    0xffffffff,  // white
    0x80ffffff,  // white with transparency
    0x00000000   // transparent
};

const int kCSSTestColorsCount = arraysize(kCSSTestColors);

using RenderPassOptions = uint32_t;
const uint32_t kUseMasks = 1 << 0;
const uint32_t kUseAntialiasing = 1 << 1;
const uint32_t kUseColorMatrix = 1 << 2;
const uint32_t kForceShaders = 1 << 3;

class LayerTreeHostBlendingPixelTest
    : public LayerTreeHostPixelResourceTest,
      public ::testing::WithParamInterface<
          ::testing::tuple<PixelResourceTestCase, SkBlendMode>> {
 public:
  LayerTreeHostBlendingPixelTest()
      : force_antialiasing_(false), force_blending_with_shaders_(false) {
    pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
  }

  PixelResourceTestCase resource_type() const {
    return ::testing::get<0>(GetParam());
  }
  SkBlendMode current_blend_mode() const {
    return ::testing::get<1>(GetParam());
  }

 protected:
  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
      const viz::RendererSettings& renderer_settings,
      double refresh_rate,
      scoped_refptr<viz::ContextProvider> compositor_context_provider,
      scoped_refptr<viz::RasterContextProvider> worker_context_provider)
      override {
    viz::RendererSettings modified_renderer_settings = renderer_settings;
    modified_renderer_settings.force_antialiasing = force_antialiasing_;
    modified_renderer_settings.force_blending_with_shaders =
        force_blending_with_shaders_;
    return LayerTreeHostPixelResourceTest::CreateLayerTreeFrameSink(
        modified_renderer_settings, refresh_rate, compositor_context_provider,
        worker_context_provider);
  }

  sk_sp<SkSurface> CreateColorfulSurface(int width, int height) {
    // Draw the backdrop with horizontal lanes.
    const int kLaneWidth = width;
    const int kLaneHeight = height / kCSSTestColorsCount;
    sk_sp<SkSurface> backing_store =
        SkSurface::MakeRasterN32Premul(width, height);
    SkCanvas* canvas = backing_store->getCanvas();
    canvas->clear(SK_ColorTRANSPARENT);
    for (int i = 0; i < kCSSTestColorsCount; ++i) {
      SkPaint paint;
      paint.setColor(kCSSTestColors[i]);
      canvas->drawRect(
          SkRect::MakeXYWH(0, i * kLaneHeight, kLaneWidth, kLaneHeight), paint);
    }
    return backing_store;
  }

  scoped_refptr<Layer> CreateColorfulBackdropLayer(int width, int height) {
    sk_sp<SkSurface> backing_store = CreateColorfulSurface(width, height);
    scoped_refptr<PictureImageLayer> layer = PictureImageLayer::Create();
    layer->SetIsDrawable(true);
    layer->SetBounds(gfx::Size(width, height));
    layer->SetImage(PaintImageBuilder::WithDefault()
                        .set_id(PaintImage::GetNextId())
                        .set_image(backing_store->makeImageSnapshot(),
                                   PaintImage::GetNextContentId())
                        .TakePaintImage(),
                    SkMatrix::I(), false);
    return layer;
  }

  void SetupMaskLayer(scoped_refptr<Layer> layer) {
    gfx::Size bounds = layer->bounds();
    scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create();
    mask->SetIsDrawable(true);
    mask->SetLayerMaskType(Layer::LayerMaskType::MULTI_TEXTURE_MASK);
    mask->SetBounds(bounds);

    sk_sp<SkSurface> surface =
        SkSurface::MakeRasterN32Premul(bounds.width(), bounds.height());
    SkCanvas* canvas = surface->getCanvas();
    SkPaint paint;
    paint.setColor(SK_ColorWHITE);
    canvas->clear(SK_ColorTRANSPARENT);
    // This layer is a long skinny layer of size 2, so have the mask
    // cover the right half of it
    canvas->drawRect(
        SkRect::MakeXYWH(1, 0, bounds.width() - 1, bounds.height()), paint);
    mask->SetImage(PaintImageBuilder::WithDefault()
                       .set_id(PaintImage::GetNextId())
                       .set_image(surface->makeImageSnapshot(),
                                  PaintImage::GetNextContentId())
                       .TakePaintImage(),
                   SkMatrix::I(), false);
    layer->SetMaskLayer(mask.get());
  }

  void SetupColorMatrix(scoped_refptr<Layer> layer) {
    FilterOperations filter_operations;
    filter_operations.Append(FilterOperation::CreateSepiaFilter(.001f));
    layer->SetFilters(filter_operations);
  }

  void CreateBlendingColorLayers(int lane_width,
                                 int lane_height,
                                 scoped_refptr<Layer> background,
                                 RenderPassOptions flags) {
    gfx::Rect child_rect(lane_width, lane_height);

    scoped_refptr<SolidColorLayer> lane =
        CreateSolidColorLayer(child_rect, misc_opaque_color_);
    lane->SetBlendMode(current_blend_mode());
    lane->SetForceRenderSurfaceForTesting(true);

    // Layers with kDstIn blend mode with a mask is not supported.
    if (flags & kUseMasks)
      SetupMaskLayer(lane);
    if (flags & kUseColorMatrix) {
      SetupColorMatrix(lane);
    }
    background->AddChild(lane);
  }

  SkBitmap CreateBlendingWithRenderPassExpected(int width,
                                                int height,
                                                RenderPassOptions flags) {
    // Should match RunBlendingWithRenderPass.
    sk_sp<SkSurface> surface = CreateColorfulSurface(width, height);

    SkPaint paint;
    paint.setBlendMode(current_blend_mode());
    paint.setColor(misc_opaque_color_);

    SkRect rect;
    if (flags & kUseMasks) {
      rect = SkRect::MakeXYWH(1, 0, width - 1, height);
    } else {
      rect = SkRect::MakeWH(width, height);
    }
    surface->getCanvas()->drawRect(rect, paint);

    SkBitmap expected;
    expected.allocN32Pixels(width, height);
    SkCanvas canvas(expected);
    canvas.clear(SK_ColorWHITE);
    canvas.drawImage(surface->makeImageSnapshot(), 0, 0);

    return expected;
  }

  void RunBlendingWithRenderPass(RenderPassOptions flags) {
    const int kRootWidth = 2;
    const int kRootHeight = kRootWidth * kCSSTestColorsCount;
    InitializeFromTestCase(resource_type());

    // Force shaders only applies to gl renderer.
    if (test_type_ != PIXEL_TEST_GL && flags & kForceShaders)
      return;

    SCOPED_TRACE(test_type_ == PIXEL_TEST_GL ? "GL" : "Software");
    SCOPED_TRACE(SkBlendMode_Name(current_blend_mode()));

    scoped_refptr<SolidColorLayer> root = CreateSolidColorLayer(
        gfx::Rect(kRootWidth, kRootHeight), SK_ColorWHITE);
    scoped_refptr<Layer> background =
        CreateColorfulBackdropLayer(kRootWidth, kRootHeight);

    background->SetIsRootForIsolatedGroup(true);
    root->AddChild(background);

    CreateBlendingColorLayers(kRootWidth, kRootHeight, background.get(), flags);

    this->force_antialiasing_ = (flags & kUseAntialiasing);
    this->force_blending_with_shaders_ = (flags & kForceShaders);

    if ((flags & kUseAntialiasing) && (test_type_ == PIXEL_TEST_GL)) {
      // Blending results might differ with one pixel.
      // Don't allow large errors here, only off by ones.
      // However, large error still has to be specified to satisfy
      // the pixel comparator so set it equivalent to small errors.
      int large_error_allowed = 1;
      int small_error_allowed = 1;
      float percentage_pixels_small_error = 35.0f;
      float percentage_pixels_error = 35.0f;
      // The average error is still close to 1.
      float average_error_allowed_in_bad_pixels = 1.4f;

      pixel_comparator_.reset(
          new FuzzyPixelComparator(false,  // discard_alpha
                                   percentage_pixels_error,
                                   percentage_pixels_small_error,
                                   average_error_allowed_in_bad_pixels,
                                   large_error_allowed,
                                   small_error_allowed));
    }

    RunPixelResourceTest(root, CreateBlendingWithRenderPassExpected(
                                   kRootWidth, kRootHeight, flags));
  }

  bool force_antialiasing_;
  bool force_blending_with_shaders_;
  SkColor misc_opaque_color_ = 0xffc86464;
};

INSTANTIATE_TEST_CASE_P(B,
                        LayerTreeHostBlendingPixelTest,
                        ::testing::Combine(::testing::Values(SOFTWARE,
                                                             ZERO_COPY),
                                           ::testing::ValuesIn(kBlendModes)));

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRoot) {
  const int kRootWidth = 2;
  const int kRootHeight = 2;
  InitializeFromTestCase(resource_type());

  scoped_refptr<SolidColorLayer> background =
      CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);

  // Orange child layers will blend with the green background
  gfx::Rect child_rect(0, 0, kRootWidth, kRootHeight);
  scoped_refptr<SolidColorLayer> green_lane =
      CreateSolidColorLayer(child_rect, kCSSGreen);
  background->AddChild(green_lane);
  green_lane->SetBlendMode(current_blend_mode());

  SkBitmap expected;
  expected.allocN32Pixels(kRootWidth, kRootHeight);
  SkCanvas canvas(expected);
  canvas.drawColor(kCSSOrange);
  SkPaint paint;
  paint.setBlendMode(current_blend_mode());
  paint.setColor(kCSSGreen);
  canvas.drawRect(SkRect::MakeWH(kRootWidth, kRootHeight), paint);

  RunPixelResourceTest(background, expected);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
  const int kRootWidth = 2;
  const int kRootHeight = 2;
  InitializeFromTestCase(resource_type());

  scoped_refptr<SolidColorLayer> background =
      CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);

  // Orange child layers have a background filter set and they will blend with
  // the green background
  gfx::Rect child_rect(0, 0, kRootWidth, kRootHeight);
  scoped_refptr<SolidColorLayer> green_lane =
      CreateSolidColorLayer(child_rect, kCSSGreen);
  background->AddChild(green_lane);
  FilterOperations filters;
  filters.Append(FilterOperation::CreateGrayscaleFilter(.75));
  green_lane->SetBackgroundFilters(filters);
  green_lane->SetBlendMode(current_blend_mode());

  SkBitmap expected;
  expected.allocN32Pixels(kRootWidth, kRootHeight);
  SkCanvas canvas(expected);
  SkiaPaintCanvas paint_canvas(&canvas);
  PaintFlags grayscale;
  grayscale.setColor(kCSSOrange);

  sk_sp<PaintFilter> paint_filter = RenderSurfaceFilters::BuildImageFilter(
      filters, gfx::SizeF(kRootWidth, kRootHeight));
  grayscale.setImageFilter(paint_filter);
  paint_canvas.drawRect(SkRect::MakeWH(kRootWidth, kRootHeight), grayscale);

  PaintFlags blend_green;
  blend_green.setBlendMode(current_blend_mode());
  blend_green.setColor(kCSSGreen);
  paint_canvas.drawRect(SkRect::MakeWH(kRootWidth, kRootHeight), blend_green);

  RunPixelResourceTest(background, expected);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithTransparent) {
  const int kRootWidth = 2;
  const int kRootHeight = 2;
  InitializeFromTestCase(resource_type());

  // Intermediate layer here that should be ignored because of the isolated
  // group.
  scoped_refptr<SolidColorLayer> root =
      CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSBrown);

  scoped_refptr<SolidColorLayer> background =
      CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange);

  root->AddChild(background);
  background->SetIsRootForIsolatedGroup(true);

  // Orange child layers will blend with the green background
  gfx::Rect child_rect(kRootWidth, kRootHeight);
  scoped_refptr<SolidColorLayer> green_lane =
      CreateSolidColorLayer(child_rect, kCSSGreen);
  background->AddChild(green_lane);
  green_lane->SetBlendMode(current_blend_mode());

  SkBitmap expected;
  expected.allocN32Pixels(kRootWidth, kRootHeight);
  SkCanvas canvas(expected);
  canvas.drawColor(kCSSOrange);
  SkPaint paint;
  paint.setBlendMode(current_blend_mode());
  paint.setColor(kCSSGreen);
  canvas.drawRect(SkRect::MakeWH(kRootWidth, kRootHeight), paint);

  RunPixelResourceTest(root, expected);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass) {
  RunBlendingWithRenderPass(0);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA) {
  RunBlendingWithRenderPass(kUseAntialiasing);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix) {
  RunBlendingWithRenderPass(kUseColorMatrix);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask) {
  RunBlendingWithRenderPass(kUseMasks);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrixAA) {
  RunBlendingWithRenderPass(kUseAntialiasing | kUseColorMatrix);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA) {
  RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing);
}

TEST_P(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassWithMaskColorMatrix) {
  RunBlendingWithRenderPass(kUseMasks | kUseColorMatrix);
}

TEST_P(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassWithMaskColorMatrixAA) {
  RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kUseColorMatrix);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShaders) {
  RunBlendingWithRenderPass(kForceShaders);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA) {
  RunBlendingWithRenderPass(kUseAntialiasing | kForceShaders);
}

TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersWithMask) {
  RunBlendingWithRenderPass(kUseMasks | kForceShaders);
}

TEST_P(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersWithMaskAA) {
  RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kForceShaders);
}

TEST_P(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersColorMatrix) {
  RunBlendingWithRenderPass(kUseColorMatrix | kForceShaders);
}

TEST_P(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersColorMatrixAA) {
  RunBlendingWithRenderPass(kUseAntialiasing | kUseColorMatrix | kForceShaders);
}

TEST_P(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersWithMaskColorMatrix) {
  RunBlendingWithRenderPass(kUseMasks | kUseColorMatrix | kForceShaders);
}

TEST_P(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersWithMaskColorMatrixAA) {
  RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kUseColorMatrix |
                            kForceShaders);
}

}  // namespace
}  // namespace cc

#endif  // OS_ANDROID
