// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/renderer/render_tree_pixel_tester.h"

#include <algorithm>
#include <string>

#include "base/file_path.h"
#include "base/file_util.h"
#include "cobalt/renderer/backend/default_graphics_system.h"
#include "cobalt/renderer/backend/graphics_context.h"
#include "cobalt/renderer/backend/graphics_system.h"
#include "cobalt/renderer/backend/render_target.h"
#include "cobalt/renderer/rasterizer/rasterizer.h"
#include "cobalt/renderer/renderer_module.h"
#include "cobalt/renderer/test/png_utils/png_decode.h"
#include "cobalt/renderer/test/png_utils/png_encode.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPixelRef.h"
#include "third_party/skia/include/effects/SkBlurImageFilter.h"

// Avoid overriding of Windows' CreateDirectory macro.
#undef CreateDirectory

using cobalt::render_tree::ResourceProvider;
using cobalt::renderer::backend::GraphicsContext;
using cobalt::renderer::backend::GraphicsSystem;
using cobalt::renderer::backend::RenderTarget;
using cobalt::renderer::test::png_utils::DecodePNGToRGBA;
using cobalt::renderer::test::png_utils::EncodeRGBAToPNG;

namespace cobalt {
namespace renderer {

RenderTreePixelTester::Options::Options()
    : gaussian_blur_sigma(6.2f),
      acceptable_channel_range(0.08f),
      output_failed_test_details(false),
      output_all_test_details(false) {}

RenderTreePixelTester::RenderTreePixelTester(
    const math::Size& test_surface_dimensions,
    const FilePath& expected_results_directory,
    const FilePath& output_directory, const Options& options)
    : expected_results_directory_(expected_results_directory),
      output_directory_(output_directory),
      options_(options) {
  graphics_system_ = cobalt::renderer::backend::CreateDefaultGraphicsSystem();
  graphics_context_ = graphics_system_->CreateGraphicsContext();

  // Create our offscreen surface that will be the target of our test
  // rasterizations.
  test_surface_ =
      graphics_context_->CreateDownloadableOffscreenRenderTarget(
          test_surface_dimensions);

  // Create the rasterizer using the platform default RenderModule options.
  RendererModule::Options render_module_options;

  // Don't purge the Skia font caches on destruction. Doing so will result in
  // too much font thrashing during the tests.
  render_module_options.purge_skia_font_caches_on_destruction = false;

  rasterizer_ = render_module_options.create_rasterizer_function.Run(
      graphics_context_.get(), render_module_options);
}

RenderTreePixelTester::~RenderTreePixelTester() {}

ResourceProvider* RenderTreePixelTester::GetResourceProvider() const {
  return rasterizer_->GetResourceProvider();
}

namespace {

// Convenience function that will modify a base file path (without an
// extension) to include a postfix and an extension.
// e.g. ModifyBaseFileName("output/tests/my_test", "-expected", "png")
//      will return "output/tests/my_test-expected.png".
FilePath ModifyBaseFileName(const FilePath& base_file_name,
                            const std::string& postfix,
                            const std::string& extension) {
  return base_file_name.InsertBeforeExtension(postfix).AddExtension(extension);
}

// This utility function will take a SkBitmap and perform a Gaussian blur on
// it, returning a new, blurred SkBitmap.  The sigma parameter defines how
// strong the blur should be.
SkBitmap BlurBitmap(const SkBitmap& bitmap, float sigma) {
  SkBitmap premul_alpha_bitmap;
  if (bitmap.info().colorType() == kN32_SkColorType &&
      bitmap.info().alphaType() == kPremul_SkAlphaType) {
    premul_alpha_bitmap = bitmap;
  } else {
    // We need to convert our image to premultiplied alpha and N32 color
    // before proceeding to blur them, as Skia is designed to primarily deal
    // only with images in this format.
    SkImageInfo premul_alpha_image_info =
        SkImageInfo::MakeN32Premul(bitmap.width(), bitmap.height());
    bool allocation_successful =
        premul_alpha_bitmap.tryAllocPixels(premul_alpha_image_info);
    // Since this is a test, just crash.
    DCHECK(allocation_successful);
    bitmap.readPixels(premul_alpha_image_info, premul_alpha_bitmap.getPixels(),
                      premul_alpha_bitmap.rowBytes(), 0, 0);
  }
  SkBitmap blurred_bitmap;
  bool blurred_bitmap_allocated =
      blurred_bitmap.tryAllocN32Pixels(bitmap.width(), bitmap.height());
  DCHECK(blurred_bitmap_allocated);

  SkPaint paint;
  sk_sp<SkImageFilter> blur_filter(
      SkBlurImageFilter::Make(sigma, sigma, nullptr));
  paint.setImageFilter(blur_filter);

  SkCanvas canvas(blurred_bitmap);
  canvas.clear(SkColorSetARGB(0, 0, 0, 0));
  canvas.drawBitmap(premul_alpha_bitmap, 0, 0, &paint);

  return blurred_bitmap;
}

bool BitmapsAreEqual(const SkBitmap& bitmap_a, const SkBitmap& bitmap_b) {
  if (bitmap_a.height() != bitmap_b.height() ||
      bitmap_a.rowBytes() != bitmap_b.rowBytes()) {
    return false;
  }

  // Do not need to lock pixels here.  See:
  // https://bugs.chromium.org/p/skia/issues/detail?id=6481&desc=2
  void* pixels_a = reinterpret_cast<void*>(bitmap_a.getPixels());
  void* pixels_b = reinterpret_cast<void*>(bitmap_b.getPixels());
  size_t byte_count = bitmap_a.rowBytes() * bitmap_a.height();
  return memcmp(pixels_a, pixels_b, byte_count) == 0;
}

// Compares bitmap_a with bitmap_b, where the comparison is done by checking
// each pixel to see if any one of its color channel values differ between
// bitmap_a to bitmap_b by more than acceptable_channel_range.  If so,
// number_of_diff_pixels is incremented and the corresponding pixel in the
// returned diff SkBitmap is set to white with full alpha.  If the pixel color
// channel values are not found to differ significantly, the corresponding
// pixel in the returned diff SkBitmap is set to black with no alpha.
SkBitmap DiffBitmaps(const SkBitmap& bitmap_a, const SkBitmap& bitmap_b,
                     int acceptable_channel_range, int* number_of_diff_pixels) {
  // Construct a diff bitmap where we can place the results of our diff,
  // allowing us to mark which pixels differ between bitmap_a and bitmap_b.
  SkBitmap bitmap_diff;
  bitmap_diff.allocPixels(SkImageInfo::Make(bitmap_a.width(), bitmap_a.height(),
                                            kRGBA_8888_SkColorType,
                                            kUnpremul_SkAlphaType));

  // Initialize the number of pixels that we have found to differ significantly
  // from bitmap_a to bitmap_b to 0.
  *number_of_diff_pixels = 0;
  // Start checking for pixel differences row by row.
  for (int r = 0; r < bitmap_a.height(); ++r) {
    const uint8_t* pixels_a =
        static_cast<uint8_t*>(bitmap_a.pixelRef()->pixels()) +
        bitmap_a.rowBytes() * r;
    const uint8_t* pixels_b =
        static_cast<uint8_t*>(bitmap_b.pixelRef()->pixels()) +
        bitmap_b.rowBytes() * r;
    // Since the diff image will be set to either all black or all white, we
    // reference its pixels with a uint32_t since it simplifies writing to it.
    uint32_t* pixels_diff =
        static_cast<uint32_t*>(bitmap_diff.pixelRef()->pixels()) +
        bitmap_diff.rowBytes() * r / sizeof(uint32_t);
    for (int c = 0; c < bitmap_a.width(); ++c) {
      // Check each pixel in the current row for differences.  We do this by
      // looking at each color channel separately and taking the max of the
      // differences we see in each channel.
      int max_diff = 0;
      for (int i = 0; i < 4; ++i) {
        max_diff = std::max(max_diff, std::abs(pixels_a[i] - pixels_b[i]));
      }

      // If the maximum color channel difference is larger than the acceptable
      // error range, we count one diff pixel and adjust the diff SkBitmap
      // accordingly.
      if (max_diff > acceptable_channel_range) {
        ++*number_of_diff_pixels;
        // Set the diff image pixel to all white with full alpha.
        *pixels_diff = 0xFF0000FF;
      } else {
        // Set the diff image pixel to all black with no alpha.
        *pixels_diff = 0x00000000;
      }

      // Get ready for the next pixel in the row.
      pixels_a += 4;
      pixels_b += 4;
      pixels_diff += 1;
    }
  }

  return bitmap_diff;
}

// Helper function to simplify the process of encoding a Skia RGBA8 SkBitmap
// object to a PNG file.
void EncodeSkBitmapToPNG(const FilePath& output_file, const SkBitmap& bitmap) {
  DLOG(INFO) << "Writing " << output_file.value();
  if (bitmap.info().alphaType() == kUnpremul_SkAlphaType &&
      bitmap.info().colorType() == kRGBA_8888_SkColorType) {
    // No conversion needed here, simply write out the pixels as is.
    EncodeRGBAToPNG(output_file,
                    static_cast<uint8_t*>(bitmap.pixelRef()->pixels()),
                    bitmap.width(), bitmap.height(), bitmap.rowBytes());
  } else {
    // First convert the pixels to the proper format and then output them.
    SkImageInfo output_image_info =
        SkImageInfo::Make(bitmap.width(), bitmap.height(),
                          kRGBA_8888_SkColorType, kUnpremul_SkAlphaType);
    scoped_array<uint8_t> pixels(
        new uint8_t[output_image_info.minRowBytes() * bitmap.height()]);

    // Reformat and copy the pixel data into our fresh pixel buffer.
    bitmap.readPixels(output_image_info, pixels.get(),
                      output_image_info.minRowBytes(), 0, 0);

    // Write the pixels out to disk.
    EncodeRGBAToPNG(output_file, pixels.get(), bitmap.width(), bitmap.height(),
                    output_image_info.minRowBytes());
  }
}

// Given a chunk of memory formatted as RGBA8 with pitch = width * 4, this
// function will wrap that memory in a SkBitmap that does *not* own the
// pixels and return that.
const SkBitmap CreateBitmapFromRGBAPixels(const math::SizeF& dimensions,
                                          const uint8_t* pixels) {
  const int kRGBABytesPerPixel = 4;
  SkBitmap bitmap;
  bitmap.installPixels(
      SkImageInfo::Make(dimensions.width(), dimensions.height(),
                        kRGBA_8888_SkColorType, kUnpremul_SkAlphaType),
      const_cast<uint8_t*>(pixels), dimensions.width() * kRGBABytesPerPixel);
  return bitmap;
}

bool TestActualAgainstExpectedBitmap(float gaussian_blur_sigma,
                                     float acceptable_channel_range,
                                     const SkBitmap& expected_bitmap,
                                     const SkBitmap& actual_bitmap,
                                     const FilePath& output_base_filename,
                                     bool output_failed_test_details,
                                     bool output_all_test_details) {
  DCHECK_EQ(kRGBA_8888_SkColorType, expected_bitmap.colorType());
  DCHECK_EQ(kRGBA_8888_SkColorType, actual_bitmap.colorType());

  // We can try an exact comparison if we don't need to dump out the
  // diff and blur images.
  bool quick_test_ok = !output_failed_test_details && !output_all_test_details;

  if (quick_test_ok && BitmapsAreEqual(expected_bitmap, actual_bitmap)) {
    return true;
  }

  // We first blur both the actual and expected bitmaps before testing them.
  // This is done to permit small 1 or 2 pixel translation differences in the
  // images.  If these small differences are not acceptable, the blur amount
  // specified by gaussian_blur_sigma should be lowered to make the tests
  // stricter.
  SkBitmap blurred_actual_bitmap =
      BlurBitmap(actual_bitmap, gaussian_blur_sigma);
  SkBitmap blurred_expected_bitmap =
      BlurBitmap(expected_bitmap, gaussian_blur_sigma);

  // Diff the blurred actual image with the blurred expected image and
  // count how many pixels are out of range.
  int number_of_diff_pixels = 0;
  SkBitmap diff_image =
      DiffBitmaps(blurred_expected_bitmap, blurred_actual_bitmap,
                  acceptable_channel_range * 255, &number_of_diff_pixels);

  // If the user has requested it via command-line flags, we can also output
  // the images that were used by this test to help debug any problems.
  if (output_all_test_details ||
      (number_of_diff_pixels > 0 && output_failed_test_details)) {
    file_util::CreateDirectory(output_base_filename.DirName());

    EncodeSkBitmapToPNG(
        ModifyBaseFileName(output_base_filename, "-actual", "png"),
        actual_bitmap);
    EncodeSkBitmapToPNG(
        ModifyBaseFileName(output_base_filename, "-expected", "png"),
        expected_bitmap);
    EncodeSkBitmapToPNG(
        ModifyBaseFileName(output_base_filename, "-actual-blurred", "png"),
        blurred_actual_bitmap);
    EncodeSkBitmapToPNG(
        ModifyBaseFileName(output_base_filename, "-expected-blurred", "png"),
        blurred_expected_bitmap);
    EncodeSkBitmapToPNG(
        ModifyBaseFileName(output_base_filename, "-diff", "png"), diff_image);
  }

  // Execute the main check for this rasterizer test:  Are all pixels
  // in the generated image in the given range of the expected image
  // pixels.
  return number_of_diff_pixels == 0;
}
}  // namespace

scoped_array<uint8_t> RenderTreePixelTester::RasterizeRenderTree(
    const scoped_refptr<cobalt::render_tree::Node>& tree) const {
  // Rasterize the test render tree to the rasterizer's offscreen render target.
  rasterizer::Rasterizer::Options rasterizer_options;
  rasterizer_options.flags = rasterizer::Rasterizer::kSubmitFlags_Clear;
  rasterizer_->Submit(tree, test_surface_, rasterizer_options);

  // Load the texture's pixel data into a CPU memory buffer and return it.
  return graphics_context_->DownloadPixelDataAsRGBA(test_surface_);
}

void RenderTreePixelTester::Rebaseline(
    const scoped_refptr<cobalt::render_tree::Node>& test_tree,
    const FilePath& expected_base_filename) const {
  scoped_array<uint8_t> test_image_pixels = RasterizeRenderTree(test_tree);

  // Wrap the generated image's raw RGBA8 pixel data in a SkBitmap so that
  // we can manipulate it using Skia.
  const SkBitmap actual_bitmap = CreateBitmapFromRGBAPixels(
      test_surface_->GetSize(), test_image_pixels.get());

  FilePath output_base_filename(
      output_directory_.Append(expected_base_filename));

  // Create the output directory if it doesn't already exist.
  file_util::CreateDirectory(output_base_filename.DirName());

  // If the 'rebase' flag is set, we should not run any actual tests but
  // instead output the results of our tests so that they can be used as
  // expected output for subsequent tests.
  EncodeSkBitmapToPNG(
      ModifyBaseFileName(output_base_filename, "-expected", "png"),
      actual_bitmap);
}

bool RenderTreePixelTester::TestTree(
    const scoped_refptr<cobalt::render_tree::Node>& test_tree,
    const FilePath& expected_base_filename) const {
  scoped_array<uint8_t> test_image_pixels = RasterizeRenderTree(test_tree);

  // Wrap the generated image's raw RGBA8 pixel data in a SkBitmap so that
  // we can manipulate it using Skia.
  const SkBitmap actual_bitmap = CreateBitmapFromRGBAPixels(
      test_surface_->GetSize(), test_image_pixels.get());

  // Here we proceed with the the pixel tests.  We must first load the
  // expected output image from disk and use that to compare against
  // the synthesized image.
  int expected_width;
  int expected_height;
  FilePath expected_output_file = expected_results_directory_.Append(
      ModifyBaseFileName(expected_base_filename, "-expected", "png"));
  if (!file_util::PathExists(expected_output_file)) {
    DLOG(WARNING) << "Expected pixel test output file \""
                  << expected_output_file.value() << "\" cannot be found.";
    // If the expected output file does not exist, we cannot continue, so
    // return in failure.
    return false;
  }
  scoped_array<uint8_t> expected_image_pixels =
      DecodePNGToRGBA(expected_output_file, &expected_width, &expected_height);

  DCHECK_EQ(test_surface_->GetSize().width(), expected_width);
  DCHECK_EQ(test_surface_->GetSize().height(), expected_height);

  // We then wrap the expected image in a SkBitmap so that we can manipulate
  // it with Skia.
  const SkBitmap expected_bitmap = CreateBitmapFromRGBAPixels(
      test_surface_->GetSize(), expected_image_pixels.get());

  // Finally we perform the actual pixel tests on the bitmap given the
  // actual and expected bitmaps.  If it is requested that test details
  // be output, then this function call may have the side effect of generating
  // these details as output files.
  return TestActualAgainstExpectedBitmap(
      options_.gaussian_blur_sigma, options_.acceptable_channel_range,
      expected_bitmap, actual_bitmap,
      output_directory_.Append(expected_base_filename),
      options_.output_failed_test_details, options_.output_all_test_details);
}

}  // namespace renderer
}  // namespace cobalt
