// 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/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 kBlendModesCount = arraysize(kBlendModes);
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:
  LayerTreeHostBlendingPixelTest()
      : force_antialiasing_(false), force_blending_with_shaders_(false) {
    pixel_comparator_.reset(new FuzzyPixelOffByOneComparator(true));
  }

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

  void RunBlendingWithRootPixelTestType(PixelResourceTestCase type) {
    const int kLaneWidth = 2;
    const int kLaneHeight = kLaneWidth;
    const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
    const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
    InitializeFromTestCase(type);

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

    // Orange child layers will blend with the green background
    for (int i = 0; i < kBlendModesCount; ++i) {
      gfx::Rect child_rect(
          (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
      scoped_refptr<SolidColorLayer> green_lane =
          CreateSolidColorLayer(child_rect, kCSSGreen);
      background->AddChild(green_lane);
      green_lane->SetBlendMode(kBlendModes[i]);
    }

    RunPixelResourceTest(
        background,
        base::FilePath(FILE_PATH_LITERAL("blending_with_root.png")));
  }

  void RunBlendingWithTransparentPixelTestType(PixelResourceTestCase type) {
    const int kLaneWidth = 2;
    const int kLaneHeight = 3 * kLaneWidth;
    const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
    const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
    InitializeFromTestCase(type);

    scoped_refptr<SolidColorLayer> root =
        CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSBrown);

    scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
        gfx::Rect(0, kLaneWidth * 2, kRootWidth, kLaneWidth), kCSSOrange);

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

    // Orange child layers will blend with the green background
    for (int i = 0; i < kBlendModesCount; ++i) {
      gfx::Rect child_rect(
          (i + 1) * kLaneWidth, -kLaneWidth, kLaneWidth, kLaneHeight);
      scoped_refptr<SolidColorLayer> green_lane =
          CreateSolidColorLayer(child_rect, kCSSGreen);
      background->AddChild(green_lane);
      green_lane->SetBlendMode(kBlendModes[i]);
    }

    RunPixelResourceTest(
        root, base::FilePath(FILE_PATH_LITERAL("blending_transparent.png")));
  }

  scoped_refptr<Layer> CreateColorfulBackdropLayer(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);
    }
    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) {
    const int kMaskOffset = 2;
    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);
    canvas->drawRect(SkRect::MakeXYWH(kMaskOffset, kMaskOffset,
                                      bounds.width() - kMaskOffset * 2,
                                      bounds.height() - kMaskOffset * 2),
                     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) {
    const int kLanesCount = kBlendModesCount + 4;
    const SkColor kMiscOpaqueColor = 0xffc86464;
    const SkColor kMiscTransparentColor = 0x80c86464;
    const SkBlendMode kCoeffBlendMode = SkBlendMode::kScreen;
    const SkBlendMode kShaderBlendMode = SkBlendMode::kColorBurn;
    // add vertical lanes with each of the blend modes
    for (int i = 0; i < kLanesCount; ++i) {
      gfx::Rect child_rect(i * lane_width, 0, lane_width, lane_height);
      SkBlendMode blend_mode = SkBlendMode::kSrcOver;
      float opacity = 1.f;
      SkColor color = kMiscOpaqueColor;

      if (i < kBlendModesCount) {
        blend_mode = kBlendModes[i];
      } else if (i == kBlendModesCount) {
        blend_mode = kCoeffBlendMode;
        opacity = 0.5f;
      } else if (i == kBlendModesCount + 1) {
        blend_mode = kCoeffBlendMode;
        color = kMiscTransparentColor;
      } else if (i == kBlendModesCount + 2) {
        blend_mode = kShaderBlendMode;
        opacity = 0.5f;
      } else if (i == kBlendModesCount + 3) {
        blend_mode = kShaderBlendMode;
        color = kMiscTransparentColor;
      }
      scoped_refptr<SolidColorLayer> lane =
          CreateSolidColorLayer(child_rect, color);
      lane->SetBlendMode(blend_mode);
      lane->SetOpacity(opacity);
      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);
    }
  }

  void RunBlendingWithRenderPass(PixelResourceTestCase type,
                                 const base::FilePath::CharType* expected_path,
                                 RenderPassOptions flags) {
    const int kLaneWidth = 8;
    const int kRootWidth = kLaneWidth * (kBlendModesCount + 4);
    const int kRootHeight = kLaneWidth * kCSSTestColorsCount;
    InitializeFromTestCase(type);

    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(kLaneWidth, kRootHeight, background.get(), flags);

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

    if ((flags & kUseAntialiasing) && (test_type_ == PIXEL_TEST_GL)) {
      // Anti aliasing causes differences up to 8 pixels at the edges.
      int large_error_allowed = 8;
      // Blending results might differ with one pixel.
      int small_error_allowed = 1;
      // Most of the errors are one pixel errors.
      float percentage_pixels_small_error = 13.2f;
      // Because of anti-aliasing, around 10% of pixels (at the edges) have
      // bigger errors (from small_error_allowed + 1 to large_error_allowed).
      float percentage_pixels_error = 22.5f;
      // 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, base::FilePath(expected_path));
  }

  bool force_antialiasing_;
  bool force_blending_with_shaders_;
};

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_GL) {
  RunBlendingWithRootPixelTestType(ZERO_COPY);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRoot_Software) {
  RunBlendingWithRootPixelTestType(SOFTWARE);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithBackgroundFilter) {
  const int kLaneWidth = 2;
  const int kLaneHeight = kLaneWidth;
  const int kRootWidth = (kBlendModesCount + 2) * kLaneWidth;
  const int kRootHeight = 2 * kLaneWidth + kLaneHeight;
  InitializeFromTestCase(ZERO_COPY);

  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
  for (int i = 0; i < kBlendModesCount; ++i) {
    gfx::Rect child_rect(
        (i + 1) * kLaneWidth, kLaneWidth, kLaneWidth, kLaneHeight);
    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(kBlendModes[i]);
  }

  RunPixelResourceTest(
      background, base::FilePath(FILE_PATH_LITERAL("blending_and_filter.png")));
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_GL) {
  RunBlendingWithTransparentPixelTestType(ZERO_COPY);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithTransparent_Software) {
  RunBlendingWithTransparentPixelTestType(SOFTWARE);
}

// Tests for render passes
TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass.png"), 0);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPass_Software) {
  RunBlendingWithRenderPass(SOFTWARE,
                            FILE_PATH_LITERAL("blending_render_pass.png"), 0);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass.png"),
                            kUseAntialiasing);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassAA_Software) {
  RunBlendingWithRenderPass(SOFTWARE,
                            FILE_PATH_LITERAL("blending_render_pass.png"),
                            kUseAntialiasing);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMask_GL) {
  RunBlendingWithRenderPass(
      ZERO_COPY, FILE_PATH_LITERAL("blending_render_pass_mask.png"), kUseMasks);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassWithMask_Software) {
  RunBlendingWithRenderPass(
      SOFTWARE, FILE_PATH_LITERAL("blending_render_pass_mask.png"), kUseMasks);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassWithMaskAA_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kUseAntialiasing);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassWithMaskAA_Software) {
  RunBlendingWithRenderPass(SOFTWARE,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kUseAntialiasing);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrix_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass.png"),
                            kUseColorMatrix);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassColorMatrix_Software) {
  RunBlendingWithRenderPass(
      SOFTWARE, FILE_PATH_LITERAL("blending_render_pass.png"), kUseColorMatrix);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassColorMatrixAA_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass.png"),
                            kUseAntialiasing | kUseColorMatrix);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassColorMatrixAA_Software) {
  RunBlendingWithRenderPass(SOFTWARE,
                            FILE_PATH_LITERAL("blending_render_pass.png"),
                            kUseAntialiasing | kUseColorMatrix);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassWithMaskColorMatrix_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kUseColorMatrix);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassWithMaskColorMatrix_Software) {
  RunBlendingWithRenderPass(SOFTWARE,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kUseColorMatrix);
}

// Often times out on Windows 10. See: https://crbug.com/870236.
#if defined(OS_WIN)
#define MAYBE_BlendingWithRenderPassWithMaskColorMatrixAA_GL \
  DISABLED_BlendingWithRenderPassWithMaskColorMatrixAA_GL
#else
#define MAYBE_BlendingWithRenderPassWithMaskColorMatrixAA_GL \
  BlendingWithRenderPassWithMaskColorMatrixAA_GL
#endif
TEST_F(LayerTreeHostBlendingPixelTest,
       MAYBE_BlendingWithRenderPassWithMaskColorMatrixAA_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kUseAntialiasing | kUseColorMatrix);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassWithMaskColorMatrixAA_Software) {
  RunBlendingWithRenderPass(SOFTWARE,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kUseAntialiasing | kUseColorMatrix);
}

// Tests for render passes forcing shaders for all the blend modes.
TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShaders_GL) {
  RunBlendingWithRenderPass(
      ZERO_COPY, FILE_PATH_LITERAL("blending_render_pass.png"), kForceShaders);
}

TEST_F(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass.png"),
                            kUseAntialiasing | kForceShaders);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersWithMask_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kForceShaders);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersWithMask_GL_TextureRect) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kForceShaders);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersWithMaskAA_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kUseAntialiasing | kForceShaders);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersWithMaskAA_GL_TextureRect) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kUseAntialiasing | kForceShaders);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersColorMatrix_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass.png"),
                            kUseColorMatrix | kForceShaders);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersColorMatrixAA_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass.png"),
                            kUseAntialiasing | kUseColorMatrix | kForceShaders);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersWithMaskColorMatrix_GL) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kUseColorMatrix | kForceShaders);
}

TEST_F(LayerTreeHostBlendingPixelTest,
       BlendingWithRenderPassShadersWithMaskColorMatrix_GL_TextureRect) {
  RunBlendingWithRenderPass(ZERO_COPY,
                            FILE_PATH_LITERAL("blending_render_pass_mask.png"),
                            kUseMasks | kUseColorMatrix | kForceShaders);
}

// Often times out on Windows 10. See: https://crbug.com/870236.
#if defined(OS_WIN)
#define MAYBE_BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL \
  DISABLED_BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL
#else
#define MAYBE_BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL \
  BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL
#endif
TEST_F(LayerTreeHostBlendingPixelTest,
       MAYBE_BlendingWithRenderPassShadersWithMaskColorMatrixAA_GL) {
  RunBlendingWithRenderPass(
      ZERO_COPY, FILE_PATH_LITERAL("blending_render_pass_mask.png"),
      kUseMasks | kUseAntialiasing | kUseColorMatrix | kForceShaders);
}

}  // namespace
}  // namespace cc

#endif  // OS_ANDROID
