// 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 "base/stl_util.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 = base::size(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_SUITE_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, BlendingWithBackdropFilter) {
  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 backdrop 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));
  gfx::RRectF backdrop_filter_bounds;
  green_lane->SetBackdropFilters(filters);
  green_lane->SetBackdropFilterBounds(backdrop_filter_bounds);
  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
