// Copyright (c) 2010 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/memory/shared_memory.h"
#include "build/build_config.h"
#include "skia/ext/platform_canvas.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/blit.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/rect.h"

namespace {

// Fills the given canvas with the values by duplicating the values into each
// color channel for the corresponding pixel.
//
// Example values = {{0x0, 0x01}, {0x12, 0xFF}} would give a canvas with:
//   0x00000000 0x01010101
//   0x12121212 0xFFFFFFFF
template <int w, int h>
void SetToCanvas(SkCanvas* canvas, uint8_t values[h][w]) {
  ASSERT_EQ(w, canvas->imageInfo().width());
  ASSERT_EQ(h, canvas->imageInfo().height());

  // This wouldn't be necessary if we extended the values in the inputs, but
  // the uint8_t values are a little bit easier to read and maintain.
  uint32_t extendedValues[w*h];
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      uint8_t value = values[y][x];
      extendedValues[y*w+x] =
          (value << 24) | (value << 16) | (value << 8) | value;
    }
  }

  SkImageInfo info = SkImageInfo::MakeN32Premul(w, h);
  canvas->writePixels(info, extendedValues, w*4, 0, 0);
}

// Checks each pixel in the given canvas and see if it is made up of the given
// values, where each value has been duplicated into each channel of the given
// bitmap (see SetToCanvas above).
template <int w, int h>
void VerifyCanvasValues(SkCanvas* canvas, uint8_t values[h][w]) {
  SkBitmap bitmap = skia::ReadPixels(canvas);
  SkAutoLockPixels lock(bitmap);
  ASSERT_EQ(w, bitmap.width());
  ASSERT_EQ(h, bitmap.height());

  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      uint8_t value = values[y][x];
      uint32_t expected = (value << 24) | (value << 16) | (value << 8) | value;
      ASSERT_EQ(expected, *bitmap.getAddr32(x, y));
    }
  }
}

}  // namespace

TEST(Blit, ScrollCanvas) {
  static const int kCanvasWidth = 5;
  static const int kCanvasHeight = 5;
  sk_sp<SkCanvas> canvas(
      skia::CreatePlatformCanvas(kCanvasWidth, kCanvasHeight, true));
  uint8_t initial_values[kCanvasHeight][kCanvasWidth] = {
      {0x00, 0x01, 0x02, 0x03, 0x04},
      {0x10, 0x11, 0x12, 0x13, 0x14},
      {0x20, 0x21, 0x22, 0x23, 0x24},
      {0x30, 0x31, 0x32, 0x33, 0x34},
      {0x40, 0x41, 0x42, 0x43, 0x44}};
  SetToCanvas<5, 5>(canvas.get(), initial_values);

  // Sanity check on input.
  VerifyCanvasValues<5, 5>(canvas.get(), initial_values);

  // Scroll none and make sure it's a NOP.
  gfx::ScrollCanvas(canvas.get(),
                    gfx::Rect(0, 0, kCanvasWidth, kCanvasHeight),
                    gfx::Vector2d(0, 0));
  VerifyCanvasValues<5, 5>(canvas.get(), initial_values);

  // Scroll with a empty clip and make sure it's a NOP.
  gfx::Rect empty_clip(1, 1, 0, 0);
  gfx::ScrollCanvas(canvas.get(), empty_clip, gfx::Vector2d(0, 1));
  VerifyCanvasValues<5, 5>(canvas.get(), initial_values);

  // Scroll the center 3 pixels up one.
  gfx::Rect center_three(1, 1, 3, 3);
  gfx::ScrollCanvas(canvas.get(), center_three, gfx::Vector2d(0, -1));
  uint8_t scroll_up_expected[kCanvasHeight][kCanvasWidth] = {
      {0x00, 0x01, 0x02, 0x03, 0x04},
      {0x10, 0x21, 0x22, 0x23, 0x14},
      {0x20, 0x31, 0x32, 0x33, 0x24},
      {0x30, 0x31, 0x32, 0x33, 0x34},
      {0x40, 0x41, 0x42, 0x43, 0x44}};
  VerifyCanvasValues<5, 5>(canvas.get(), scroll_up_expected);

  // Reset and scroll the center 3 pixels down one.
  SetToCanvas<5, 5>(canvas.get(), initial_values);
  gfx::ScrollCanvas(canvas.get(), center_three, gfx::Vector2d(0, 1));
  uint8_t scroll_down_expected[kCanvasHeight][kCanvasWidth] = {
      {0x00, 0x01, 0x02, 0x03, 0x04},
      {0x10, 0x11, 0x12, 0x13, 0x14},
      {0x20, 0x11, 0x12, 0x13, 0x24},
      {0x30, 0x21, 0x22, 0x23, 0x34},
      {0x40, 0x41, 0x42, 0x43, 0x44}};
  VerifyCanvasValues<5, 5>(canvas.get(), scroll_down_expected);

  // Reset and scroll the center 3 pixels right one.
  SetToCanvas<5, 5>(canvas.get(), initial_values);
  gfx::ScrollCanvas(canvas.get(), center_three, gfx::Vector2d(1, 0));
  uint8_t scroll_right_expected[kCanvasHeight][kCanvasWidth] = {
      {0x00, 0x01, 0x02, 0x03, 0x04},
      {0x10, 0x11, 0x11, 0x12, 0x14},
      {0x20, 0x21, 0x21, 0x22, 0x24},
      {0x30, 0x31, 0x31, 0x32, 0x34},
      {0x40, 0x41, 0x42, 0x43, 0x44}};
  VerifyCanvasValues<5, 5>(canvas.get(), scroll_right_expected);

  // Reset and scroll the center 3 pixels left one.
  SetToCanvas<5, 5>(canvas.get(), initial_values);
  gfx::ScrollCanvas(canvas.get(), center_three, gfx::Vector2d(-1, 0));
  uint8_t scroll_left_expected[kCanvasHeight][kCanvasWidth] = {
      {0x00, 0x01, 0x02, 0x03, 0x04},
      {0x10, 0x12, 0x13, 0x13, 0x14},
      {0x20, 0x22, 0x23, 0x23, 0x24},
      {0x30, 0x32, 0x33, 0x33, 0x34},
      {0x40, 0x41, 0x42, 0x43, 0x44}};
  VerifyCanvasValues<5, 5>(canvas.get(), scroll_left_expected);

  // Diagonal scroll.
  SetToCanvas<5, 5>(canvas.get(), initial_values);
  gfx::ScrollCanvas(canvas.get(), center_three, gfx::Vector2d(2, 2));
  uint8_t scroll_diagonal_expected[kCanvasHeight][kCanvasWidth] = {
      {0x00, 0x01, 0x02, 0x03, 0x04},
      {0x10, 0x11, 0x12, 0x13, 0x14},
      {0x20, 0x21, 0x22, 0x23, 0x24},
      {0x30, 0x31, 0x32, 0x11, 0x34},
      {0x40, 0x41, 0x42, 0x43, 0x44}};
  VerifyCanvasValues<5, 5>(canvas.get(), scroll_diagonal_expected);
}

#if defined(OS_WIN)

TEST(Blit, WithSharedMemory) {
  const int kCanvasWidth = 5;
  const int kCanvasHeight = 5;
  base::SharedMemory shared_mem;
  ASSERT_TRUE(shared_mem.CreateAnonymous(kCanvasWidth * kCanvasHeight));
  base::SharedMemoryHandle section = shared_mem.handle();
  sk_sp<SkCanvas> canvas(skia::CreatePlatformCanvas(
      kCanvasWidth, kCanvasHeight, true, section.GetHandle(),
      skia::RETURN_NULL_ON_FAILURE));
  ASSERT_TRUE(canvas);
  shared_mem.Close();

  uint8_t initial_values[kCanvasHeight][kCanvasWidth] = {
      {0x00, 0x01, 0x02, 0x03, 0x04},
      {0x10, 0x11, 0x12, 0x13, 0x14},
      {0x20, 0x21, 0x22, 0x23, 0x24},
      {0x30, 0x31, 0x32, 0x33, 0x34},
      {0x40, 0x41, 0x42, 0x43, 0x44}};
  SetToCanvas<5, 5>(canvas.get(), initial_values);

  // Sanity check on input.
  VerifyCanvasValues<5, 5>(canvas.get(), initial_values);
}

#endif

