// Copyright 2015 Google Inc. 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) {
  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
